Skip to content

LambChat: Migrating an Agent Platform's Sandbox to CubeSandbox ​

Business Context ​

LambChat is a multi-tenant Agent system with integrated Skills capabilities, built on deepagents / LangGraph. Its core concept is the "digital space": every user binds to a resident sandbox that persists across sessions — users install packages, upload files, and let the Agent tinker freely. The sandbox layer supports three backends — E2B, CubeSandbox, Daytona — switchable by changing a single config field.

Key Challenges ​

  • Isolation as a hard requirement: free user tinkering must never let one user's actions affect other users or the host.
  • Lifecycle of user-level persistent sandboxes: auto-pause when idle, auto-resume on return, memory state preserved.
  • Control-plane / data-plane state inconsistency: after resume, the control plane shows running while the data-plane envd isn't ready and returns 504.
  • The bash -lc login shell: the e2b SDK launches a fresh login shell per execution by default, so environment variables don't persist across two-phase tasks.

Solution with Cube Sandbox ​

  • Inheritance-based adaptation: CubeSandboxBackend inherits E2BBackend and only overrides the differences (ls via an inline Python script, get_info with camelCase/snake_case bidirectional compatibility, Cube-only pause, and list_user_sandboxes enumerating by metadata.user_id) — about 200 lines of adaptation code.
  • User-level persistent binding + four-level lookup chain: in-memory LRU cache → MongoDB binding reconnect (sandbox.connect()) → enumerate and reuse existing sandboxes → create new; plus a fifth-level fallback that asynchronously cleans up duplicate sandboxes for the same user.
  • AutoPause configuration: on_timeout=pause + auto_resume=true at creation — auto-pause when idle, auto-resume on request.
  • 504 tolerance: health checks hit both the control-plane state and a lightweight data-plane request; a 504 is judged unhealthy, triggering fallback to another sandbox or a new one.
  • Login-shell workaround: explicitly re-set environment variables that must persist between two-phase tasks instead of relying on shell state.

Results and Benefits ​

  • Switching from the default backend to CubeSandbox took ~300 lines of code and one day — made possible by E2B protocol compatibility allowing direct base-class inheritance.
  • KVM hardware-level isolation plus pause/resume memory-state preservation supports the "one user, one resident sandbox" digital-space model.
  • Five distilled selection suggestions: decide binding granularity first; E2B compatibility is leverage; treat resume state inconsistency as an anomaly; know the bash -lc problem in advance; differentiated capabilities (snapshots / templates / network policies) can come later.

References ​