Conversation
…sweep expired files The /v1/files routes now answer in Anthropic's FileMetadata shape when the caller sends anthropic-version (its SDK always does) and in the OpenAI shape otherwise, and the listing is cursor-paged (limit, after/after_id, order, has_more). Uploads referenced by a request that runs otari_code_execution are seeded into the sandbox session with PutFile; container_upload blocks are staged and replaced by a marker for the model. Files a run produces are fetched with GetFile, stored as code_execution_output files owned by the same user and workspace, and named with their file_id in the tool result. A bare input_file or input_image item at the top level of a Responses input is now normalized too. A background sweep reclaims the bytes and rows of expired and deleted files. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
files_backend: fsspec plus a files_url (gcs://, abfs://, s3://, sftp://, file://, ...) and files_storage_options reach whatever filesystem fsspec has an implementation installed for, through the same FileStore protocol the local and boto3 S3 backends implement. fsspec was already in the tree through any-llm and is now a declared dependency. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…execution tool A request that declares a provider's own code-execution tool (Anthropic's code_execution_<date>, OpenAI's code_interpreter, the bare code_execution) was always forwarded to the provider, so a client written against a frontier model's sandbox broke when the model was swapped for one without a native sandbox. The executor decides who runs the code: auto (the default) keeps the declaration with a provider that runs it natively for the dispatched model and wire format, and brings it to the gateway's sandbox otherwise, answering in the caller's own vocabulary (server_tool_use and code_execution_tool_result on Messages, code_interpreter_call on Responses). The deployment sets the default (code_execution_executor), a workspace policy may pin a value, and the X-Otari-Code-Execution header chooses per request where the workspace has not pinned. A deployment without a sandbox is untouched, and otari_code_execution keeps working unchanged. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
|
Important Draft PR not reviewedDraft PRs are not automatically reviewed by default.
To automatically review draft PRs, update your CodeRabbit configuration: reviews:
auto_review:
drafts: trueThanks 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 |
…half follow the executor Merges origin/feat/files-api-parity (#1364): both SDKs' Files APIs on the same routes, cursor paging, the fsspec storage backend, the retention sweep, and uploads seeded into the sandbox with produced files stored back. Adapted to the executor: attachments are staged whenever the code runs on the gateway's sandbox, whether the request said otari_code_execution or a provider's own declaration was brought here, and a container_upload falls back to a document when the provider keeps its declaration. A gateway-run execution's native code_execution_output entries carry the stored file_id a caller can download, never the sandbox's internal id. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
15 tasks
…fely, fold echoed interpreter calls Four review fixes on the executor and files work. The sandbox backend streams a produced file under the files size cap instead of buffering it first: a declared Content-Length over the cap is refused before a byte is read, and a body with no length is abandoned as soon as it passes the cap. What a run writes is untrusted, so the gateway must never hold a file it is about to refuse. A staged upload is seeded under its last path segment, suffixed when an earlier attachment took the name, so a name with separators neither nests nor escapes and two uploads named alike are both there. The marker the model is given carries the name the file actually has. A gateway-minted code_interpreter_call echoed on a Responses turn is folded into an assistant message rather than dropped, as the Messages route already folds its pair: the logs exist nowhere else in the transcript. SandboxFileBridge.outputs was written and never read. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
daavoo
had a problem deploying
to
integration-tests
September 18, 2026 15:09 — with
GitHub Actions
Error
daavoo
had a problem deploying
to
integration-tests
September 18, 2026 15:09 — with
GitHub Actions
Error
daavoo
had a problem deploying
to
integration-tests
September 18, 2026 15:09 — with
GitHub Actions
Error
daavoo
had a problem deploying
to
integration-tests
September 18, 2026 15:09 — with
GitHub Actions
Error
… only the result block The contract's result block carries a list of the files a call produced, but the reference container leaves it empty and reports files only through ListFiles, so against the only OSS backend no produced file ever reached /v1/files. The backend now lists the workspace after seeding and again after each call, and treats every path that appeared or changed as produced, unioned with whatever the block names. A backend without ListFiles answers 404 and the diff is simply empty, leaving the block's list as the only source, exactly as before. The rendered result and the Anthropic code_execution_output entries now list every stored file, whichever source found it. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
daavoo
force-pushed
the
feat/code-execution-executor
branch
from
September 18, 2026 15:10
dbb0d5d to
6eb79b6
Compare
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.
Description
Today a request that declares a provider's own code-execution tool (Anthropic's
code_execution_20250825, OpenAI'scode_interpreter, the barecode_execution) is always forwarded to the provider, and only the Otari-specificotari_code_executiontype reaches the gateway's sandbox. A client written against Anthropic's sandbox therefore breaks the moment its model is swapped for one with no native sandbox, and the same is true of the files it attaches.The executor. This PR introduces who runs the code such a declaration asks for.
auto(the new default) keeps the declaration with a provider that runs it natively for the dispatched model and wire format, and brings it to the gateway's sandbox otherwise, answering in the caller's own vocabulary (server_tool_use+code_execution_tool_resultblocks on Messages, acode_interpreter_callitem on Responses).otarialways runs it here;provideralways forwards it. The deployment sets the default (code_execution_executor, on the Tools page), a workspace policy may pin a value, and theX-Otari-Code-Executionheader chooses per request where the workspace has not pinned.Files, held to the same standard. This PR absorbs #1364 (the files API parity work, superseding it) and makes its sandbox half follow the executor rather than the
otari_code_executiontype alone:FileMetadatafor a caller sendinganthropic-version, the OpenAI file object otherwise), listings are cursor-paged, anfsspecstorage backend joinslocalands3, and a retention sweep reclaims expired and deleted files.otari_code_executionor a provider's declaration the executor brought here. When the provider keeps its declaration, an Anthropiccontainer_uploadfalls back to being read as a document, exactly as it does without a sandbox.code_execution_outputfiles owned by the same user and workspace, and a caller who spoke Anthropic's vocabulary gets theirfile_idin thecode_execution_outputentries of the native result block, which is where its SDK looks.A deployment without a sandbox is untouched: provider declarations are forwarded exactly as before and no policy is read for them.
otari_code_executionkeeps working unchanged.Not in this PR, and tracked as follow-ups: a
CodeExecutionPortwith an e2b adapter behind the existing HTTP contract, cross-request container ids (acontainerid from a previous turn still addresses the provider's container), files in hybrid mode (no local database),cfile_ids on the Responses wire, a platform-side executor pin in hybrid mode (the control plane's resolve is only consulted once the decision already points at the sandbox, so no natively served request turns into a 403), and staging attachments for a request a workspace pin pulls here (the pin is read after normalization; the docs say so).How to test it locally
docker compose --profile code-exec up, then send an Anthropic Messages request withtools: [{"type": "code_execution_20250825", "name": "code_execution"}]against a non-Anthropic model. The code runs on the sandbox and the response carriesserver_tool_useandcode_execution_tool_resultblocks withotari_srvtoolu_ids.X-Otari-Code-Execution: otariand it runs here instead.GET /api/v1/files?limit=2pages withhas_moreandlast_id. Reference it from a request that runs on the sandbox: the file is in the session's working directory, and a file the run writes comes back as afile_idin the tool result and, for an Anthropic-native caller, in the result block.GET /api/v1/toolslists the provider keywords underotari_code_execution.accepted_typesunless the default isprovider.Automated coverage:
tests/unit/test_code_executor.py(the decision, and when attachments are staged),tests/integration/test_code_execution_executor.py(the request path, header, pin, folding), native block minting intests/unit/test_mcp_loop_messages.pyandtests/unit/test_mcp_loop_responses.py, echoed-block folding intests/unit/test_messages_minted_block_stripping.py, the files work's own tests (tests/integration/test_files_endpoint.py,tests/unit/test_sandbox_backend.py,tests/unit/test_content_normalizer.py,tests/unit/test_fsspec_file_store.py), plus the tool-settings, tools-discovery and dashboard tests.make lint,make typecheck, the unit suite, the full integration suite, the OSS smoke gate and the dashboard suite pass locally.PR Type
Relevant issues
Supersedes #1364 (and through it #976 and #977). Part of #786. Groundwork for the code-execution provider abstraction discussed alongside #896.
Checklist
tests/unit,tests/integration).make lint,make typecheck,make test).uv run python scripts/generate_openapi.py).ARCHITECTURE.mdorscripts/check_architecture.py, the description names the rule and says why.AI Usage
AI Model/Tool used: Claude Code (Claude Fable 5.1)
Any additional AI details you'd like to share: Design agreed with the maintainer in conversation. The executor half was implemented, tested and documented by the agent; the files half is the maintainer's #1364, merged in and adapted to the executor by the agent. Everything was verified locally.
🤖 Generated with Claude Code