Skip to content

feat(computer): add Daytona cloud sandbox provider and unify computer gateway - #57

Closed
mu-hashmi wants to merge 8 commits into
CopilotKit:mainfrom
mu-hashmi:feat/daytona-provider
Closed

feat(computer): add Daytona cloud sandbox provider and unify computer gateway#57
mu-hashmi wants to merge 8 commits into
CopilotKit:mainfrom
mu-hashmi:feat/daytona-provider

Conversation

@mu-hashmi

Copy link
Copy Markdown
Contributor

Summary

This change adds support for Daytona cloud sandboxes to OpenBot. Each Bot can now run in its own isolated cloud container with Chromium, Playwright, and bash access.

This change also refactors the computer subsystem into three clear layers:

  • server/src/computer/provider.ts defines the ComputerProvider interface (locate, status, stop, reset, list, warm) for Daytona, Docker supervisor, and shared environments.
  • server/src/computer/daytona.ts implements the Daytona cloud backend. It builds container snapshots from agent-computer/, manages sandbox lifecycles, and resolves preview URLs.
  • server/src/computer/gateway.ts consolidates governance into a single module. It resolves element references before policy evaluation, enforces Common Expression Language (CEL) rules, writes audit events, and manages human takeover.
  • server/src/computer/client.ts operates as a pure HTTP transport client without lifecycle logic.

Key Decisions

  • Lifecycle serialization: An in-memory queue (runLifecycle) serializes locate, stop, and reset operations per Bot ID. This prevents concurrent creation races during rapid requests.
  • Monotonic reset masking: Daytona list queries have eventual-consistency delays. A deleted sandbox ID is stored in a map to prevent deleted sandboxes from appearing in subsequent status reads.
  • Snapshot caching: The provider computes a SHA-256 hash of the agent-computer/ directory. It reuses existing snapshots when the hash matches.
  • Security enforcement: Configuration validation requires COMPUTER_TOKEN whenever DAYTONA_API_KEY is present. It also rejects configurations that set both DAYTONA_API_KEY and COMPUTER_SUPERVISOR_URL.

Limitations

  • Lifecycle queues serialize operations within a single process instance only. Deployments with multiple API server replicas need external coordination for cross-process lifecycle locks.

Verification

Ran the test suite in server/:

  • Command: bun test tests/computer* tests/config*
  • Result: 163 tests passed across 10 files in 395ms (0 failures, 388 assertions).
  • Tests cover snapshot caching, sandbox lifecycle transitions, monotonic reset masking, concurrency serialization, element reference resolution, CEL action policy denial, and configuration validation.

Signed-off-by: Muhammad Hashmi <mhashmi@berkeley.edu>
Signed-off-by: Muhammad Hashmi <mhashmi@berkeley.edu>
Signed-off-by: Muhammad Hashmi <mhashmi@berkeley.edu>
Signed-off-by: Muhammad Hashmi <mhashmi@berkeley.edu>
Signed-off-by: Muhammad Hashmi <mhashmi@berkeley.edu>
Signed-off-by: Muhammad Hashmi <mhashmi@berkeley.edu>
Signed-off-by: Muhammad Hashmi <mhashmi@berkeley.edu>
Signed-off-by: Muhammad Hashmi <mhashmi@berkeley.edu>
@davidmckayv

Copy link
Copy Markdown
Contributor

Closing this, with thanks — the part we wanted is already in.

The provider seam from this work is on main (server/src/computer/provider.ts), and the changelog credits it to you: "Where a Bot's computer runs is now a plug. One ComputerProvider interface sits under the gateway... A computer somewhere else is an adapter rather than a change to the governed path." That refactor is the durable contribution here and it is what makes a remote backend possible at all.

The Daytona backend itself we took out deliberately rather than by oversight, so it is not sitting in another branch waiting — that decision is why there is nothing matching daytona on main.

If you want to take the seam further, the interesting question now is isolation rather than another provider: code a model wrote, on a computer shared between Bots, is not contained by the container it runs in. A per-Bot backend with gVisor or a microVM under it is the shape that matters, and the seam you built is where it plugs in.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants