One customer turn goes in as STT text. A fixed cascade of layers tries to answer it, cheapest and most deterministic first. Pre-synthesised audio clips come out. The LLM is the last layer tried, and even then it can only pick from options the code built. Watch a sample call run through it just below.
Below is a real workflow, the Bank KYC template, playing out turn by turn. As the customer speaks, their words stream out of STT, drop into the layer cascade, change shape as layers normalise them, and stop at the layer that answers. You can see when a turn reaches the LLM, when a reply needs live TTS, how the flow moves forward, and how the call clock and cost add up. Everything after this section explains what you just watched.
Press play to start the call.
This is an illustrative replay based on the Bank KYC template and how the engine behaves; it is not a recording of a real call. The layer order matches the engine's real dispatch order. Timings are typical ranges: 600 ms endpointing gap, L4 shortlist embeddings 600–700 ms, chat 800–900 ms, Sarvam live TTS 430–620 ms. Costs are estimates at ₹88/$: gpt-4o-mini about ₹0.046 per L4 call, Sarvam about ₹3.5 per 1,000 characters. STT cost isn't included. "Saved" is measured against an LLM-first agent that makes one L4 call on every customer turn (≈₹0.047, ≈1.5 s) and synthesises every line with live TTS (≈0.45 s each). All rupee figures are illustrative estimates of third-party provider spend for this one sample call, not VARTA pricing.
Cheap rule-based layers decide first. L4 runs only when they can't, and it must answer in structured JSON or pick from a list.
The engine contains no language-specific strings or checks. Every per-language line, keyword and number word is workflow data written by DAKSH.
Pre-built clips cost ₹0 and play in about 0 ms. Live TTS is only a fallback. Filler clips cover the wait when L4 runs.
A layer that can't decide re-asks or passes the turn down. An LLM answer that doesn't validate triggers a re-ask; it never moves the call forward.
At call time, every reasoning call is costed onto that call's record. At build time, every generation step is costed onto the workflow it built.
Starting the server never triggers LLM work. Warm-up reads caches only, so nobody pays for work they didn't ask for.
Browser tests, live SIP calls and the benchmark simulator all end up in the same turn engine. The difference is only how speech becomes text before that point, so a fix to the engine reaches every transport at once.
Each layer is named in Hindi after what it does in a conversation. The name column gives the code name, then the Hindi word, then its English meaning.
| Layer | Name (Hindi) (English meaning) | Purpose | Description |
|---|---|---|---|
| Core layers | |||
| L1 | DHADKAN (धड़कन) (Heartbeat) | Instant reflexes | Matches the utterance against a compiled regex cache of yes / no / wait / repeat / bye / handoff phrases. The phrases are generated per language by DAKSH, and the cache includes phonetic variants. The fallback yes/no matches whole words only, so "hmm what" is not a yes. It also runs the confirm gate (L1 CONFIRM), which takes "haan, sahi hai" after a readback. No LLM, microseconds. |
| L2 | PEHCHAAN (पहचान) (Recognition) | Work out what the customer said and which step it belongs to | Cleans up STT text first: spoken numbers and letters, filler words. Then it pulls out entities such as phone numbers, dates, pincodes and codes from anywhere in the sentence, and matches the utterance to a step. If the match is confident (≥ 50) and the value validates, it can jump ahead. It won't jump while a confirmation or re-ask is pending. |
| L3 | MAARG (मार्ग) (Path) | Choose the branch | A pure function over the step's authored branches, matching keywords, digit counts and regex. It returns advance, ambiguous, no match or skip. Only "ambiguous" goes to the LLM, as a constrained pick of one option from a list. It never changes session state. |
| L4 | BUDDHI (बुद्धि) (Intellect) | Reason when rules can't decide | The LLM, used only as a last resort. It shortlists the relevant rules with embeddings, builds the prompt, and requires a structured JSON reply. It can route, handle drift, extract a value, generate a line or validate. The specialist calls pick from a list the code built, a pick below 0.6 confidence passes the turn on, and an invalid result means re-ask. Every call is billed, and a filler clip covers the wait. |
| L5 | NITI (नीति) (Policy / Rules) | Validate the answer and capture it | Runs per-step and global rules (regex, keywords, slot aliases, phonetic variants). The result is ACCEPT, REPROMPT, CONFIRM_VALUE, FALLBACK_LLM, DEFER or ESCALATE. It also handles condition branches and the pincode/address check. Steps marked confirm-before-advance hold the cursor until the customer confirms. No LLM. |
| L5·a | PRASANG (प्रसंग) (Context / Episode) | Answer side-questions without the LLM | Runs first inside L5. A weighted-keyword matcher, with a winning margin, over scenario groups that apply across the whole workflow. Takes 0–2 ms and answers from cached clips. It can combine up to 3 scenarios in one reply. Negated triggers ("not that") go to L4 instead of getting a wrong answer. |
| L6 | VANI (वाणी) (Speech / Voice) | Say the reply | Builds the reply: acknowledgement plus next prompt, captured values filled into templates, readback with SSML. It plays the pre-built clip for that reply and uses live TTS only for text that can't be built in advance, such as reading back a customer's own address. Every reply passes through one response builder. |
| L7 | DRISHTI (दृष्टि) (Sight / Observation) | Watch patterns across turns | Spots hearing problems ("hello? hello?"), dead ends (no progress on one step) and gibberish (STT failing again and again). It re-prompts, offers a human, or ends the call politely. It runs before normal processing on each turn. |
| — | VIRAM (विराम) (Pause) | Step off the script to handle emotion | The empathy specialist, with about 12 scenarios such as a past complaint, price negotiation or scam suspicion. It moves through 4 phases: ACKNOWLEDGE → RESOLVE → STEER → ESCALATE. The first turn plays the DAKSH-written clip; later turns use live L4. It exits with HANDOVER (back to the flow), CALLBACK, CLOSE or ESCALATE. |
| build | DAKSH (दक्ष) (Skilled / Expert) | Write the workflow; not a runtime layer | The design-time LLM author. It turns what the author describes into steps, branches, NITI rules, FAQ, language tables, aliases and clips. It never runs during a customer call; every layer above reads what it wrote. |
| Supporting layers (no Hindi name) | |||
| guard | LOOP_GUARD (Stuck-loop guard) | Stop endless loops | After 7 or more agent turns on the same step, the call ends politely. It's a safety rail, not a fix; the underlying loop still needs fixing. |
| guard | HANDOFF (Human handoff) | Take the answer to a handoff offer | When a "talk to a colleague?" offer is waiting, it takes the customer's yes/no and moves offered → connecting → qna → listening. It runs before L7. |
| guard | POLICY (Abuse / wait / resume) | Handle conduct and pauses | Handles abuse, "hold on a minute" and resuming afterwards, using DAKSH-written phrase lists. |
| L1.6 | STT GATE (Confidence gate) | Don't trust a bad transcript | Blocks transcripts below the workflow's minimum STT confidence and re-asks. After 2 blocks in a row it lets the text through, but that turn can fill an empty slot and never overwrite one that has a value. |
| L1.7 | OOS (Out of scope) | Steer off-topic talk back | Custom out-of-scope keywords, with the regex compiled once per workflow. It politely brings the customer back to the current step. |
| L1.5 | INTERJECT (Interjection) | Answer meta-requests | "What number did I give?", "wait". It answers without moving the cursor, then asks the current question again. |
| tool | TOOL (API action step) | Call external systems | Runs the workflow's API action steps during the call. |
| match | FUZZY (Sample fuzzy match) | Catch near-miss phrasings | Fuzzy string matching against authored samples, used before the rule engine. |
Each layer either answers the turn and returns, or passes it to the next layer. The numbers show the real dispatch order. The labels are the ones you'll see in the layer trace, so this list doubles as a guide to reading one.
This list lights up in step with the live call above: grey while a layer checks, teal where the turn was answered for free, orange where it cost money.
Most turns spend microseconds in the engine. The time goes to what happens around it. The 600 ms endpointing gap is paid on every turn, while L4 and live TTS are only paid when the ladder or the clip cache misses.
turn(call, workflow, text) ├─ rebuild the step index │ # every turn, never cached ├─ compile the step graph if needed ├─ start the layer trace ├─ LOOP_GUARD → HANDOFF → L7 → VIRAM → … │ … → L5 NITI → L3 MAARG → L4 BUDDHI ├─ commit the step result │ # cursor moves, slot writes, completion └─ build the response # audio check, one re-synthesis rescue, # cost stamp, trace attached
call state = {
current step: …, # the cursor
completed: {…},
captured: {step: {slot: value}},
return stack: […], # drift bookmarks, depth 5
invalidated: {…}, # steps to redo after a revisit
}
# plus per-call flags for the closing grace turn,
# handoff, low-confidence turns and billing
The engine can stay language-neutral and cheap because the language-specific and costly work happens before the call. DAKSH writes the per-language data. The builder synthesises every clip that can be known in advance, and fingerprints each one so a rebuild only re-synthesises clips whose inputs changed.
The empathy specialist, with about 12 scenarios such as PAST_COMPLAINT, PRICE_NEGOTIATION and SCAM_SUSPICION. It exits with HANDOVER, CALLBACK, CLOSE or ESCALATE. Its first turn plays a pre-built clip; later turns reason live.
Handles REPEAT (says the captured value again, cursor stays put), REVISIT (bookmarks the step, resets the target, invalidates everything after it) and CROSS_TOPIC (answers, then returns). A keyword pre-check runs before any LLM list-pick.
Weighted-keyword side-intents, answered from cached clips. It keeps side-intents that would otherwise run through large L4 rule sets off the LLM. Anything it can't match falls through to L4.
Can be triggered by L1, an L4 request for a human, an L7 dead end, a VIRAM or NITI escalation. It dials into the LiveKit room and hands over an LLM-written brief. A human's follow-up Q&A skips L1–L7 entirely.
The step graph is the source of truth for flow: explicit next steps and branches plus completion tracking. Every goto target is checked against the current set of steps before it's used.
Authored FAQ answers. Address verification runs against a 3 s wall-clock budget, and a timeout counts as an inconclusive soft pass. Tone detection shapes the delivery.
OpenAI and Gemini chat behind one factory, with the provider and model chosen per workflow. Embeddings and moderation use OpenAI. Every client reuses pooled connections.
Per-layer timings and a cumulative clock on every turn. Network timing per request (DNS, TLS, time to first byte, server versus transit). A per-call SIP timeline, a searchable call index and spreadsheet reports.