Skip to content
View as .md

Runtime

The model in one line: secrets live on the house; environments live on the house, bind the secrets they need, and target one sandbox; sandboxes run code on daytona by default.

Three CLI command groups manage arbe’s runtime layer: sandboxes run code, environments configure them, and secrets store credentials. For the underlying concepts, see daytona runtime, system/environments, and system/secrets.

What it takes to dispatch

Dispatch runs in-process — see dispatch. An env-bound thread is a normal thread whose bots get a sandbox to reach via the run_command tool; selection and authorship are identical to a local thread. Three things must line up for it to round-trip:

  • the worker has OPENROUTER_API_KEY (the default in-process pi-ai key);
  • the house has the provider key required by the env-bound model (for example, openrouter/... needs OPENROUTER_API_KEY);
  • the environment names a runtime and the worker can reach it: daytona (the default) provisions on demand via DAYTONA_API_KEY; the legacy sprite runtime instead needs the house’s SPRITES_TOKEN (secrets).

The sandbox is the bot’s hands, reached per tool call. Envs stay useful even with one sandbox: they’re the seam for named profiles — different repos or secret sets per branch — and for splitting one sandbox across configurations.

Sandboxes

A sandbox is a remote machine + working tree where a bot’s hands run. Daytona is the runtime; you rarely provision one by hand — creating an environment auto-provisions a daytona box (DAYTONA_API_KEY), and delegate_task spins a fresh box per coding run. See daytona runtime for how a run mirrors into its thread and resumes.

arbe sandbox inspects and manages machines. The CRUD verbs take --runtime daytona to act on daytona machines (identity is the daytona sandbox.id):

Terminal window
arbe sandbox list --runtime daytona # house's live daytona machines
arbe sandbox <id> --runtime daytona # detailed view
arbe sandbox stop <id> --runtime daytona # stop (start to resume)
arbe sandbox start <id> --runtime daytona
arbe sandbox destroy <id> --runtime daytona # delete

The CLI reads the house’s DAYTONA_API_KEY server-side, so no local key is needed for any verb. Bare arbe sandbox (no --runtime) targets the legacy sprite runtime and its forensics (setup, ping, diagnose, env) — see system/sandbox-sprite. arbe env diagnose <env> is the one-stop dispatch preflight: it probes the env’s sandbox plus static secret checks.

All commands accept --json for machine-readable output.

Environments

Environments link a sandbox to a house with configuration — which repo to clone and which secrets to inject. A sandbox is created once and reused across runs.

Terminal window
arbe env list # list all in the active house
arbe env view staging # detailed view with secret bindings
arbe env create staging --sandbox my-sandbox --repo https://github.com/org/repo
arbe env create openrouter --sandbox openrouter --secret OPENROUTER_API_KEY
arbe env bind-secret staging GITHUB_TOKEN # add or upgrade a binding
arbe env bind-secret staging NICE_TO_HAVE_KEY --optional # warn instead of fail
arbe env unbind-secret staging GITHUB_TOKEN # remove a binding
arbe env delete staging # remove it

When creating an environment, --sandbox is required. If you pass --repo, it’s also added to the allowed repos list. Secret bindings can be set inline at creation with --secret NAME (required) or --optional-secret NAME (warn-only) — both repeatable — or managed afterward with bind-secret / unbind-secret. Bindings store names; values resolve at dispatch — see secrets.

Aliases: ls/l for list, rm/del for delete.

Secrets

Secrets are house-scoped encrypted values. They get injected into sandboxes at runtime through environment secret bindings.

Terminal window
arbe secret list # see all in the active house
arbe secret view OPENAI_API_KEY # metadata, timestamps, audience
echo "sk-..." | arbe secret set OPENAI_API_KEY # create (or rotate if it exists)
arbe secret delete OPENAI_API_KEY # remove it

Values are always read from stdin, never passed as arguments — so they don’t end up in shell history. If a secret with the same name already exists, set rotates it rather than creating a duplicate.

Options on set:

  • --audience environment|capability controls scope (default: environment)
  • --shared makes the secret available to other agents in the same scope

Aliases: ls/l for list, rm/del for delete. All commands accept --json.

Typical setup workflow

Starting from nothing, here’s the sequence to get ready for dispatching work:

Terminal window
# 1. Store credentials (values come from stdin)
printf '%s' "$OPENROUTER_API_KEY" | arbe secret set OPENROUTER_API_KEY --shared
printf '%s' "$GITHUB_TOKEN" | arbe secret set GITHUB_TOKEN --shared
# 2. Create the environment — daytona auto-provisions the sandbox
arbe env create prod --repo https://github.com/org/repo \
--secret OPENROUTER_API_KEY --secret GITHUB_TOKEN
# 3. Dispatch work
arbe env use prod # set active env once
THREAD_ID=$(arbe thread create <parent-ref>) # active env fills in --env
arbe thread entries create "$THREAD_ID" "implement the login page"

arbe thread create --env prod <parent> is the explicit form; without --env it falls back to the active env. The leading entry kicks off dispatch — tail with arbe thread entries read "$THREAD_ID" (exits on dispatch terminals, non-zero on failed).

On www at /threads/new, step 2 collapses to ”+ Create env”: the server auto-provisions the daytona box when sandbox_id is omitted, given DAYTONA_API_KEY is configured.

Day-to-day usage is arbe thread create + arbe thread entries create, plus arbe sandbox list --runtime daytona to check live machines.

Each bot replies with its own model ref (agent.model, default openrouter/anthropic/claude-haiku-4.5). A thread-level model override can pin a conversation when needed; otherwise each agent keeps its assigned model. OPENROUTER_API_KEY is the base credential for both local pi and in-thread bot replies.