Skip to main content
agent.yaml is the declarative description of the agent: what it says, what it can do, and who it can reach. Nothing in it belongs to one target; the runtime half lives in targets.yaml. An optional manifest: manifest links the company contract copied into the package root. If that file exists, the link is required. See Manifest for the rules and saved defaults. YAML decoding is strict. An unknown field is an error with the file and the line, not a shrug. Durations use Go duration syntax, for example 90s, 15m, or 1h30m.
agent.yaml
That turn.detector binding runs as written on Pipecat, which forwards a model identity unchecked. silero is a voice activity detector, not a turn detector, and LiveKit checks the identity and refuses it. A LiveKit target names its own detector in targets.yaml:
targets.yaml
One agent.yaml, two targets, and only the override changes. That is the split this page and targets.yaml hold between them.

All keys

integer
required
Schema version. Accepts 1. Required; omission is refused.
string
required
What the deployed agent is called. Accepts lowercase letters, digits, single hyphens; 3 to 64 characters. Required; omission is refused.
string
required
Agent that answers. Accepts declared agent name. Required; omission is refused.
cascade | realtime | live
Which pipeline to build. Left out, it is cascade. It decides which models sections are legal, so it is read before the rest of the file. See Architecture.
map
required
Model palette grouped by kind. Accepts sections think, speak, listen, turn, and the speech to speech sections realtime and live. Required; omission is refused.
string
Listen entry to use. Accepts declared models.listen name. Selects the sole listen chain head; required when there are two or more.
string
Turn entry to use. Accepts declared models.turn name. Selects the sole turn entry; required when there are two or more.
map
Per-call values. Accepts lower snake case names. If omitted, there are no declared session values.
list
Field groups a variable’s type: can refer to. Accepts one or more named field groups, CapWords names. If omitted, there are no custom types.
list
Facts resolved once per call, before the greeting, in the order written. Accepts one entry per fact, each with a name:. If omitted, no pre-fetch runs.
list of strings
Environment values the generated project reads. Accepts UPPER_SNAKE names. If omitted, there is no explicit secret inventory; inferred requirements still apply and missing declarations warn.
map of strings
Phone destinations an escalation may use. Accepts lower snake case names to UPPER_SNAKE env names. If omitted, there are no transfer destinations; required when an escalation uses one.
map
Folders of documents a tool can search. Accepts 3 to 64 characters of [a-z0-9_]. If omitted, there are no document bases.
map
required
Agent prompts, models, nested tasks, and other callable names. Accepts one or more lower snake case names. Required; omission is refused.
map
Ordered task sequences, named by the agents that run them. Accepts lower snake case names. If omitted, there are no task groups.
map
Agent to agent, and never returns. Accepts lower snake case names. If omitted, there are no agent handoffs.
map
Agent to a person. Accepts lower snake case names. If omitted, there are no human transfers.
list of strings
Tool files to load. Accepts loaded tool file names. If omitted, no tool files are loaded.
object
Greeting, interruption, inactivity, and limits. Accepts keys below. If omitted, code targets open with a model-written greeting and default interruption behavior. SLNG requires an explicit greeting.
object
Tracing provider. Accepts provider: langfuse or provider: coval. If omitted, no tracing is configured.
map
required
How people reach the agent. Accepts one or more channel definitions. Required; omission is refused.
object
Traffic estimate. Accepts positive values; constraints below. Required for code targets or telephony; otherwise no traffic estimate is declared.

name

What this agent is called. Required on every target.
agent.yaml
The deployed name is this joined to the target it was compiled for, so acme-support on a target called slng deploys as acme-support-slng, and on a target called livekit_eu as acme-support-livekit-eu. The target half is there for one collision the package half cannot solve: a package with two targets of the same provider would otherwise deploy one name twice and overwrite itself. Where the deployed name lands: name: on its own, without the target, labels the generated project: the pyproject distribution name, the logger, the trace name, the README title.

Why unmute does not infer it

Both candidates look like names and neither is an identity.
  • The target is called slng, livekit or pipecat, because that is what the docs, the examples and the console all call it. Unmute used to deploy under it, so two packages in one organisation claimed one live agent and the second deploy replaced the first, prompt, models and attached tools included.
  • The folder is named by whoever cloned the repository. It changes on a rename, a copy, or a CI checkout into another path, and it changes silently.

Shape

Lowercase letters, digits and single hyphens, starting with a letter, 3 to 64 characters. The name is written into a PEP 508 name = in pyproject.toml, a Pipecat Cloud agent, a LiveKit agent_name and an SLNG agent. SLNG is the loosest of the four and pyproject the strictest, so unmute holds one shape all four accept rather than rewriting yours per target.

Renaming an agent that is already deployed

A rename does not move a deployment. It leaves the old one running and creates a second, so after changing name::
  • slng: the old agent stays in your organisation. Delete it, or leave it and point your sessions at the new id.
  • pipecat: pipecat cloud deploy creates a new agent, and the old one keeps billing. Delete it with pipecat cloud agent delete <old-name>, and re-create the secret set under the new name.
  • livekit: the agent itself is fine, because lk agent deploy targets the id in the preserved livekit.toml and re-registers the worker under the new name. The SIP dispatch rule is what breaks: it still names the old worker, so inbound calls ring and nothing answers. Delete it (lk sip dispatch delete <id>) and re-run telephony-setup.sh, which skips the step while a rule for that trunk still exists.
There is no way to keep the old bare name. An agent deployed as livekit was named after the target, and the new name always carries the package half, so the first compile after this change renames every existing deployment once. Do that rename deliberately, with the steps above, rather than discovering it on a call.

models

Six sections. The section an entry sits in decides its kind: think (LLM), speak (TTS), listen (STT), turn (turn detection), and realtime and live, a live model that does the first three as one and compiles on both code targets. The first four are maps keyed by entry name; live is a list whose items carry name:. Entry names share one namespace across sections and are yours to choose.
Which fields are legal depends on the section: A turn entry’s provider is local (the on-device pair) or, on Pipecat, listen, which hands the decision to the listening model’s own turn detection. listen takes no model of its own and needs a Deepgram Flux or Cartesia Turns listening model. Under listen the pace ceiling becomes the transcriber’s own end-of-turn timeout, and semantic_endpointing, endpointing_delay and interruption.minimum_words are refused because nothing reads them; see Turn detection. | fallback | think, listen | | name, provider, model, voice, backend, description | live, and nothing else: every other field is refused on a live entry by name, with its line. backend names a models.think entry with provider: openai that runs the model’s tools and reasoning. See Live model | | name, provider, model, voice, turn_detection, description | realtime, and nothing else. turn_detection is server_vad, semantic or local. voice and an agent speak: binding are mutually exclusive, and neither is refused. See Realtime | | prompt_suffix | think: literal text appended to every prompt this binding sends, up to 512 characters, no {{variables}}. A per-target override cannot name a different value. See Context Router | | agent_id, upstream | think, and only on a binding routed through the SLNG Context Router; refused on any other binding. See Context Router | pace and endpointing_delay are the two turn-timing settings and they do different jobs: the pace sets the ceiling on a turn, the duration sets only the floor. Turn taking has every legal value and what each becomes on each target.
string
A provider supported for this role and target, listed on the model pages. Required for an API binding; there is no inferred API provider. local selects local placement.
string
Provider model id, passed through as written. Required where the selected integration requires a model; otherwise its default applies. LiveKit turn bindings accept only turn-detector-mini or turn-detector.
string
Voice id on a speak entry. No voice is chosen by Unmute when omitted; the selected integration may require one or use its own default.
number
Speaking speed on a speak entry. Provider-defined values and limits; omitted leaves the provider default.
string
BCP-47 language tag, such as en or en-US, on listen or speak. Omit to leave language selection to the integration.
number
Sampling temperature on a think entry. Provider-defined values and limits; omitted leaves the provider default.
number
Nucleus sampling value on a think entry. Provider-defined values and limits; omitted leaves the provider default.
integer
Sampling count on a think entry. Provider-defined values and limits; omitted leaves the provider default.
string
An UPPER_SNAKE environment variable name holding a custom endpoint URL. Omit to use the integration’s endpoint. Required for Pipecat’s unlisted-provider path.
string
Accepts api or local. If omitted, provider: local selects local placement; another named model selects API placement. Target-specific turn detection may decide placement itself.
object
Provider parameter names and values. Omit to add no extra parameters. Provider limits apply; Unmute does not define a universal accepted set. The Responses directive below is checked separately.
list of strings
Names from the same think or listen section, in retry order. Omit for no fallback chain. Cycles and other roles are refused; Pipecat refuses generated fallback.
string
An author note. Omit for no note.
string
On turn, accepts required, preferred, or off. Omit to keep the target’s semantic detector. off removes it; see turn detection.
string
On turn, accepts snappy, balanced, or patient. Omitted means balanced. Sets the ceiling and, unless endpointing_delay is present, the floor. Cannot be authored in a per-target override.
string
On turn, a positive Go duration such as 300ms. Sets only the silence floor; LiveKit requires at least 250ms. Omit to use the pace’s floor. See turn taking.
string
Required on a Context Router think binding: a stable id of at most 128 printable ASCII characters, with no whitespace or colon. No id is generated. See Context Router for scope rules.
object
Required on a Context Router think binding; no upstream is inferred. Names the provider and its credentials. See upstream fields. Refused on other bindings.
string
Literal text on a think entry, up to 512 characters, with no {{variables}}. Appended to every prompt using the profile. Omit to append nothing. A target override cannot declare a different value.
Entries you do not reference are legal alternates. The provider catalogue has two wildcard routes. Pipecat accepts an unlisted listen, speak, or think provider only with endpoint_env, through an OpenAI-compatible integration. LiveKit accepts an unlisted think provider through LiveKit Inference; its listen and speak provider lists are closed. Never invent a provider name for either route. model and voice are passthrough. Most params are too: a name the target’s settings object has no field for rides that target’s overflow field and reaches the provider. The narrow exception is api: responses on a LiveKit OpenAI reasoning binding. Unmute checks that directive, selects the Responses client, and turns reasoning_effort into the API’s nested reasoning setting. Reasoning model shows the target-local form and explains why. Do not guess model ids, voice ids, or params. Use values the user supplied or values verified in the provider’s own documentation.

variables

string
required
A single-line Python type expression. Accepts str, int, float, bool, Phone, Date, Time, Id, EmailStr, NameEmail, a declared shape name, Literal[...], list[T], or T | None. The aliases string, integer, number, and boolean also work. See the type grammar for composition rules and target limits.
string
A sentence explaining what the value means. Used to describe the task finish argument derived from this variable. Required for source: conversation; otherwise omit for no extra description. The saved value is still shared only through placeholders.
matching the declared type
A scalar starting value, checked against type. Shapes, lists, and NameEmail take no authored default. If omitted, a scalar or shape starts unset and a list starts as []. An unset value renders as none recorded yet. in a prompt.
string
Accepts call_start, conversation (SLNG only), or a system call fact. If omitted, the variable has no automatic call-fact source; a task, pre-fetch, or session payload can still fill it. Route support is checked for system sources. conversation requires a description and forbids a default; inbound code-target calls require a default for call_start.
string
The name of the task that must hear the caller agree to a pre-fetched value. Until confirmed, only that task can read it in a prompt and tools cannot silently use it. If omitted, the value is usable as soon as it arrives.
Full detail on variables.

shapes

A pre-fetch cannot fill a shape or a list. Use a task to produce grouped fields; use separate scalar variables for clock and lookup pre-fetch results. A single pre-fetch may assign several scalar variables from one result.
A top-level list. Each item names one group of fields a variable can use as its type:. Task finish fields derive that type from their assignment destinations. Full field reference and what it takes to reach the model as structured data: variables.

prefetch

One reading of the clock fills both variables above, at no extra cost: an entry assigns as many variables as the result has fields, from one call. An ordered list of facts resolved once per call, before the greeting: the clock, a fact the call itself carries, or the result of one already-declared tool with writes: declared on the entry. Entries resolve top to bottom, and one that cannot resolve is skipped rather than failing the call. A clock: entry also carries its own timezone:, an IANA zone name. It is required there, never defaulted, because a container’s own clock is UTC, so a business elsewhere needs it to date a call correctly. It sits on the entry rather than on the package, because two entries may honestly want two zones. A tool: entry needs writes: true or writes: false. There is no default, because a pre-fetch runs unasked on every call. writes: true compiles: it is named in compile-report.json and the runbook, rather than printing a warning. Full field reference, the ordering rule, every result field a clock gives you, and what an empty value does to a prompt: variables.

secrets

A list of UPPER_SNAKE environment variable names. Never values, and never usable in a {{template}}. That list is a worked example: two model keys, the four names a SIP connection maps, and the two desks the agent can transfer to. Declare every environment name the generated project reads. That means names written in tool and connection fields, destination values, literal os.environ reads in local handlers, provider API keys inferred from the model catalogue, and the names your tracing provider needs. Names the driver or platform supplies, such as REDIS_URL or DAILY_API_KEY, stay out. See secrets.

destinations

The symbols an escalation can name. A value is only the UPPER_SNAKE name of an environment variable holding an E.164 number or a sip: URI, read at call time. A number written here is refused, because agent.yaml is the portable half of a package:
The model never sees a number, and cannot dial one that is not listed here.

knowledge

Each base has a name of 3 to 64 characters using [a-z0-9_]. The name is the map key and becomes the search collection and build folder name.
Folders of your own documents an agent can search, so it quotes them instead of guessing. Each folder is read, split and embedded once when the agent starts, and held in memory, so content is fixed until the next compile.
string
required
Path to a folder inside the package containing .txt, .md, or .pdf documents. No folder is inferred.
string
An embedding service. Omitted means openai. Keyword mode makes no embedding call.
string
Accepts meaning, keyword, or hybrid. Omitted means hybrid.
integer
Passage size in tokens, from 1 to 2048. Omitted means 90.
integer
Tokens shared by neighboring passages, from 0 through chunk_size. Omitted means 20.
integer
Maximum passages returned by a lookup, from 1 to 20. Omitted means 3.
number
Minimum accepted result score, from 0 to 1. Omit for no score filtering. Scores are similarities, not probabilities.
The five retrieval fields are per base, because a price list and a prose policy want different treatment. mode: keyword is the one with a structural consequence: it uses BM25, needs no embedding service, no credential and no network call, and the emitted image installs no embeddings package. min_score needs care, and needs mode: meaning to do anything useful. These are similarity scores, not probabilities, and in practice they land well below 1, so a value near 1 returns nothing. On hybrid the unscored keyword results pass through any cutoff. See Knowledge bases for how to set it. top_k times chunk_size is roughly what reaches the model on every lookup, and the compiler warns above about 1500 tokens. A tool reaches a base by name, with a knowledge: block, and an agent reaches it by being given that tool. The base selects a search mode and may set a minimum score. Full behaviour, every message, and what a lookup gives the model: Knowledge bases.

agents

string
required
Path to a Markdown prompt inside the package. No prompt is inferred.
string
required
Name of an entry in models.think. No profile is inferred. Required under architecture: cascade, and refused under the other two, where one model does this job.
string
Name of an entry in models.realtime, in place of think and speak. Legal only under architecture: realtime.
string
Name of an entry in models.live, in place of think and speak. Legal only under architecture: live.
string
required
Name of an entry in models.speak. No profile is inferred.
list of strings
Names of loaded tool files this agent may call. Omit for no ordinary tools.
list of definitions or names
Nested task definitions or bare names of tasks defined by another agent. Omit for no tasks. See task fields.
list of strings
Names from the top-level task_groups catalog. Omit for no groups.
list of strings
Names from the top-level handoffs catalog. Omit for no agent handoffs.
list of strings
Names from the top-level escalations catalog. Omit for no human transfers.

tasks

A task is nested inside the agent that defines it, not written in a top-level catalog. Each item of an agent’s tasks: list is either a full definition or a bare string naming a task another agent already defines:
string
required
A lower snake case name, unique across all agents in the package. To reuse an existing task, write its bare name instead of defining it again.
string
required
Path to the task’s Markdown prompt inside the package. No prompt is inferred.
string
The situation the model reads to decide whether to start the task. If omitted, the task is a definition only and must be used in a task group; it cannot be attached elsewhere by bare name.
string
A fixed spoken line with no {{placeholders}}. Omit it for no fixed announcement. Required when opening is listen.
string
Accepts generate or listen. Omitted means generate, so the model writes the opening turn. listen speaks announce and waits for the caller without a model request.
list of strings
Names of tool files loaded by the package. Omit for no ordinary tools in this task; it does not inherit its owner’s tools.
list of strings
Names from the top-level handoffs catalog. Omit for no handoffs from this task.
list of one-key pairs
Pairs of variable: result.field, including dotted result paths. Use variable+ to append one list item. Omit to save no values; the task can still finish. Types and descriptions come from the destination variables.
list of objects
Tools whose successful results finish the task automatically. Each entry requires tool and a non-empty success list of one-key output field/value pairs. Values must be declared output enum choices; a list means alternatives. If omitted, the model ends the task by calling its generated finish tool.
string
A models.think entry name. LiveKit only. If omitted, use the entry agent’s think profile, even when another agent defines the task.
object
The history fields. Omit for history: messages. A returning task restores its owner’s earlier context and adds only completion or unserved status.
result, expect, and requires are retired task fields. A package that writes one gets a located migration error. Declare variables, save them with assign:, and reference only the values a receiving prompt needs. Two agents defining a task under the same name is refused:
when makes a task callable; assign says which values it saves. A task may omit assign: and still finish. Every generated finish also takes optional unserved_request; it returns only an unserved status to the owner. Ordinary tool input: and output: JSON Schemas are unchanged.

context

Used by tasks and by handoffs.
string
Accepts full, messages, last_n, summary, or reset. Omitted means messages: keep speech and remove tool calls with their replies. summary is LiveKit only; SLNG refuses authored context settings.
integer
Required and positive with history: last_n. There is no default count. Refused with other history modes.
string
Required with history: summary: a models.think entry name. No model is inferred. Refused with other history modes.
boolean
Accepts true or false. Omitted behaves as true in modes that keep tool records. It cannot add tool records to messages or reset. Explicit false is LiveKit only.
include_tool_calls: true does not add tool records to messages or reset. To keep old tool results, use full or last_n. Pipecat supports those two modes plus messages and reset; it refuses summary and explicit include_tool_calls: false. SLNG refuses task and handoff context settings. For example, these are two separate context blocks:
History controls entry into the receiver. A returning task always restores the owner’s earlier conversation and adds only a status. Saved values reach either prompt only through explicit placeholders. See Reduce context sharing step by step.

task_groups

An agent runs a group by naming it in its own task_groups: list. The group carries its own when:, the situation the model reads to decide whether to run it:
list of strings or objects
required
One or more task names, in execution order. An object requires task and may set skip_when_confirmed to a variable that task confirms. Omit that condition to run the step every time. An empty or absent steps list is refused.
string
The situation the model reads to decide whether to run the group. Omission is accepted but supplies no trigger guidance, so write one.
string
One fixed spoken line, with no {{placeholders}}, when the group starts. Omit for no announcement.
string
required
Accepts shared or isolated. There is no default. Each member still applies its own context.history; an isolated group cannot be widened by a member’s full.
string
required
Accepts return, transfer, or end. There is no default.
string
Required with then: transfer: an existing agent name. Refused for return or end; there is no inferred destination.
string
Only results is accepted. Omission also means results.
The group decides whether members share the group’s running conversation. Each member still applies its own context.history. An isolated group cannot be widened by a member’s full.

handoffs, escalations

Everything the model can hand the caller to and not get back, in one block per kind. The block an entry is written in is what it is, so there is no kind: field.

handoffs

The conversation becomes another agent, and never comes back.
string
required
An existing agent name. The conversation moves to that agent and does not return. No destination is inferred.
string
The situation the model reads to decide whether to hand over. Omission supplies no trigger guidance, so write one.
string
Exact text spoken before handing over. Omit for a silent handoff.
object
The history fields. Omitted means messages. Saved values are visible only where the receiving prompt names them.
Saved state stays with the call, but the receiving model sees only values its prompt references. A reset handoff gets no automatic briefing or triggering sentence. announce is exact spoken text, not a model instruction: write the short sentence the caller should hear. Omit it for a silent handoff.

escalations

Puts the caller through to a person.
string
The situation the model reads to decide whether to transfer. Omission supplies no trigger guidance, so write one.
object
A cold transfer using the destination and timeout fields below. Exactly one of cold and warm is required; there is no default transfer form.
object
A warm transfer using the fields below, including optional briefing. Exactly one of cold and warm is required. Supported only on LiveKit SIP.
A human transfer names its shape with a block, so a warm only field cannot be written on a cold transfer: on_unavailable is return_to_caller or hangup; omitted means return_to_caller. ring_timeout must be a positive Go duration. When omitted, Pipecat uses 25 seconds. LiveKit leaves the value unset, so the LiveKit platform default applies. Pipecat cloud-websocket requires explicit on_unavailable: hangup; it cannot reconnect the original media stream. destination is a symbol resolved in the top level destinations: map above.

Transfer fields

string
required
A symbol declared in destinations, whose value names an environment variable holding the destination. No destination is inferred. Valid inside both cold and warm.
string
A positive Go duration, such as 25s. Omitted means 25 seconds on Pipecat; LiveKit leaves it unset for the platform default.
string
Accepts return_to_caller or hangup. Omitted means return_to_caller. Pipecat cloud-websocket requires explicit hangup, because the original media stream cannot be reconnected.
string
Instructions for briefing the person before connecting the caller. Legal only inside warm. Omit for the runtime’s standard briefing instructions.
Whether a route can carry the shape you asked for is decided by the connection. A warm transfer is supported only on LiveKit sip; Unmute does not support warm transfer on any Pipecat target. A warm transfer on a route with no leg to move is refused by name:

tools

Which tools/<name>.yaml files to load. Availability is decided by the tools list on each agent and task. This top-level list and every agent or task list contain names only. Define each tool once. Put its full contract in tools/<name>.yaml; never inline description, input, output, inject, or an execution block under a tools: list in agent.yaml.

Tool files

One file per tool, in tools/. The top level is the contract with the model; exactly one execution block says how it runs.
string
Required for local, webhook, and knowledge tools: explains when the model should call the tool. Builtins use their registry description if omitted; hosted slng tools inherit their published description. Refused on MCP sources.
object
Required for authored local and webhook contracts: a JSON Schema with type: object describing model arguments. Refused on builtin, MCP, knowledge, and hosted slng tools, which own their schemas.
object
An author-side JSON Schema with type: object. Omit for no declared result schema. Used by assignments and success checks; it is not a general runtime result validator or a model prompt. Refused on builtin, MCP, knowledge, and hosted slng tools.
list of one-key pairs
Hidden argument/value pairs. Values are scalars or strings with {{variable}} placeholders. Omit to inject nothing. Legal on local, webhook, and hosted slng tools; builtin send_sms requires its literal from_number setting.
string
Accepts provider_default, continue, or cancel. Omitted means provider_default. Refused on MCP sources. Target support is listed above.
string
Accepts returns_data or ends_conversation. Omitted means returns_data, except builtins whose effect comes from the registry. Refused on MCP and knowledge tools.
string
A fixed spoken sentence with no {{variables}}. Omit for no announcement. Legal on local, webhook, knowledge, and hosted slng tools.
A knowledge file takes no input, output, inject or effect: the tool owns both sides of its contract, taking one string and returning passages. An mcp file is the block and nothing else. The seven contract fields above are all illegal on one, because the server describes its own tools.
string
Accepts sse or streamable_http. Inside mcp, omission uses the runtime’s URL-based transport choice; a URL ending in /mcp selects streamable HTTP.
Builtin ids: end_call, send_sms. end_call compiles on every target. send_sms is a capability SLNG curates, so it compiles on the slng target only. It takes one setting from the package: inject: with a single from_number. That is the sender, as a literal number in international format starting with a plus sign. The model supplies the recipient and the body itself, and SLNG reads the Twilio credentials from your vault under TWILIO_ACCOUNT_SID and TWILIO_AUTH_TOKEN, which unmute deploy checks. webhook.auth:
string
required
Accepts bearer or api_key. Required when auth is present; no scheme is inferred.
string
required
An UPPER_SNAKE environment variable name holding the token, never the token itself. There is no default.
string
An HTTP header name, legal only with type: api_key. Omitted means X-API-Key. Bearer authentication uses Authorization: Bearer.

conversation

object
Opening behavior using speaks_first and optional text. If omitted, LiveKit and Pipecat generate an opening line. SLNG requires an explicit greeting with text.
string
Required when greeting is present. Accepts agent or user; there is no default inside an authored block. SLNG requires agent.
string
The exact opening line, with eligible variable placeholders. Requires speaks_first: agent. If omitted on a code target, the model writes the greeting; SLNG requires text.
object
Barge-in settings. If omitted, interruptions remain enabled. Pipecat phone routes also protect the greeting by default.
boolean
Required when interruption is present. Accepts true or false. There is no default inside an authored block.
list of strings
Accepts greeting, tool_calls, or both on Pipecat. Omit to protect the greeting on a Pipecat phone route and nothing on a browser route. Set [] to protect nothing. Non-empty protection is refused with enabled: false.
integer
A positive count sets how many words count as an interruption on code targets. Omitted or zero leaves the runtime’s default word threshold.
list of strings
Phrases that do not interrupt on code targets. Omit for no authored ignored phrases.
object
Optional nudge_after and end_after timers. Omit for no authored inactivity timers. SLNG refuses this block.
string
A positive Go duration, such as 15s, before an idle nudge. Omit for no authored nudge timer.
string
A positive Go duration, such as 45s, before ending an idle call. Omit for no authored idle end timer.
string
A positive Go duration, such as 15m, limiting a call on code targets. Omit for no package-defined limit. SLNG refuses this field.
string
Accepts none or subtle. Omitted means no thinking audio. subtle is LiveKit only.

tracing

Tracing fields

string
required
Accepts langfuse or coval. Required inside tracing; no provider is inferred. Omit the whole tracing block to disable tracing. Supported on LiveKit and Pipecat; refused on SLNG.
provider takes one of two values, langfuse or coval. Tracing works on both targets. LiveKit uses the room name as the Langfuse session ID. Pipecat uses the runner session ID as both its conversation ID and the Langfuse session ID. Pipecat tracing owns the process OpenTelemetry provider and startup fails if another SDK provider is installed first. With coval, each trace is attached to the Coval simulation that placed the call, and the agent finds that simulation ID on the call itself. See tracing for how the ID reaches the agent on each target. Traces can contain caller speech, model input and output, and tool arguments and results. Use only fake identities and fake customer data for release tests. Use a separate project on your tracing provider for those tests, and do not send real customer data until its access and retention rules are approved.

channels

string
required
Accepts realtime_audio or telephony. No kind is inferred.
boolean
Accepts true or false for telephony only. Omitted does not enable inbound calls. At least one of inbound and outbound must be true.
boolean
Accepts true or false for telephony only. Omitted does not enable outbound calls. Required as true for warm transfer or voicemail handling.
list of strings
Telephony only. Accepts cold_transfer, warm_transfer, dtmf_send, dtmf_receive, hold, hangup, voicemail_detection, and ivr_navigation; the route must support each requested control. Omit for no extra explicit requirements.
string
Accepts hangup or leave_message where supported by the route. Requires kind: telephony and outbound: true. Omit for no package-defined voicemail action.

Three rules a telephony channel brings with it

All three are enforced, fail validation, and are easier to read here than to meet by trial and error. At least one direction must be enabled. A channel with both inbound: false and outbound: false has no call leg and is refused. A warm transfer needs outbound: true. A warm transfer dials the destination itself, so the agent places a call, and a channel that only receives them cannot:
Write outbound: true even on a line people only ring in on. It describes what the agent does, not what the number is for. capacity.peak_starts_per_second becomes required. The moment any channel is telephony, the field stops being optional and must be positive:
Calls arrive in bursts and each one starts a session, so a rate is the number the compiler sizes workers from. One is a fine answer for a first line.

capacity

Capacity is required for LiveKit and Pipecat, the two code targets. A telephony channel also makes peak_starts_per_second required.
integer
required
Expected concurrent sessions at peak; must be positive. No estimate is inferred.
integer
required
Maximum concurrent sessions; must be positive and at least peak_sessions. No ceiling is inferred.
number
Required and positive for any telephony channel. Omit on a browser-only package to declare no call-start rate.
string
required
A positive Go duration, such as 5m. No duration is inferred.
The compiler turns these into worker and quota numbers, marked [unbenchmarked].

Reachability

Models are a palette, so an unused model entry is legal. Other declarations must be reachable from entry_agent. An unused handoff, escalation, destination, task group, or non-entry agent is a build error, and so is a tool no agent’s tools: list names. Attach it to the reachable graph or remove it. A task is reachable a different way, because it is defined inside the agent that lists it rather than in a top-level catalog. A task with no when: and no task group naming it in steps: is a build error too. Give it a when: so an agent can decide to run it, or list it as a step of a task group that is reached.

Where to go next

targets.yaml

The runtime half.

Models

Which provider: values each target accepts.