Skip to content

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.