sandbox-agent/examples/cloudflare
Nathan Flurry 76586f409f
Add ACP permission mode support to the SDK (#224)
* chore: recover hamburg workspace state

* chore: drop workspace context files

* refactor: generalize permissions example

* refactor: parse permissions example flags

* docs: clarify why fs and terminal stay native

* feat: add interactive permission prompt UI to Inspector

Add permission request handling to the Inspector UI so users can
Allow, Always Allow, or Reject tool calls that require permissions
instead of having them auto-cancelled. Wires up SDK
onPermissionRequest/respondPermission through App → ChatPanel →
ChatMessages with proper toolCallId-to-pendingId mapping.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: prevent permission reply from silently escalating "once" to "always"

Remove allow_always from the fallback chain when the user replies "once",
aligning with the ACP spec which says "map by option kind first" with no
fallback for allow_once. Also fix Inspector to use rawSend, revert
hydration guard to accept empty configOptions, and handle respondPermission
errors by rejecting the pending promise.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 21:52:43 -07:00
..
frontend Add ACP permission mode support to the SDK (#224) 2026-03-10 21:52:43 -07:00
src fix(cloudflare): fix streaming responses 2026-02-25 01:39:27 -08:00
.gitignore docs: add Cloudflare Sandbox SDK deployment guide (#57) 2026-02-03 02:15:34 -08:00
Dockerfile chore(release): update version to 0.3.0 2026-03-07 18:54:35 -08:00
package.json chore: simplify cloudflare compatibility (#191) 2026-02-23 19:31:54 +00:00
README.md fix(cloudflare): fix streaming responses 2026-02-25 01:39:27 -08:00
tsconfig.json docs: add Cloudflare Sandbox SDK deployment guide (#57) 2026-02-03 02:15:34 -08:00
vite.config.ts docs: add Cloudflare Sandbox SDK deployment guide (#57) 2026-02-03 02:15:34 -08:00
wrangler.jsonc docs: add mcp and skill session config (#106) 2026-02-09 10:13:25 +00:00

Cloudflare Sandbox Agent Example

Deploy sandbox-agent inside a Cloudflare Sandbox.

Prerequisites

  • Cloudflare account with Workers Paid plan
  • Docker running locally for wrangler dev
  • ANTHROPIC_API_KEY or OPENAI_API_KEY for the coding agents

Setup

  1. Install dependencies:
pnpm install
  1. Create .dev.vars with your API keys:
echo "ANTHROPIC_API_KEY=your-api-key" > .dev.vars

Development

Start the development server:

pnpm run dev

Test the endpoint:

curl http://localhost:8787

Test prompt routing through the SDK with a custom sandbox fetch handler:

curl -N -X POST "http://localhost:8787/sandbox/demo/prompt" \
  -H "Content-Type: application/json" \
  -H "Accept: text/event-stream" \
  -d '{"agent":"codex","prompt":"Reply with one short sentence."}'

The response is an SSE stream with events:

  • session.created
  • session.event
  • prompt.completed
  • done

Troubleshooting: only two events

If you only see:

  • outbound session/prompt
  • inbound prompt result with stopReason: "end_turn"

then ACP session/update notifications are not flowing. In Cloudflare sandbox paths this can happen if you forward AbortSignal from SDK fetch init into containerFetch(...) for long-lived ACP SSE requests.

Use:

const sdk = await SandboxAgent.connect({
  fetch: (input, init) =>
    sandbox.containerFetch(
      input as Request | string | URL,
      {
        ...(init ?? {}),
        // Avoid passing AbortSignal through containerFetch; it can drop ACP SSE updates.
        signal: undefined,
      },
      PORT,
    ),
});

Without session/update events, assistant text/tool deltas will not appear in UI streams.

Deploy

pnpm run deploy

Note: Production preview URLs require a custom domain with wildcard DNS routing. See Cloudflare Production Deployment for details.