Runner and sandbox configuration
Every operator-facing runner variable, its default, and where it is set. The runner parses all of
its AGENTA_RUNNER_* variables once before it starts listening. An invalid value fails startup
with the error shown in Startup validation.
For the model behind these settings, see How agents run.
For the general platform variables, see the configuration reference.
The local subscription mount variables (PI_CODING_AGENT_DIR and CLAUDE_CONFIG_DIR) are covered
by Use your own subscription.
The bundled Compose env examples group these variables under Agenta - Agent runner in the same
order as the sections below, so the file and this page mirror each other.
Service
Set on the runner service.
| Variable | Role | Default | Secret | Helm |
|---|---|---|---|---|
AGENTA_RUNNER_HOST | Bind interface | 127.0.0.1 | no | agentRunner.env.AGENTA_RUNNER_HOST |
AGENTA_RUNNER_PORT | Bind port | 8765 | no | Chart-managed (8765) |
AGENTA_RUNNER_CONCURRENCY_LIMIT | Maximum concurrent runs | 1000 | no | agentRunner.env.AGENTA_RUNNER_CONCURRENCY_LIMIT |
AGENTA_RUNNER_LOG_LEVEL | Log verbosity | silent | no | agentRunner.logLevel |
AGENTA_RUNNER_REPLICA_ID | Replica identity for logs | Generated when unset | no | agentRunner.env.AGENTA_RUNNER_REPLICA_ID |
Every variable on this page treats an empty value as unset, so leaving a line blank selects the default rather than an empty string.
The code default host is 127.0.0.1. The bundled Compose files set AGENTA_RUNNER_HOST=0.0.0.0
so the Services container can reach the runner across the Compose network. AGENTA_RUNNER_PORT and
AGENTA_RUNNER_CONCURRENCY_LIMIT must be positive integers.
The runner does not take a static API key. Session coordination, mount signing, and trace export use the per-run caller credential.
Routing and authentication
These locate the runner and authenticate the call. Two of the three are caller-side: the Services API and its SDK read them, not the runner.
| Variable | Role | Read by | Default | Secret | Helm |
|---|---|---|---|---|---|
AGENTA_RUNNER_INTERNAL_URL | Runner locator | Services API (caller-side) | Compose: http://runner:8765 | no | agentRunner.externalUrl, else derived from agentRunner.enabled |
AGENTA_RUNNER_TOKEN | Shared request credential | Services sends it; runner verifies it | Unset | yes | agentRunner.env.AGENTA_RUNNER_TOKEN |
AGENTA_RUNNER_TIMEOUT_SECONDS | Idle timeout the caller allows on the run request | Services API and SDK (caller-side) | 180 | no | n/a |
AGENTA_RUNNER_TOKEN is the same credential at both ends. It does not belong to a sandbox or a
harness. The runner enforces the check only when the value is set, so leaving it unset (the bundled
Compose and Helm default) disables it. To turn it on, set the same value on the runner and on the
Services API.
AGENTA_RUNNER_TIMEOUT_SECONDS bounds idle time on the caller's streaming transport, not the total
run duration, and the runner never reads it. The runner enforces its own deadlines through
Run limits. Set the caller timeout above the runner's idle timeout, or the caller
gives up on a run the runner still considers healthy.
Sandbox providers
Read by both the runner and the Services API, so the operator sets each value once and hosting templates apply it to both.
| Variable | Role | Default | Helm |
|---|---|---|---|
AGENTA_RUNNER_ENABLED_SANDBOX_PROVIDERS | Providers this deployment can use | local | agentRunner.providers.enabled (list, rendered comma-joined) |
AGENTA_RUNNER_DEFAULT_SANDBOX_PROVIDER | Provider used when a run does not choose | local | agentRunner.providers.default |
Rules:
- Values are lowercase provider ids separated by commas. The known ids are
localanddaytona. - Unset enabled providers means exactly
local. - An explicitly empty list is invalid, and so is an empty entry inside the list.
- Unknown ids and duplicate ids are invalid.
- The default must be one of the enabled providers.
- A run may select any enabled provider. A run that selects a known but disabled provider fails before any working directory, mount, secret, or sandbox is created. There is no fallback to another provider.
The enabled list is also the security posture switch. This is capability configuration for the deployment, not a per-user authorization list.
Daytona
Read by the runner service. Required only when daytona is enabled.
| Variable | Role | Default | Secret | Helm |
|---|---|---|---|---|
AGENTA_RUNNER_DAYTONA_API_KEY | Provisioning credential | Unset | yes | agentRunner.providers.daytona.apiKeySecretRef |
AGENTA_RUNNER_DAYTONA_API_URL | Daytona API locator | Unset | no | ...daytona.apiUrl |
AGENTA_RUNNER_DAYTONA_TARGET | Region or target | Unset | no | ...daytona.target |
AGENTA_RUNNER_DAYTONA_SNAPSHOT | Snapshot to start from | Runner's pinned agenta-agent-sandbox-v1 | no | ...daytona.snapshot |
AGENTA_RUNNER_DAYTONA_IMAGE | Image to start from | Unset | no | ...daytona.image |
AGENTA_RUNNER_DAYTONA_AUTOSTOP_MINUTES | Idle minutes before stop | 15 | no | ...daytona.autostopMinutes |
AGENTA_RUNNER_DAYTONA_AUTODELETE_MINUTES | Idle minutes before delete | 30 | no | ...daytona.autodeleteMinutes |
When neither AGENTA_RUNNER_DAYTONA_SNAPSHOT nor AGENTA_RUNNER_DAYTONA_IMAGE is set, the runner
starts from its pinned default snapshot agenta-agent-sandbox-v1. The two variables are mutually
exclusive. The autostop and autodelete values must be positive integers. See
Run agents in a cloud sandbox (Daytona) for the setup flow.
DAYTONA_* variables are a different sandbox, and the snapshot is not shareableDAYTONA_API_KEY, DAYTONA_API_URL, DAYTONA_TARGET, DAYTONA_SNAPSHOT, and
DAYTONA_SNAPSHOT_CODE configure the code evaluator's sandbox, which runs custom evaluator
code. The agent runner never reads them. Only the AGENTA_RUNNER_DAYTONA_* variables in the table
above reach it, so setting the bare names does not give agents a Daytona sandbox, and the runner
still fails to start with a missing-key error.
The account is shareable: AGENTA_RUNNER_DAYTONA_API_KEY, _API_URL, and _TARGET may hold
the same values as their bare counterparts. The snapshot is not. The evaluator's snapshot (for
example daytona-small) is a plain runtime image with no agent harness installed. Copying
DAYTONA_SNAPSHOT into AGENTA_RUNNER_DAYTONA_SNAPSHOT boots agents into an image that cannot run
them. The agent runner needs its own snapshot, agenta-agent-sandbox-v1, built by the recipe in
Run agents in a cloud sandbox (Daytona).
Warm sessions and scale
A session stays warm between turns so a follow-up turn skips a cold start. Both providers pool
sessions, but they budget different things: the Daytona pool budgets billed compute, and the local
pool budgets host memory inside the runner container. All of these are read by the runner service,
and all are safe to leave unset.
Daytona, one warm sandbox per parked session:
| Variable | Role | Default | Secret | Helm |
|---|---|---|---|---|
AGENTA_RUNNER_DAYTONA_SESSION_IDLE_TTL_MS | How long a sandbox stays running with its live session after a clean turn | 120000 (2 minutes) | no | ...daytona.sessionIdleTtlMs |
AGENTA_RUNNER_DAYTONA_SESSION_MAX_WARM | How many idle sandboxes may stay running between turns | 20 | no | ...daytona.sessionMaxWarm |
Set AGENTA_RUNNER_DAYTONA_SESSION_IDLE_TTL_MS to 0 to stop a sandbox after each turn. There is
no separate enable flag. AGENTA_RUNNER_DAYTONA_SESSION_MAX_WARM bounds idle spend only; it never
blocks an active turn. Overflow sandboxes park in the stopped state.
AGENTA_RUNNER_DAYTONA_SESSION_IDLE_TTL_MS must stay below
AGENTA_RUNNER_DAYTONA_AUTOSTOP_MINUTES. Autostop is Daytona's own idle timer, and it does not
know about the runner's warm pool. If the TTL is the longer of the two, Daytona stops a sandbox the
runner still believes is warm: the next turn takes the cold path anyway, and you paid for the warm
window without getting it. The defaults (2 minutes against 15) satisfy this. Raise autostop first
whenever you raise the TTL.
Local, one pooled harness process per parked session inside the runner container:
| Variable | Role | Default | Secret | Helm |
|---|---|---|---|---|
AGENTA_RUNNER_SESSION_POOL_MAX | How many local sessions may stay pooled | 8 | no | agentRunner.env.AGENTA_RUNNER_SESSION_POOL_MAX |
AGENTA_RUNNER_SESSION_TTL_MS | Idle lifetime of a pooled local session | 60000 (1 minute) | no | agentRunner.env.AGENTA_RUNNER_SESSION_TTL_MS |
AGENTA_RUNNER_SESSION_APPROVAL_TTL_MS | Idle lifetime while a run waits for a human approval | 300000 (5 minutes) | no | agentRunner.env.AGENTA_RUNNER_SESSION_APPROVAL_TTL_MS |
AGENTA_RUNNER_SESSION_KEEPALIVE | Whether local sessions are reused at all | Enabled | no | agentRunner.env.AGENTA_RUNNER_SESSION_KEEPALIVE |
Local keep-alive is on by default. Set AGENTA_RUNNER_SESSION_KEEPALIVE=off (0, false, and no
also work) to make every local turn take the cold path, which trades latency for a lower and more
predictable memory ceiling. The approval TTL is longer than the plain TTL on purpose: a run parked
on a human approval is waiting on a person, not wedged. These four apply to the local provider
only; Daytona ignores them and uses the two variables above.
A Daytona sandbox moves through three states:
| State | When | Billing |
|---|---|---|
| Running | While a turn executes, and during the warm window after a clean turn | Compute and disk |
| Stopped | After AGENTA_RUNNER_DAYTONA_AUTOSTOP_MINUTES idle minutes | Disk only; restart is cheap and the session reloads on the same instance |
| Deleted | After AGENTA_RUNNER_DAYTONA_AUTODELETE_MINUTES idle minutes | None; the next turn creates a fresh sandbox and reloads the working directory from the store |
Run limits
Four deadlines bound a single run. They exist because a wedged run holds its sandbox, its mount, and
its socket while the platform still reports the session healthy, so without a deadline a stuck run
bills forever. Whichever limit trips first aborts the run and releases everything the run held. All
four are read by the runner service and apply to every provider.
| Variable | Role | Default | Secret | Helm |
|---|---|---|---|---|
AGENTA_RUNNER_RUN_TOTAL_TIMEOUT_MS | Hard deadline for one run, measured from the first message | 2700000 (45 minutes) | no | agentRunner.env.AGENTA_RUNNER_RUN_TOTAL_TIMEOUT_MS |
AGENTA_RUNNER_RUN_IDLE_TIMEOUT_MS | Longest gap between two progress events before the run is abandoned | 300000 (5 minutes) | no | agentRunner.env.AGENTA_RUNNER_RUN_IDLE_TIMEOUT_MS |
AGENTA_RUNNER_RUN_TTFB_TIMEOUT_MS | Longest wait for the first response after the run starts | 120000 (2 minutes) | no | agentRunner.env.AGENTA_RUNNER_RUN_TTFB_TIMEOUT_MS |
AGENTA_RUNNER_TOOL_CALL_TIMEOUT_MS | Longest a single tool call may take | 300000 (5 minutes) | no | agentRunner.env.AGENTA_RUNNER_TOOL_CALL_TIMEOUT_MS |
The defaults are deliberately wide, so a long, healthy agent run never trips them. Lower the total deadline to cap the cost of one run. Lower the idle and TTFB timeouts to fail a broken harness fast.
Three rules govern how they interact:
- A run paused for a human approval is exempt from all four. The pause freezes every timer, because a person taking an hour to answer is a legitimate wait, not a wedge.
- The idle timeout must stay below the total deadline, or it could never fire first. A value at or above the total is clamped to half the total, and the runner logs the clamp rather than failing to start.
- The TTFB timer only covers the wait for the first response. The first progress event of any kind cancels it and arms the idle timer instead.
An invalid value (not a number, or negative) falls back to the default for that variable. These are
the runner's own deadlines and are unrelated to AGENTA_RUNNER_TIMEOUT_SECONDS, which is the
caller's idle timeout on the streaming transport.
Callback API
Set on the runner service. It gives the runner the in-network address of the API for session
heartbeats, working-directory mount signing, and the trace-export fallback.
| Variable | Role | Default | Helm |
|---|---|---|---|
AGENTA_API_INTERNAL_URL | API locator for runner callbacks | Compose: http://api:8000 | Wired by the chart |
Point this at the API as reached from inside the runner container (its Compose or cluster service
name, for example http://api:8000), not the public URL, which does not resolve inside a
container. If it is unset, the runner falls back to the public AGENTA_API_URL and then to the
base inferred from each request.
Internal settings
The runner reads two more variables that exist for debugging and for custom sandbox images. They are not part of the supported configuration surface and may change without notice. Leave them unset on a normal deployment. Every other variable the runner reads is documented above.
AGENTA_RUNNER_DEBUG_TOOLS: when set to any value, the runner logs verbose tool-callback diagnostics to standard error. Unset by default.AGENTA_AGENT_SANDBOX_PI_DIR: where the Pi agent directory lives inside a Daytona sandbox, defaulting to/home/sandbox/.pi/agent. This describes the sandbox image's own layout, not the deployment. Change it only if you build a custom snapshot that puts Pi somewhere else.
Startup validation
The runner fails to start when configuration is invalid, before it listens. The exact messages:
| Cause | Error |
|---|---|
| Enabled list is set but empty | AGENTA_RUNNER_ENABLED_SANDBOX_PROVIDERS is set but empty; unset it for the default 'local', or list at least one provider. |
| Empty entry in the enabled list | AGENTA_RUNNER_ENABLED_SANDBOX_PROVIDERS has an empty entry in '<list>'. |
| Unknown provider id in the enabled list | AGENTA_RUNNER_ENABLED_SANDBOX_PROVIDERS lists unknown provider '<id>'; known providers: local, daytona. |
| Duplicate provider id | AGENTA_RUNNER_ENABLED_SANDBOX_PROVIDERS lists provider '<id>' more than once. |
| Default is an unknown provider | AGENTA_RUNNER_DEFAULT_SANDBOX_PROVIDER is unknown provider '<id>'; known providers: local, daytona. |
| Default not in the enabled set | AGENTA_RUNNER_DEFAULT_SANDBOX_PROVIDER '<id>' is not in the enabled set [<list>]. Add it to AGENTA_RUNNER_ENABLED_SANDBOX_PROVIDERS or change the default. |
| Daytona enabled without a key | AGENTA_RUNNER_DAYTONA_API_KEY is required when 'daytona' is in AGENTA_RUNNER_ENABLED_SANDBOX_PROVIDERS. |
| Snapshot and image both set | AGENTA_RUNNER_DAYTONA_SNAPSHOT and AGENTA_RUNNER_DAYTONA_IMAGE are mutually exclusive; set only one. |
| Non-integer positive value | <variable> must be a positive integer, got '<value>'. |
The last message covers AGENTA_RUNNER_PORT, AGENTA_RUNNER_CONCURRENCY_LIMIT,
AGENTA_RUNNER_DAYTONA_AUTOSTOP_MINUTES, and AGENTA_RUNNER_DAYTONA_AUTODELETE_MINUTES.
On a valid start, the runner logs one redacted summary. No credential value or source path is logged.
runner providers enabled=[local,daytona] default=local
runner daytona target=eu artifact=snapshot:agenta-agent-sandbox-v1
The first line always prints. The second line appears only when daytona is enabled. target
reads default when AGENTA_RUNNER_DAYTONA_TARGET is unset, and artifact reads
snapshot:agenta-agent-sandbox-v1 (the pinned default), snapshot:<name>, or image:<name>
depending on what is set.
Troubleshooting
A run fails with Sandbox provider '<id>' is not enabled on this deployment (enabled: <list>).
The run requested a provider that is not in AGENTA_RUNNER_ENABLED_SANDBOX_PROVIDERS. Add it and
recreate the runner, or change the run to use an enabled provider.
Services cannot reach the runner, or calls are rejected.
Check that AGENTA_RUNNER_INTERNAL_URL points at the runner and that AGENTA_RUNNER_TOKEN
matches on both the Services API and the runner. A token set on one side only rejects the call.
A self-managed local run fails because the harness has no login.
The subscription mount is missing or PI_CODING_AGENT_DIR / CLAUDE_CONFIG_DIR does not point at
it. See Use your own subscription.
A self-managed run requested Daytona and failed. Personal subscriptions are local-only. Run Daytona with a managed model key instead. See Sandbox isolation and security.
A run fails naming a missing Pi executable. The Daytona snapshot or image lacks the pinned Pi and the runtime install failed. Rebuild the snapshot with the recipe.
The runner fails to start with a Daytona authentication error.
AGENTA_RUNNER_DAYTONA_API_KEY is wrong or lacks access to the target. Check the key and
AGENTA_RUNNER_DAYTONA_TARGET.
Durable working directories do not persist across turns, and the runner logs a mount-degradation warning. A Daytona sandbox could not reach the store. Make the store publicly reachable. See Run agents in a cloud sandbox (Daytona).