11 KiB
Proposal: Move Static v1 HTTP Endpoints into ACP Extensions
Goal
Keep GET /v1/health as the only static control endpoint, except for dedicated binary filesystem transfer endpoints.
Move all other current static v1 HTTP routes to ACP JSON-RPC methods (Sandbox Agent extensions under _sandboxagent/...) on /v1/rpc.
Retain these HTTP endpoints intentionally:
GET /v1/fs/filePUT /v1/fs/filePOST /v1/fs/upload-batch
No implementation in this proposal. This is a migration plan.
Current State (from server/packages/sandbox-agent/src/router.rs)
Static v1 endpoints today:
GET /v1/agentsPOST /v1/agents/:agent/installGET /v1/sessionsGET /v1/sessions/:session_idGET /v1/fs/entriesGET /v1/fs/filePUT /v1/fs/fileDELETE /v1/fs/entryPOST /v1/fs/mkdirPOST /v1/fs/moveGET /v1/fs/statPOST /v1/fs/upload-batch
Non-static ACP transport endpoints (remain):
POST /v1/rpcGET /v1/rpc(SSE)DELETE /v1/rpc
Health endpoint (remain):
GET /v1/health
Proposed Target Surface
Keep:
GET /v1/healthPOST/GET/DELETE /v1/rpcGET /v1/fs/filePUT /v1/fs/filePOST /v1/fs/upload-batch
Remove all other static v1 control/file routes after migration.
Add ACP extension methods:
_sandboxagent/agent/list_sandboxagent/agent/install_sandboxagent/session/list_sandboxagent/session/get_sandboxagent/fs/list_entries_sandboxagent/fs/read_file(parallel with HTTP)_sandboxagent/fs/write_file(parallel with HTTP)_sandboxagent/fs/delete_entry_sandboxagent/fs/mkdir_sandboxagent/fs/move_sandboxagent/fs/stat_sandboxagent/fs/upload_batch(parallel with HTTP)
Interpretation for clients: all agent/session operations and non-binary filesystem operations move to ACP extension calls over /v1/rpc. Binary file transfer has a dual surface: ACP equivalents exist in parallel, but HTTP remains the primary transport for large/streaming payloads.
Endpoint-to-Method Mapping
| Existing HTTP | New ACP method | Notes |
|---|---|---|
GET /v1/agents |
_sandboxagent/agent/list |
Response keeps current AgentListResponse shape for low migration risk. |
POST /v1/agents/:agent/install |
_sandboxagent/agent/install |
Params include agent, reinstall, agentVersion, agentProcessVersion. |
GET /v1/sessions |
_sandboxagent/session/list |
Return current SessionListResponse shape (not ACP unstable list shape). |
GET /v1/sessions/:session_id |
_sandboxagent/session/get |
Return current SessionInfo shape; error on missing session. |
GET /v1/fs/entries |
_sandboxagent/fs/list_entries |
Preserve path + optional sessionId resolution semantics. |
GET /v1/fs/file |
keep HTTP + _sandboxagent/fs/read_file |
HTTP is primary because responses may require large streaming reads; ACP variant exists for compatibility/smaller payloads. |
PUT /v1/fs/file |
keep HTTP + _sandboxagent/fs/write_file |
HTTP is primary for large binary writes; ACP variant exists for compatibility/smaller payloads. |
DELETE /v1/fs/entry |
_sandboxagent/fs/delete_entry |
Preserve recursive directory delete behavior. |
POST /v1/fs/mkdir |
_sandboxagent/fs/mkdir |
Preserve create-dir behavior. |
POST /v1/fs/move |
_sandboxagent/fs/move |
Preserve overwrite behavior. |
GET /v1/fs/stat |
_sandboxagent/fs/stat |
Preserve FsStat shape. |
POST /v1/fs/upload-batch |
keep HTTP + _sandboxagent/fs/upload_batch |
HTTP is primary for large tar uploads; ACP variant exists for compatibility/smaller payloads. |
ACP Contract Details
Capability Advertisement
Extend initialize metadata (_meta[sandboxagent.dev].extensions) in acp_runtime/ext_meta.rs with booleans + method names for all new methods above, same pattern as existing:
sessionDetach,sessionTerminate,sessionListModels,sessionSetMetadata, etc.
Add keys for new extensions (agentList, agentInstall, fsListEntries, fsStat, ...).
Filesystem Exception (Intentional)
GET/PUT /v1/fs/file and POST /v1/fs/upload-batch stay as first-class Sandbox Agent HTTP APIs.
Reason:
- These operations are host/runtime capabilities implemented by Sandbox Agent, not agent-process behavior.
- Keeping them server-owned gives consistent behavior across agents.
- ACP envelopes are JSON-RPC payloads and are not suitable for streaming very large binary files efficiently.
GET /v1/fs/filespecifically needs efficient streamed responses for large reads.
ACP parity note:
- Maintain ACP extension equivalents in parallel (
_sandboxagent/fs/read_file,_sandboxagent/fs/write_file,_sandboxagent/fs/upload_batch) for compatibility. - ACP and HTTP variants should call the same underlying filesystem service code path to keep behavior consistent.
- ACP variants are not intended for very large file transfer workloads.
Error Mapping
Keep existing SandboxError -> ProblemDetails semantics over HTTP transport. For extension methods, surface structured JSON-RPC error payloads that map to existing invalid request / not found behavior.
TypeScript Client Impact Assessment
Current behavior in sdks/typescript/src/client.ts:
listAgentsandinstallAgentcall static HTTP endpoints.listSessionsandgetSessioncall static HTTP endpoints.- FS helpers (
listFsEntries,readFsFile,writeFsFile,deleteFsEntry,mkdirFs,moveFs,statFs,uploadFsBatch) call static HTTP endpoints. - ACP/session methods already use ACP (
newSession,loadSession,prompt, etc).
Required change for ACP-only behavior:
- Reimplement non-binary helpers above as ACP extension wrappers via
acp.extMethod(...). - Keep method names stable in
SandboxAgentClientto minimize user breakage. - Make ACP-backed helpers connection-scoped (same as ACP methods): they must throw
NotConnectedErrorwhen disconnected. - Keep direct HTTP helper calls only for:
getHealth()readFsFile()(GET /v1/fs/file)writeFsFile()(PUT /v1/fs/file)uploadFsBatch()(POST /v1/fs/upload-batch)
- Keep ACP variants available through low-level
extMethod(...)for advanced/smaller-payload use cases, but do not make them the SDK default path.
Package boundary after migration:
acp-http-clientremains protocol-pure ACP transport and genericextMethod/extNotification.sandbox-agentremains the typed wrapper that maps convenience methods to_sandboxagent/...extension methods.- No direct
/v1/agents*,/v1/sessions*, or non-binary/v1/fs/*fetches in SDK runtime code. - Binary file transfer keeps direct HTTP fetches on the three endpoints listed above.
- SDK policy: prefer HTTP for
readFsFile/writeFsFile/uploadFsBatcheven if ACP extension variants exist.
Type changes expected in sdks/typescript/src/types.ts:
- Add typed request/response interfaces for new ACP extension methods.
- Keep compatibility aliases where needed (
bytes_writtenandbytesWritten, etc.) for one migration window.
Integration test impact (sdks/typescript/tests/integration.test.ts):
- Replace assumptions that agent/session/fs helpers are usable without ACP connection.
- Add coverage that helpers work after
connect()and use ACP extension paths end-to-end. - Keep real-server runtime tests (no fetch mocks for server behavior).
Bootstrap Model (Important)
Today, first call to a new ACP server id should be initialize, and requires params._meta["sandboxagent.dev"].agent.
Implication after migration:
- Agent and ACP-backed filesystem control methods must run on an ACP connection.
- Bootstrap flow should use
initializewith_meta["sandboxagent.dev"].agent = "mock"for control-plane-only clients before calling extension methods.
Alternative (optional): introduce a runtime-only control connection mode that does not require backend agent init. This is a larger behavior change and can be deferred.
Phased Migration Plan
Phase 1: Add ACP Extension Equivalents
- Add methods to runtime extension handlers (
acp_runtime/ext_methods.rs). - Reuse existing router/support mapping logic where possible to keep response parity.
- Keep binary file-transfer ACP methods in parallel with HTTP (
_sandboxagent/fs/read_file,_sandboxagent/fs/write_file,_sandboxagent/fs/upload_batch) and route both surfaces through shared implementation code. - Advertise new capabilities in
acp_runtime/ext_meta.rs. - Add ACP extension tests for each new method in
server/packages/sandbox-agent/tests/v1_api/acp_extensions.rs.
Phase 2: Migrate Clients (No HTTP Route Removal Yet)
- TypeScript SDK (
sdks/typescript/src/client.ts):- Repoint
listAgents,installAgent,listSessions,getSession,listFsEntries,deleteFsEntry,mkdirFs,moveFs, andstatFsto ACP extension calls. - Keep
readFsFile,writeFsFile, anduploadFsBatchon HTTP endpoints. - Remove direct runtime fetch usage for
/v1/agents*,/v1/sessions*, and non-binary/v1/fs/*. - Keep method names stable for callers.
- Move these methods to connected-only semantics (
NotConnectedErrorwhen disconnected).
- Repoint
- CLI (
server/packages/sandbox-agent/src/cli.rs):- Make
api agents list/installcall ACP extension methods (via ACP post flow), not direct/v1/agents*HTTP calls.
- Make
- Inspector flow/docs:
- Stop depending on
GET /v1/agentsin startup path; use ACP extension instead.
- Stop depending on
Phase 3: Remove Static Endpoints (Except Health + Binary FS Transfer)
- Remove route registrations for
/v1/agents*,/v1/sessions*,/v1/fs/entries,/v1/fs/entry,/v1/fs/mkdir,/v1/fs/move,/v1/fs/statfromrouter.rs. - Keep
/v1/health,/v1/rpc,GET /v1/fs/file,PUT /v1/fs/file, andPOST /v1/fs/upload-batch. - Optional short deprecation period: convert removed routes to
410 Gonewith explicit extension method indetail.
Phase 4: Docs/OpenAPI/Test Cleanup
- Regenerate
docs/openapi.json(should now primarily describe/v1/health,/v1/rpc, and retained binary fs transfer endpoints). - Update:
docs/cli.mdxdocs/inspector.mdxdocs/sdks/typescript.mdx
- Replace current
control_plane.rsHTTP-route assertions with ACP-extension assertions.
Validation Plan
Server:
- ACP extension integration tests for all new methods.
- Auth parity checks (token required behavior unchanged).
- Existing ACP transport tests unchanged and green.
SDK:
- Real-server integration tests verify moved helpers now use ACP extensions.
- No fetch transport mocks for server behavior.
CLI:
api agents list/installe2e tests validate ACP-backed behavior.
Inspector:
- Browser e2e (
agent-browser) still passes with ACP-only startup path.
Rollout Strategy
- Ship Phase 1 + 2 behind no route removals.
- Verify SDK/CLI/Inspector consume ACP extensions in CI.
- Remove static endpoints in one cut (Phase 3).
- Land docs/openapi updates immediately with removal.
Open Decisions
- Should removed
/v1/agents*,/v1/sessions*, and non-binary/v1/fs/*return410for one release or be dropped immediately? - Do we keep a strict response-shape parity layer for session/file methods, or normalize to ACP-native shapes?
- Should
/service-root remain as informational HTTP, or be treated as out-of-scope for this “only health static + binary fs transfer” policy?