Sandbox API

Supported agents

Every curated catalog agent, which API accepts it, and how to discover live ids.

This page answers: which agents can I run? Examples elsewhere use real catalog ids — if something is missing here, treat the live catalog as source of truth.

export SANDBOX_GATEWAY_URL="${SANDBOX_GATEWAY_URL:-http://localhost:8780}"

# Curated catalog (Tier 1) — what Agent runs accept
curl -sS -H "X-Api-Key: $SANDBOX_API_KEY" \
  "$SANDBOX_GATEWAY_URL/sandbox/v1/catalog?kind=agent"

# Catalog ∪ Harbor factory (Tier 2) — each item has source: catalog | harbor_factory
curl -sS -H "X-Api-Key: $SANDBOX_API_KEY" \
  "$SANDBOX_GATEWAY_URL/sandbox/agent/v1/agents"

Curated catalog (Tier 1)

Source: infra/catalog/agents/*.yaml. Ids below are what you pass as agent_id (Agent API) or agents[].harbor_agent (Harbor API).

IdDisplay nameNeeds model?Needs task solution/solve.sh?IntegrationUse on
opencodeOpenCodeYesNosandboxAgent + Harbor — recommended default
claude-codeClaude CodeYesNosandboxAgent + Harbor
codexOpenAI CodexYesNosandboxAgent + Harbor
gemini-cliGemini CLIYesNosandboxAgent + Harbor
openhandsOpenHandsYesNosandboxAgent + Harbor
cursor-cliCursor CLIYesNosandboxAgent + Harbor
aiderAiderYesNosandboxAgent + Harbor
cline-cliCline CLIYesNosandboxAgent + Harbor (W&B certified)
terminus-2Terminus 2YesNoharborHarbor (and Agent when catalog allows)
oracleOracle (deterministic)NoYesharborHarbor / Agent only with a task that ships solution/solve.sh

Which API?

SurfaceEnforcementWhat you may send
Agent POST /sandbox/agent/v1/runsAlways strictTier 1 catalog agent_id only → unknown → 400
Harbor …/jobs/execute-tasksSANDBOX_CATALOG_ENFORCE_AGENTSwarn (prod default): catalog or Harbor factory agent; strict: catalog only

Preconditions (do not skip)

Catalog fieldIf true
requires_modelSend model as provider/name (e.g. anthropic/claude-sonnet-4-5). Bare names are refused.
requires_reference_solutionThe agent applies the task’s own solution/solve.sh. Free-text Agent instructions without a task archive that contains that file are refused at enqueue.

oracle is for validating a task (oracle should score 1.0). It is not a coding agent for open-ended instructions.

Examples by agent

OpenCode (default for ad-hoc work)

Agent run:

curl -sS -H "X-Api-Key: $SANDBOX_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "agent_id": "opencode",
    "instruction": "List files and propose a fix for the failing test",
    "model": "anthropic/claude-sonnet-4-5",
    "agent_options": { "opencode_agent": "plan" }
  }' \
  "$SANDBOX_GATEWAY_URL/sandbox/agent/v1/runs"

Harbor agent block:

{
  "name": "builder",
  "harbor_agent": "opencode",
  "model": "anthropic/claude-opus-4-7",
  "harbor_extensions": { "opencode_agent": "build" }
}

Plan/Build and opencode_config: OpenCode flags.

Claude Code

{
  "agent_id": "claude-code",
  "instruction": "Fix the type errors",
  "model": "anthropic/claude-opus-4-7",
  "agent_options": { "agent_kwargs": { "version": "2.1.228" } }
}

CLI version is pinned in the catalog (agent_kwargs.version) so Opus 4.7+ adaptive thinking works.

Codex

{
  "agent_id": "codex",
  "instruction": "Implement the failing test",
  "model": "openai/gpt-5",
  "agent_options": {
    "agent_kwargs": { "model_reasoning_effort": "high" }
  }
}

Codex defaults to high reasoning effort — use a reasoning-capable model. Models like gpt-4.1-mini return provider 400 (reasoning.effort unsupported).

Terminus 2 (Harbor-oriented)

{
  "name": "terminus",
  "harbor_agent": "terminus-2",
  "model": "anthropic/claude-opus-4-7",
  "pass_at_k": 8,
  "params": { "reasoning_effort": "xhigh" }
}

Keep model and effort in separate fields — never anthropic/claude-opus-max.

Oracle (task validation only)

{
  "name": "oracle",
  "harbor_agent": "oracle",
  "pass_at_k": 1
}

Requires a Harbor task archive that includes solution/solve.sh. No model.

Gemini / OpenHands / Cursor / Aider / Cline

Same Agent shape — change agent_id:

{
  "agent_id": "gemini-cli",
  "instruction": "…",
  "model": "google/gemini-2.5-pro"
}
IdTypical model form
gemini-cligoogle/…
openhandsany Gateway-certified provider your project has
cursor-cliGateway-certified provider
aiderGateway-certified provider
cline-clioften wandb/… (certified)

You never send the provider API key in the body — workers obtain credentials via SANDBOX_LLM_EGRESS (KeyHive lease or LLM Gateway). See Provisioning.

Tier 2 — Harbor factory

GET /sandbox/agent/v1/agents may list additional Harbor AgentFactory agents with "source": "harbor_factory". Those ids work on Harbor when enforcement is warn or off. They are rejected on Agent runs.

ModeHarborAgent runs
strictUnknown → 400Always strict
warn (prod default)Factory agents allowedAlways strict
offNo catalog checkAlways strict

Options passthrough

FieldWherePurpose
agent_optionsAgent APIPreferred name on Agent runs
harbor_extensionsHarbor API (and deprecated alias on Agent)Same power-user flags
agents[].paramsHarborMerged into Harbor --ak

Common keys: agent_env, sandbox (docker / daytona / k8s), n_concurrent, opencode_agent, opencode_config, agent_kwargs. Full matrix: OpenCode flags.

Daytona (Harbor only — worker needs DAYTONA_API_KEY):

{
  "task_slug": "my-task",
  "sandbox": "daytona",
  "agents": [{ "name": "a", "harbor_agent": "codex", "model": "openai/gpt-5" }],
  "metadata": { "task_archive_url": "https://…" }
}

Catalog profiles and languages

Agents are not the only catalog kind. Discover the rest the same way:

# Workspace / desktop profiles (driver_hint → pod, VM, or external)
curl -sS -H "X-Api-Key: $SANDBOX_API_KEY" \
  "$SANDBOX_GATEWAY_URL/sandbox/v1/catalog?kind=profile"

# CodeEdit languages
curl -sS -H "X-Api-Key: $SANDBOX_API_KEY" \
  "$SANDBOX_GATEWAY_URL/sandbox/v1/catalog?kind=language"
# or: GET /sandbox/codeedit/v1/languages
Profile iddriver_hintSubstrateEnabled by default?
sandboxes-defaultk8sPodYes
desktop-ubuntuk8sPod + noVNCYes
desktop-windowsec2-vmWindows VMNo — after verify
desktop-macosexternalExternal MacNo — after verify
harbor-defaultk8sPodYes
agent-defaultk8sPodYes
codeedit-defaultdockerDocker-style execYes
Language id (dev)Entrypoint
python3.12main.py
cpp20main.cpp

Always prefer the live catalog over this table — environments can enable extra entries.