mirror of
https://github.com/harivansh-afk/sandbox-agent.git
synced 2026-04-15 22:03:48 +00:00
366 lines
15 KiB
Markdown
366 lines
15 KiB
Markdown
# V1 Spec: ACP Over HTTP
|
|
|
|
## 0) Delete/Remove First
|
|
|
|
Before implementing v1, remove in-house protocol files and remove v1 API behavior as documented in:
|
|
|
|
- `research/acp/00-delete-first.md`
|
|
- `research/acp/v1-schema-to-acp-mapping.md` (endpoint/event-by-event conversion target)
|
|
|
|
This is mandatory to prevent dual-protocol drift.
|
|
|
|
## 1) Goals
|
|
|
|
- v1 is intentionally breaking and ACP-native.
|
|
- Internal runtime uses ACP end-to-end (no custom universal event schema).
|
|
- Existing agent managers are replaced with ACP agent process runtimes.
|
|
- v1 API is completely removed; all `/v1/*` requests return explicit removed errors.
|
|
- OpenCode <-> ACP support is preserved as a product requirement, but implemented in a separate step after ACP core is stable.
|
|
|
|
## 2) Non-goals for first v1 cut
|
|
|
|
- No guarantee of v1 endpoint compatibility.
|
|
- No v1 compatibility layer in the initial v1 release.
|
|
- No OpenCode compatibility during ACP core bring-up (`/opencode/*` is disabled until the dedicated bridge step).
|
|
- No in-house universal event format.
|
|
|
|
## 3) Protocol baseline
|
|
|
|
Use ACP v1 schema from:
|
|
|
|
- `~/misc/acp-docs/schema/schema.json`
|
|
- `~/misc/acp-docs/schema/meta.json`
|
|
- `research/acp/v1-schema-to-acp-mapping.md` (required for preserving v1 feature coverage during migration)
|
|
|
|
Supported agent methods (minimum):
|
|
|
|
- `initialize`, `authenticate` (if needed), `session/new`, `session/prompt`, `session/cancel`
|
|
|
|
Supported client methods (minimum):
|
|
|
|
- `session/request_permission`
|
|
|
|
Included unstable ACP methods for v1 profile:
|
|
|
|
- `session/list`
|
|
- `session/fork`
|
|
- `session/resume`
|
|
- `session/set_model`
|
|
- `$/cancel_request`
|
|
|
|
Phase-1 optional methods (still optional per agent process capability):
|
|
|
|
- `fs/read_text_file`, `fs/write_text_file`
|
|
- `terminal/*`
|
|
- `session/load`, `session/set_mode`, `session/set_config_option`
|
|
|
|
Sandbox Agent ACP extension methods currently implemented:
|
|
|
|
- `_sandboxagent/session/detach`
|
|
- `_sandboxagent/session/list_models`
|
|
- `_sandboxagent/session/set_metadata`
|
|
- `_sandboxagent/session/request_question` (agent -> client request pattern)
|
|
- `_sandboxagent/session/terminate`
|
|
- `_sandboxagent/session/ended` (runtime -> client notification)
|
|
|
|
## 4) Transport: ACP over HTTP (repo-specific draft)
|
|
|
|
ACP streamable HTTP is draft upstream, so this spec defines a concrete transport that stays close to current ACP transport guidance and JSON-RPC semantics.
|
|
|
|
### 4.1 Endpoints
|
|
|
|
- `POST /v1/rpc`
|
|
- `GET /v1/rpc` (SSE stream, `Accept: text/event-stream`)
|
|
- `DELETE /v1/rpc` (explicit connection close)
|
|
|
|
### 4.2 Connection model
|
|
|
|
- Each ACP HTTP connection maps to a logical client connection id (`X-ACP-Connection-Id`).
|
|
- Agent processes are shared per `AgentId` (one backend process per agent type on a server), not per HTTP connection.
|
|
- Session inventory is server-global in memory across connections; `session/list` returns this aggregated inventory.
|
|
- Connection identity is `X-ACP-Connection-Id` header.
|
|
- First `initialize` request may omit `X-ACP-Connection-Id` and must include `params._meta["sandboxagent.dev"].agent`.
|
|
- Server ensures backend exists for that agent, creates connection, returns `X-ACP-Connection-Id` in response headers.
|
|
- All subsequent `POST /v1/rpc` and `GET /v1/rpc` requests must include `X-ACP-Connection-Id`.
|
|
- `DELETE /v1/rpc` with `X-ACP-Connection-Id` detaches/closes only the transport connection and releases connection-scoped resources.
|
|
- `DELETE /v1/rpc` does not terminate the session or agent process. Session termination is explicit via `_sandboxagent/session/terminate`.
|
|
|
|
### 4.3 Message routing
|
|
|
|
- Client -> agent requests/notifications: sent as JSON-RPC payloads to `POST /v1/rpc`.
|
|
- Agent -> client notifications/requests: delivered on `GET /v1/rpc` SSE stream as JSON-RPC envelopes.
|
|
- Client replies to agent-initiated requests by POSTing JSON-RPC responses to `POST /v1/rpc`.
|
|
|
|
### 4.4 SSE framing
|
|
|
|
- `event: message`
|
|
- `id: <monotonic-sequence>`
|
|
- `data: <single JSON-RPC object>`
|
|
|
|
Keepalive:
|
|
|
|
- SSE comment heartbeat every 15s.
|
|
|
|
Resume:
|
|
|
|
- `Last-Event-ID` accepted for best-effort replay from in-memory ring buffer.
|
|
|
|
### 4.5 HTTP status and errors
|
|
|
|
- JSON-RPC request success: HTTP 200 with JSON-RPC response object.
|
|
- JSON-RPC notification accepted: HTTP 202, empty body.
|
|
- Invalid envelope: HTTP 400 with `application/problem+json`.
|
|
- Unknown connection: HTTP 404 with `application/problem+json`.
|
|
- Server timeout waiting on agent process response: HTTP 504 with `application/problem+json`.
|
|
- Successful `DELETE /v1/rpc`: HTTP 204.
|
|
- Repeated `DELETE /v1/rpc` on an already-closed connection: HTTP 204 (idempotent close).
|
|
- All `/v1/*` endpoints: HTTP 410 with `application/problem+json` and message `v1 API removed; use /v1`.
|
|
|
|
Note: ACP method-level failures still return JSON-RPC error objects inside 200 responses.
|
|
|
|
### 4.6 Ordering and concurrency
|
|
|
|
- Per-connection outbound SSE order is preserved.
|
|
- JSON-RPC `id` is opaque and passed through unchanged.
|
|
- Multiple in-flight requests are allowed.
|
|
|
|
### 4.7 Security
|
|
|
|
- Reuse existing bearer token auth middleware.
|
|
- Validate bearer auth at request time for `/v1/*` routes when configured.
|
|
- ACP runtime connection ids are in-memory server ids and are not additionally principal-scoped inside runtime.
|
|
- Do not expose agent process stderr on stdout channel.
|
|
|
|
### 4.8 Field research alignment (2026-02-10)
|
|
|
|
Based on current ACP community implementations/discussion:
|
|
|
|
- Streamable HTTP and WebSocket are both being piloted.
|
|
- Streamable HTTP implementations are converging on MCP-like request patterns while keeping ACP JSON-RPC payloads.
|
|
- WebSocket implementations report simpler handling for bidirectional/server-initiated ACP traffic.
|
|
|
|
Decision for this repo:
|
|
|
|
- v1 public transport remains Streamable HTTP (`POST`/`GET` SSE over `/v1/rpc`) as the canonical contract.
|
|
- WebSocket transport is not part of initial v1 surface; consider later only if HTTP profile proves insufficient operationally.
|
|
|
|
Reference:
|
|
|
|
- `research/acp/acp-over-http-findings.md`
|
|
|
|
## 5) Agent process runtime and install model
|
|
|
|
## 5.1 Runtime
|
|
|
|
Replace custom per-agent protocol parsers with one ACP agent process process contract:
|
|
|
|
- Spawn ACP agent process binary (stdio JSON-RPC).
|
|
- Bridge stdio <-> internal ACP client dispatcher.
|
|
- No agent-specific JSON parsing in server core.
|
|
|
|
## 5.2 Installers
|
|
|
|
Current auto-installer installs native CLIs. v1 installer must install:
|
|
|
|
- native agent binary (if needed by agent process)
|
|
- ACP agent process binary required for that agent
|
|
|
|
Add a manifest-driven mapping (new file to create in implementation phase):
|
|
|
|
- `claude`: agent process `claude-code-acp`
|
|
- `codex`: agent process `codex-acp`
|
|
- `opencode`: native ACP mode (agent process optional)
|
|
- `amp`: pending decision (official agent process required or unsupported in v1 initial release)
|
|
|
|
## 5.3 ACP Registry install instructions
|
|
|
|
Yes, this must be handled.
|
|
|
|
V1 installer/docs must include install instructions sourced from ACP registry metadata where available, with explicit fallback for non-registry agent processes.
|
|
|
|
Requirements:
|
|
|
|
- Maintain a local agent process manifest with:
|
|
- registry slug (if present)
|
|
- agent process package/repo source
|
|
- native agent dependency
|
|
- supported platform matrix
|
|
- install verification command
|
|
- Prefer ACP registry source of truth when agent process is published there.
|
|
- If agent process is not in registry, use pinned fallback source and mark as `non_registry`.
|
|
- Support `SANDBOX_AGENT_ACP_REGISTRY_URL` override for controlled/test environments.
|
|
- Generate user-facing install instructions from this manifest (do not hand-maintain per-agent docs).
|
|
- Expose install provenance in API/CLI (`registry` vs `fallback`).
|
|
|
|
Output surfaces:
|
|
|
|
- `GET /v1/agents`: include agent process install source + verification status.
|
|
- `POST /v1/agents/{agent}/install`: return concrete installed artifacts and source provenance.
|
|
|
|
## 5.4 Install commands and lazy agent process install
|
|
|
|
This must match current ergonomics where installs can be explicit or automatic.
|
|
|
|
Explicit install interfaces:
|
|
|
|
- API: `POST /v1/agents/{agent}/install`
|
|
- CLI (v1 surface): `sandbox-agent api v1 agents install <agent> [--reinstall] [--agent-version <v>] [--agent process-version <v>]`
|
|
|
|
Lazy install behavior (default on):
|
|
|
|
- Trigger point: first ACP bootstrap request (`initialize`) on `/v1/rpc` with `params._meta["sandboxagent.dev"].agent`.
|
|
- If required binaries are missing, server installs:
|
|
- ACP agent process
|
|
- native agent binary if agent process requires it
|
|
- Then server starts the agent process process and continues normal ACP handshake.
|
|
|
|
Operational requirements:
|
|
|
|
- Per-agent install lock to prevent duplicate concurrent downloads.
|
|
- Idempotent install response when artifacts already exist.
|
|
- Clear provenance in result (`registry` vs `fallback`) plus concrete artifact versions.
|
|
- Config switch to disable lazy install (`require_preinstall=true`) for controlled environments.
|
|
|
|
## 6) Public v1 API shape
|
|
|
|
Expose ACP directly, not custom session endpoints.
|
|
|
|
- `POST /v1/rpc`: transport write path
|
|
- `GET /v1/rpc`: transport read path (SSE)
|
|
|
|
Non-ACP endpoints retained in v1:
|
|
|
|
- `GET /v1/health`
|
|
- `GET /v1/agents` (capabilities + install status)
|
|
- `POST /v1/agents/{agent}/install`
|
|
- `GET /v1/sessions`
|
|
- `GET /v1/sessions/{id}`
|
|
- `GET /v1/fs/file`
|
|
- `PUT /v1/fs/file`
|
|
- `POST /v1/fs/upload-batch`
|
|
- `GET /ui/` (Inspector UI shell)
|
|
|
|
Agent discovery note:
|
|
|
|
- Do not add standalone `/v1/agents/{agent}/models` or `/v1/agents/{agent}/modes` endpoints.
|
|
- Expose optional `models`/`modes` properties on agent response payloads when the agent is installed.
|
|
|
|
Legacy endpoints retained only as removals:
|
|
|
|
- `ALL /v1/*` return HTTP 410 with a stable "v1 removed" error body.
|
|
- `/opencode/*` is commented out/disabled until Phase 7 and is expected to be broken during ACP core bring-up.
|
|
|
|
Everything related to prompting/sessions/permissions/tools happens through ACP JSON-RPC messages.
|
|
|
|
## 6.3 Filesystem Boundary (Intentional)
|
|
|
|
Sandbox Agent keeps a separate host-owned filesystem API from ACP native filesystem methods.
|
|
|
|
Rationale:
|
|
|
|
- ACP `fs/*` methods are agent-protocol capabilities and can vary by agent implementation.
|
|
- Sandbox Agent filesystem HTTP endpoints are host/runtime capabilities and should behave consistently across all agents.
|
|
- Large binary transfers (raw file read/write and tar upload) need streaming-friendly HTTP behavior; ACP JSON-RPC envelopes are not suitable for super-large binary payload transport.
|
|
- `GET /v1/fs/file` specifically benefits from HTTP response streaming for large reads.
|
|
|
|
For this reason, `GET /v1/fs/file`, `PUT /v1/fs/file`, and `POST /v1/fs/upload-batch` remain dedicated HTTP endpoints even as other static control APIs migrate to ACP extensions.
|
|
|
|
Parallel ACP compatibility is still supported:
|
|
|
|
- Keep ACP extension variants in parallel for these operations.
|
|
- ACP and HTTP variants should call into the same underlying filesystem service logic so behavior remains consistent.
|
|
- ACP variants are not intended for very large file transfer; SDK defaults should prefer HTTP for these methods.
|
|
|
|
## 6.1 TypeScript SDK integration (mandatory)
|
|
|
|
Use the existing ACP TypeScript SDK (`@agentclientprotocol/sdk`) inside our SDK implementation.
|
|
|
|
Rules:
|
|
|
|
- Do not build a second in-house ACP protocol implementation in `sdks/typescript`.
|
|
- Wrap and embed ACP SDK primitives (`ClientSideConnection`/transport handling) in our SDK surface.
|
|
- Implement our own ACP-over-HTTP transport agent process for the SDK because the official ACP client SDK does not currently provide our required Streamable HTTP client behavior out of the box.
|
|
- Keep our SDK focused on:
|
|
- auth/token handling
|
|
- endpoint/bootstrap convenience
|
|
- spawn/embedded server ergonomics
|
|
- product-specific helper APIs
|
|
- ACP message framing, JSON-RPC lifecycle, and protocol object modeling should come from upstream ACP SDK.
|
|
|
|
## 6.2 Inspector (mandatory)
|
|
|
|
The inspector must be ACP-native in v1.
|
|
|
|
- Replace v1 session/event calls in inspector with ACP-over-HTTP connection flow (`initialize`, `session/new`, `session/prompt`, streamed `session/update`).
|
|
- Add inspector support for rendering raw ACP envelopes and decoded session updates.
|
|
- Keep inspector route at `/ui/`; remove dependency on v1 REST session endpoints.
|
|
- Inspector end-to-end verification is mandatory via `agent-browser` automation (not only unit/integration tests).
|
|
|
|
## 7) Data model changes (breaking)
|
|
|
|
Removed from public contract:
|
|
|
|
- `UniversalEvent`
|
|
- `UniversalItem`
|
|
- custom `permission.reply` and `question.reply` REST endpoints
|
|
- v1 `sessions/*` REST resources
|
|
|
|
Added:
|
|
|
|
- raw ACP JSON-RPC envelopes over HTTP
|
|
- explicit connection identity (`X-ACP-Connection-Id`)
|
|
|
|
## 8) Test contract for v1
|
|
|
|
Consolidated must-have suites (duplicates collapsed):
|
|
|
|
- ACP protocol conformance (JSON-RPC + ACP schema/semantics)
|
|
- Transport contract (`/v1/rpc` POST/SSE routing, ordering, replay, errors)
|
|
- End-to-end agent process matrix (includes core turn flow, cancel, HITL, streaming)
|
|
- Installer suite (explicit + lazy install, registry/fallback provenance)
|
|
- Security/auth isolation
|
|
- TypeScript SDK end-to-end (embedded + server mode, embedding `@agentclientprotocol/sdk`)
|
|
- v1 removal contract suite (`/v1/*` => HTTP 410 + stable error payload)
|
|
- Inspector ACP suite executed with `agent-browser` (ACP session flow + streaming render correctness)
|
|
- OpenCode <-> ACP bridge suite (dedicated later phase)
|
|
|
|
No synthetic protocol fixtures. Use real agent processes in integration tests.
|
|
|
|
Minimum required `agent-browser` inspector coverage:
|
|
|
|
1. Open `/ui/`, spawn an agent/session, send one message, and verify a response is rendered.
|
|
|
|
Current automation entrypoint:
|
|
|
|
- `frontend/packages/inspector/tests/agent-browser.e2e.sh`
|
|
- `server/packages/sandbox-agent/tests/v1_agent_process_matrix.rs` (deterministic agent process matrix smoke + JSON-RPC conformance checks)
|
|
|
|
## 9) Open questions to resolve before implementation lock
|
|
|
|
- Amp agent process availability and support level for v1 launch.
|
|
- Whether additional non-binary filesystem endpoints remain HTTP or migrate to ACP extensions after initial cut.
|
|
|
|
## 10) Deferred Dedicated Step: OpenCode <-> ACP
|
|
|
|
- During ACP core implementation, `/opencode/*` is commented out/disabled.
|
|
- After ACP core is stable, complete the dedicated OpenCode <-> ACP bridge step and re-enable `/opencode/*`.
|
|
- Mark the step complete only after dedicated integration tests pass.
|
|
|
|
## 11) Companion Docs
|
|
|
|
- `research/acp/v1-schema-to-acp-mapping.md` (normative 1:1 endpoint/event mapping)
|
|
- `research/acp/migration-steps.md` (execution order and rollout steps)
|
|
- `research/acp/todo.md` (phase checklist and validation tracker)
|
|
- `research/acp/acp-over-http-findings.md` (community transport findings and decision context)
|
|
- `research/acp/friction.md` (ongoing issue/decision log)
|
|
- `docs/quickstart.mdx`, `docs/cli.mdx`, `docs/sdks/typescript.mdx` (external migration and rollout guidance)
|
|
|
|
## 12) Documentation Updates (mandatory)
|
|
|
|
When implementing this spec, update docs in the same change set:
|
|
|
|
- API reference/openapi docs for v1 and `/v1/*` removal semantics
|
|
- `docs/cli.mdx` for v1 ACP and removed v1 commands
|
|
- `docs/inspector.mdx` for ACP-based inspector behavior
|
|
- SDK docs (`docs/sdks/typescript.mdx`) for ACP-over-HTTP transport usage
|
|
- Any OpenCode compatibility docs that reference `/opencode/*`
|