VARTA
Runtime · the turn engine

VARTA Engine Architecture

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.

inSTT final text + payload decideLOOP_GUARD → … → L4 BUDDHI commitstep result: cursor, slots outresponse → audio clips

Last reviewed 15 September 2026. Companion page: DAKSH Architecture, which covers how the workflow data is written.

See it run

Watch one bank call go through VARTA

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.

Bank KYC Update · live call replay

Bank KYC Update template · outbound · hi-en · agent Anaya · STT Deepgram · TTS Sarvam · LLM gpt-4o-mini
Jump to turn
Turn0 / 13
Call time00:00
Current stepopening
Turns without LLM
LLM calls0
Live TTS clips0
Cached clips0
Est. cost (ex-STT)₹0.000
Cost saved₹0.00
Waiting saved0.0 s
This call vs an LLM-first agent
saved (cost or waiting avoided)spent (LLM call, live TTS)answered free (rule layer, cached clip)network (embeddings, address API)risk avoided / silence covered

Workflow

0%

    Conversation

    Hinglish shown romanised · English below

    Inside VARTA

    turn cascade
    STT · Deepgram streamingidle
      Embeddings0 calls
      LLM0 calls
      Address API0 calls
      Live TTS0 clips
      answered here, free answered here, paid checking faded = not reached

      What just happened

      Press play to start the call.

      Layer trace

      at_ms cumulative · dur_ms per layer
      
          

      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.

      Design rules

      Six rules the engine is built on

      Determinism ladder

      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.

      Language-neutral engine

      The engine contains no language-specific strings or checks. Every per-language line, keyword and number word is workflow data written by DAKSH.

      Cache-first audio

      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.

      Re-ask, never silently advance

      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.

      Every LLM call is metered

      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.

      Silent boot

      Starting the server never triggers LLM work. Warm-up reads caches only, so nobody pays for work they didn't ask for.

      System context

      Three transports, one engine

      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.

      TRANSPORTS API ENGINE EXTERNAL Browser test call in the designer STT: streaming proxy SIP / LiveKit worker phone calls over SIP STT: LiveKit plugins Benchmark simulator scripted test calls LLM plays the customer Turn endpoint one request per turn turns kept in order per-session lock VARTA turn engine layer cascade commit step result build response Workflow data steps · clips · graph language text · aliases DAKSH + builder design time LLM author + audio build LLM OpenAI · Gemini + embeddings TTS ElevenLabs Sarvam Session store call state periodic flush POST turn POST turn threadpool calls the engine directly read every turn generates L4 fallback persist
      Red edges cost money on each call. The dashed boxes run at design time and are read at call time. The step index is rebuilt on every turn and never cached, so a call never acts on a stale copy of the flow.
      Layer reference

      The layers, by name

      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.

      LayerName (Hindi) (English meaning)PurposeDescription
      Core layers
      L1DHADKAN (धड़कन) (Heartbeat)Instant reflexesMatches 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.
      L2PEHCHAAN (पहचान) (Recognition)Work out what the customer said and which step it belongs toCleans 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.
      L3MAARG (मार्ग) (Path)Choose the branchA 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.
      L4BUDDHI (बुद्धि) (Intellect)Reason when rules can't decideThe 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.
      L5NITI (नीति) (Policy / Rules)Validate the answer and capture itRuns 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·aPRASANG (प्रसंग) (Context / Episode)Answer side-questions without the LLMRuns 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.
      L6VANI (वाणी) (Speech / Voice)Say the replyBuilds 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.
      L7DRISHTI (दृष्टि) (Sight / Observation)Watch patterns across turnsSpots 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 emotionThe 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.
      buildDAKSH (दक्ष) (Skilled / Expert)Write the workflow; not a runtime layerThe 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)
      guardLOOP_GUARD (Stuck-loop guard)Stop endless loopsAfter 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.
      guardHANDOFF (Human handoff)Take the answer to a handoff offerWhen 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.
      guardPOLICY (Abuse / wait / resume)Handle conduct and pausesHandles abuse, "hold on a minute" and resuming afterwards, using DAKSH-written phrase lists.
      L1.6STT GATE (Confidence gate)Don't trust a bad transcriptBlocks 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.7OOS (Out of scope)Steer off-topic talk backCustom out-of-scope keywords, with the regex compiled once per workflow. It politely brings the customer back to the current step.
      L1.5INTERJECT (Interjection)Answer meta-requests"What number did I give?", "wait". It answers without moving the cursor, then asks the current question again.
      toolTOOL (API action step)Call external systemsRuns the workflow's API action steps during the call.
      matchFUZZY (Sample fuzzy match)Catch near-miss phrasingsFuzzy string matching against authored samples, used before the rule engine.
      The turn cascade

      Layers in dispatch order

      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.

      local, µs–ms network I/O cached or paid
      1. Guards: before understanding
      2. 01LOOP_GUARDBails politely if the call has been stuck on the same step for 7 or more turns.counter
      3. 02HANDOFFIf a human-handoff offer is waiting, this turn is the customer's yes or no.offered → connecting → qna → listeningstate machine
      4. 03L7 DRISHTIदृष्टि · sightDetects gibberish, "I can't hear you", and dead ends.heuristics
      5. 04VIRAMविराम · pauseHandles empathy scenarios in 4 phases: ACKNOWLEDGE → RESOLVE → STEER → ESCALATE.turn 1 cached · then L4
      6. 05POLICYHandles abuse, "please wait" and resume.may call out
      7. Reflexes: fixed patterns
      8. 06L1 DHADKANधड़कन · heartbeatYes / no / wait / repeat reflexes from a compiled regex cache that includes phonetic variants.regex
      9. 07STT GATEL1.6Blocks low-confidence transcripts. Lets them through after 2 blocks in a row, but those turns can't overwrite a slot that already has a value.threshold
      10. 08L1 CONFIRMAnswers a pending confirmation ("did you say…").regex
      11. 09L1.7 OOSCatches out-of-scope keywords using regex compiled once per workflow.regex
      12. Understanding: rules and recognition
      13. 10L2 PEHCHAANपहचान · recognitionRecognises the step, jumps ahead, or captures a slot value directly.matcher
      14. 11L1 INTERJECTHandles interjections in the middle of the flow.regex
      15. 12TOOLRuns API action steps during the call.external API
      16. 13FUZZYFuzzy-matches the utterance against authored samples.string distance
      17. 14L5 NITIनीति · policyRule-based validation, slot capture and condition branches. Its first check is PRASANG, a 0–2 ms weighted-keyword matcher for side-intents that apply across the whole workflow.rules
      18. Escalation: reasoning
      19. 15L3 MAARGमार्ग · pathA routing shortcut that can hand the turn to the full L4.shortcut
      20. 16L4 BUDDHIबुद्धि · intellectThe LLM step. It routes, handles drift, extracts, generates and validates. First it shortlists rules with embeddings, then makes a structured-JSON call. Picks below 0.6 confidence are treated as "can't decide" and the turn is re-asked.
      21. Expression: always last
      22. 17L6 VANIवाणी · speechBuilds the response: picks the pre-built clip, reads values back, summarises the address. Every response goes through one builder, which replaces empty audio, stamps the cost and attaches the trace.clip ₹0 · live TTS
      Where a turn's time goes

      The latency anatomy

      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.

      Indicative ranges, not p95, from network traces measured in India (September 2026). Of each LLM call, about 420–570 ms is network backhaul that stays roughly constant whatever the prompt size, so connection pooling can't remove it. Embeddings are about 60 ms of compute and ~520 ms of transit.
      Turn lifecycle

      One turn, start to finish

      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

      What a call remembers

      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
      Build time vs call time

      DAKSH writes what the engine reads

      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.

      DESIGN TIME · cost logged per workflow CALL TIME · cost stamped on each call Designer + DAKSH chat, drafts, rebuilds rules · side-question groups Language data system lines · slot aliases phonetic variants Builder clip synthesis fingerprinted, in parallel Workflow steps · samples[] compiled step graph synth clips persist L1 · L5 matchers also match on phonetic variants Turn engine DAKSH-written text for every system line L6 VANI resolve the pre-built clip live TTS only on miss loaded per call
      Anything the agent might say that can be known at build time becomes a sample. The fingerprint covers text, SSML, voice, model, language, provider and speech rate. Change any one of them and only that clip is rebuilt.
      Specialist subsystems

      What the layers call into

      VIRAM

      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.

      Drift

      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.

      PRASANG

      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.

      Human handoff

      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.

      Navigator

      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.

      FAQ, address, tone

      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.

      LLM providers

      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.

      Observability

      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.