mirror of
https://github.com/harivansh-afk/sandbox-agent.git
synced 2026-04-15 05:02:11 +00:00
feat: add configuration for model, mode, and thought level (#205)
* feat: add configuration for model, mode, and thought level
* docs: document Claude effort-level filesystem config
* fix: prevent panic on empty modes/thoughtLevels in parse_agent_config
Use `.first()` with safe fallback instead of direct `[0]` index access,
which would panic if the Vec is empty and no default is set.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: harden session lifecycle and align cli.mdx example with claude.json
- destroySession: wrap session/cancel RPC in try/catch so local cleanup
always succeeds even when the agent is unreachable
- createSession/resumeOrCreateSession: clean up the remote session if
post-creation config calls (setMode/setModel/setThoughtLevel) fail,
preventing leaked orphan sessions
- cli.mdx: fix example output to match current claude.json (model name,
model order, and populated modes)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: harden session lifecycle and align config persistence logic
- resumeOrCreateSession: Remove destroy-on-error for the resume path. Config
errors now propagate without destroying a pre-existing session. The destroy
pattern remains in createSession (where the session is newly created and has
no prior state to preserve).
- setSessionMode fallback: When session/set_mode returns -32601 and the
fallback uses session/set_config_option, now keep modes.currentModeId
in sync with the updated currentValue. Prevents stale cached state in
getModes() when the fallback path is used.
- persistSessionStateFromMethod: Re-read the record from persistence instead
of using a stale pre-await snapshot. Prevents race conditions where
concurrent session/update events (processed by persistSessionStateFromEvent)
are silently overwritten by optimistic updates.
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
* fix: correct doc examples with valid Codex modes and update stable API list
- Replace invalid Codex mode values ("plan", "build") with valid ones
("auto", "full-access") in agent-sessions.mdx and sdk-overview.mdx
- Update CLAUDE.md stable method enumerations to include new session
config methods (setSessionMode, setSessionModel, etc.)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: add OpenAPI annotations for process endpoints and fix config persistence race
Add summary/description to all process management endpoint specs and the
not_found error type. Fix hydrateSessionConfigOptions to re-read from
persistence after the network call, and sync mode-category configOptions
on session/update current_mode_update events.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
e7343e14bd
commit
c91791f88d
18 changed files with 1675 additions and 70 deletions
127
docs/agent-capabilities.mdx
Normal file
127
docs/agent-capabilities.mdx
Normal file
|
|
@ -0,0 +1,127 @@
|
|||
---
|
||||
title: "Agent Capabilities"
|
||||
description: "Models, modes, and thought levels supported by each agent."
|
||||
---
|
||||
|
||||
Capabilities are subject to change as the agents are updated. See [Agent Sessions](/agent-sessions) for full session configuration API details.
|
||||
|
||||
|
||||
<Info>
|
||||
_Last updated: March 5th, 2026. See [Generating a live report](#generating-a-live-report) for up-to-date reference._
|
||||
</Info>
|
||||
|
||||
## Claude
|
||||
|
||||
| Category | Values |
|
||||
|----------|--------|
|
||||
| **Models** | `default`, `sonnet`, `opus`, `haiku` |
|
||||
| **Modes** | `default`, `acceptEdits`, `plan`, `dontAsk`, `bypassPermissions` |
|
||||
| **Thought levels** | Unsupported |
|
||||
|
||||
### Configuring Effort Level For Claude
|
||||
|
||||
Claude does not natively support changing effort level after a session starts, so configure it in the filesystem before creating the session.
|
||||
|
||||
```ts
|
||||
import { mkdir, writeFile } from "node:fs/promises";
|
||||
import path from "node:path";
|
||||
import { SandboxAgent } from "sandbox-agent";
|
||||
|
||||
const cwd = "/path/to/workspace";
|
||||
await mkdir(path.join(cwd, ".claude"), { recursive: true });
|
||||
await writeFile(
|
||||
path.join(cwd, ".claude", "settings.json"),
|
||||
JSON.stringify({ effortLevel: "high" }, null, 2),
|
||||
);
|
||||
|
||||
const sdk = await SandboxAgent.connect({ baseUrl: "http://127.0.0.1:2468" });
|
||||
await sdk.createSession({
|
||||
agent: "claude",
|
||||
sessionInit: { cwd, mcpServers: [] },
|
||||
});
|
||||
```
|
||||
|
||||
<Accordion title="Supported file locations (highest precedence last)">
|
||||
|
||||
1. `~/.claude/settings.json`
|
||||
2. `<session cwd>/.claude/settings.json`
|
||||
3. `<session cwd>/.claude/settings.local.json`
|
||||
|
||||
</Accordion>
|
||||
|
||||
## Codex
|
||||
|
||||
| Category | Values |
|
||||
|----------|--------|
|
||||
| **Models** | `gpt-5.3-codex` (default), `gpt-5.3-codex-spark`, `gpt-5.2-codex`, `gpt-5.1-codex-max`, `gpt-5.2`, `gpt-5.1-codex-mini` |
|
||||
| **Modes** | `read-only` (default), `auto`, `full-access` |
|
||||
| **Thought levels** | `low`, `medium`, `high` (default), `xhigh` |
|
||||
|
||||
## OpenCode
|
||||
|
||||
| Category | Values |
|
||||
|----------|--------|
|
||||
| **Models** | See below |
|
||||
| **Modes** | `build` (default), `plan` |
|
||||
| **Thought levels** | Unsupported |
|
||||
|
||||
<Accordion title="See all models">
|
||||
|
||||
| Provider | Models |
|
||||
|----------|--------|
|
||||
| **Anthropic** | `anthropic/claude-3-5-haiku-20241022`, `anthropic/claude-3-5-haiku-latest`, `anthropic/claude-3-5-sonnet-20240620`, `anthropic/claude-3-5-sonnet-20241022`, `anthropic/claude-3-7-sonnet-20250219`, `anthropic/claude-3-7-sonnet-latest`, `anthropic/claude-3-haiku-20240307`, `anthropic/claude-3-opus-20240229`, `anthropic/claude-3-sonnet-20240229`, `anthropic/claude-haiku-4-5`, `anthropic/claude-haiku-4-5-20251001`, `anthropic/claude-opus-4-0`, `anthropic/claude-opus-4-1`, `anthropic/claude-opus-4-1-20250805`, `anthropic/claude-opus-4-20250514`, `anthropic/claude-opus-4-5`, `anthropic/claude-opus-4-5-20251101`, `anthropic/claude-opus-4-6`, `anthropic/claude-sonnet-4-0`, `anthropic/claude-sonnet-4-20250514`, `anthropic/claude-sonnet-4-5`, `anthropic/claude-sonnet-4-5-20250929` |
|
||||
| **OpenAI** | `openai/gpt-5.1-codex`, `openai/gpt-5.1-codex-max`, `openai/gpt-5.1-codex-mini`, `openai/gpt-5.2`, `openai/gpt-5.2-codex`, `openai/gpt-5.3-codex` |
|
||||
| **Cerebras** | `cerebras/gpt-oss-120b`, `cerebras/qwen-3-235b-a22b-instruct-2507`, `cerebras/zai-glm-4.7` |
|
||||
| **OpenCode Zen** | `opencode/big-pickle`, `opencode/claude-3-5-haiku`, `opencode/claude-haiku-4-5`, `opencode/claude-opus-4-1`, `opencode/claude-opus-4-5`, `opencode/claude-opus-4-6`, `opencode/claude-sonnet-4`, `opencode/claude-sonnet-4-5`, `opencode/gemini-3-flash`, `opencode/gemini-3-pro` (default), `opencode/glm-4.6`, `opencode/glm-4.7`, `opencode/gpt-5`, `opencode/gpt-5-codex`, `opencode/gpt-5-nano`, `opencode/gpt-5.1`, `opencode/gpt-5.1-codex`, `opencode/gpt-5.1-codex-max`, `opencode/gpt-5.1-codex-mini`, `opencode/gpt-5.2`, `opencode/gpt-5.2-codex`, `opencode/kimi-k2`, `opencode/kimi-k2-thinking`, `opencode/kimi-k2.5`, `opencode/kimi-k2.5-free`, `opencode/minimax-m2.1`, `opencode/minimax-m2.1-free`, `opencode/trinity-large-preview-free` |
|
||||
|
||||
</Accordion>
|
||||
|
||||
## Cursor
|
||||
|
||||
| Category | Values |
|
||||
|----------|--------|
|
||||
| **Models** | See below |
|
||||
| **Modes** | Unsupported |
|
||||
| **Thought levels** | Unsupported |
|
||||
|
||||
<Accordion title="See all models">
|
||||
|
||||
| Group | Models |
|
||||
|-------|--------|
|
||||
| **Auto** | `auto` |
|
||||
| **Composer** | `composer-1.5`, `composer-1` |
|
||||
| **GPT-5.3 Codex** | `gpt-5.3-codex`, `gpt-5.3-codex-low`, `gpt-5.3-codex-high`, `gpt-5.3-codex-xhigh`, `gpt-5.3-codex-fast`, `gpt-5.3-codex-low-fast`, `gpt-5.3-codex-high-fast`, `gpt-5.3-codex-xhigh-fast` |
|
||||
| **GPT-5.2** | `gpt-5.2`, `gpt-5.2-high`, `gpt-5.2-codex`, `gpt-5.2-codex-low`, `gpt-5.2-codex-high`, `gpt-5.2-codex-xhigh`, `gpt-5.2-codex-fast`, `gpt-5.2-codex-low-fast`, `gpt-5.2-codex-high-fast`, `gpt-5.2-codex-xhigh-fast` |
|
||||
| **GPT-5.1** | `gpt-5.1-high`, `gpt-5.1-codex-max`, `gpt-5.1-codex-max-high` |
|
||||
| **Claude** | `opus-4.6-thinking` (default), `opus-4.6`, `opus-4.5`, `opus-4.5-thinking`, `sonnet-4.5`, `sonnet-4.5-thinking` |
|
||||
| **Other** | `gemini-3-pro`, `gemini-3-flash`, `grok` |
|
||||
|
||||
</Accordion>
|
||||
|
||||
## Amp
|
||||
|
||||
| Category | Values |
|
||||
|----------|--------|
|
||||
| **Models** | `amp-default` |
|
||||
| **Modes** | `default`, `bypass` |
|
||||
| **Thought levels** | Unsupported |
|
||||
|
||||
## Pi
|
||||
|
||||
| Category | Values |
|
||||
|----------|--------|
|
||||
| **Models** | `default` |
|
||||
| **Modes** | Unsupported |
|
||||
| **Thought levels** | Unsupported |
|
||||
|
||||
## Generating a live report
|
||||
|
||||
Requires a running Sandbox Agent server. `--endpoint` defaults to `http://127.0.0.1:2468`.
|
||||
|
||||
```bash
|
||||
sandbox-agent api agents report
|
||||
```
|
||||
|
||||
<Note>
|
||||
The live report reflects what the agent adapter returns for the current credentials. Some models may be gated by subscription (e.g. Claude's `opus` requires a paid plan) and will not appear in the report if the credentials don't have access.
|
||||
</Note>
|
||||
|
|
@ -82,6 +82,49 @@ if (sessions.items.length > 0) {
|
|||
}
|
||||
```
|
||||
|
||||
## Configure model, mode, and thought level
|
||||
|
||||
Set the model, mode, or thought level on a session at creation time or after:
|
||||
|
||||
```ts
|
||||
// At creation time
|
||||
const session = await sdk.createSession({
|
||||
agent: "codex",
|
||||
model: "gpt-5.3-codex",
|
||||
mode: "auto",
|
||||
thoughtLevel: "high",
|
||||
});
|
||||
```
|
||||
|
||||
```ts
|
||||
// After creation
|
||||
await session.setModel("gpt-5.2-codex");
|
||||
await session.setMode("full-access");
|
||||
await session.setThoughtLevel("medium");
|
||||
```
|
||||
|
||||
Query available modes:
|
||||
|
||||
```ts
|
||||
const modes = await session.getModes();
|
||||
console.log(modes?.currentModeId, modes?.availableModes);
|
||||
```
|
||||
|
||||
### Advanced config options
|
||||
|
||||
For config options beyond model, mode, and thought level, use `getConfigOptions` to discover what the agent supports and `setConfigOption` to set any option by ID:
|
||||
|
||||
```ts
|
||||
const options = await session.getConfigOptions();
|
||||
for (const opt of options) {
|
||||
console.log(opt.id, opt.category, opt.type);
|
||||
}
|
||||
```
|
||||
|
||||
```ts
|
||||
await session.setConfigOption("some-agent-option", "value");
|
||||
```
|
||||
|
||||
## Destroy a session
|
||||
|
||||
```ts
|
||||
|
|
|
|||
59
docs/cli.mdx
59
docs/cli.mdx
|
|
@ -167,6 +167,65 @@ Shared option:
|
|||
|
||||
```bash
|
||||
sandbox-agent api agents list [--endpoint <URL>]
|
||||
sandbox-agent api agents report [--endpoint <URL>]
|
||||
sandbox-agent api agents install <AGENT> [--reinstall] [--endpoint <URL>]
|
||||
```
|
||||
|
||||
#### api agents list
|
||||
|
||||
List all agents and their install status.
|
||||
|
||||
```bash
|
||||
sandbox-agent api agents list
|
||||
```
|
||||
|
||||
#### api agents report
|
||||
|
||||
Emit a JSON report of available models, modes, and thought levels for every agent. Calls `GET /v1/agents?config=true` and groups each agent's config options by category.
|
||||
|
||||
```bash
|
||||
sandbox-agent api agents report --endpoint http://127.0.0.1:2468 | jq .
|
||||
```
|
||||
|
||||
Example output:
|
||||
|
||||
```json
|
||||
{
|
||||
"generatedAtMs": 1740000000000,
|
||||
"endpoint": "http://127.0.0.1:2468",
|
||||
"agents": [
|
||||
{
|
||||
"id": "claude",
|
||||
"installed": true,
|
||||
"models": {
|
||||
"currentValue": "default",
|
||||
"values": [
|
||||
{ "value": "default", "name": "Default" },
|
||||
{ "value": "sonnet", "name": "Sonnet" },
|
||||
{ "value": "opus", "name": "Opus" },
|
||||
{ "value": "haiku", "name": "Haiku" }
|
||||
]
|
||||
},
|
||||
"modes": {
|
||||
"currentValue": "default",
|
||||
"values": [
|
||||
{ "value": "default", "name": "Default" },
|
||||
{ "value": "acceptEdits", "name": "Accept Edits" },
|
||||
{ "value": "plan", "name": "Plan" },
|
||||
{ "value": "dontAsk", "name": "Don't Ask" },
|
||||
{ "value": "bypassPermissions", "name": "Bypass Permissions" }
|
||||
]
|
||||
},
|
||||
"thoughtLevels": { "values": [] }
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
See [Agent Capabilities](/agent-capabilities) for a full reference of supported models, modes, and thought levels per agent.
|
||||
|
||||
#### api agents install
|
||||
|
||||
```bash
|
||||
sandbox-agent api agents install codex --reinstall
|
||||
```
|
||||
|
|
|
|||
|
|
@ -94,6 +94,7 @@
|
|||
{
|
||||
"group": "Reference",
|
||||
"pages": [
|
||||
"agent-capabilities",
|
||||
"cli",
|
||||
"inspector",
|
||||
"opencode-compatibility",
|
||||
|
|
|
|||
|
|
@ -954,6 +954,8 @@
|
|||
"tags": [
|
||||
"v1"
|
||||
],
|
||||
"summary": "List all managed processes.",
|
||||
"description": "Returns a list of all processes (running and exited) currently tracked\nby the runtime, sorted by process ID.",
|
||||
"operationId": "get_v1_processes",
|
||||
"responses": {
|
||||
"200": {
|
||||
|
|
@ -982,6 +984,8 @@
|
|||
"tags": [
|
||||
"v1"
|
||||
],
|
||||
"summary": "Create a long-lived managed process.",
|
||||
"description": "Spawns a new process with the given command and arguments. Supports both\npipe-based and PTY (tty) modes. Returns the process descriptor on success.",
|
||||
"operationId": "post_v1_processes",
|
||||
"requestBody": {
|
||||
"content": {
|
||||
|
|
@ -1042,6 +1046,8 @@
|
|||
"tags": [
|
||||
"v1"
|
||||
],
|
||||
"summary": "Get process runtime configuration.",
|
||||
"description": "Returns the current runtime configuration for the process management API,\nincluding limits for concurrency, timeouts, and buffer sizes.",
|
||||
"operationId": "get_v1_processes_config",
|
||||
"responses": {
|
||||
"200": {
|
||||
|
|
@ -1070,6 +1076,8 @@
|
|||
"tags": [
|
||||
"v1"
|
||||
],
|
||||
"summary": "Update process runtime configuration.",
|
||||
"description": "Replaces the runtime configuration for the process management API.\nValidates that all values are non-zero and clamps default timeout to max.",
|
||||
"operationId": "post_v1_processes_config",
|
||||
"requestBody": {
|
||||
"content": {
|
||||
|
|
@ -1120,6 +1128,8 @@
|
|||
"tags": [
|
||||
"v1"
|
||||
],
|
||||
"summary": "Run a one-shot command.",
|
||||
"description": "Executes a command to completion and returns its stdout, stderr, exit code,\nand duration. Supports configurable timeout and output size limits.",
|
||||
"operationId": "post_v1_processes_run",
|
||||
"requestBody": {
|
||||
"content": {
|
||||
|
|
@ -1170,6 +1180,8 @@
|
|||
"tags": [
|
||||
"v1"
|
||||
],
|
||||
"summary": "Get a single process by ID.",
|
||||
"description": "Returns the current state of a managed process including its status,\nPID, exit code, and creation/exit timestamps.",
|
||||
"operationId": "get_v1_process",
|
||||
"parameters": [
|
||||
{
|
||||
|
|
@ -1219,6 +1231,8 @@
|
|||
"tags": [
|
||||
"v1"
|
||||
],
|
||||
"summary": "Delete a process record.",
|
||||
"description": "Removes a stopped process from the runtime. Returns 409 if the process\nis still running; stop or kill it first.",
|
||||
"operationId": "delete_v1_process",
|
||||
"parameters": [
|
||||
{
|
||||
|
|
@ -1273,6 +1287,8 @@
|
|||
"tags": [
|
||||
"v1"
|
||||
],
|
||||
"summary": "Write input to a process.",
|
||||
"description": "Sends data to a process's stdin (pipe mode) or PTY writer (tty mode).\nData can be encoded as base64, utf8, or text. Returns 413 if the decoded\npayload exceeds the configured `maxInputBytesPerRequest` limit.",
|
||||
"operationId": "post_v1_process_input",
|
||||
"parameters": [
|
||||
{
|
||||
|
|
@ -1354,6 +1370,8 @@
|
|||
"tags": [
|
||||
"v1"
|
||||
],
|
||||
"summary": "Send SIGKILL to a process.",
|
||||
"description": "Sends SIGKILL to the process and optionally waits up to `waitMs`\nmilliseconds for the process to exit before returning.",
|
||||
"operationId": "post_v1_process_kill",
|
||||
"parameters": [
|
||||
{
|
||||
|
|
@ -1417,6 +1435,8 @@
|
|||
"tags": [
|
||||
"v1"
|
||||
],
|
||||
"summary": "Fetch process logs.",
|
||||
"description": "Returns buffered log entries for a process. Supports filtering by stream\ntype, tail count, and sequence-based resumption. When `follow=true`,\nreturns an SSE stream that replays buffered entries then streams live output.",
|
||||
"operationId": "get_v1_process_logs",
|
||||
"parameters": [
|
||||
{
|
||||
|
|
@ -1515,6 +1535,8 @@
|
|||
"tags": [
|
||||
"v1"
|
||||
],
|
||||
"summary": "Send SIGTERM to a process.",
|
||||
"description": "Sends SIGTERM to the process and optionally waits up to `waitMs`\nmilliseconds for the process to exit before returning.",
|
||||
"operationId": "post_v1_process_stop",
|
||||
"parameters": [
|
||||
{
|
||||
|
|
@ -1578,6 +1600,8 @@
|
|||
"tags": [
|
||||
"v1"
|
||||
],
|
||||
"summary": "Resize a process terminal.",
|
||||
"description": "Sets the PTY window size (columns and rows) for a tty-mode process and\nsends SIGWINCH so the child process can adapt.",
|
||||
"operationId": "post_v1_process_terminal_resize",
|
||||
"parameters": [
|
||||
{
|
||||
|
|
@ -1659,6 +1683,8 @@
|
|||
"tags": [
|
||||
"v1"
|
||||
],
|
||||
"summary": "Open an interactive WebSocket terminal session.",
|
||||
"description": "Upgrades the connection to a WebSocket for bidirectional PTY I/O. Accepts\n`access_token` query param for browser-based auth (WebSocket API cannot\nsend custom headers). Streams raw PTY output as binary frames and accepts\nJSON control frames for input, resize, and close.",
|
||||
"operationId": "get_v1_process_terminal_ws",
|
||||
"parameters": [
|
||||
{
|
||||
|
|
@ -2013,6 +2039,7 @@
|
|||
"permission_denied",
|
||||
"not_acceptable",
|
||||
"unsupported_media_type",
|
||||
"not_found",
|
||||
"session_not_found",
|
||||
"session_already_exists",
|
||||
"mode_not_supported",
|
||||
|
|
|
|||
|
|
@ -115,6 +115,25 @@ await restored.prompt([{ type: "text", text: "Continue from previous context." }
|
|||
await sdk.destroySession(restored.id);
|
||||
```
|
||||
|
||||
## Session configuration
|
||||
|
||||
Set model, mode, or thought level at creation or on an existing session:
|
||||
|
||||
```ts
|
||||
const session = await sdk.createSession({
|
||||
agent: "codex",
|
||||
model: "gpt-5.3-codex",
|
||||
});
|
||||
|
||||
await session.setModel("gpt-5.2-codex");
|
||||
await session.setMode("auto");
|
||||
|
||||
const options = await session.getConfigOptions();
|
||||
const modes = await session.getModes();
|
||||
```
|
||||
|
||||
See [Agent Sessions](/agent-sessions) for full details on config options and error handling.
|
||||
|
||||
## Events
|
||||
|
||||
Subscribe to live events:
|
||||
|
|
@ -188,13 +207,3 @@ Parameters:
|
|||
- `waitForHealth` (optional, defaults to enabled): waits for `/v1/health` before HTTP helpers and ACP session setup proceed; pass `false` to disable or `{ timeoutMs }` to bound the wait
|
||||
- `signal` (optional): aborts the startup `/v1/health` wait used by `connect()`
|
||||
|
||||
## Types
|
||||
|
||||
```ts
|
||||
import type {
|
||||
AgentInfo,
|
||||
HealthResponse,
|
||||
SessionEvent,
|
||||
SessionRecord,
|
||||
} from "sandbox-agent";
|
||||
```
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue