Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/ISSUE_TEMPLATE/bug-report.yml
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ body:
- label: evals
- label: harbor
- label: daytona
- label: e2b
- label: modal
- label: quickjs
- label: runloop
Expand Down
1 change: 1 addition & 0 deletions .github/ISSUE_TEMPLATE/feature-request.yml
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ body:
- label: evals
- label: harbor
- label: daytona
- label: e2b
- label: modal
- label: quickjs
- label: runloop
Expand Down
1 change: 1 addition & 0 deletions .github/ISSUE_TEMPLATE/privileged.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ body:
- label: evals
- label: harbor
- label: daytona
- label: e2b
- label: modal
- label: quickjs
- label: runloop
Expand Down
2 changes: 2 additions & 0 deletions .github/RELEASING.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ This document describes the release process for packages in the Deep Agents mono
| `deepagents-acp` | `libs/acp` | `deepagents-acp` | [`deepagents-acp`](https://pypi.org/project/deepagents-acp/) |
| `deepagents-code` | `libs/code` | `deepagents-code` | [`deepagents-code`](https://pypi.org/project/deepagents-code/) |
| `langchain-daytona` | `libs/partners/daytona` | `langchain-daytona` | [`langchain-daytona`](https://pypi.org/project/langchain-daytona/) |
| `langchain-e2b` | `libs/partners/e2b` | `langchain-e2b` | [`langchain-e2b`](https://pypi.org/project/langchain-e2b/) |
| `langchain-modal` | `libs/partners/modal` | `langchain-modal` | [`langchain-modal`](https://pypi.org/project/langchain-modal/) |
| `langchain-runloop` | `libs/partners/runloop` | `langchain-runloop` | [`langchain-runloop`](https://pypi.org/project/langchain-runloop/) |
| `langchain-quickjs` | `libs/partners/quickjs` | `langchain-quickjs` | [`langchain-quickjs`](https://pypi.org/project/langchain-quickjs/) |
Expand Down Expand Up @@ -153,6 +154,7 @@ Tracks the current version of each package. Automatically updated by release-ple
"libs/deepagents": "0.5.1",
"libs/acp": "0.0.5",
"libs/partners/daytona": "0.0.5",
"libs/partners/e2b": "0.0.1",
"libs/partners/modal": "0.0.3",
"libs/partners/runloop": "0.0.4",
"libs/partners/quickjs": "0.0.1"
Expand Down
1 change: 1 addition & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ updates:
- "/libs/evals"
- "/libs/acp"
- "/libs/partners/daytona"
- "/libs/partners/e2b"
- "/libs/partners/modal"
- "/libs/partners/quickjs"
- "/libs/partners/runloop"
Expand Down
7 changes: 7 additions & 0 deletions .github/scripts/pr-labeler-config.json
Original file line number Diff line number Diff line change
Expand Up @@ -58,11 +58,13 @@
"deepagents-code": "dcode",
"deps": "dependencies",
"docs": "documentation",
"e2b": "e2b",
"evals": "evals",
"examples": "examples",
"harbor": "harbor",
"infra": "infra",
"langchain-daytona": "daytona",
"langchain-e2b": "e2b",
"langchain-modal": "modal",
"langchain-quickjs": "quickjs",
"langchain-runloop": "runloop",
Expand Down Expand Up @@ -109,6 +111,11 @@
"prefix": "libs/partners/daytona/",
"skipExcludedFiles": true
},
{
"label": "e2b",
"prefix": "libs/partners/e2b/",
"skipExcludedFiles": true
},
{
"label": "modal",
"prefix": "libs/partners/modal/",
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/auto-label-by-package.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ jobs:
"evals": "evals",
"harbor": "harbor",
"daytona": "daytona",
"e2b": "e2b",
"modal": "modal",
"quickjs": "quickjs",
"runloop": "runloop",
Expand Down
28 changes: 28 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ jobs:
evals: ${{ steps.filter.outputs.evals }}
acp: ${{ steps.filter.outputs.acp }}
daytona: ${{ steps.filter.outputs.daytona }}
e2b: ${{ steps.filter.outputs.e2b }}
modal: ${{ steps.filter.outputs.modal }}
runloop: ${{ steps.filter.outputs.runloop }}
quickjs: ${{ steps.filter.outputs.quickjs }}
Expand Down Expand Up @@ -103,6 +104,12 @@ jobs:
- '.github/workflows/_lint.yml'
- '.github/workflows/_test.yml'
- '.github/actions/**'
e2b:
- 'libs/partners/e2b/**'
- '.github/workflows/ci.yml'
- '.github/workflows/_lint.yml'
- '.github/workflows/_test.yml'
- '.github/actions/**'
modal:
- 'libs/partners/modal/**'
- '.github/workflows/ci.yml'
Expand Down Expand Up @@ -177,6 +184,15 @@ jobs:
working-directory: "libs/partners/daytona"
python-version: "3.11"

lint-e2b:
name: "🧹 Lint e2b"
needs: changes
if: needs.changes.outputs.e2b == 'true' || github.event_name == 'push'
uses: ./.github/workflows/_lint.yml
with:
working-directory: "libs/partners/e2b"
python-version: "3.11"

lint-modal:
name: "🧹 Lint modal"
needs: changes
Expand Down Expand Up @@ -266,6 +282,16 @@ jobs:
python-versions: '["3.11", "3.12", "3.13", "3.14"]'
coverage-python-version: "3.12"

test-e2b:
name: "🧪 Test e2b"
needs: changes
if: needs.changes.outputs.e2b == 'true' || github.event_name == 'push'
uses: ./.github/workflows/_test.yml
with:
working-directory: "libs/partners/e2b"
python-versions: '["3.11", "3.12", "3.13", "3.14"]'
coverage-python-version: "3.12"

test-modal:
name: "🧪 Test modal"
needs: changes
Expand Down Expand Up @@ -356,6 +382,7 @@ jobs:
- lint-evals
- lint-acp
- lint-daytona
- lint-e2b
- lint-modal
- lint-runloop
- lint-quickjs
Expand All @@ -365,6 +392,7 @@ jobs:
- test-evals
- test-acp
- test-daytona
- test-e2b
- test-modal
- test-runloop
- test-quickjs
Expand Down
8 changes: 7 additions & 1 deletion .github/workflows/harbor.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Harbor evaluation workflow for Deep Agents
#
# Runs terminal-bench evaluations via Harbor with configurable sandbox
# environments (Docker, Daytona, LangSmith, Modal, Runloop).
# environments (Docker, Daytona, E2B, LangSmith, Modal, Runloop).
# Models are selected via dropdown or comma-separated override.
#
# Required secrets (vary by sandbox + model provider):
Expand All @@ -19,6 +19,7 @@
# FIREWORKS_API_KEY — needed for Fireworks-hosted models
# OPENROUTER_API_KEY — needed for OpenRouter-hosted models
# DAYTONA_API_KEY — needed for Daytona sandbox
# E2B_API_KEY — needed for E2B sandbox
# MODAL_TOKEN_ID — needed for Modal sandbox
# MODAL_TOKEN_SECRET — needed for Modal sandbox
# RUNLOOP_API_KEY — needed for Runloop sandbox
Expand Down Expand Up @@ -123,6 +124,7 @@ on:
options:
- docker
- daytona
- e2b
- langsmith
- modal
- runloop
Expand Down Expand Up @@ -238,6 +240,7 @@ jobs:
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
BASETEN_API_KEY: ${{ secrets.BASETEN_API_KEY }}
DAYTONA_API_KEY: ${{ secrets.DAYTONA_API_KEY }}
E2B_API_KEY: ${{ secrets.E2B_API_KEY }}
FIREWORKS_API_KEY: ${{ secrets.FIREWORKS_API_KEY }}
GOOGLE_API_KEY: ${{ secrets.GOOGLE_API_KEY }}
GROQ_API_KEY: ${{ secrets.GROQ_API_KEY }}
Expand Down Expand Up @@ -269,6 +272,9 @@ jobs:
daytona)
[ -z "$DAYTONA_API_KEY" ] && missing+=("DAYTONA_API_KEY")
;;
e2b)
[ -z "$E2B_API_KEY" ] && missing+=("E2B_API_KEY")
;;
langsmith)
;; # LANGSMITH_API_KEY already checked above
modal)
Expand Down
3 changes: 3 additions & 0 deletions .github/workflows/integration_tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ on:
- libs/deepagents
- libs/cli
- libs/partners/daytona
- libs/partners/e2b
- libs/partners/modal
- libs/partners/runloop
working-directory-override:
Expand All @@ -40,6 +41,7 @@ env:
["libs/deepagents",
"libs/cli",
"libs/partners/daytona",
"libs/partners/e2b",
"libs/partners/modal",
"libs/partners/runloop"]

Expand Down Expand Up @@ -114,6 +116,7 @@ jobs:
working-directory: ${{ matrix.working-directory }}
env:
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
E2B_API_KEY: ${{ secrets.E2B_API_KEY }}
LANGSMITH_API_KEY: ${{ secrets.LANGSMITH_API_KEY }} # sandboxes
MODAL_TOKEN_ID: ${{ secrets.MODAL_TOKEN_ID }}
MODAL_TOKEN_SECRET: ${{ secrets.MODAL_TOKEN_SECRET }}
Expand Down
4 changes: 3 additions & 1 deletion .github/workflows/pr_lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
#
# Allowed Scope(s) (required):
# acp, ci, cli, cli-gha, code, daytona, deepagents, deepagents-acp, deepagents-cli,
# deepagents-code, deps, deps-dev, evals, examples, harbor, infra, langchain-daytona, langchain-modal,
# deepagents-code, deps, deps-dev, e2b, evals, examples, harbor, infra, langchain-daytona, langchain-e2b, langchain-modal,
# langchain-quickjs, langchain-runloop, langsmith-sandbox, modal,
# quickjs, runloop, sdk
#
Expand Down Expand Up @@ -119,11 +119,13 @@ jobs:
deepagents-code
deps
deps-dev
e2b
evals
examples
harbor
infra
langchain-daytona
langchain-e2b
langchain-modal
langchain-quickjs
langchain-runloop
Expand Down
12 changes: 12 additions & 0 deletions .github/workflows/release-please.yml
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ jobs:
acp-release: ${{ steps.check-releases.outputs.acp-release }}
code-release: ${{ steps.check-releases.outputs.code-release }}
daytona-release: ${{ steps.check-releases.outputs.daytona-release }}
e2b-release: ${{ steps.check-releases.outputs.e2b-release }}
modal-release: ${{ steps.check-releases.outputs.modal-release }}
runloop-release: ${{ steps.check-releases.outputs.runloop-release }}
quickjs-release: ${{ steps.check-releases.outputs.quickjs-release }}
Expand Down Expand Up @@ -154,6 +155,13 @@ jobs:
echo "daytona-release=false" >> "$GITHUB_OUTPUT"
fi

if echo "$CHANGED" | grep -q "^libs/partners/e2b/CHANGELOG.md$" && echo "$COMMIT_MSG" | grep -qE "^release\(langchain-e2b\):"; then
echo "e2b-release=true" >> "$GITHUB_OUTPUT"
echo "E2B release detected: $COMMIT_MSG"
else
echo "e2b-release=false" >> "$GITHUB_OUTPUT"
fi

if echo "$CHANGED" | grep -q "^libs/partners/modal/CHANGELOG.md$" && echo "$COMMIT_MSG" | grep -qE "^release\(langchain-modal\):"; then
echo "modal-release=true" >> "$GITHUB_OUTPUT"
echo "Modal release detected: $COMMIT_MSG"
Expand Down Expand Up @@ -525,6 +533,7 @@ jobs:
needs.detect-release-commit.outputs.acp-release == 'true' ||
needs.detect-release-commit.outputs.code-release == 'true' ||
needs.detect-release-commit.outputs.daytona-release == 'true' ||
needs.detect-release-commit.outputs.e2b-release == 'true' ||
needs.detect-release-commit.outputs.modal-release == 'true' ||
needs.detect-release-commit.outputs.runloop-release == 'true' ||
needs.detect-release-commit.outputs.quickjs-release == 'true'
Expand All @@ -542,6 +551,7 @@ jobs:
ACP_RELEASE: ${{ needs.detect-release-commit.outputs.acp-release }}
CODE_RELEASE: ${{ needs.detect-release-commit.outputs.code-release }}
DAYTONA_RELEASE: ${{ needs.detect-release-commit.outputs.daytona-release }}
E2B_RELEASE: ${{ needs.detect-release-commit.outputs.e2b-release }}
MODAL_RELEASE: ${{ needs.detect-release-commit.outputs.modal-release }}
RUNLOOP_RELEASE: ${{ needs.detect-release-commit.outputs.runloop-release }}
QUICKJS_RELEASE: ${{ needs.detect-release-commit.outputs.quickjs-release }}
Expand Down Expand Up @@ -612,6 +622,7 @@ jobs:
ACP_RELEASE="${ACP_RELEASE:-false}"; assert_bool ACP_RELEASE "$ACP_RELEASE"
CODE_RELEASE="${CODE_RELEASE:-false}"; assert_bool CODE_RELEASE "$CODE_RELEASE"
DAYTONA_RELEASE="${DAYTONA_RELEASE:-false}"; assert_bool DAYTONA_RELEASE "$DAYTONA_RELEASE"
E2B_RELEASE="${E2B_RELEASE:-false}"; assert_bool E2B_RELEASE "$E2B_RELEASE"
MODAL_RELEASE="${MODAL_RELEASE:-false}"; assert_bool MODAL_RELEASE "$MODAL_RELEASE"
RUNLOOP_RELEASE="${RUNLOOP_RELEASE:-false}"; assert_bool RUNLOOP_RELEASE "$RUNLOOP_RELEASE"
QUICKJS_RELEASE="${QUICKJS_RELEASE:-false}"; assert_bool QUICKJS_RELEASE "$QUICKJS_RELEASE"
Expand Down Expand Up @@ -640,6 +651,7 @@ jobs:
if [ "$ACP_RELEASE" = "true" ]; then dispatch deepagents-acp; fi
if [ "$CODE_RELEASE" = "true" ]; then dispatch deepagents-code; fi
if [ "$DAYTONA_RELEASE" = "true" ]; then dispatch langchain-daytona; fi
if [ "$E2B_RELEASE" = "true" ]; then dispatch langchain-e2b; fi
if [ "$MODAL_RELEASE" = "true" ]; then dispatch langchain-modal; fi
if [ "$RUNLOOP_RELEASE" = "true" ]; then dispatch langchain-runloop; fi
if [ "$QUICKJS_RELEASE" = "true" ]; then dispatch langchain-quickjs; fi
Expand Down
8 changes: 7 additions & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ on:
- deepagents-code
- deepagents-evals
- langchain-daytona
- langchain-e2b
- langchain-modal
- langchain-quickjs
- langchain-runloop
Expand Down Expand Up @@ -125,6 +126,9 @@ jobs:
langchain-daytona)
echo "working-dir=libs/partners/daytona" >> $GITHUB_OUTPUT
;;
langchain-e2b)
echo "working-dir=libs/partners/e2b" >> $GITHUB_OUTPUT
;;
langchain-modal)
echo "working-dir=libs/partners/modal" >> $GITHUB_OUTPUT
;;
Expand All @@ -136,7 +140,7 @@ jobs:
;;
*)
echo "Error: Unknown package '$PACKAGE'"
echo "Valid packages are: deepagents, deepagents-cli, deepagents-acp, deepagents-code, deepagents-evals, langchain-daytona, langchain-modal, langchain-quickjs, langchain-runloop"
echo "Valid packages are: deepagents, deepagents-cli, deepagents-acp, deepagents-code, deepagents-evals, langchain-daytona, langchain-e2b, langchain-modal, langchain-quickjs, langchain-runloop"
exit 1
;;
esac
Expand Down Expand Up @@ -793,6 +797,8 @@ jobs:
LANGSMITH_API_KEY: ${{ secrets.LANGSMITH_API_KEY }}
# langchain-daytona, CLI test_sandbox_operations.py
DAYTONA_API_KEY: ${{ secrets.DAYTONA_API_KEY }}
# langchain-e2b, CLI test_sandbox_operations.py
E2B_API_KEY: ${{ secrets.E2B_API_KEY }}
# langchain-modal
MODAL_TOKEN_ID: ${{ secrets.MODAL_TOKEN_ID }}
MODAL_TOKEN_SECRET: ${{ secrets.MODAL_TOKEN_SECRET }}
Expand Down
1 change: 1 addition & 0 deletions .release-please-manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
"libs/acp": "0.0.8",
"libs/code": "0.1.11",
"libs/partners/daytona": "0.0.7",
"libs/partners/e2b": "0.0.1",
"libs/partners/modal": "0.0.5",
"libs/partners/runloop": "0.0.6",
"libs/partners/quickjs": "0.1.4"
Expand Down
5 changes: 3 additions & 2 deletions examples/ralph_mode/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,10 @@ python ralph_mode.py "Create a CLI tool" --model claude-sonnet-4-6
# With a specific working directory
python ralph_mode.py "Build a web app" --work-dir ./my-project

# Run in a remote sandbox (AgentCore, Modal, Daytona, or Runloop)
# Run in a remote sandbox (AgentCore, Modal, Daytona, E2B, or Runloop)
python ralph_mode.py "Build an app" --sandbox modal
python ralph_mode.py "Build an app" --sandbox daytona --sandbox-setup ./setup.sh
python ralph_mode.py "Build an app" --sandbox e2b

# Reuse an existing sandbox instance
python ralph_mode.py "Build an app" --sandbox modal --sandbox-id my-sandbox
Expand All @@ -77,7 +78,7 @@ for provider setup (API keys, etc.) and the
[sandboxes concept guide](https://docs.langchain.com/oss/python/deepagents/sandboxes)
for architecture details.

Supported providers: **AgentCore**, **Modal**, **Daytona**, **Runloop**.
Supported providers: **AgentCore**, **Modal**, **Daytona**, **E2B**, **Runloop**.

## How It Works

Expand Down
6 changes: 4 additions & 2 deletions examples/ralph_mode/ralph_mode.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
python ralph_mode.py "Create a CLI tool" --work-dir ./my-project
python ralph_mode.py "Create a CLI tool" --model claude-sonnet-4-6
python ralph_mode.py "Build an app" --sandbox modal
python ralph_mode.py "Build an app" --sandbox e2b
python ralph_mode.py "Build an app" --sandbox modal --sandbox-id my-sandbox
python ralph_mode.py "Build an app" --shell-allow-list recommended
python ralph_mode.py "Build an app" --no-stream
Expand Down Expand Up @@ -75,7 +76,7 @@ async def ralph(
to auto-detection from environment API keys
(`ANTHROPIC_API_KEY`, `OPENAI_API_KEY`, `GOOGLE_API_KEY`).
model_params: Additional model parameters (e.g. `{"temperature": 0.5}`).
sandbox_type: Sandbox provider (`"none"`, `"agentcore"`, `"modal"`, `"daytona"`, etc.).
sandbox_type: Sandbox provider (`"none"`, `"agentcore"`, `"modal"`, `"daytona"`, `"e2b"`, etc.).
sandbox_id: Existing sandbox instance ID to reuse.
sandbox_setup: Path to a setup script to run inside the sandbox.
stream: Whether to stream model output.
Expand Down Expand Up @@ -167,6 +168,7 @@ def main() -> None:
python ralph_mode.py "Create a CLI tool" --model claude-sonnet-4-6
python ralph_mode.py "Build a web app" --work-dir ./my-project
python ralph_mode.py "Build an app" --sandbox modal
python ralph_mode.py "Build an app" --sandbox e2b
python ralph_mode.py "Build an app" --shell-allow-list recommended
python ralph_mode.py "Build an app" --model-params '{"temperature": 0.5}'
""",
Expand All @@ -190,7 +192,7 @@ def main() -> None:
parser.add_argument(
"--sandbox",
default="none",
help="Sandbox provider (e.g., agentcore, modal, daytona). Default: none",
help="Sandbox provider (e.g., agentcore, modal, daytona, e2b). Default: none",
)
parser.add_argument(
"--sandbox-id",
Expand Down
Loading
Loading