Documentation / Core concepts / Architecture
Architecture: product choices above, runtime mechanics below¶
VAANI is a deep runtime boundary, not a prebuilt assistant. A consumer supplies the complete bot definition; VAANI runs it consistently across supported adapters.
The current API favors explicit, frozen construction over convenience builders.
It also stops at LiveKitCallHandoff: deployments still need a worker/room
bridge that emits normalized events and plays returned frames. That bridge is
not yet a turnkey component in the VAANI package.
flowchart TB
subgraph Consumer["Consumer voicebot"]
UI["Frontend and deployment composition"]
PROMPT["Prompts, persona, and languages"]
DOMAIN["Tools, business rules, and state"]
ROUTES["Providers, models, voices, fallbacks"]
POLICY["Conversation, transfer, recording, result policy"]
end
subgraph VAANI["VAANI reusable runtime"]
SETUP["Typed setup and preflight"]
LIFE["Lifecycle, deadlines, and interaction gate"]
ADAPTERS["Provider-neutral adapter coordination"]
RESULT["Evidence and exactly one CallResult"]
end
subgraph Infrastructure["Deployment infrastructure"]
LK["Already-routed LiveKit call"]
PROVIDERS["Speech and reasoning providers"]
SINKS["GCS / PostgreSQL"]
end
UI --> SETUP
PROMPT --> SETUP
DOMAIN --> SETUP
ROUTES --> SETUP
POLICY --> SETUP
SETUP --> LIFE --> ADAPTERS --> RESULT
LK <--> ADAPTERS
PROVIDERS <--> ADAPTERS
RESULT --> SINKS
The boundary in practice¶
Suppose a product team wants to:
- change the assistant from formal English to concise Hinglish;
- add
lookup_product_catalog; - move reasoning from an approved Google route to an approved OpenRouter route;
- use a different TTS voice; or
- compose a new operator-facing frontend.
Those are consumer changes. The team edits its prompt builder, tool module, profile/configuration, or frontend. VAANI still performs the same work: preflight, acquire resources, wait for readiness, deliver turns, enforce deadlines, coordinate ending, release resources, and publish one result.
Telephony boundary¶
VAANI 1.0 accepts an already-routed LiveKit job and room. The deployment owns
numbers, trunks, SIP credentials, routing, and dispatch. A transport adapter
normalizes approved LiveKit attributes into TelephonyIdentity; VAANI does not
infer identity from room naming or call a telephony vendor to discover it.
This matters operationally: the consumer can change its SIP carrier or inbound routing without changing the call result model, while VAANI can improve lifecycle correctness without taking ownership of carrier provisioning.
The proven external Vertex module does not close this gap: its live command
validates required environment names and reports connected: false. Its
credential-free call is the actual end-to-end runtime proof; no live connection
success is claimed.
Adapters are capabilities, not policy¶
Adapters translate provider operations, usage, errors, and transport signals. Their manifests declare what they can do. They do not choose:
- which model is appropriate;
- whether a fallback is acceptable;
- what wording to use;
- whether a tool action is allowed;
- where a blind transfer should go; or
- whether recording is legally permitted.
Those decisions must already be explicit in the consumer's setup.
Results are evidence, not your CRM record¶
CallResult is the immutable provider-neutral evidence for one call attempt.
It is intentionally not a business disposition or mutable analytics row.
Consumers map it into their own reporting schemas after Closure. Publication
failure cannot change the call's outcome.
Next: understand setup and profiles or follow the lifecycle.