Skip to main content

Example on GitHub

Full working example with type-checked TypeScript execution.
Give your agent a code-execution tool with explicit CPU and memory limits. The agent writes code, runs it in an isolate, and gets back structured results.

Run generated JavaScript

The agent writes JavaScript, assigns a return value to module.exports, and gets it back.
JavaScript Execution
import { generateText, stepCountIs, tool } from "ai";
import { anthropic } from "@ai-sdk/anthropic";
import { NodeRuntime, createNodeDriver, createNodeRuntimeDriverFactory } from "secure-exec";
import { z } from "zod";

const runtime = new NodeRuntime({
  systemDriver: createNodeDriver({
    permissions: {
      fs: () => ({ allow: true }),
      network: () => ({ allow: true }),
    },
  }),
  runtimeDriverFactory: createNodeRuntimeDriverFactory(),
  memoryLimit: 64,
  cpuTimeLimitMs: 5000,
});

const { text } = await generateText({
  model: anthropic("claude-sonnet-4-6"),
  prompt: "Calculate the first 20 fibonacci numbers",
  stopWhen: stepCountIs(5),
  tools: {
    execute: tool({
      description: "Run JavaScript in a secure sandbox. Assign the result to module.exports to return data.",
      inputSchema: z.object({ code: z.string() }),
      execute: async ({ code }) => runtime.run(code),
    }),
  },
});

console.log(text);

Type-check generated TypeScript before execution

If the agent writes TypeScript, type-check it first. Failed diagnostics go back to the agent for repair; passing code gets compiled and executed.
Type-Checked Execution
import { generateText, stepCountIs, tool } from "ai";
import { anthropic } from "@ai-sdk/anthropic";
import {
  NodeRuntime,
  createNodeDriver,
  createNodeRuntimeDriverFactory,
} from "secure-exec";
import { createTypeScriptTools } from "@secure-exec/typescript";
import { z } from "zod";

const systemDriver = createNodeDriver({
  permissions: {
    fs: () => ({ allow: true }),
    network: () => ({ allow: true }),
  },
});
const runtimeDriverFactory = createNodeRuntimeDriverFactory();

const runtime = new NodeRuntime({
  systemDriver,
  runtimeDriverFactory,
  memoryLimit: 64,
  cpuTimeLimitMs: 5000,
});
const ts = createTypeScriptTools({
  systemDriver,
  runtimeDriverFactory,
  memoryLimit: 256,
  cpuTimeLimitMs: 5000,
});

const { text } = await generateText({
  model: anthropic("claude-sonnet-4-6"),
  prompt:
    "Write TypeScript that calculates the first 20 fibonacci numbers. Assign the result to module.exports.",
  stopWhen: stepCountIs(5),
  tools: {
    execute_typescript: tool({
      description:
        "Type-check TypeScript in a sandbox, compile it, then run the emitted JavaScript in a sandbox. Return diagnostics when validation fails.",
      inputSchema: z.object({ code: z.string() }),
      execute: async ({ code }) => {
        const typecheck = await ts.typecheckSource({
          sourceText: code,
          filePath: "/root/generated.ts",
          compilerOptions: {
            module: "commonjs",
            target: "es2022",
          },
        });

        if (!typecheck.success) {
          return {
            ok: false,
            stage: "typecheck",
            diagnostics: typecheck.diagnostics,
          };
        }

        const compiled = await ts.compileSource({
          sourceText: code,
          filePath: "/root/generated.ts",
          compilerOptions: {
            module: "commonjs",
            target: "es2022",
          },
        });

        if (!compiled.success || !compiled.outputText) {
          return {
            ok: false,
            stage: "compile",
            diagnostics: compiled.diagnostics,
          };
        }

        const execution = await runtime.run<Record<string, unknown>>(
          compiled.outputText,
          "/root/generated.js"
        );

        if (execution.code !== 0) {
          return {
            ok: false,
            stage: "run",
            errorMessage:
              execution.errorMessage ?? `Sandbox exited with code ${execution.code}`,
          };
        }

        return {
          ok: true,
          stage: "run",
          exports: execution.exports,
        };
      },
    }),
  },
});

console.log(text);
See TypeScript for the lower-level compile and type-check APIs.