@bthn/codemode-local-executor
v0.1.1
Published
Local vm2-based executor for @cloudflare/codemode — runs LLM-generated TypeScript in an isolated sandbox
Downloads
149
Maintainers
Readme
@bthn/codemode-local-executor
Local vm2-based executor for @cloudflare/codemode.
@cloudflare/codemode lets LLMs write executable TypeScript instead of making individual tool calls. It ships with DynamicWorkerExecutor which runs code inside a Cloudflare Worker — this package provides a drop-in replacement that runs the same code locally using Node.js vm2, so you can use codemode in any Node environment without a Workers deployment.
Installation
npm install @bthn/codemode-local-executor @cloudflare/codemode agents ai zodUsage
Replace DynamicWorkerExecutor with NodeVMExecutor and everything else stays the same:
import { createCodeTool } from "@cloudflare/codemode/ai";
import { NodeVMExecutor } from "@bthn/codemode-local-executor";
import { streamText, tool } from "ai";
import { z } from "zod";
const tools = {
getWeather: tool({
description: "Get weather for a location",
inputSchema: z.object({ location: z.string() }),
execute: async ({ location }) => `Weather in ${location}: 72°F, sunny`,
}),
sendEmail: tool({
description: "Send an email",
inputSchema: z.object({
to: z.string(),
subject: z.string(),
body: z.string(),
}),
execute: async ({ to, subject, body }) => `Email sent to ${to}`,
}),
};
const executor = new NodeVMExecutor({
env: {
SOME_API_KEY: process.env.SOME_API_KEY ?? "",
},
});
const codemode = createCodeTool({ tools, executor });
const result = streamText({
model,
system: "You are a helpful assistant.",
messages,
tools: { codemode },
});Constructor options
new NodeVMExecutor(options?: NodeVMExecutorOptions)| Option | Type | Default | Description |
|--------|------|---------|-------------|
| env | Record<string, string> | {} | Environment variables exposed inside the sandbox as process.env.* |
| compiler | 'typescript' \| 'coffeescript' \| 'javascript' | 'typescript' | Compiler used to transpile the LLM-generated code before execution |
| allowEval | boolean | false | Whether to allow eval() inside the sandbox |
| allowWasm | boolean | false | Whether to allow WebAssembly inside the sandbox |
| logCode | boolean | true | Log the generated code to stdout before executing (useful for debugging) |
How it works
createCodeToolgenerates TypeScript type definitions from your tools and builds a description the LLM can read.- The LLM writes an async arrow function that calls
codemode.toolName(args). NodeVMExecutorreceives the code string and spins up a freshNodeVMinstance, injects the tool functions ascodemode.*, and runs the snippet.- The result (or error) is returned as
ExecuteResult— the executor never throws.
Security
vm2 provides V8-level isolation. The sandbox:
- Cannot access
process.envbeyond what you explicitly pass inenv - Cannot use
evalorWebAssemblyby default - Console output is intercepted and returned in
logs, not forwarded to host stdout
Note: vm2 is a best-effort sandbox. Do not use this to run untrusted code in production without additional hardening.
License
MIT
