feat(copilot): E2B cloud sandbox — unified file tools, persistent execution, output truncation - #12212
Conversation
The tool supplement previously used a static `/tmp/copilot-<session>/` placeholder, so the agent had no idea what its real working directory was and wasted turns probing wrong paths before getting an error. Now the exact cwd is pre-computed and formatted into the prompt so the agent knows immediately where it can read and write.
There was a problem hiding this comment.
Your free trial has ended. If you'd like to continue receiving code reviews, you can add a payment method here.
🔍 PR Overlap DetectionThis check compares your PR against all other open PRs targeting the same branch to detect potential merge conflicts early. 🔴 Merge Conflicts DetectedThe following PRs have been tested and will have merge conflicts if merged after this PR. Consider coordinating with the authors.
🟢 Low Risk — File Overlap OnlyThese PRs touch the same files but different sections (click to expand)
Summary: 2 conflict(s), 0 medium risk, 6 low risk (out of 8 PRs with file overlap) Auto-generated on push. Ignores: |
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
WalkthroughAdds optional E2B sandbox support to CoPilot: E2B-aware tool selection and disallowed lists, sandbox lifecycle with Redis persistence, two-way workspace sync, E2B-backed MCP file tools and E2B execution path for bash_exec, config flags/validators, async workspace-file handling, tests and compose entries for end-to-end validation. Changes
Sequence Diagram(s)sequenceDiagram
participant Client
participant SDK_Service as SDK Service
participant Redis
participant E2B as E2B Sandbox
participant LocalFS as Local Filesystem
participant Tool as bash_exec/MCP
Client->>SDK_Service: stream_chat_completion_sdk(session_id, ...)
SDK_Service->>Redis: get_or_create_sandbox(session_id, api_key, template, timeout) [if configured]
Redis-->>SDK_Service: sandbox_id / metadata
SDK_Service->>E2B: initialize AsyncSandbox (get_or_create_sandbox)
SDK_Service->>LocalFS: ensure sdk_cwd exists
SDK_Service->>E2B: sync_from_sandbox(sandbox, sdk_cwd)
SDK_Service->>SDK_Service: build system prompt + _build_sdk_tool_supplement(cwd, use_e2b)
SDK_Service->>Tool: set_execution_context(user_id, session, sandbox) and invoke tools
alt sandbox present
Tool->>E2B: _execute_on_e2b(command, workdir, env, timeout)
E2B-->>Tool: execution result / files
else no sandbox
Tool->>LocalFS: run bubblewrap-local command
LocalFS-->>Tool: execution result / files
end
SDK_Service->>E2B: sync_to_sandbox(sandbox, sdk_cwd) /* persist outputs */
SDK_Service-->>Client: stream completion / tool results
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
Suggested labels
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@autogpt_platform/backend/backend/copilot/sdk/service.py`:
- Around line 461-465: Compute the SDK working directory once with
_precomputed_cwd = _make_sdk_cwd(session_id) and use that same variable
everywhere instead of recomputing cwd later (remove the second call that
re-derives cwd around the code that currently uses it), and ensure any
exceptions from _make_sdk_cwd propagate into the main error-handling path
(either by awaiting it where exceptions bubble up or by catching and
re-raising/logging via the existing stream error handler). Update references to
the recomputed cwd to use _precomputed_cwd and keep the call to
_build_sdk_tool_supplement(_precomputed_cwd) as the single source-of-truth so
the prompt and execution directory cannot drift.
ℹ️ Review info
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Disabled knowledge base sources:
- Linear integration is disabled
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (1)
autogpt_platform/backend/backend/copilot/sdk/service.py
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
- GitHub Check: types
- GitHub Check: test (3.12)
- GitHub Check: test (3.13)
- GitHub Check: Check PR Status
🧰 Additional context used
📓 Path-based instructions (4)
autogpt_platform/backend/**/*.py
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
autogpt_platform/backend/**/*.py: Use Python 3.11 (required; managed by Poetry via pyproject.toml) for backend development
Always run 'poetry run format' (Black + isort) before linting in backend development
Always run 'poetry run lint' (ruff) after formatting in backend development
Files:
autogpt_platform/backend/backend/copilot/sdk/service.py
autogpt_platform/backend/**/*.{py,txt}
📄 CodeRabbit inference engine (autogpt_platform/backend/CLAUDE.md)
Use
poetry runprefix for all Python commands, including testing, linting, formatting, and migrations
Files:
autogpt_platform/backend/backend/copilot/sdk/service.py
autogpt_platform/backend/backend/**/*.py
📄 CodeRabbit inference engine (autogpt_platform/backend/CLAUDE.md)
Use Prisma ORM for database operations in PostgreSQL with pgvector for embeddings
Files:
autogpt_platform/backend/backend/copilot/sdk/service.py
autogpt_platform/**/*.py
📄 CodeRabbit inference engine (AGENTS.md)
Format Python code with
poetry run format
Files:
autogpt_platform/backend/backend/copilot/sdk/service.py
🧬 Code graph analysis (1)
autogpt_platform/backend/backend/copilot/sdk/service.py (1)
autogpt_platform/backend/backend/copilot/service.py (1)
_build_system_prompt(211-242)
🔇 Additional comments (1)
autogpt_platform/backend/backend/copilot/sdk/service.py (1)
86-139: Good improvement to tool supplement clarity and deterministic cwd injection.This segment cleanly replaces the placeholder path with a concrete cwd and adds a clearer “Working directory” section for the agent.
… feat/improve-copilot-file
- Wrap _make_sdk_cwd() in try/except so a ValueError yields a clean StreamError rather than propagating outside the stream error path - Reuse _precomputed_cwd inside the try block instead of recomputing, ensuring the system prompt and execution directory cannot drift - Reset frontend files (useCredits.ts, client.ts) to dev state — they were carried in from a master hotfix that is not yet in dev
makedirs can raise OSError which was previously outside the stream error-handling path. Move it into the early try/except alongside _make_sdk_cwd, widen the catch to (ValueError, OSError), and remove the now-redundant sdk_cwd = "" initialiser — sdk_cwd is assigned directly from _precomputed_cwd before the main try block.
_precomputed_cwd was a pointless intermediate. sdk_cwd is now set directly from _make_sdk_cwd() in the early try/except and used everywhere, eliminating the redundant variable.
…execution bash_exec now routes to E2B sandbox.commands.run() when CHAT_USE_E2B_SANDBOX=true, giving full internet access, persistent /home/user across turns, and pre-installed packages — without requiring any special container capabilities. Workspace sync approach (replaces FUSE/sshfs which can't reach E2B's HTTP-proxy infrastructure): at turn start, files are downloaded from E2B /home/user → sdk_cwd via E2B's files API so SDK tools see the previous turn's state; at turn end, local files are uploaded back so bash_exec sees SDK-tool writes next turn. Config: set CHAT_USE_E2B_SANDBOX=true and E2B_API_KEY in backend/.env. New files: - backend/copilot/tools/e2b_sandbox.py — sandbox lifecycle + sync helpers - backend/test_e2b_integration.py — docker-compose e2e test Changes: - config.py — added use_e2b_sandbox, e2b_api_key, template, timeout fields - tool_adapter.py — added _current_sandbox context var + get/set helpers - bash_exec.py — E2B execution path via get_current_sandbox() - service.py — E2B setup (connect/create + sync_from) and teardown (sync_to) - Dockerfile — updated comment (no new packages needed) - docker-compose.yml — added e2b_integration_test service (profile: e2b-test)
Pull request was converted to draft
Covers the asyncio.TimeoutError path when E2B API calls exceed the 10s wait_for timeout in kill_sandbox.
autogpt-reviewer
left a comment
There was a problem hiding this comment.
PR #12212 — feat(copilot): E2B cloud sandbox — unified file tools, persistent execution, output truncation
Author: majdyz | RE-REVIEW v9 (bc57672 → 41da564) | Delta: 1 commit, 1 file changed (+16 lines) | CI: ✅ All green
🎯 Verdict: APPROVE
What Changed Since Last Approval (v8)
Single commit 41da5646 — test(copilot): add kill_sandbox timeout test
Adds test_kill_timeout_returns_false to TestKillSandbox in e2b_sandbox_test.py. The test:
- Patches
asyncio.wait_forto raiseasyncio.TimeoutError - Asserts
kill_sandbox()returnsFalse(graceful degradation, not crash) - Asserts Redis key is still cleaned up despite timeout
This was the sole remaining should-fix from our v8 review. It is now addressed. ✅
Specialist Findings (8/8 reported)
🛡️ Security ✅ — No security concerns. Test-only change with mocked dependencies. Validates Redis cleanup on timeout (prevents stale sandbox references). Path traversal protections intact from v8.
🏗️ Architecture ✅ — Clean test, correct abstraction boundary. Patches asyncio.wait_for at module level rather than reaching into E2B internals. Follows established _mock_redis/_patch_redis patterns.
⚡ Performance ✅ — Zero production code changes. No performance implications.
🧪 Testing ✅ — Well-structured test covering the last uncovered branch in kill_sandbox. The TestKillSandbox class now has 6 tests covering all branches: no key, creating state, happy path, connect failure, bytes Redis value, and timeout. Full branch coverage achieved.
📖 Quality ✅ — Excellent naming, docstring present, follows existing test patterns consistently. Proper arrange-act-assert structure.
📦 Product ✅ — No user-facing changes. Strictly positive test coverage improvement.
📬 Discussion ✅ — All review threads resolved. Sentry bot findings are pre-existing patterns already accepted at v8. No new human reviewer comments. CI fully green (all 20+ checks).
🔎 QA ✅ — Frontend loads successfully (login page renders). Backend responsive. No regressions observed.
QA Screenshots
Blockers
None.
Risk Assessment
Merge risk: LOW (feature-flagged, safely falls back to bubblewrap) | Rollback: EASY (set CHAT_USE_E2B_SANDBOX=false)
@ntindle Single commit adds the timeout test we flagged as "should-fix" in v8. All 8 specialists approve unanimously. 9th iteration — all feedback from 8 rounds fully incorporated. This is ready. Recommend merge.
Issues attributed to commits in this pull requestThis pull request was merged and Sentry observed the following issues:
|


Summary
read_file/write_file/edit_file/glob/grep) that operate directly on the E2B sandbox filesystem (/home/user). When E2B is active, these replace SDK built-inRead/Write/Edit/Glob/Grepso all tools share a single coherent filesystem withbash_exec— no sync needed.e2b_sandbox.pymanages sandbox creation and reconnection via Redis, with stale-key cleanup on reconnection failure.use_e2b_sandboxdefaults toTrue; setCHAT_USE_E2B_SANDBOX=falseto disable._truncatingwrapper and stashed (_pending_tool_outputs) to bypass SDK's head-truncation for the frontend.GenericTool.tsxnow renders bash stdout/stderr, file content, edit diffs (old/new), todo lists, and glob/grep results with category-specific icons and status text.read_workspace_file'ssave_to_pathandwrite_workspace_file'ssource_pathroute to E2B sandbox when active.Files changed
sdk/e2b_file_tools.py,sdk/e2b_file_tools_test.pytools/e2b_sandbox.pysdk/tool_adapter.pysdk/service.pysdk/security_hooks.py,sdk/security_hooks_test.pytools/bash_exec.pytools/workspace_files.py,tools/workspace_files_test.pycopilot/config.pyutil/truncate.pyGenericTool.tsxTest plan
security_hooks_test.py— 43 tests (path validation, tool access, deny messages)e2b_file_tools_test.py— 19 tests (path resolution, local read safety)workspace_files_test.py— 17 tests (ephemeral path validation)