Add TenkiExecutor for remote code execution in Tenki sandboxes#2563
Open
ginoli-lux wants to merge 9 commits into
Open
Add TenkiExecutor for remote code execution in Tenki sandboxes#2563ginoli-lux wants to merge 9 commits into
ginoli-lux wants to merge 9 commits into
Conversation
Adds a new remote executor backed by Tenki Cloud sandboxes (disposable Linux microVMs), following the existing Jupyter Kernel Gateway pattern used by ModalExecutor and BlaxelExecutor: - TenkiExecutor in remote_executors.py: creates a sandbox via the tenki-sandbox SDK, starts a kernel gateway, exposes the port through a preview URL, and executes code over websocket - executor_type="tenki" wired into CodeAgent - 'tenki' extra in pyproject.toml - Unit tests with mocked SDK - Docs: secure_code_execution tutorial, executor reference, guided tour Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- Resolve project_id from create_kwargs, TENKI_PROJECT_ID env var, or the account's sole project via who_am_i (the API requires it) - Bootstrap pip via ensurepip/apt when the image lacks it, and install the kernel gateway to the user site (sandbox filesystem does not support virtualenv symlinks; system site is externally managed) - Set PIP_USER/PIP_BREAK_SYSTEM_PACKAGES on the kernel gateway process so in-kernel '!pip install' works on externally-managed images Verified end-to-end against the real Tenki API: sandbox creation, stateful multi-step execution, final_answer flow, and cleanup. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- TestTenkiExecutorIntegration reuses CommonDockerExecutorIntegration
(same pattern as Modal/Docker), gated behind RUN_ALL
- Document create_kwargs={"max_duration": ...} as a server-side cost
safety net when cleanup does not get to run
All 10 integration tests pass against the real Tenki API.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Live test showed a sandbox created with max_duration=120 was PAUSED (retaining storage), not terminated, so the tip's claim of a server-side termination safety net does not hold on the current platform. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- Create the user-site directory in the bootstrap: CPython only adds it
to sys.path when it exists at startup, so on images with the kernel
gateway preinstalled the kernel could not import packages installed
by in-kernel '!pip install'
- Surface stderr when the kernel gateway bootstrap fails, and append
the gateway process output when waiting for the server times out
- Use PIP_BREAK_SYSTEM_PACKAGES=1 instead of --break-system-packages,
which pip < 23.0.1 rejects as an unknown option
- Construct the Tenki Client explicitly and close it in cleanup (the
SDK's terminate does not close the control-plane channel), reusing
it for project resolution; route gateway_url/cookie_name to it
- Let create_kwargs={"workspace_id": ...} disambiguate project
resolution, and point the ambiguity error at executor_kwargs
- Strengthen unit tests (9 now): bootstrap invocation and env wiring,
client-kwarg routing, bootstrap-failure stderr, workspace filtering,
client closed on cleanup and on ambiguity
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Verified against the 0.4.0 release: the Client/create/who_am_i/shell API surface TenkiExecutor relies on is unchanged, and the two prior workarounds (owning the Client to close its control-plane channel, and not documenting max_duration as a termination safety net) are still needed since that behavior didn't change in this release. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Follow-up review by camcalaquian on PR #1: - Allocate the sandbox with wait=False, retain the handle, then call wait_ready() inside the guarded block. create(wait=True) can allocate a session and then fail while waiting for readiness before the assignment, leaving cleanup() with no handle and the session stuck in CREATING. - Catch BaseException during init: KeyboardInterrupt / cancellation inherit from BaseException, not Exception, so a Ctrl+C mid-startup previously leaked both the sandbox and the client. Clean up, then re-raise unchanged. - Mark cleanup complete only after close_if_open() succeeds; on a transient termination failure, retain the sandbox handle and client so a later cleanup() can retry instead of turning the leak permanent. - Add the Tenki extra / executor to installation.md (pip + uv), the README inventories, the docs index, and the sandbox example. - Extend the unit tests: assert wait=False + wait_ready(), cleanup retry after a transient failure, and cleanup + unchanged re-raise on KeyboardInterrupt. Verified: Tenki unit tests pass, ruff clean, and the full live E2E suite (TestTenkiExecutorIntegration) is 10/10 green. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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
TenkiExecutor, a remote code executor backed by Tenki sandboxes.executor_type="tenki"support toCodeAgent.tenkiextra topyproject.toml(tenki-sandbox>=0.4.0,websocket-client).TenkiExecutor, following the existingCommonDockerExecutorIntegrationpattern shared with Docker/Modal.Notes
@require_run_alland need real Tenki credentials, consistent with the other remote executors' integration tests.make qualityand the non-integration test suite pass locally.