Skip to content

Call Flow Builder & AI Actions System Documentation ​

The Call Flow Builder and AI Actions (in the agent editor's "Tools & Transfer" section) configure how calls are handled before and during AI conversation. The Call Flow Builder shows a visual graph for IVR flows; AI Actions shows a categorized list of agent capabilities.


How They Relate ​

UI ViewWhereWhat it shows
IVR Flow Editor/agents/new/ivr-flow or /agents/:id/ivr-flowVisual canvas for IVR flow agents (agentType: 'ivr_flow')
AI ActionsAgent Editor → Tools & Transfer tabCategorized list: On Call Connected, Flow Actions, AI Transfers

Note: The standalone Call Flow Builder page at /call-flow-builder and the embedded "Call Flow Builder" step in the voice agent editor have been removed. IVR flows are now configured exclusively through the IVR Flow Editor page for dedicated ivr_flow agent types.


Architecture (Current) ​

Entry Point: Interactive Start ​

The only entry point. Always present, cannot be removed. Has two routing modes:

Routing ModeHow it works
DTMFPlays TTS prompt → waits for keypad press → routes by digit binding
Voice IntentPlays TTS prompt → listens to speech → AI classifies intent → routes

Pre-Action: Auto DTMF (On Call Connected) ​

Optional. Fires BEFORE the entry point. Sends a DTMF sequence automatically when the call connects. Used to navigate external IVR systems.

Configured via the Auto DTMF node on the canvas (drag from Node Palette → "On Call Connected" section).

AI Transfer Actions (During Conversation) ​

LLM-triggered transfers that happen DURING the AI conversation (not during IVR):

TypeTriggerWhat happens
Transfer to Agent (Cold AI)LLM decides based on descriptionSIP REFER to target agent/number
Transfer to Number (Cold AI)LLM decides based on descriptionSIP REFER to phone number
End ConversationLLM decides conversation is completeHangs up the call

Node Types ​

Canvas Nodes (Call Flow Builder) ​

NodeCategoryTerminal?Description
interactiveStartEntry PointNo (source)The IVR entry point TTS prompt + routing
autoDtmfStartOn Call ConnectedNo (source)Pre-action DTMF sequence
menuPromptFlow ActionsNo (source+target)Sub-menu for nested IVR trees
connectAgentFlow ActionsYes (target only)Handoff to another AI agent
transfer (direct)Flow ActionsYes (target only)SIP transfer to phone number
transfer (cold_ai)AI TransfersStandaloneLLM-triggered cold transfer
transfer (warm_ai)AI TransfersStandaloneLLM-triggered warm transfer with DTMF nav
collectDigitsFlow ActionsNo (source+target)Collect N-digit input from caller
repeatFlow ActionsNo (source+target)Loop back to previous menu

Terminal Nodes ​

connectAgent and transfer (direct) are terminal they cannot have outgoing connections. Once a call reaches these nodes, control is handed off:

  • connectAgent → new agent takes over (its prompt, LLM, tools, first message)
  • transfer → call leaves the system entirely (SIP transfer)

The UI enforces this: no source handle on these nodes, isValidConnection blocks outgoing edges.


Data Model (MongoDB Agent Document) ​

javascript
{
  agent_id: "r7_vZ96yewMc",
  
  // IVR Configuration (per direction)
  inboundIvrConfig: {
    enabled: true,
    mode: "interactive",           // Always "interactive" for new configs
    routingMode: "dtmf",           // "dtmf" | "voice_intent"
    routingGoal: null,             // For voice_intent mode
    greetingSource: "menu_prompt",
    onCallConnected: {             // Auto DTMF pre-action
      enabled: true,
      dtmfSequence: [
        { type: "wait", value: "2000" },
        { type: "digit", value: "1" }
      ]
    },
    rootNode: {                    // Interactive Start node
      nodeId: "start",
      prompt: "Press 1 for Sales, Press 2 for Support",
      bindings: {
        "1": { type: "transfer", transferTarget: "+919876543210" },
        "2": { type: "connect_agent", targetAgentId: "support-agent-id" }
      },
      timeoutSeconds: 10,
      timeoutAction: "connect_agent"
    },
    nodes: []                      // Sub-menu nodes (flat list)
  },
  
  outboundIvrConfig: { /* same shape */ },
  
  // AI Transfer Actions (LLM-triggered during conversation)
  ivrActions: [
    {
      actionId: "act_123",
      name: "Transfer to Claims",
      description: "Transfer when caller asks about insurance claims",
      transferTarget: "+14155550100",
      transferType: "cold",        // "cold" | "warm"
      dtmfSequence: []             // Only for warm transfers
    }
  ]
}

API Endpoints ​

IVR Config (per direction) ​

MethodEndpointPurpose
GET/api/agents/:agentId/inbound-ivr-configGet inbound IVR config
PUT/api/agents/:agentId/inbound-ivr-configSave inbound IVR config
DELETE/api/agents/:agentId/inbound-ivr-configDelete inbound IVR config
GET/api/agents/:agentId/outbound-ivr-configGet outbound IVR config
PUT/api/agents/:agentId/outbound-ivr-configSave outbound IVR config
DELETE/api/agents/:agentId/outbound-ivr-configDelete outbound IVR config

IVR Actions (AI Transfers) ​

MethodEndpointPurpose
GET/api/agents/:agentId/ivr-actionsGet AI transfer actions
PUT/api/agents/:agentId/ivr-actionsSave AI transfer actions

Internal (Agent Server) ​

MethodEndpointPurpose
GET/internal/agent-inbound-ivr-config/:agentIdFallback config fetch for inbound calls

Validation Rules ​

Backend Validation (inbound-ivr.controller.ts) ​

RuleDescription
Root node requiredrootNode must exist when enabled
Prompt optional for voice_intentTTS prompt not required when routingMode === "voice_intent"
Bindings required for DTMFAt least one digit binding when routingMode === "dtmf"
Transfer target formatMust be E.164 phone number or SIP URI
Max tree depth3 levels of sub-menus

Frontend Validation (validator.ts) ​

RuleDescription
Menu nodes need 1-12 bindingsOutgoing edges count
Prompt ≤ 500 charsFor menu nodes
No disconnected nodesEvery non-entry node needs incoming edge
Terminal nodes no outgoingconnectAgent and direct transfer can't have children
Tree depth ≤ 3From root menu node

TTS Prompt vs First Message ​

ScenarioWhat plays
TTS prompt configured + IVR enabledTTS prompt plays as IVR greeting
No TTS prompt + voice_intent modeAgent's first message plays as greeting
IVR disabledAgent's first message plays normally
After IVR with agent handoffConnected agent's first message plays
After IVR without handoffNothing extra (IVR prompt was the greeting)

Priority: TTS Prompt > First Message. If TTS prompt is set, it always takes priority.


Frontend File Reference ​

FileRole
src/pages/customer/IvrFlowEditorPage.tsxIVR Flow Editor page canvas, state, save/load
src/components/ivr-builder/FlowCanvas.tsxReact Flow canvas, drag-drop, terminal node enforcement
src/components/ivr-builder/ConfigPanel.tsxRight-side node config forms
src/components/ivr-builder/FlowTestSimulator.tsxText-based flow walkthrough simulator
src/components/ivr-builder/NodePalette.tsxLeft-side draggable nodes
src/components/ivr-builder/nodes/*.tsxCustom node components
src/lib/ivr-builder/serializer.tsReact Flow ↔ Backend config conversion
src/lib/ivr-builder/validator.tsClient-side flow validation
src/lib/ivr-builder/templates.tsPre-built flow templates
src/lib/ivr-builder/types.tsTypeScript type definitions
src/components/features/call-flow-actions/actionMeta.tsAI Actions categories and metadata
src/stores/callFlowStore.tsZustand store for call flow state

Removed files:

  • IvrBuilderPage.tsx Standalone IVR builder (replaced by IvrFlowEditorPage)
  • CallFlowBuilderPage.tsx Wrapper for standalone page (removed)
  • CallFlowStep.tsx Embedded builder in agent wizard (removed)

Agent Server File Reference ​

FileRole
Agent/src/core/ivr_menu_engine.pyIVR tree execution TTS, DTMF, voice intent, actions
Agent/src/core/auto_dtmf_runner.pyAutomated DTMF sequence sender
Agent/src/core/first_message_resolver.pyFirst message priority resolution
Agent/src/core/ivr_tools.pyCold/warm transfer + DTMF utilities
Agent/src/handlers/call_handler.pyOutbound call lifecycle
Agent/src/handlers/inbound_call_handler.pyInbound call lifecycle
Agent/src/schemas/metadata_schema.pyPydantic models for IVR config
Agent/agent.pySession setup, background audio

See Agent/docs/CALL-FLOW-BUILDER.md for detailed Agent Server implementation guide.


Changelog ​

DateChange
2026-05-11Consolidated to 1 entry point (Interactive Start) + 1 pre-action (Auto DTMF)
2026-05-11Terminal node enforcement (connect_agent/transfer can't have children)
2026-05-11Removed On Call Connected toggle panel (use canvas node instead)
2026-05-11Removed "IVR menu prompt" messaging (TTS prompt > first message)
2026-05-11Agent audio muting during DTMF IVR execution
2026-05-11Background audio pausing during IVR
2026-05-11Confirmation messages on valid DTMF press
2026-05-11Connected agent's first message plays after handoff
2026-05-06Voice intent routing mode
2026-05-06AI Transfer nodes on canvas
2026-05-06Template system
2026-05-05Agent handoff via targetAgentId
2026-05-05Outbound IVR support
2026-04-28Initial IVR menu engine
2026-04-20IVR call transfer tools

Last updated: