config.prompt is the system prompt, and where the agent’s behaviour lives. The {{…}} tokens it may contain are specified in variables and userdata; this page is about writing it.

Structure

Write rules as actions (“ask for the order number before you look anything up”) rather than prohibitions. When the agent fails on a real call, add the rule that would have prevented it.

Writing for speech

On voice and video, everything the model writes is spoken by a text-to-speech voice.
  • Two or three sentences per turn. Give the next useful piece and ask whether to go on.
  • No markdown, emoji, JSON or lists in anything spoken. Say so in the prompt.
  • Spell out what the voice will mangle, with the spoken form you want:
    • amounts: “one thousand two hundred rupees”, not “₹1200”
    • codes: one character at a time, in groups
    • dates and times: “Thursday the ninth of April, at four in the afternoon”
    • abbreviations and names: give the pronunciation once
  • Say what to do while a tool runs. A tool call is silence on the line: “Before you look an order up, say ‘Let me pull that up, one moment.’”
  • Give it an out: what to say when it does not know, and when to hand over.
On text, formatting and longer answers are fine.

Personalizing

The prompt and greeting are resolved once per session, before the agent starts:
  • A missing userdata field resolves to empty text, so write sentences that survive it: If you know the caller's name it is {{userdata.name}} - use it if it is there, and ask otherwise.
  • Branch on {{system_vars.direction}} to open inbound and outbound calls differently.
  • The clock variables are frozen when the agent starts and need config.timezone. {{system_vars.now}} is ISO 8601 for tools, not for reading aloud.
  • An unknown root ({{name}}, {{customer.number}}, a typo like {{userdate.name}}), a bare {{userdata}}, {{args.*}}, {{tooldata.*}} and {{secrets.*}} are refused on save. An undeclared {{vars.x}} is only a warning.

Greeting

config.greeting is how a voice or video agent opens, on connect and when a handoff brings it in. Set exactly one key: Both are personalized like the prompt. Use a message when the words matter (a disclosure, a brand line) or the first second does; use instructions when the opening should adapt to the caller.

Keeping track of time

config.elapsed_time: true prefixes every user message the model reads with the time since the session began:
The format is m:ss under an hour, h:mm:ss under a day, then 2d 3h. The clock starts when a call is answered or when a chat’s first message arrives. A handoff does not restart it; a resumed call does. Earlier sessions loaded as context are not stamped, nor are turns held by an agent task. The agent is told what the stamps mean and never to say them, so your prompt only needs the pacing rule: “Spend about 30 minutes on each problem. Past 25, start steering toward a solution.” The stamp appears wherever the transcript does, as elapsed on conversation items. Refused on a realtime agent.

What belongs elsewhere

Examples

Adapt one and test it with a real call before publishing; the dashboard editor has a test panel beside the config.

Next

Variables

Declaring {{vars.*}} and supplying values per session.

Tools

Giving the agent something to do besides talk.