config.tasks field — not about running one on its own with POST /v1/task-runs
(that is agent tasks overview). Each attached task becomes a tool; when
the model calls it, the task takes over the same call, in the same voice, until it calls
submit_result, and its typed output comes back as the tool’s result.
Fields
description and message take the calling agent’s template variables.
What the task runs on
A task has no channel or media of its own. It uses the call’s speech-to-text, voice, turn handling and avatar, so one task works under voice, video and text agents. It keeps its ownllm and timezone — except on a realtime agent, where the task runs
on the call’s speech-to-speech model and its llm is ignored.
Which variables the model is asked for
The task’svars become the tool’s parameters minus every variable the call already
answers: anything the calling agent declares (even if blank) or the session was started
with. Those are filled in automatically and never shown to the model.
Inside the task, {{vars.*}} resolves in order: the task’s own default, then the calling
agent’s {{vars.*}} bag, then the arguments the model supplied (only for parameters it was
shown). A required task variable is enforced only on the parameters the model is shown.
Declare a task variable only for what the caller or model must supply. Anything already in
{{userdata.*}}, {{vars.*}} or {{system_vars.*}} should be read in the task’s prompt.
Publishing the agent warns when a task requires a variable the agent does not declare
and that has no default — the model would be asked to supply it and may invent one.
Context in and out
Messages cross in both directions; tool calls never do.- In: the task sees the calling agent’s conversation (not its system prompt or tool calls). It speaks first, generating its opening from its own prompt — say in the prompt how to open and not to greet again.
- Out: everything said during the task merges into the agent’s context, and the typed
result is the tool’s return value, as JSON (
{"status": "shipped", "eta": "Friday"}). The agent does not greet again.
untrusted or file input cannot be attached: the agent’s model would have
to pass that value as a tool argument. Run such a task with POST /v1/task-runs.
userdata is shared: the task reads and writes the call’s bag, which persists to the
contact record.
Tools inside a task
While the task holds the floor, the calling agent’s tools are unavailable — give the
task any tool it needs. A task cannot attach tasks of its own.
Ending without a result
finish_without_result exists only when a task is entered from a conversation and cannot
be removed. If the task gives up too readily, narrow finish_without_result_description on
the task — the tool description, not the prompt, is what the model weighs. A value it may
legitimately fail to find is better as an output field with required: false (null
allowed).
Limits and behaviour
- Steps: the calling session’s
max_stepsapplies per reply (default 4 on voice and video, 25 on text), not the task’s ownmax_steps(standalone runs only). - Two task tools in one model message run sequentially.
- Text: an open task does not survive the chat going idle for about a minute; the task and its pending result are dropped and the calling agent answers the next message.
- Transcript: the sub-conversation is bracketed by Started <name> and Back to <agent> rows; the tool card shows arguments and result.
- Billing: no separate task run or bill — tokens and speech are the call’s.
- Recording: a task inherits the call’s recording; everything said in it is recorded and transcribed. Do not use it to capture card numbers.
- Deleting a task an agent still attaches is refused, naming the agents.
Attaching one
1
Publish the task
Only published tasks can be attached by
task_id.2
Attach it
Agent editor → Tasks: give it a tool name, pick the task, write the description. The Inputs table marks each task variable from the call or from the model.
3
Publish the agent
This pins the task version; republishing the task changes nothing until the agent is published again.
Next
Inputs and output
vars, output and submit_result.Handoffs
Passing the caller on for good.