Overview
Every agent run comes with a set of default variables: who started the run, how it arrived, where the caller is, which project the agent belongs to, and how many tokens the run has used so far. You read them in the agent’s prompts with{{ bud.<name> }}.
- They work in the system prompt and in prompt messages.
- The caller sends nothing extra. Bud fills them on the server from the request’s credentials, network address and entry path.
- A value that does not apply to a run (for example the trigger fields on an API call) renders as an empty string.
Use them in a prompt
Write the variables into the prompt like any other template variable. This system prompt:{{ customer_name }}) are rendered in the same pass, so you can mix both freely.
Add them in the agent builder
- Open the agent and click the System Prompt node.
- Click Expand system prompt and stay on the System Prompt tab.
- Type
{{ bud.— a Governance context list opens with every variable and a short description. - Keep typing to filter, then pick one with the arrow keys and Enter (or click it).
- Click Save.
{{ bud.city }}.
Call the agent
Nothing changes in the request. Call the agent as usual and Bud fills the values:Variable reference
Values by entry path
What each variable holds depends on how the agent was started.- API key — a
/v1/responsescall authenticated with an API key.principalis empty because a key is not a person. - Studio / Playground — testing the agent while signed in. The Playground server sends the request to the gateway
on your behalf, so the location values and
client_typedescribe that server, not your browser, and the location values can be empty. - Background — a
/v1/responsescall withbackground: true. The values are captured when the request is submitted and reused when the run executes, solocal_timeis the submission time even if the run starts later.principalis your user ID when you submit while signed in, and empty for an API key. - Sub-agent (A2A) — the agent is called by another agent as a tool. It reports its own project and counts only its own model calls; the calling agent’s usage is not included.
- Trigger — an event from an event connection starts the run.
trigger_originis the provider’s event, such asissues.openedorpull_request.closedfor GitHub andIssue.createfor Linear.principalis the actor’s ID on that provider, for example the GitHub user’s numeric ID. - Bot chat — a message to the agent in Slack or Teams.
principalis the chat user’s ID on that platform, such as a SlackU…ID.
Every
/v1/responses call reports channel as api, including calls from Studio and the Playground. Each turn of a
conversation is a separate request: the values are filled again and the counters start from zero.To try prompts that use location or
client_type, call the agent through the API from the client you care about
rather than from the Playground.Location values
user_country, region, city, timezone and continent come from the caller’s public IP address, looked up in the
IP location database bundled with the gateway (MaxMind GeoLite2 City). local_time is the current time in that
timezone.
- Only the fields the database knows are filled; the rest stay empty. Many addresses are known only at country level,
which is common for VPNs, mobile networks and cloud or anycast addresses. For example,
8.8.8.8givesUS,America/ChicagoandNAwith no region or city. - Private and internal addresses are never looked up, so their location values are empty.
regionis the code of the state or region within the country, such asTNfor Tamil Nadu, not the full name.
Live counters
tokens_so_far and cost_so_far change while the run is in progress. When an agent calls tools, it makes several
model calls in one run, and each call sees the totals of the calls before it:
- The stored conversation and the response’s
instructionskeep the text from the start of the run. Traces show the text each model call actually received. - The counters cover one request. A new turn of a conversation, and a sub-agent’s run, start from zero.
tokens_so_farcounts input and output tokens.cost_so_faruses public list prices in USD, so it is an estimate, not your bill. It stays empty until a call can be priced, and stays empty for models without a public price.- Very small costs print in scientific notation (
1.23e-05). Format them for the model with{{ "%.6f" | format(bud.cost_so_far) if bud.cost_so_far else "n/a" }}.
Empty values and safe templates
A value that is missing renders as an empty string. Write templates that still read well when it is.-
Give a fallback with
default(..., true)oror. Thetruematters: without it,defaultleaves an empty value unchanged. -
Branch on a value with
{% if %}: -
Check spelling. A name that is not in the list above, such as
{{ bud.citty }}, also renders as an empty string, with no error.
Reserved names
bud, ctx, headers and meta are reserved, including any dotted name that starts with them (such as bud.city).
You cannot use them as names for your own input variables; the agent builder marks such a variable as a reserved name
and will not save until you rename it.
A plain {{ city }} is an ordinary input variable that the caller fills, not the default value. Use {{ bud.city }}
for the value Bud provides.
Limits
- Default variables are rendered in the system prompt and prompt messages only. The request’s
input, tool descriptions and input/output schemas are passed through as written. client_typeis whateverUser-Agentthe caller sends. Use it to adapt the reply, not to make security decisions.local_timeis fixed when the request arrives and does not advance during a long run.- In background runs, default variables are rendered in plain-text prompt messages only, not in messages that contain images or files.
Next Steps
Version Management
Roll out prompt changes that use default variables safely.
Context Compaction
Keep long agent conversations inside the context window.
Event Connections
Start agents from events and fill the trigger variables.
Create a Response
Call an agent through the Responses API.