Documentation/docs/managed-agents/agent-harnesses

#Agent Harnesses

An agent harness is the Sandbox0 runtime adapter behind a Managed Agents session.

The public API still uses the Claude Managed Agents object model. The harness decides where the agent loop runs, which model API shape it expects, how credentials are projected, and how tool events are mapped back to the Managed Agents event stream.

Official references:

Execution Models#

Sandbox0 supports two execution models.

ModelHow it worksHarnesses
Agent in sandboxThe agent runtime process runs inside the per-session Sandbox0 sandbox. The sandbox contains the agent process, workspace, tools, and harness state.claude, codex
Sandbox as toolA resident runtime service runs the agent loop outside the sandbox. The sandbox is claimed lazily and exposed to the agent as tools such as bash.openai-agents

Use agent in sandbox when you want the agent process itself to live with the workspace. This is the most direct fit for coding agents that expect local files, shell commands, home-directory state, and long-lived process state inside the sandbox.

Use sandbox as tool when you want to embed an agent into a product workflow or control plane. The agent harness stays in a managed runtime service, while Sandbox0 provides isolated tool execution only when the agent needs to inspect files or run commands.

Supported Harnesses#

HarnessExecution modelRuntime adapterModel API shapeBest fit
claudeAgent in sandboxClaude Agent SDK wrapperAnthropic-compatibleClaude Code style coding agents and Anthropic-compatible providers
codexAgent in sandboxCodex app-server wrapperOpenAI-compatibleCodex app-server sessions that should keep Codex state inside the workspace
openai-agentsSandbox as toolResident OpenAI Agents Python runtimeOpenAI Responses-compatibleProduct copilots and agent workflows built on the OpenAI Agents SDK

Retry Behavior#

All supported harnesses report observable automatic retry attempts through the same Managed Agents events: session.error with error.retry_status.type = "retrying", session.status_rescheduled, then session.status_running if the run resumes.

HarnessRetry signal used by Sandbox0
claudeClaude Agent SDK system messages with subtype = "api_retry"
codexCodex app-server error notifications with willRetry = true
openai-agentsOpenAI Agents SDK runner-managed ModelRetrySettings policy decisions

Sandbox0 disables hidden OpenAI Python client retries for the openai-agents runtime and routes model retries through the OpenAI Agents SDK retry policy so retry state is visible in the session event stream.

Select A Harness#

The session harness is selected by the attached LLM vault. The metadata key remains sandbox0.managed_agents.engine for compatibility:

typescript
const claudeVault = await client.beta.vaults.create({ display_name: "Claude LLM", metadata: { "sandbox0.managed_agents.role": "llm", "sandbox0.managed_agents.engine": "claude", "sandbox0.managed_agents.llm_base_url": "https://api.anthropic.com", }, });

For codex:

typescript
const codexVault = await client.beta.vaults.create({ display_name: "Codex LLM", metadata: { "sandbox0.managed_agents.role": "llm", "sandbox0.managed_agents.engine": "codex", "sandbox0.managed_agents.llm_base_url": "https://api.openai.com/v1", }, });

For openai-agents:

typescript
const openAIAgentsVault = await client.beta.vaults.create({ display_name: "OpenAI Agents LLM", metadata: { "sandbox0.managed_agents.role": "llm", "sandbox0.managed_agents.engine": "openai-agents", "sandbox0.managed_agents.llm_base_url": "https://api.openai.com/v1", }, });

Add the model provider token to the selected LLM vault:

typescript
await client.beta.vaults.credentials.create(openAIAgentsVault.id, { display_name: "Model provider API key", auth: { type: "static_bearer", token: process.env.MODEL_API_KEY!, } as any, });

Use the vault id for the harness you want. LLM credentials must be unbound static_bearer credentials; do not set mcp_server_url for the model provider token.

Attach exactly one LLM vault to the session:

typescript
const session = await client.beta.sessions.create({ agent: agent.id, environment_id: environment.id, vault_ids: [openAIAgentsVault.id], });

If no LLM vault selects a harness, Sandbox0 defaults to claude.

AI Gateway Integration#

Managed Agents does not require Sandbox0 to own model-provider routing. You can put a third-party AI gateway between the selected agent harness and the model provider when you need protocol normalization, request logs, caching, retry policy, rate limits, budget controls, or bring-your-own-key storage.

Choose the gateway endpoint that matches the selected harness:

HarnessGateway endpoint must expose
claudeAnthropic Messages-compatible API
codexOpenAI-compatible API
openai-agentsOpenAI Responses-compatible API

If you only need to bridge a Claude Code-compatible provider into an OpenAI-style harness, LLMProxy is the simplest option. The hosted tool does not require a Sandbox0 account, an LLMProxy login, or gateway-side setup. Use the LLMProxy URL as the LLM vault base URL, keep the upstream provider token in the vault credential, and let the selected runtime call it directly.

LLMProxy

Use the free no-login protocol bridge for Claude-compatible providers and OpenAI-style harnesses.

The gateway can route to whichever upstream providers it supports. For example, Cloudflare AI Gateway, LiteLLM Proxy, Portkey, Helicone, Kong AI Gateway, Envoy AI Gateway, TrueFoundry, and similar products can sit behind an LLM vault as long as the configured gateway endpoint speaks the API shape required by the harness.

In this setup, the LLM vault stores the gateway base URL and the gateway API token. Provider keys should usually live in the AI gateway through BYOK, virtual keys, or gateway-managed billing. Sandbox0 still owns the Managed Agents API, session truth, sandbox lifecycle, workspace state, network policy, and runtime credential projection.

typescript
const cloudflareAccountId = process.env.CLOUDFLARE_ACCOUNT_ID!; const cloudflareGatewayVault = await client.beta.vaults.create({ display_name: "OpenAI Agents through Cloudflare AI Gateway", metadata: { "sandbox0.managed_agents.role": "llm", "sandbox0.managed_agents.engine": "openai-agents", "sandbox0.managed_agents.llm_base_url": `https://api.cloudflare.com/client/v4/accounts/${cloudflareAccountId}/ai/v1`, }, }); await client.beta.vaults.credentials.create(cloudflareGatewayVault.id, { display_name: "Cloudflare AI Gateway token", auth: { type: "static_bearer", token: process.env.CLOUDFLARE_API_TOKEN!, } as any, });

Configure the agent model to the gateway's model identifier, such as anthropic/claude-sonnet-4 on Cloudflare AI Gateway or the model alias configured in LiteLLM, Portkey, or another gateway.

Do not point a harness at a gateway endpoint with the wrong API shape. For example, the openai-agents harness needs an OpenAI Responses-compatible endpoint even if the gateway routes the request to an Anthropic model upstream.

Claude Harness#

The Claude harness runs the Claude Agent SDK wrapper inside the session sandbox. It expects an Anthropic-compatible API. Use it when the provider already exposes the Anthropic Messages API shape and you want Claude Code style behavior.

Sandbox0 sets compatibility environment values such as ANTHROPIC_API_KEY, ANTHROPIC_AUTH_TOKEN, and ANTHROPIC_BASE_URL, then injects the real credential through egress auth for the configured LLM host.

Codex Harness#

The Codex harness launches Codex app-server inside the session sandbox. It expects an OpenAI-compatible model endpoint. Sandbox0 stores Codex home and thread state under the session workspace so runtime state stays session-scoped.

For Minimax-compatible endpoints, Sandbox0 detects the provider from the LLM base URL and configures Codex provider settings accordingly.

OpenAI Agents Harness#

The openai-agents harness uses a resident Python runtime service built on the official OpenAI Agents SDK. The runtime receives the session snapshot from the Managed Agents gateway, runs the agent loop in the runtime service, and claims a Sandbox0 sandbox only when the agent needs sandbox tools.

This is the sandbox as tool model. The session still has durable Managed Agents event history, but the agent process is not the same process as the sandbox. The sandbox is an isolated tool target for commands and workspace work.

The harness expects an OpenAI Responses-compatible endpoint. If the target provider does not expose that API shape directly, use an AI gateway that provides an OpenAI Responses-compatible surface and routes to the provider upstream.

For self-hosted deployments, configure the OpenAI Agents runtime callback base URL to an internal gateway URL when possible. The runtime sends session events back to the Managed Agents gateway; routing that callback through a public edge can introduce avoidable policy and timeout failures.

Harness Configuration#

Agent harness behavior can be configured by deployment defaults and internal harness config. Application-level harness selection should normally happen through the LLM vault, not by putting reserved Sandbox0 keys into session metadata.

Do not use sandbox0.managed_agents.engine as session metadata. Reserved sandbox0.managed_agents.* keys are only supported on vault metadata today.

Next Steps#

Vaults

Store the selected harness, model gateway URL, and credential material.

Compatibility

Review supported behavior and current compatibility boundaries.