# How to add a code execution tool to the Vercel AI SDK Pass `runtimeTools(sbx)` from `withruntime/ai` to `generateText` or `streamText`, and the model's commands run in a microVM. **Runtime's tools work with any model the AI SDK can call, and cost $0.03125 an hour per 2 vCPU, 4 GiB sandbox while the model thinks.** `runtimeTools(sbx)` returns four AI SDK tools bound to one Firecracker microVM with its own Linux kernel: run a command, read a file, write a file, list a directory. The model picks commands and paths; your code picks the sandbox. The `ai` package was at 7.0.114 on npm on 25 September 2026; the adapter needs version 5 or later and was tested in the SDK's own loop with 7.0.87 on 23 September 2026. ## Install ```bash no-run npm install withruntime ai npx withruntime login ``` The login prints a link to approve in the browser, so there is no key to copy. In production, set `RUNTIME_API_KEY` from your secret store. ## One call with tools ```ts check import { generateText, stepCountIs, type LanguageModel } from "ai"; import { Sandbox } from "withruntime"; import { runtimeTools } from "withruntime/ai"; export async function solve(model: LanguageModel, prompt: string) { await using sbx = await Sandbox.create(); const { text } = await generateText({ model, tools: runtimeTools(sbx), stopWhen: stepCountIs(20), prompt, }); return text; } console.log( await solve( "anthropic/claude-sonnet-4.6", "Download nothing. Compute 2**521 - 1 in Python and say if it is prime.", ), ); ``` - **`stopWhen: stepCountIs(20)`** lets the model call tools and read the results for up to 20 steps. Without it, `generateText` makes one generation. - **The model string** is an AI Gateway id; a provider object such as one from `@ai-sdk/openai` works the same way. - **`await using`** stops the sandbox when `solve` returns. The tools are `runtime_exec`, `runtime_read_file`, `runtime_write_file` and `runtime_list_files` ([frameworks](/docs/frameworks#vercel-ai-sdk)). ## Stream from a route handler A chat route streams while the model works. `await using` would stop the sandbox before the stream ends, so stop it in `onFinish`, and let the lease stop it if the client disconnects first: ```ts check import { stepCountIs, streamText } from "ai"; import { Sandbox } from "withruntime"; import { runtimeTools } from "withruntime/ai"; export async function POST(request: Request) { const { prompt } = (await request.json()) as { prompt: string }; const sbx = await Sandbox.create({ timeoutSeconds: 600, onLeaseEnd: "stop" }); const result = streamText({ model: "anthropic/claude-sonnet-4.6", tools: runtimeTools(sbx, { timeoutSeconds: 120, maxOutputChars: 8_000 }), stopWhen: stepCountIs(20), prompt, onFinish: async () => { await sbx.stop(); }, }); return result.toTextStreamResponse(); } ``` `timeoutSeconds` is the default for a command the model starts without one (300 otherwise), and `maxOutputChars` cuts each of stdout, stderr and a file read from the front, keeping the end, where errors usually are. ## Built-in code execution in the AI SDK, compared The AI SDK has other ways to run code. What each is, from the AI SDK docs read on 25 September 2026: | Option | Where code runs | Models | What the docs say | | ---------------------------------------- | ------------------------------------- | ------ | -------------------------------------------------------------------------------- | | `openai.tools.codeInterpreter()` | OpenAI's hosted container | OpenAI | "allows models to write and execute Python code" | | `anthropic.tools.codeExecution_20260120` | Anthropic's container | Claude | "gives Claude direct access to a real Python environment" | | `openai.tools.localShell()` | Your own machine | OpenAI | Runs "shell commands locally on a machine you or the user provides" | | `ai-sdk-tool-code-execution` | Vercel Sandbox | Any | Python 3.13 in "an isolated environment" | | `experimental_sandbox` | Wherever your implementation sends it | Any | "does not sandbox the tool itself"; tool code runs "in your application process" | | `runtimeTools(sbx)` | A Runtime microVM your code owns | Any | Shell, files and listings in Ubuntu 24.04, with Python, Node.js, Bun and gcc | Provider tools lock the choice of model to the provider that runs the container. Runtime's tools are ordinary AI SDK tools, so switching models is a one-word change. For prices of the hosted containers, see [OpenAI Code Interpreter alternative](/compare/openai-code-interpreter-alternative) and [Claude code execution tool alternative](/compare/claude-code-execution-tool-alternative). ## What the model can do in the sandbox The sandbox is a full Linux machine with `sudo`, so the model can `pip install`, `npm install`, compile C, run a test suite or start a server. Your code holds `sbx` and can add more between steps or turns: - **Show the user what was built.** `sbx.previews.create(3000)` shares a port at a private HTTPS address under `runtimehost.com` ([share a port](/docs/javascript#share-a-port)). - **Keep a session across chat turns.** `Sandbox.getOrCreate("chat-42")` returns the same sandbox for the same name, woken if it was paused, so a user's files survive between requests ([sandboxes by name](/docs/javascript#sandboxes-by-name)). - **Pause when idle.** `idlePauseSeconds: 600` pauses after ten quiet minutes, with memory kept, and the next tool call wakes it in about half a second. - **Branch.** `sbx.fork({ count: 3 })` makes three running copies to try three fixes at once ([snapshots and forks](/docs/javascript#snapshots-and-forks)). - **Notebook-style cells.** `sbx.interpreter.run(code)` keeps variables between calls and returns charts as PNG, for a data chat ([code interpreter for chatbots](/use-cases/code-interpreter-for-chatbots)). ## Keep keys and spending safe The model provider's key never enters the sandbox: `generateText` runs in your server and sends the sandbox only commands. To bound the sandbox: - **`maxCostMicros`** on `Sandbox.create` refuses a sandbox whose first lease would cost more, in microdollars. - **A daily spending limit** on the Runtime key stops creates, wakes and extensions past it with `spending_limit_reached` (HTTP 402), and nothing is charged ([read-only keys and daily limits](/docs/security#read-only-keys-and-daily-limits)). - **A read-only key** for the admin page that lists sandboxes and their cost. - **`network`** at create, such as `{ internet: true, allow: ["registry.npmjs.org"] }`, or `{ internet: false }` for pure computation. The host enforces it, root included. - **Secrets** for tokens the model's code needs: the sandbox sees a placeholder, and the host adds the value on HTTPS requests to the hosts you name ([secrets](/docs/security#secrets-sandboxes-never-see)). ## What it costs CPU is billed as used at $0.025 per vCPU-hour, with a floor of a twentieth of a vCPU, and memory at $0.0075 per GiB-hour, so a sandbox that waits on the model costs little. With both CPUs busy, 2 vCPU and 4 GiB is $0.08 an hour ([pricing](/docs/pricing)). New accounts get 50 free sandbox hours, no card. Mastra agents take these same tools; see [Mastra](/integrations/mastra). ## Sources Checked 25 September 2026. - [AI SDK: tools and tool calling](https://ai-sdk.dev/docs/ai-sdk-core/tools-and-tool-calling): `stopWhen` and the single-generation default - [AI SDK: OpenAI provider](https://ai-sdk.dev/providers/ai-sdk-providers/openai): `openai.tools.codeInterpreter()` and `openai.tools.localShell()` - [AI SDK: Anthropic provider](https://ai-sdk.dev/providers/ai-sdk-providers/anthropic): `codeExecution_20260120` and its description - [AI SDK: Experimental_SandboxSession](https://ai-sdk.dev/docs/reference/ai-sdk-core/sandbox): that it does not sandbox the tool itself - [AI SDK tools registry: code execution](https://ai-sdk.dev/tools-registry/code-execution): `ai-sdk-tool-code-execution` on Vercel Sandbox with Python 3.13 - [ai on npm](https://www.npmjs.com/package/ai): version 7.0.114 - [AI Gateway models](https://ai-gateway.vercel.sh/v1/models): the `anthropic/claude-sonnet-4.6` id Facts on this page were checked on 25 September 2026.