From faa28fe80c4645164f61fa0ae230b8d189dcb418 Mon Sep 17 00:00:00 2001 From: Krrish Dholakia Date: Tue, 23 Jun 2026 12:39:55 -0700 Subject: [PATCH 1/6] docs(sandbox): document opensandbox provider and chat completions interception Adds the opensandbox backend alongside e2b and documents the code interpreter interceptor on /v1/chat/completions in addition to /v1/responses. Reorders the page so the interceptor sits up front since it is the main entry point for most users. Co-Authored-By: Claude Opus 4.7 --- docs/sandbox.md | 346 +++++++++++++++++++++++++++++++----------------- 1 file changed, 227 insertions(+), 119 deletions(-) diff --git a/docs/sandbox.md b/docs/sandbox.md index 071f4b0cd..e2dc4b2ba 100644 --- a/docs/sandbox.md +++ b/docs/sandbox.md @@ -3,14 +3,14 @@ import TabItem from '@theme/TabItem'; # Sandbox / Code Execution -Run model-generated code inside an isolated sandbox and get its output back. The API is provider-agnostic; e2b is the first supported backend, talked to directly over HTTPS with no extra SDK dependency. +Run model-generated code inside an isolated sandbox and get its output back. The API is provider-agnostic; e2b and opensandbox are supported backends, talked to directly over HTTPS with no extra SDK dependency. | Feature | Supported | |---------|-----------| -| Supported Providers | `e2b` | +| Supported Providers | `e2b`, `opensandbox` | | Cost Tracking | Passthrough (sandbox billing stays with the provider) | | Logging | Via the standard `@client` logging path used by `litellm.asearch` | -| Proxy Endpoint | Via the Responses API code interpreter interceptor (see below); no standalone `/v1/sandbox` yet | +| Proxy Endpoint | Via the code interpreter interceptor on `/v1/responses` and `/v1/chat/completions` (see below); no standalone `/v1/sandbox` yet | :::tip @@ -18,124 +18,55 @@ Run model-generated code inside an isolated sandbox and get its output back. The ::: -## Quick start (ephemeral) +## Code interpreter interceptor -The fastest path is `acode_interpreter_tool`. It creates a sandbox, runs the code, then deletes the sandbox in a `finally` block so a raised exception still cleans up. - -```python showLineNumbers title="Ephemeral code execution" -import asyncio, os, litellm - -os.environ["E2B_API_KEY"] = "e2b_..." - -async def main(): - result = await litellm.acode_interpreter_tool( - provider="e2b", - code="print(sum(range(10)))", - ) - print(result.stdout) # '45\n' - print(result.error) # None +Route OpenAI's `code_interpreter` tool to your sandbox instead of OpenAI's container. Works on both `/v1/responses` and `/v1/chat/completions`; client requests stay plain OpenAI shape. On the chat path the native `{"type": "code_interpreter"}` tool is rewritten into a `litellm_code_execution` function tool, LiteLLM runs the generated code in your sandbox, appends the result as a `role: tool` message, and continues the loop until a final answer. -asyncio.run(main()) -``` - -If the code raises inside the sandbox, the error surfaces in `result.error` rather than as a Python exception, so a sandbox-level `ZeroDivisionError` does not crash the caller: - -```python -result = await litellm.acode_interpreter_tool(provider="e2b", code="1/0") -result.error["name"] # 'ZeroDivisionError' -result.error["value"] # 'division by zero' -result.error["traceback"] # full traceback string -``` +### SDK -## Low-level lifecycle +Register the sandbox tool, install the interceptor as a callback, call `litellm.aresponses` (or `litellm.acompletion`) with the `code_interpreter` tool unchanged. -When you want to reuse a sandbox across multiple `arun_code` calls, drive the lifecycle yourself with `acreate_sandbox`, `arun_code`, and `adelete_sandbox`. The low-level names are sandbox-scoped on purpose so they do not collide with the existing OpenAI Containers API (`litellm.create_container`), which is unrelated and stays untouched. + + -```python showLineNumbers title="Manual sandbox lifecycle" -import asyncio, os, litellm +```python showLineNumbers title="sandbox_interceptor.py" +import os, litellm +from litellm.sandbox.sandbox_tools import register_sandbox_tools +from litellm.integrations.code_interpreter_interception.handler import ( + CodeInterpreterInterceptionLogger, +) os.environ["E2B_API_KEY"] = "e2b_..." +os.environ["OPENAI_API_KEY"] = "sk-..." -async def main(): - container = await litellm.acreate_sandbox(provider="e2b") - try: - first = await litellm.arun_code( - provider="e2b", container=container, code="x = 6 * 7\nprint(x)", - ) - print(first.stdout) # '42\n' - - second = await litellm.arun_code( - provider="e2b", container=container, code="print(x + 1)", - ) - print(second.stdout) # '43\n' (state persists inside the container) - finally: - await litellm.adelete_sandbox(provider="e2b", container=container) - -asyncio.run(main()) -``` - -`arun_code` and `adelete_sandbox` accept either the `ContainerHandle` returned by `acreate_sandbox` or a bare sandbox id string, so you can persist the id between processes and pick the sandbox back up later. - -## Parameters - -### `acode_interpreter_tool` - -| Parameter | Type | Required | Description | -|-----------|------|----------|-------------| -| `provider` | string | Yes | Sandbox provider slug. Currently `"e2b"`. | -| `code` | string | Yes | Executable string passed straight to the sandbox. | -| `template` | string | No | Provider template id. Defaults to e2b's `code-interpreter-v1`. | -| `timeout` | int | No | Sandbox lifetime in seconds. Defaults to 300. | -| `api_key` | string | No | Overrides the env var lookup. | -| `api_base` | string | No | Overrides the provider's default host. Use this to point a self-hosted sandbox at a cluster URL. | - -### `acreate_sandbox` - -Same shape as above without `code`, plus `allow_internet_access: bool = True` for backends that gate egress. - -### `arun_code` and `adelete_sandbox` - -`provider`, `container` (a `ContainerHandle` or sandbox id string), and optional `api_key` / `api_base`. `arun_code` also takes `code`. - -## Response: `CodeExecutionResult` - -The return shape is a thin pydantic model that preserves whatever the sandbox emitted. - -| Field | Type | Description | -|-------|------|-------------| -| `stdout` | string | Captured stdout. Empty string if nothing was printed. | -| `stderr` | string | Captured stderr. | -| `results` | list[dict] | Rich outputs such as base64 PNG charts; passed through unchanged. | -| `error` | dict \| None | `{name, value, traceback}` when the sandboxed code raised, else `None`. | -| `execution_count` | int \| None | Jupyter-style cell counter for the run. | -| `object` | string | Always `"code_execution"`. | - -## Provider setup - -### e2b +register_sandbox_tools([ + { + "sandbox_tool_name": "my-e2b", + "litellm_params": { + "sandbox_provider": "e2b", + "api_key": "os.environ/E2B_API_KEY", + }, + } +]) -Set `E2B_API_KEY` (or pass `api_key=...` per call). Defaults: template `code-interpreter-v1`, sandbox timeout 300s, internet access on. Override `template` to use any custom e2b template you have published. +litellm.callbacks = [ + CodeInterpreterInterceptionLogger( + sandbox_tool_name="my-e2b", + ) +] -```python -result = await litellm.acode_interpreter_tool( - provider="e2b", - code="...", - template="my-org/custom-template", - timeout=120, +response = await litellm.aresponses( + model="openai/gpt-5", + tools=[{"type": "code_interpreter", "container": {"type": "auto"}}], + input="Product of first 6 primes. Just the number.", ) +print(response.output_text) ``` -Behind the scenes the call goes directly to e2b's REST API: `POST api.e2b.app/sandboxes` to create, a streamed NDJSON `POST` to the per-sandbox host on port 49999 to execute, and `DELETE api.e2b.app/sandboxes/{id}` to tear down. - -## Responses API code interpreter interceptor - -Route OpenAI's `code_interpreter` tool to your sandbox instead of OpenAI's container. The client request stays plain Responses API. - -### SDK - -Register the sandbox tool, install the interceptor as a callback, call `litellm.aresponses` with the `code_interpreter` tool unchanged. + + -```python showLineNumbers title="sandbox_interceptor.py" +```python showLineNumbers title="sandbox_interceptor_chat.py" import os, litellm from litellm.sandbox.sandbox_tools import register_sandbox_tools from litellm.integrations.code_interpreter_interception.handler import ( @@ -157,19 +88,24 @@ register_sandbox_tools([ litellm.callbacks = [ CodeInterpreterInterceptionLogger( - enabled_providers=["openai"], sandbox_tool_name="my-e2b", ) ] -response = await litellm.aresponses( - model="openai/gpt-5", +response = await litellm.acompletion( + model="openai/gpt-4o-mini", + messages=[{"role": "user", "content": "Product of first 6 primes. Just the number."}], tools=[{"type": "code_interpreter", "container": {"type": "auto"}}], - input="Product of first 6 primes. Just the number.", + max_agentic_loops=4, ) -print(response.output_text) +print(response.choices[0].message.content) ``` +`max_agentic_loops` caps how many sandbox round-trips LiteLLM will run before returning whatever the model has produced; the loop also short-circuits on repeated tool-call fingerprints. Defaults are conservative, raise it if your task needs deeper chained execution. + + + + ### Proxy setup #### 1. Set keys @@ -197,22 +133,19 @@ sandbox_tools: litellm_settings: callbacks: ["code_interpreter_interception"] code_interpreter_interception_params: - enabled_providers: ["openai"] sandbox_tool_name: my-e2b ``` -Only providers in `enabled_providers` get their `code_interpreter` tool swapped. - #### 3. Start the proxy ```bash litellm --config /path/to/config.yaml ``` -#### 4. Call `/v1/responses` +#### 4. Call the proxy - + ```bash curl -s "http://localhost:4000/v1/responses" \ @@ -226,7 +159,7 @@ curl -s "http://localhost:4000/v1/responses" \ ``` - + ```python from openai import OpenAI @@ -241,11 +174,186 @@ response = client.responses.create( print(response.output_text) ``` + + + +```bash +curl -s "http://localhost:4000/v1/chat/completions" \ + -H "Authorization: Bearer sk-1234" \ + -H "Content-Type: application/json" \ + -d '{ + "model": "gpt-4o-mini", + "messages": [ + {"role": "user", "content": "Product of first 6 primes. Just the number."} + ], + "tools": [{"type": "code_interpreter", "container": {"type": "auto"}}] + }' +``` + + + + +```python +from openai import OpenAI + +client = OpenAI(api_key="sk-1234", base_url="http://localhost:4000/v1") + +response = client.chat.completions.create( + model="gpt-4o-mini", + messages=[{"role": "user", "content": "Product of first 6 primes. Just the number."}], + tools=[{"type": "code_interpreter", "container": {"type": "auto"}}], +) +print(response.choices[0].message.content) +``` + -Response contains a `code_interpreter_call` item with a `cntr_*` `container_id` wrapping the e2b sandbox id. +On the Responses path the result contains a `code_interpreter_call` item with a `cntr_*` `container_id` wrapping the sandbox id. On the Chat Completions path the tool call shows up as a `litellm_code_execution` function call with the executed code, followed by a `role: tool` message holding the stdout; the model's final answer arrives in the next assistant message. + +To run against OpenSandbox instead of e2b, swap the `sandbox_tools` entry: + +```yaml +sandbox_tools: + - sandbox_tool_name: my-opensandbox + litellm_params: + sandbox_provider: opensandbox + api_base: os.environ/OPEN_SANDBOX_API_BASE + api_key: os.environ/OPEN_SANDBOX_API_KEY +``` ### Notes Response shape matches OpenAI's native `code_interpreter_call`. `stream: true` works. Forced `tool_choice: {"type":"code_interpreter"}` is rewritten automatically. One sandbox per request, deleted on completion; concurrent requests are isolated by a server-minted cache key. Removing a tool from `sandbox_tools` clears its credentials on reload. v0 does not support file upload or download yet. + +## Direct sandbox SDK + +If you want to drive the sandbox yourself, without a model in the loop, the same providers are exposed as plain Python helpers. + +### Quick start (ephemeral) + +The fastest path is `acode_interpreter_tool`. It creates a sandbox, runs the code, then deletes the sandbox in a `finally` block so a raised exception still cleans up. + +```python showLineNumbers title="Ephemeral code execution" +import asyncio, os, litellm + +os.environ["E2B_API_KEY"] = "e2b_..." + +async def main(): + result = await litellm.acode_interpreter_tool( + provider="e2b", + code="print(sum(range(10)))", + ) + print(result.stdout) # '45\n' + print(result.error) # None + +asyncio.run(main()) +``` + +If the code raises inside the sandbox, the error surfaces in `result.error` rather than as a Python exception, so a sandbox-level `ZeroDivisionError` does not crash the caller: + +```python +result = await litellm.acode_interpreter_tool(provider="e2b", code="1/0") +result.error["name"] # 'ZeroDivisionError' +result.error["value"] # 'division by zero' +result.error["traceback"] # full traceback string +``` + +### Low-level lifecycle + +When you want to reuse a sandbox across multiple `arun_code` calls, drive the lifecycle yourself with `acreate_sandbox`, `arun_code`, and `adelete_sandbox`. The low-level names are sandbox-scoped on purpose so they do not collide with the existing OpenAI Containers API (`litellm.create_container`), which is unrelated and stays untouched. + +```python showLineNumbers title="Manual sandbox lifecycle" +import asyncio, os, litellm + +os.environ["E2B_API_KEY"] = "e2b_..." + +async def main(): + container = await litellm.acreate_sandbox(provider="e2b") + try: + first = await litellm.arun_code( + provider="e2b", container=container, code="x = 6 * 7\nprint(x)", + ) + print(first.stdout) # '42\n' + + second = await litellm.arun_code( + provider="e2b", container=container, code="print(x + 1)", + ) + print(second.stdout) # '43\n' (state persists inside the container) + finally: + await litellm.adelete_sandbox(provider="e2b", container=container) + +asyncio.run(main()) +``` + +`arun_code` and `adelete_sandbox` accept either the `ContainerHandle` returned by `acreate_sandbox` or a bare sandbox id string, so you can persist the id between processes and pick the sandbox back up later. + +## Parameters + +### `acode_interpreter_tool` + +| Parameter | Type | Required | Description | +|-----------|------|----------|-------------| +| `provider` | string | Yes | Sandbox provider slug. One of `"e2b"`, `"opensandbox"`. | +| `code` | string | Yes | Executable string passed straight to the sandbox. | +| `template` | string | No | Provider template id. Defaults to e2b's `code-interpreter-v1`. | +| `timeout` | int | No | Sandbox lifetime in seconds. Defaults to 300. | +| `api_key` | string | No | Overrides the env var lookup. | +| `api_base` | string | No | Overrides the provider's default host. Use this to point a self-hosted sandbox at a cluster URL. | + +### `acreate_sandbox` + +Same shape as above without `code`, plus `allow_internet_access: bool = True` for backends that gate egress. + +### `arun_code` and `adelete_sandbox` + +`provider`, `container` (a `ContainerHandle` or sandbox id string), and optional `api_key` / `api_base`. `arun_code` also takes `code`. + +## Response: `CodeExecutionResult` + +The return shape is a thin pydantic model that preserves whatever the sandbox emitted. + +| Field | Type | Description | +|-------|------|-------------| +| `stdout` | string | Captured stdout. Empty string if nothing was printed. | +| `stderr` | string | Captured stderr. | +| `results` | list[dict] | Rich outputs such as base64 PNG charts; passed through unchanged. | +| `error` | dict \| None | `{name, value, traceback}` when the sandboxed code raised, else `None`. | +| `execution_count` | int \| None | Jupyter-style cell counter for the run. | +| `object` | string | Always `"code_execution"`. | + +## Provider setup + +### e2b + +Set `E2B_API_KEY` (or pass `api_key=...` per call). Defaults: template `code-interpreter-v1`, sandbox timeout 300s, internet access on. Override `template` to use any custom e2b template you have published. + +```python +result = await litellm.acode_interpreter_tool( + provider="e2b", + code="...", + template="my-org/custom-template", + timeout=120, +) +``` + +Behind the scenes the call goes directly to e2b's REST API: `POST api.e2b.app/sandboxes` to create, a streamed NDJSON `POST` to the per-sandbox host on port 49999 to execute, and `DELETE api.e2b.app/sandboxes/{id}` to tear down. + +### opensandbox + +Use [OpenSandbox](https://github.com/opensandboxai/opensandbox) for self-hosted code execution. Set `OPEN_SANDBOX_API_BASE` (or pass `api_base=...` per call) to point at your server; there is no localhost fallback. `OPEN_SANDBOX_API_KEY` is optional, leave it empty for a local no-auth server. Sandboxes are created with egress denied by default; pass `allow_internet_access=True` or an explicit `network_policy` to open it up. + +```python +import os, litellm + +os.environ["OPEN_SANDBOX_API_BASE"] = "http://127.0.0.1:8080/v1" +os.environ["OPEN_SANDBOX_API_KEY"] = "" # optional for local no-auth servers + +result = await litellm.acode_interpreter_tool( + provider="opensandbox", + code="print(sum(range(10)))", +) +print(result.stdout) # '45\n' +``` + +The provider drives OpenSandbox's REST lifecycle directly: `POST /v1/sandboxes` to create, resolves the per-sandbox execd endpoint, streams `/code` SSE into a `CodeExecutionResult`, then `DELETE /v1/sandboxes/{id}` to tear down. Other defaults (template, entrypoint, language, polling interval, execd port, default network policy, output cap) live as literals in `litellm/constants.py`. From c68fefe930700a05a12bd2b8aa22d72345454101 Mon Sep 17 00:00:00 2001 From: Krrish Dholakia Date: Tue, 23 Jun 2026 12:44:49 -0700 Subject: [PATCH 2/6] blog: announce code interpreter sandbox swap New post covering the code_interpreter interceptor as a drop-in replacement for OpenAI's hosted code interpreter, with E2B and OpenSandbox as backends. Same OpenAI client contract, execution runs in a sandbox the user controls. Co-Authored-By: Claude Opus 4.7 --- blog/swap_openai_code_interpreter/index.md | 158 +++++++++++++++++++++ 1 file changed, 158 insertions(+) create mode 100644 blog/swap_openai_code_interpreter/index.md diff --git a/blog/swap_openai_code_interpreter/index.md b/blog/swap_openai_code_interpreter/index.md new file mode 100644 index 000000000..08b89498f --- /dev/null +++ b/blog/swap_openai_code_interpreter/index.md @@ -0,0 +1,158 @@ +--- +slug: swap_openai_code_interpreter +title: "Swap OpenAI Code Interpreter for E2B/OpenSandbox" +date: 2026-06-23T10:00:00 +authors: + - krrish +description: "Keep the OpenAI code_interpreter tool in your requests, run the code in your own sandbox. LiteLLM intercepts the tool call and routes it to E2B or OpenSandbox; no client changes." +tags: [code interpreter, sandbox, e2b, opensandbox, agents] +hide_table_of_contents: false +--- + +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + +The OpenAI Responses and Chat Completions APIs let you declare a `code_interpreter` tool and the model runs Python inside an OpenAI-hosted container. That container is opaque, billed by OpenAI, and the code (often customer data) leaves your perimeter. LiteLLM now intercepts that tool call and runs it in a sandbox you control. The client request is unchanged. + +{/* truncate */} + +## How the swap works + +Register a sandbox tool, enable the interceptor, then call the model the way you already do. When the model emits a `code_interpreter` tool call, LiteLLM creates a sandbox (E2B or OpenSandbox), executes the generated code, feeds the result back into the loop, and tears the sandbox down on completion. The response shape stays compatible with OpenAI's native `code_interpreter_call`. + +Two backends are supported today: [E2B](https://e2b.dev/) for a managed sandbox, and [OpenSandbox](https://github.com/opensandboxai/opensandbox) for self-hosted Docker-backed execution when the code or data cannot leave your network. + +## SDK + + + + +```python +import os, litellm +from litellm.sandbox.sandbox_tools import register_sandbox_tools +from litellm.integrations.code_interpreter_interception.handler import ( + CodeInterpreterInterceptionLogger, +) + +os.environ["E2B_API_KEY"] = "e2b_..." +os.environ["OPENAI_API_KEY"] = "sk-..." + +register_sandbox_tools([ + { + "sandbox_tool_name": "my-e2b", + "litellm_params": { + "sandbox_provider": "e2b", + "api_key": "os.environ/E2B_API_KEY", + }, + } +]) + +litellm.callbacks = [ + CodeInterpreterInterceptionLogger(sandbox_tool_name="my-e2b") +] + +response = await litellm.aresponses( + model="openai/gpt-5", + tools=[{"type": "code_interpreter", "container": {"type": "auto"}}], + input="Product of first 6 primes. Just the number.", +) +print(response.output_text) +``` + + + + +```python +import os, litellm +from litellm.sandbox.sandbox_tools import register_sandbox_tools +from litellm.integrations.code_interpreter_interception.handler import ( + CodeInterpreterInterceptionLogger, +) + +os.environ["E2B_API_KEY"] = "e2b_..." +os.environ["OPENAI_API_KEY"] = "sk-..." + +register_sandbox_tools([ + { + "sandbox_tool_name": "my-e2b", + "litellm_params": { + "sandbox_provider": "e2b", + "api_key": "os.environ/E2B_API_KEY", + }, + } +]) + +litellm.callbacks = [ + CodeInterpreterInterceptionLogger(sandbox_tool_name="my-e2b") +] + +response = await litellm.acompletion( + model="openai/gpt-4o-mini", + messages=[{"role": "user", "content": "Product of first 6 primes. Just the number."}], + tools=[{"type": "code_interpreter", "container": {"type": "auto"}}], + max_agentic_loops=4, +) +print(response.choices[0].message.content) +``` + + + + +The native `code_interpreter` tool is rewritten before it reaches OpenAI; on the chat path it becomes a `litellm_code_execution` function tool and LiteLLM appends each sandbox result as a `role: tool` message until the model returns a final answer. + +## Proxy + +Same swap behind the AI gateway, with no client-side change. + +```yaml title="config.yaml" +model_list: + - model_name: gpt-5 + litellm_params: + model: openai/gpt-5 + api_key: os.environ/OPENAI_API_KEY + +sandbox_tools: + - sandbox_tool_name: my-e2b + litellm_params: + sandbox_provider: e2b + api_key: os.environ/E2B_API_KEY + +litellm_settings: + callbacks: ["code_interpreter_interception"] + code_interpreter_interception_params: + sandbox_tool_name: my-e2b +``` + +The OpenAI SDK keeps working unchanged. Point it at the proxy, declare `code_interpreter`, and the gateway handles the rest. + +```python +from openai import OpenAI + +client = OpenAI(api_key="sk-1234", base_url="http://localhost:4000/v1") + +response = client.responses.create( + model="gpt-5", + tools=[{"type": "code_interpreter", "container": {"type": "auto"}}], + input="Product of first 6 primes. Just the number.", +) +print(response.output_text) +``` + +To run fully on-prem, swap the `sandbox_tools` entry to OpenSandbox: + +```yaml +sandbox_tools: + - sandbox_tool_name: my-opensandbox + litellm_params: + sandbox_provider: opensandbox + api_base: os.environ/OPEN_SANDBOX_API_BASE + api_key: os.environ/OPEN_SANDBOX_API_KEY +``` + +OpenSandbox runs sandboxes locally with egress denied by default; flip `allow_internet_access=True` or pass an explicit `network_policy` when the code needs the network. + +## Why route it through your own sandbox + +You keep the OpenAI client contract while owning the execution layer. The generated code and any uploaded data stay inside the sandbox you operate, billing for execution stops going to OpenAI, and the same setup works for Responses and Chat Completions across any model the gateway routes to. Streaming, forced `tool_choice`, and concurrent requests are isolated per request and cleaned up on completion. + +Full reference is in the [sandbox docs](/docs/sandbox). From 1dbcf34aaa1ab4c8e12e5b74cd4e58b09f4f2a96 Mon Sep 17 00:00:00 2001 From: Krrish Dholakia Date: Tue, 23 Jun 2026 12:50:11 -0700 Subject: [PATCH 3/6] blog: tweak code interpreter swap intro Co-Authored-By: Claude Opus 4.7 --- blog/swap_openai_code_interpreter/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/blog/swap_openai_code_interpreter/index.md b/blog/swap_openai_code_interpreter/index.md index 08b89498f..9480690b2 100644 --- a/blog/swap_openai_code_interpreter/index.md +++ b/blog/swap_openai_code_interpreter/index.md @@ -12,7 +12,7 @@ hide_table_of_contents: false import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; -The OpenAI Responses and Chat Completions APIs let you declare a `code_interpreter` tool and the model runs Python inside an OpenAI-hosted container. That container is opaque, billed by OpenAI, and the code (often customer data) leaves your perimeter. LiteLLM now intercepts that tool call and runs it in a sandbox you control. The client request is unchanged. +The OpenAI Responses and Chat Completions APIs let you declare a `code_interpreter` tool and the model runs Python inside an OpenAI-hosted container. That container is opaque, billed by OpenAI, and the code (often customer data) leaves your perimeter. LiteLLM now let's you intercept that tool call and runs it in a sandbox you control. The client request is unchanged. {/* truncate */} From 68ebe06a132561ea642fcc0cc684484ff328e464 Mon Sep 17 00:00:00 2001 From: Krrish Dholakia Date: Tue, 23 Jun 2026 12:54:02 -0700 Subject: [PATCH 4/6] blog: note v1.91.0.dev1 availability for code interpreter swap Co-Authored-By: Claude Opus 4.7 --- blog/swap_openai_code_interpreter/index.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/blog/swap_openai_code_interpreter/index.md b/blog/swap_openai_code_interpreter/index.md index 9480690b2..1b9ef9c97 100644 --- a/blog/swap_openai_code_interpreter/index.md +++ b/blog/swap_openai_code_interpreter/index.md @@ -14,6 +14,8 @@ import TabItem from '@theme/TabItem'; The OpenAI Responses and Chat Completions APIs let you declare a `code_interpreter` tool and the model runs Python inside an OpenAI-hosted container. That container is opaque, billed by OpenAI, and the code (often customer data) leaves your perimeter. LiteLLM now let's you intercept that tool call and runs it in a sandbox you control. The client request is unchanged. +Available starting `LiteLLM v1.91.0.dev1`. + {/* truncate */} ## How the swap works From 2878595f43f9e2816eb556cd693f689724a603fc Mon Sep 17 00:00:00 2001 From: Krrish Dholakia Date: Tue, 23 Jun 2026 12:55:21 -0700 Subject: [PATCH 5/6] blog: link to LiteLLM releases page Co-Authored-By: Claude Opus 4.7 --- blog/swap_openai_code_interpreter/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/blog/swap_openai_code_interpreter/index.md b/blog/swap_openai_code_interpreter/index.md index 1b9ef9c97..d45d0614d 100644 --- a/blog/swap_openai_code_interpreter/index.md +++ b/blog/swap_openai_code_interpreter/index.md @@ -14,7 +14,7 @@ import TabItem from '@theme/TabItem'; The OpenAI Responses and Chat Completions APIs let you declare a `code_interpreter` tool and the model runs Python inside an OpenAI-hosted container. That container is opaque, billed by OpenAI, and the code (often customer data) leaves your perimeter. LiteLLM now let's you intercept that tool call and runs it in a sandbox you control. The client request is unchanged. -Available starting `LiteLLM v1.91.0.dev1`. +Available starting `LiteLLM v1.91.0.dev1`. Check here for [releases](https://github.com/BerriAI/litellm/releases). {/* truncate */} From 7efd75b9d106bc720b30174564bd6395129db170 Mon Sep 17 00:00:00 2001 From: Krrish Dholakia Date: Tue, 23 Jun 2026 13:31:40 -0700 Subject: [PATCH 6/6] blog: add hero image for code interpreter swap Co-Authored-By: Claude Opus 4.7 --- blog/swap_openai_code_interpreter/hero.png | Bin 0 -> 752831 bytes blog/swap_openai_code_interpreter/index.md | 3 +++ 2 files changed, 3 insertions(+) create mode 100644 blog/swap_openai_code_interpreter/hero.png diff --git a/blog/swap_openai_code_interpreter/hero.png b/blog/swap_openai_code_interpreter/hero.png new file mode 100644 index 0000000000000000000000000000000000000000..7a082c14f5c5710ec2d0fb3444b34f0d3ad47ea7 GIT binary patch literal 752831 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