An agent DAG is a directed-acyclic graph describing how the gateway should drive an AI conversation: which model to call, which tools it can use, which fallback prompts to play, and which conditions trigger hand-off to a human. Trunks bind to a DAG by agent_id; calls that land on the trunk inherit it.
No SDK wrapper. Drive these methods via the raw RPC envelope.

DAG shape

A DAG is a JSON document. The gateway treats the body as opaque on the wire (it’s a string); validation happens server-side after decode. The shape is:
{
  "id": "support-bot-v3",
  "version": 7,
  "entry": "greet",
  "nodes": {
    "greet": {
      "type": "tts",
      "args": { "text": "Hello, how can I help?" },
      "next": "listen"
    },
    "listen": {
      "type": "stt",
      "args": { "model": "deepgram-nova-2" },
      "next": "decide"
    },
    "decide": {
      "type": "llm",
      "args": { "model": "gpt-4.1", "tools": ["lookup_order"] },
      "branches": {
        "tool:lookup_order": "do_lookup",
        "intent:human":       "transfer",
        "*":                  "listen"
      }
    },
    "do_lookup": { "type": "tool", "args": { "name": "lookup_order" }, "next": "decide" },
    "transfer":  { "type": "transfer", "args": { "trunk_id": "support-queue" } }
  }
}
Node type values the gateway recognises today: tts, stt, llm, tool, transfer, playback, dtmf, hangup, webhook. New types are additive and ignored by older gateways (forward-compat).

Tools available to LLM nodes

An llm node’s args.tools is a list of tool names. Names resolve through the runtime’s ToolRegistry — the LLM sees the tool’s name, description, and JSON schema; the runtime executes it and feeds the result back as a tool_result.

Built-in implicit telephony toolset

Every session running through TeleQuick’s agent runtime automatically advertises these to the LLM:
NameArgsWhat it does
transfer_calldestination (E.164 / SIP URI), caller_id?RFC 3515 SIP REFER. Subject to per-trunk realm policy.
hold_callnonesendrecv → sendonly re-INVITE.
unhold_callnoneLifts a previous hold_call.
disconnect_callnoneWire-level BYE — distinct from the model saying “goodbye”.
send_dtmfdigit, mode (rfc2833|info), duration_msDTMF for IVR navigation post-transfer.
request_supervisornoneRecords an escalation-requested signal. Pair with transfer_call to actually route.
get_current_timenoneISO-8601 timestamp.
To hide a subset per-tenant, write the names to telequick:tenant:<tenant_id>:telephony_disabled_tools as a JSON array. Disabled tools are filtered out before the toolset reaches the model.

Custom tools

Custom tools are added by subclassing host::core::Tool in the runtime build (no SDK-level registration path today). See the telequick-tool-calling skill for the C++ shape and the register_tool call site.

Client-side tool calling

When you bridge the call yourself (default_app=ANSWER), you handle tool calling directly via the LLM provider’s wire format — for OpenAI Realtime that’s a tools array in session.update, with response.function_call_arguments.done events flowing back. The telequick-tool-calling skill walks through the round-trip.

PublishAgentDag

Request (PublishAgentDagRequest):
FieldTypeNotes
admin_tokenstring
tenant_idstring
agent_idstringStable id; matches AddTrunkRequest.agent_id.
dag_jsonstringThe DAG document above. Validated server-side.
commentstringFree-form changelog; surfaces in ListAgentDags.
Response (PublishAgentDagResponse):
FieldTypeNotes
statusstring"ok" or "error".
error_messagestring
versionint32Auto-incremented; version=1 for the first publish.
published_at_msint64
Each publish creates a new version; the gateway keeps the last 50 by default. New calls bind to the latest version at the moment of dial.

GetAgentDag

FieldTypeNotes
admin_tokenstring
tenant_idstring
agent_idstring
versionint320 = latest. >0 = specific historical version.
Response (GetAgentDagResponse):
FieldTypeNotes
foundbool
agent_idstring
versionint32Resolved version (in case you asked for 0).
dag_jsonstringThe DAG document.
published_at_msint64
commentstring

ListAgentDags

FieldType
admin_tokenstring
tenant_idstring
Response (ListAgentDagsResponse):
FieldTypeNotes
agentsvector<AgentSummary>Latest version per agent_id.
AgentSummary:
FieldType
agent_idstring
latest_versionint32
published_at_msint64
commentstring

DeleteAgentDag

FieldTypeNotes
admin_tokenstring
tenant_idstring
agent_idstring
purge_historybooltrue = also drop version history; false = keep it.
Returns Empty. Trunks pointing at the deleted agent_id will start failing inbound HANDLE_AI routing with ERR_INVALID_DESTINATION until you either rebind them to another agent or republish.