Repository navigation
refactor: monorepo with the Python and TypeScript packages - #3
Merged
Merged
Conversation
Each ADK session gets its own lazily created sandbox, so a module-level agent serves concurrent users and keeps files and kernels across messages and confirmation pauses. ADK close() no longer kills anything; the application releases workspaces with destroySession() and destroyAll(). - Operations of one session are serialized; a cancelled waiter has no SDK side effects and never lets later work overtake the active one. - run_command runs in its own process group and is killed as a group on deadline or abort; run_code restarts its per-language kernel. - timeoutMs is 1..maxOperationMs (default 10 minutes); the deadline starts when the operation runs. - A paused sandbox is resumed; a missing one is reported once with workspace_expired, then a new workspace is created. - Background commands no longer die at the SDK's 60 s default. - The build cleans dist before compiling.
Rewrite the README and data-analysis example for a module-level agent with explicit destroySession() cleanup. Extend the live harness to cover stop mechanisms, pause/resume, expiry, background lifetime and a multi-user conversation, with an optional test-only OpenAI model.
- destroy() waits for a sandbox that is still being created and kills it; if that kill fails the handle is kept, reuse is blocked and a retry works. - A stopped command counts as gone only when the process-group kill succeeds or reports that no process is left, and the command exits. Otherwise the workspace is blocked until destroySession(); there is no leader-only fallback. - Every async setup step rechecks destroy, block and cancellation before side effects, and a result is not reported as a success after a destroy. - The deadline covers command start and kernel start-up. A handle that arrives after the deadline is killed; code that never started does not claim a kernel restart.
A rejected SDK call does not prove that nothing ran. A command start fails as an ordinary error only when the sandbox refuses it before creating a process (InvalidArgumentError, e.g. a missing cwd); any other start failure blocks the workspace until destroySession(). A lost command stream is followed by a process-group kill and a lost code stream by a kernel restart before the error is returned; if either cannot be confirmed, the workspace is blocked. Background starts follow the same rule.
After a lost code stream the kernel is restarted, so its variables are gone; the result now says so with kernel_restarted: true instead of a generic failure. A context the kernel server no longer knows returns kernel_reset: true and says the next call starts an empty kernel. Both state that sandbox files are kept. The direct executor reports the same text in stderr.
Sandboxes are created with adkAppName, adkUserId and adkSessionId in their metadata. A process that does not hold a session's sandbox lists by that metadata and connects to the oldest match, resuming a paused one; only when none exists does it create, and if another instance created one at the same moment the older sandbox wins and the newer is killed. This is the model of E2B's Vercel AI SDK and Mastra integrations. - Lifetime is extended with connect(), which never shortens what another instance granted; a sandbox-level 404 is reported as expiry. - run_code uses the sandbox's default kernel per language, shared by every instance; restarts look the kernel up with listCodeContexts(). - A sandbox destroyed from another process is reported as expired, not as a blocked workspace. - destroySession() also kills session sandboxes this process never held, including after a restart. - Tests run two workspaces or toolsets over a registry double of the control plane; scripts/live-processes.ts does it with three real processes.
- A namespace option becomes adkNamespace in the sandbox metadata used to find, reuse and destroy a session's sandbox, so deployments that share one E2B API key and app name stay apart. - When the list after a create fails, the just-created sandbox is discarded instead of used; if that kill fails, the workspace stays blocked until destroySession() retries. - A deadline that fires before the language kernel exists waits for the in-flight request to settle within the recovery window and restarts the kernel that came up; if the request never settles, the workspace is blocked. - README and guide: operations are serialized per instance only, and create-race convergence is best effort.
…be confirmed stopped
- adkNamespace is always written ('default' when unset): E2B's list matches
any sandbox containing the queried pairs, so an untagged instance could
find and destroy a namespaced deployment's sandbox
- one stop path for code whose request already went out: restart the listed
kernel, else let the request settle and restart the kernel it started,
return the result if the code finished, otherwise block the workspace;
kernel_restarted is reported only after an actual restart
- maxOperationMs is capped at the largest delay setTimeout honours
- README/guide: race resolution is best effort; destroyAll() covers the
workspaces this instance knows
docs: improve readme
# Conflicts: # .github/workflows/release.yml
PyPI already has e2b-adk 0.1.1, and the fixed changesets group counts from package.json, so the first shared release lands on 0.1.2.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Moves e2b-dev/e2b-adk-plugin-js into this repo, laid out like e2b-dev/claude-toolsets: one repo, one release workflow, both packages on one version.
Merge with "Create a merge commit", not squash.
chore: import e2b-adk-plugin-js historymerges the 19 JS commits in, sogit log --follow packages/e2b-adk-js/...and blame keep Maksim's history. A squash would flatten it.Review guide
Most of the +9.6k lines are the imported JS repo and
pnpm-lock.yaml. The parts worth reading:0a5df30rootpackage.json,pnpm-workspace.yaml, the JSpackage.json(addsrepositorywithdirectoryfor npm provenance, dropspackageManager),packages/e2b-adk-python/package.json(wraps uv so pnpm and changesets drive it), root README.51952e4release.yml, adapted from claude-toolsets:workflow_dispatchon main only,changeset versionsyncs the Python version throughuv version, thenuv publishandchangeset publishover OIDC trusted publishing.Behavior changes worth knowing:
allowBuildsdenies the five the JS repo already skipped under pnpm 10. No JS dependency changed version in the lockfile.twine check: a hatchling release newer than main's last green run (2026-10-10) emits Metadata 2.5, which the locked twine 6.2.0 rejects, so main's own next CI run would fail the same way. Building isuv build, anduv publishvalidates on upload.pnpm changeset, merge, thengh workflow run release.yml --ref main.## Configurationheading so the#configurationlinks in Add E2B to the integrations catalog google/adk-docs#2155 and e2b-dev/docs still resolve.Before the first release
deploymentenvironment limited tomainVERSION_BUMPER_APPID/VERSION_BUMPER_SECRETavailable to this repoe2b-adk: add a trusted publisher forrelease.yml+deployment@e2b/adk: first publish by hand, then a trusted publisher forrelease.yml+deploymentAfter merge
agents/google-adk.mdxatpackages/e2b-adk-python/examples/Test plan
pnpm checkfrom the root: Python ruff, mypy, 72 tests,uv build; JS typecheck, eslint, prettier, 119 tests, buildpnpm run versionbumps both packages to 0.2.0 and syncspyproject.tomlanduv.locknpm pack --dry-runships onlydist, README, LICENSE, package.json; the sdist still holds the package, tests and examples