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/...needsOPENROUTER_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’sSPRITES_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):
arbe sandbox list --runtime daytona # house's live daytona machinesarbe sandbox <id> --runtime daytona # detailed viewarbe sandbox stop <id> --runtime daytona # stop (start to resume)arbe sandbox start <id> --runtime daytonaarbe sandbox destroy <id> --runtime daytona # deleteThe 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.
arbe env list # list all in the active housearbe env view staging # detailed view with secret bindingsarbe env create staging --sandbox my-sandbox --repo https://github.com/org/repoarbe env create openrouter --sandbox openrouter --secret OPENROUTER_API_KEYarbe env bind-secret staging GITHUB_TOKEN # add or upgrade a bindingarbe env bind-secret staging NICE_TO_HAVE_KEY --optional # warn instead of failarbe env unbind-secret staging GITHUB_TOKEN # remove a bindingarbe env delete staging # remove itWhen 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.
arbe secret list # see all in the active housearbe secret view OPENAI_API_KEY # metadata, timestamps, audienceecho "sk-..." | arbe secret set OPENAI_API_KEY # create (or rotate if it exists)arbe secret delete OPENAI_API_KEY # remove itValues 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|capabilitycontrols scope (default:environment)--sharedmakes 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:
# 1. Store credentials (values come from stdin)printf '%s' "$OPENROUTER_API_KEY" | arbe secret set OPENROUTER_API_KEY --sharedprintf '%s' "$GITHUB_TOKEN" | arbe secret set GITHUB_TOKEN --shared
# 2. Create the environment — daytona auto-provisions the sandboxarbe env create prod --repo https://github.com/org/repo \ --secret OPENROUTER_API_KEY --secret GITHUB_TOKEN
# 3. Dispatch workarbe env use prod # set active env onceTHREAD_ID=$(arbe thread create <parent-ref>) # active env fills in --envarbe 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.