Skip to main content

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:
reaches the model like this for an API call from Chennai:
Your own prompt variables ({{ customer_name }}) are rendered in the same pass, so you can mix both freely.

Add them in the agent builder

  1. Open the agent and click the System Prompt node.
  2. Click Expand system prompt and stay on the System Prompt tab.
  3. Type {{ bud. — a Governance context list opens with every variable and a short description.
  4. Keep typing to filter, then pick one with the arrow keys and Enter (or click it).
  5. Click Save.
In the Prompt Message tab, type the variable by hand, for example {{ bud.city }}.

Call the agent

Nothing changes in the request. Call the agent as usual and Bud fills the values:
To see exactly what an agent receives, add a block like this to its system prompt while you test, then ask the agent to repeat it:

Variable reference

Values by entry path

What each variable holds depends on how the agent was started.
  • API key — a /v1/responses call authenticated with an API key. principal is 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_type describe that server, not your browser, and the location values can be empty.
  • Background — a /v1/responses call with background: true. The values are captured when the request is submitted and reused when the run executes, so local_time is the submission time even if the run starts later. principal is 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_origin is the provider’s event, such as issues.opened or pull_request.closed for GitHub and Issue.create for Linear. principal is 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. principal is the chat user’s ID on that platform, such as a Slack U… 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.8 gives US, America/Chicago and NA with no region or city.
  • Private and internal addresses are never looked up, so their location values are empty.
  • region is the code of the state or region within the country, such as TN for 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 instructions keep 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_far counts input and output tokens.
  • cost_so_far uses 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" }}.
A common use is a budget guard:

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) or or. The true matters: without it, default leaves 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.
Comparing an empty cost_so_far with a number fails the request with Template rendering failed. It is empty at the start of every run, so always check it first: {% if bud.cost_so_far and bud.cost_so_far > 0.5 %}. tokens_so_far and recursion_depth are always numbers and are safe to compare.

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_type is whatever User-Agent the caller sends. Use it to adapt the reply, not to make security decisions.
  • local_time is 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.