feat: daytona + e2b for sandbox - #565
Conversation
…es via SSM - Introduced the `ec2_ssm` provider to allow attach-only execution on existing EC2 instances using AWS Systems Manager (SSM). - Updated documentation to include setup instructions for `e2b`, `daytona`, and `ec2_ssm` providers. - Added examples for the `ec2_ssm` provider, including a demo script and configuration files. - Modified existing documentation to reflect the new providers and their capabilities. - Ensured that isolation warnings and prerequisites are clearly stated for the `ec2_ssm` provider.
…es for clarity - Updated references from SandboxManager to ExecutionManager throughout the codebase. - Renamed SandboxBroker to ExecutionBroker, SandboxBrokerRequest to ExecutionRequest, and SandboxCompletion to ExecutionCompletion. - Adjusted tests and documentation to reflect the new naming conventions. - Introduced environment lifecycle management with 'managed' and 'attached' options for profiles. - Enhanced validation for profile configurations regarding environment ownership. - Updated examples and documentation to clarify the use of the ec2_ssm provider in attached environments.
…stent shell behavior
…adability and maintainability
amithad
left a comment
There was a problem hiding this comment.
Reviewed against ak-dev-architecture, ak-dev-new-sandbox-provider, ak-dev-code-quality, and ak-dev-testing-conventions. Overall this is a strong, complete PR — the SandboxManager→ExecutionManager rename is mechanical and thorough, the managed/attached lifecycle is well-designed (fail-closed factory validation in both directions, capabilities declared honestly), and the three providers follow the new-sandbox-provider checklist end to end (factory if/elif + _BUILTIN_PROVIDER_NAMES, config blocks on both _SandboxProfileConfig and _SandboxConfig, extras, contract-style tests, examples, docs).
Spec review (done first, per the review process):
docs/specs/494-sandbox-capability/plan.md— iteration 8/9 swap + path updates are internally consistent; every renumbered cross-reference checks out.docs/specs/494-sandbox-capability/spec.md— the 2026-07-28 amendment accurately documents the rename set and the managed/attached lifecycle. Verified against the base branch:dockerdeclaresattaches_external=True✓,AttachedEnvironmentProvider/AttachedEnvironmentbases and their fixed no-opcreate-binds /destroy/close✓, both-direction factory validation ✓, worker rules (destroy drops binding, no self-heal-provision, binding-reset idle notice) ✓. All spec claims verify.- Spec conformance (dimension 6): the implementation matches the amendment — no silent deviations found.
Findings by severity:
- blocker: 0
- suggestion: 2 (inline) — e2b
install_packagesquoting; daytona positional SDK args - question: 2 (inline) — ec2_ssm user-mode STS-per-execution; SDK-signature assumptions vs pinned versions
Un-anchorable note: the docker mode-3 attach_to-under-managed path (which worked pre-PR) is now rejected at startup by _validate_environment (managed + attach_to → SandboxConfigError). This is intentional and documented in sandbox.md's validation table, but it is a behavior change for existing docker attach_to configs — worth a line in the PR description / changelog so upgraders know to add environment: attached.
CI is still pending at review time. No prior review comments to dedupe against.
There was a problem hiding this comment.
Pull request overview
This PR extends Agent Kernel’s sandbox capability with new first-party providers and an explicit “managed vs attached” environment lifecycle, while also renaming the orchestration plane from “Sandbox*” to “Execution*” to better reflect attach-mode semantics (e.g., EC2 over SSM).
Changes:
- Add cloud SaaS sandbox providers (
e2b,daytona) plus an attach-only provider (ec2_ssm) and wire them through the provider factory + optional-dependency extras. - Introduce
environment: managed|attachedprofile lifecycle validation + attached-environment base classes, and adjust worker/manager semantics accordingly. - Update tests, docs, examples, and contributor/user skills to reflect the new providers and rename.
Reviewed changes
Copilot reviewed 52 out of 56 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| examples/sandbox/README.md | Add daytona/e2b/ec2-ssm examples to the sandbox examples index and update provider guidance. |
| examples/sandbox/ec2-ssm/README.md | New attach-mode example documentation for executing via EC2 SSM. |
| examples/sandbox/ec2-ssm/pyproject.toml | New example project dependencies for ec2_ssm demo. |
| examples/sandbox/ec2-ssm/demo.py | New CLI demo entrypoint for the ec2-ssm example. |
| examples/sandbox/ec2-ssm/config.yaml | New sandbox config showing environment: attached with ec2_ssm. |
| examples/sandbox/ec2-ssm/build.sh | New build helper for the ec2-ssm example using uv. |
| examples/sandbox/e2b/test-config.yaml | Configure example tests to use fuzzy mode for deterministic assertions. |
| examples/sandbox/e2b/README.md | New e2b provider example README (micro-VM + stateful kernel behavior). |
| examples/sandbox/e2b/pyproject.toml | New example project dependencies for the e2b demo. |
| examples/sandbox/e2b/demo.py | New CLI demo entrypoint for the e2b example. |
| examples/sandbox/e2b/demo_test.py | New e2b example integration tests using the built-in Test framework. |
| examples/sandbox/e2b/config.yaml | New sandbox config with multiple e2b profiles (default/offline/pinned). |
| examples/sandbox/e2b/build.sh | New build helper for the e2b example. |
| examples/sandbox/daytona/test-config.yaml | Configure example tests to use fuzzy mode for deterministic assertions. |
| examples/sandbox/daytona/README.md | New daytona provider example README (cloud container execution + policy mapping). |
| examples/sandbox/daytona/pyproject.toml | New example project dependencies for the daytona demo. |
| examples/sandbox/daytona/demo.py | New CLI demo entrypoint for the daytona example. |
| examples/sandbox/daytona/demo_test.py | New daytona example integration tests using the built-in Test framework. |
| examples/sandbox/daytona/config.yaml | New sandbox config with multiple daytona profiles (default/offline/small). |
| examples/sandbox/daytona/build.sh | New build helper for the daytona example. |
| docs/specs/494-sandbox-capability/spec.md | Amend spec with execution-plane rename + managed/attached lifecycle semantics. |
| docs/specs/494-sandbox-capability/plan.md | Swap iteration order and update paths/references for the provider work. |
| docs/docs/examples/overview.md | Add new sandbox examples to the docs website examples overview. |
| docs/docs/architecture/sandbox-internals.md | Update architecture doc to the Execution* naming and add attached-env classes/capabilities. |
| docs/docs/advanced/sandbox.md | Document managed vs attached environments and add provider rows + setup sections for new providers. |
| ak-py/tests/test_sandbox.py | Update tests for Execution* rename + environment lifecycle validation + new provider coverage. |
| ak-py/tests/test_sandbox_providers.py | Add extensive mocked-provider tests for ec2_ssm/e2b/daytona behaviors and mappings. |
| ak-py/tests/test_sandbox_broker.py | Update broker tests for Execution* rename and factory changes. |
| ak-py/src/agentkernel/skills/ak-add-capabilities/SKILL.md | Document `environment: managed |
| ak-py/src/agentkernel/sandbox/tools.py | Update tool wiring to ExecutionManager and add profile guidance annotations. |
| ak-py/src/agentkernel/sandbox/providers/ec2_ssm.py | New ec2_ssm attach-only provider implementation (SSM Run Command + sts:AssumeRole user mode). |
| ak-py/src/agentkernel/sandbox/providers/e2b.py | New e2b provider implementation (async SDK + stateful kernel + network policy mapping). |
| ak-py/src/agentkernel/sandbox/providers/docker.py | Update docker provider capabilities to declare attaches_external=True. |
| ak-py/src/agentkernel/sandbox/providers/daytona.py | New daytona provider implementation (sync SDK via to_thread + policy/resource mapping). |
| ak-py/src/agentkernel/sandbox/model.py | Extend capabilities model with provisions / attaches_external; update comments for renamed manager. |
| ak-py/src/agentkernel/sandbox/manager.py | Rename SandboxManager→ExecutionManager and adjust idle-reset notice for attached environments. |
| ak-py/src/agentkernel/sandbox/hooks.py | Update pre-hook completion parsing/types for ExecutionCompletion and ExecutionManager. |
| ak-py/src/agentkernel/sandbox/factory.py | Add provider branches (ec2_ssm/e2b/daytona) + environment lifecycle validation + ExecutionBrokerFactory rename. |
| ak-py/src/agentkernel/sandbox/errors.py | Rename SandboxBrokerError→ExecutionBrokerError. |
| ak-py/src/agentkernel/sandbox/broker/worker.py | Update broker contract types and implement attached-mode rules (no dispose, no self-heal provision). |
| ak-py/src/agentkernel/sandbox/broker/thread.py | Rename broker base types and error type; keep thread broker behavior consistent. |
| ak-py/src/agentkernel/sandbox/broker/embedded.py | Rename broker base types and completion model for embedded broker. |
| ak-py/src/agentkernel/sandbox/broker/base.py | Rename wire contract models + broker ABC to Execution* terminology. |
| ak-py/src/agentkernel/sandbox/broker/init.py | Update broker package docs for ExecutionBrokerFactory naming. |
| ak-py/src/agentkernel/sandbox/base.py | Add AttachedEnvironment / AttachedEnvironmentProvider base classes with attach-only lifecycle semantics. |
| ak-py/src/agentkernel/sandbox/init.py | Update sandbox package public exports to new Execution* names and attached-environment bases. |
| ak-py/src/agentkernel/core/config.py | Add config for daytona image/snapshot/env_vars, new environment field, and rename broker config model. |
| ak-py/README.md | Document new sandbox providers, extras, and environment option in user-facing README. |
| ak-py/pyproject.toml | Add e2b and daytona extras with version constraints. |
| .github/test-config.yaml | Leave e2b/daytona e2e disabled until secrets are wired; document intent. |
| .agents/skills/ak-dev-new-sandbox-provider/SKILL.md | Update contributor skill with new providers + attached-environment workflow notes. |
| .agents/skills/ak-dev-architecture/SKILL.md | Update architecture skill documentation for Execution* rename and new provider inventory. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
…and caching for assumed-role clients fix: improve command execution timeout handling in Daytona and E2B sandboxes docs: clarify attached environment behavior in profiles text
amithad
left a comment
There was a problem hiding this comment.
Re-review of the delta since my last pass (7df96b3d..e7dab2b0 — the "collision-free heredoc + assumed-role caching + timeout handling" commit).
All four of my previous findings are resolved, correctly and with tests:
- ✅ e2b
install_packagesnowshlex.quotes each package (e2b.py:65), matching daytona. - ✅ daytona now passes
timeout=as a keyword tocode_run/exec(daytona.py:57,61) — and the daytona fake was tightened to maketimeoutkeyword-only, so a regression back to positional would raiseTypeErrorinstead of silently binding wrong. Nice guard. - ✅ ec2_ssm user mode now caches one auto-refreshing assumed-role client per
(subject, role_arn)(ec2_ssm.py:171,209), so aper_sessionprofile assumes the role once, not once per execution. - ✅ SDK signatures confirmed against the pinned releases (per your reply), not just mocks.
Also picked up the two Copilot findings well: the collision-safe _heredoc_delimiter and the STS _role_session_name sanitizer ([\w+=,.@-]{2,64}).
Verified the new machinery, not just read it:
- The botocore private-API wiring in
_assumed_role_client(AssumeRoleCredentialFetcher+DeferredRefreshableCredentials+boto3.Session(botocore_session=…)) checks out againstbotocore 1.43.57: I built the client through that exact path and confirmed its credentials resolve through the injected refresher. Constructor signatures andsession._credentialsall match. _heredoc_delimiterbumps a counter until the delimiter is not a line in the code — collision-free, and covered bytest_ssm_execute_code_heredoc_avoids_delimiter_collision.- Provider suite passes locally against this head:
pytest -k "ssm or daytona or e2b"→ 38 passed. CI is green (lint, build, CodeQL, script-tests).
One observation (non-blocking, no change required): the real botocore assume-role wiring in _assumed_role_client is never exercised by a test — every ec2_ssm user-mode test monkeypatches _assumed_role_client itself. That's a reasonable call (mocking botocore internals is brittle), and I verified the path manually, but it does mean a future botocore that renames/moves AssumeRoleCredentialFetcher or DeferredRefreshableCredentials (both private API) would slip past the suite and only fail at runtime in user mode. Worth a boto3/botocore floor in the aws extra or a note, if not already implied.
No remaining findings. The delta is clean and the PR looks ready from a code-review standpoint.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 52 out of 56 changed files in this pull request and generated no new comments.
Comments suppressed due to low confidence (3)
examples/sandbox/ec2-ssm/config.yaml:24
- This example config selects the attach-only
ec2_ssmprovider but does not setenvironment: attached. With the new environment validation, the defaultmanagedmode will be rejected at startup, so the example as written cannot run.
examples/sandbox/ec2-ssm/build.sh:16 build.shinstalls withuv sync --all-extras, which pulls in every optional dependency foragentkernel(slower installs and potential extra dependency conflicts) even though this example only needscli,openai,aws(+ dev group).
docs/docs/architecture/sandbox-internals.md:57- Grammar: use “An” before “ExecutionRequest”.
A `ExecutionRequest` is **self-sufficient**: it carries the resolved principal, the policy, and the full sandbox-session handle (including the provider reconnect id), so a remote worker needs nothing else to execute it.
No description provided.