@langchain/quickjs 0.2.3 → 0.2.5-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -322,7 +322,7 @@ var ReplSession = class ReplSession {
322
322
  return this._backend;
323
323
  }
324
324
  set backend(b) {
325
- this._backend = b;
325
+ this._backend = b ? (0, deepagents.adaptBackendProtocol)(b) : null;
326
326
  }
327
327
  async ensureStarted() {
328
328
  if (this.runtime) return;
@@ -334,7 +334,7 @@ var ReplSession = class ReplSession {
334
334
  this.runtime = runtime;
335
335
  this.context = context;
336
336
  this.setupConsole();
337
- if (backend) this._backend = backend;
337
+ if (backend) this._backend = (0, deepagents.adaptBackendProtocol)(backend);
338
338
  this.injectVfs();
339
339
  if (tools && tools.length > 0) this.injectTools(tools);
340
340
  }
@@ -348,7 +348,7 @@ var ReplSession = class ReplSession {
348
348
  static getOrCreate(id, options = {}) {
349
349
  const existing = ReplSession.sessions.get(id);
350
350
  if (existing) {
351
- if (options.backend) existing._backend = options.backend;
351
+ if (options.backend) existing._backend = (0, deepagents.adaptBackendProtocol)(options.backend);
352
352
  return existing;
353
353
  }
354
354
  const session = new ReplSession(id, options);
@@ -453,8 +453,9 @@ var ReplSession = class ReplSession {
453
453
  };
454
454
  }
455
455
  async flushWrites(backend) {
456
+ const adapted = (0, deepagents.adaptBackendProtocol)(backend);
456
457
  const writes = this.pendingWrites.splice(0);
457
- for (const { path, content } of writes) await backend.write(path, content);
458
+ for (const { path, content } of writes) await adapted.write(path, content);
458
459
  }
459
460
  dispose() {
460
461
  try {
@@ -520,10 +521,23 @@ var ReplSession = class ReplSession {
520
521
  const promise = context.newPromise();
521
522
  (async () => {
522
523
  try {
523
- const fileData = await backend.readRaw(path);
524
- const val = context.newString(fileData.content.join("\n"));
525
- promise.resolve(val);
526
- val.dispose();
524
+ const result = await backend.readRaw(path);
525
+ if (result.error || !result.data) {
526
+ const err = context.newError(`ENOENT: no such file or directory '${path}'.`);
527
+ promise.reject(err);
528
+ err.dispose();
529
+ } else {
530
+ const content = Array.isArray(result.data.content) ? result.data.content.join("\n") : typeof result.data.content === "string" ? result.data.content : null;
531
+ if (content === null) {
532
+ const err = context.newError(`Cannot read binary file '${path}' as text.`);
533
+ promise.reject(err);
534
+ err.dispose();
535
+ return;
536
+ }
537
+ const val = context.newString(content);
538
+ promise.resolve(val);
539
+ val.dispose();
540
+ }
527
541
  } catch {
528
542
  const err = context.newError(`ENOENT: no such file or directory '${path}'.`);
529
543
  promise.reject(err);
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","names":["Parser","MagicString","StateBackend","z"],"sources":["../src/utils.ts","../src/transform.ts","../src/session.ts","../src/middleware.ts"],"sourcesContent":["import { compile } from \"json-schema-to-typescript\";\nimport { toJsonSchema } from \"@langchain/core/utils/json_schema\";\nimport dedent from \"dedent\";\nimport type { ReplResult } from \"./types.js\";\n\n/**\n * Convert a snake_case or kebab-case string to camelCase.\n */\nexport function toCamelCase(name: string): string {\n return name.replace(/[-_]([a-z])/g, (_, c) => c.toUpperCase());\n}\n\n/**\n * Recursively collect all string values from an object, array, or primitive.\n */\nexport function collectStrings(obj: unknown): string[] {\n const result: string[] = [];\n function walk(val: unknown) {\n if (typeof val === \"string\") {\n result.push(val);\n } else if (Array.isArray(val)) {\n for (const item of val) walk(item);\n } else if (typeof val === \"object\" && val !== null) {\n for (const v of Object.values(val)) walk(v);\n }\n }\n walk(obj);\n return result;\n}\n\n/**\n * Format the result of a REPL evaluation for the agent.\n */\nexport function formatReplResult(result: ReplResult): string {\n const parts: string[] = [];\n\n if (result.logs.length > 0) {\n parts.push(result.logs.join(\"\\n\"));\n }\n\n if (result.ok) {\n if (result.value !== undefined) {\n const formatted =\n typeof result.value === \"string\"\n ? result.value\n : JSON.stringify(result.value, null, 2);\n parts.push(`→ ${formatted}`);\n }\n } else if (result.error) {\n const errName = result.error.name || \"Error\";\n const errMsg = result.error.message || \"Unknown error\";\n parts.push(`${errName}: ${errMsg}`);\n if (result.error.stack) {\n parts.push(result.error.stack);\n }\n }\n\n return parts.join(\"\\n\") || \"(no output)\";\n}\n\nexport function safeToJsonSchema(\n schema: unknown,\n): Record<string, unknown> | undefined {\n try {\n return toJsonSchema(schema as Parameters<typeof toJsonSchema>[0]) as Record<\n string,\n unknown\n >;\n } catch {\n return undefined;\n }\n}\n\nasync function schemaToInterface(\n jsonSchema: Record<string, unknown>,\n interfaceName: string,\n): Promise<string> {\n const compiled = await compile(\n { ...jsonSchema, additionalProperties: false },\n interfaceName,\n { bannerComment: \"\", additionalProperties: false },\n );\n return compiled.replace(/^export /, \"\").trimEnd();\n}\n\nexport function capitalize(s: string): string {\n return s.charAt(0).toUpperCase() + s.slice(1);\n}\n\nexport async function toolToTypeSignature(\n name: string,\n description: string,\n jsonSchema: Record<string, unknown> | undefined,\n): Promise<string> {\n const inputType = `${capitalize(name)}Input`;\n\n if (!jsonSchema || !jsonSchema.properties) {\n return dedent`\n /**\n * ${description}\n */\n async tools.${name}(input: Record<string, unknown>): Promise<string>\n `;\n }\n\n const iface = await schemaToInterface(jsonSchema, inputType);\n return dedent`\n ${iface}\n\n /**\n * ${description}\n */\n async tools.${name}(input: ${inputType}): Promise<string>\n `;\n}\n","/**\n * AST-based code transform pipeline for the REPL.\n *\n * Transforms TypeScript/JavaScript code into plain JS that can be\n * evaluated inside QuickJS with proper state persistence:\n *\n * 1. Parse with acorn + acorn-typescript (handles TS syntax)\n * 2. Strip TypeScript-only nodes (type annotations, interfaces, etc.)\n * 3. Hoist top-level declarations to globalThis for cross-eval persistence\n * 4. Auto-return the last expression\n * 5. Wrap in async IIFE so top-level await works\n */\n\nimport { Parser } from \"acorn\";\nimport { tsPlugin } from \"@sveltejs/acorn-typescript\";\nimport { walk } from \"estree-walker\";\nimport MagicString from \"magic-string\";\nimport type {\n Node,\n Identifier,\n VariableDeclaration as EstreeVariableDeclaration,\n VariableDeclarator as EstreeVariableDeclarator,\n} from \"estree\";\n\nconst TSParser = Parser.extend(tsPlugin());\n\ntype AcornNode = Node & { start: number; end: number };\ntype AcornExpressionStatement = AcornNode & {\n type: \"ExpressionStatement\";\n expression: AcornNode;\n};\ntype AcornVariableDeclaration = EstreeVariableDeclaration & {\n start: number;\n end: number;\n declarations: AcornVariableDeclarator[];\n};\ntype AcornVariableDeclarator = EstreeVariableDeclarator & {\n start: number;\n end: number;\n id: AcornNode;\n init: AcornNode | null;\n};\n\n/**\n * Transform code for REPL evaluation.\n *\n * - Strips TypeScript syntax\n * - Hoists top-level variable declarations to globalThis\n * - Auto-returns the last expression\n * - Wraps in async IIFE for top-level await support\n */\nexport function transformForEval(code: string): string {\n let ast: AcornNode;\n try {\n ast = TSParser.parse(code, {\n ecmaVersion: \"latest\" as any,\n sourceType: \"module\",\n locations: true,\n }) as unknown as AcornNode;\n } catch {\n // If parsing fails, return the code as-is and let QuickJS report the error\n return `(async () => {\\n${code}\\n})()`;\n }\n\n const s = new MagicString(code);\n const program = ast as unknown as { body: AcornNode[] };\n const topLevelNodes = program.body;\n for (let i = 0; i < topLevelNodes.length; i++) {\n const node = topLevelNodes[i];\n\n // Remove TypeScript-only top-level declarations\n if (isTSOnlyNode(node)) {\n s.remove(node.start, node.end);\n continue;\n }\n\n // Remove import/export declarations (not supported in QuickJS eval)\n if (\n node.type === \"ImportDeclaration\" ||\n node.type === \"ExportNamedDeclaration\" ||\n node.type === \"ExportDefaultDeclaration\" ||\n node.type === \"ExportAllDeclaration\"\n ) {\n s.remove(node.start, node.end);\n continue;\n }\n\n // Hoist top-level variable declarations\n if (node.type === \"VariableDeclaration\") {\n hoistDeclaration(s, node as unknown as AcornVariableDeclaration);\n continue;\n }\n\n // Hoist function/class declarations to globalThis for cross-eval persistence\n if (\n node.type === \"FunctionDeclaration\" ||\n node.type === \"ClassDeclaration\"\n ) {\n stripTypeAnnotations(s, node);\n const name = (node as any).id?.name;\n if (name) {\n s.appendRight(node.end, `\\nglobalThis.${name} = ${name};`);\n }\n continue;\n }\n }\n\n // Strip type annotations from within expressions/statements\n for (const node of topLevelNodes) {\n if (isTSOnlyNode(node)) continue;\n if (\n node.type === \"ImportDeclaration\" ||\n node.type === \"ExportNamedDeclaration\" ||\n node.type === \"ExportDefaultDeclaration\" ||\n node.type === \"ExportAllDeclaration\"\n )\n continue;\n if (node.type !== \"VariableDeclaration\") {\n walk(node as any, {\n enter(n: any) {\n stripTypeAnnotationFromNode(s, n);\n },\n });\n }\n }\n\n // Auto-return the last expression. We insert `return (` before the\n // ExpressionStatement (to preserve any grouping parens like `({...})`),\n // but close `)` after the inner expression — not after the statement —\n // so any trailing semicolon stays outside: `return (expr);` not `return (expr;)`.\n const lastNode = findLastNonEmptyNode(topLevelNodes, s);\n if (lastNode && isExpression(lastNode)) {\n const { expression } = lastNode as AcornExpressionStatement;\n s.prependLeft(lastNode.start, \"return (\");\n s.appendRight(expression.end, \")\");\n }\n\n // Wrap in async IIFE\n s.prepend(\"(async () => {\\n\");\n s.append(\"\\n})()\");\n\n return s.toString();\n}\n\nfunction isTSOnlyNode(node: AcornNode): boolean {\n const t = node.type as string;\n return (\n t === \"TSTypeAliasDeclaration\" ||\n t === \"TSInterfaceDeclaration\" ||\n t === \"TSEnumDeclaration\" ||\n t === \"TSModuleDeclaration\" ||\n t === \"TSDeclareFunction\" ||\n t.startsWith(\"TS\")\n );\n}\n\n/**\n * Rewrite a top-level VariableDeclaration to globalThis assignments.\n *\n * `const x = 1, y = 2` → `globalThis.x = 1; globalThis.y = 2`\n *\n */\nfunction hoistDeclaration(\n s: MagicString,\n decl: AcornVariableDeclaration,\n): void {\n const parts: string[] = [];\n\n for (const d of decl.declarations) {\n const id = d.id as AcornNode;\n if (id.type === \"Identifier\") {\n const initCode = d.init ? extractCleanInit(s, d) : \"undefined\";\n parts.push(\n `globalThis.${(id as unknown as Identifier).name} = ${initCode}`,\n );\n } else if (id.type === \"ObjectPattern\" || id.type === \"ArrayPattern\") {\n const bindings = extractBindingNames(d.id as any);\n const initCode = d.init ? extractCleanInit(s, d) : \"undefined\";\n const patternCode = extractCleanSource(s, d.id as AcornNode);\n parts.push(`var ${patternCode} = ${initCode}`);\n for (const name of bindings) {\n parts.push(`globalThis.${name} = ${name}`);\n }\n }\n }\n\n s.overwrite(decl.start, decl.end, parts.join(\"; \") + \";\");\n}\n\n/**\n * Extract the initializer code, stripping TypeScript annotations from\n * within the expression (e.g. `as Type`, generics, parameter types in\n * arrow functions).\n */\nfunction extractCleanInit(s: MagicString, d: AcornVariableDeclarator): string {\n if (!d.init) return \"undefined\";\n return extractCleanSource(s, d.init as AcornNode);\n}\n\nfunction extractBindingNames(pattern: any): string[] {\n const names: string[] = [];\n if (pattern.type === \"Identifier\") {\n if (pattern.name) names.push(pattern.name);\n } else if (pattern.type === \"ObjectPattern\") {\n for (const prop of pattern.properties || []) {\n if (prop.type === \"RestElement\") {\n names.push(...extractBindingNames(prop.argument));\n } else {\n names.push(...extractBindingNames(prop.value));\n }\n }\n } else if (pattern.type === \"ArrayPattern\") {\n for (const el of pattern.elements || []) {\n if (el) names.push(...extractBindingNames(el));\n }\n } else if (pattern.type === \"RestElement\") {\n names.push(...extractBindingNames(pattern.argument));\n } else if (pattern.type === \"AssignmentPattern\") {\n names.push(...extractBindingNames(pattern.left));\n }\n return names;\n}\n\nfunction stripTypeAnnotations(s: MagicString, node: AcornNode): void {\n walk(node as any, {\n enter(n: any) {\n stripTypeAnnotationFromNode(s, n);\n },\n });\n}\n\nfunction stripTypeAnnotationFromNode(s: MagicString, n: any, offset = 0): void {\n // Type annotations on parameters, variables, return types\n if (n.typeAnnotation && n.typeAnnotation.start != null) {\n s.remove(n.typeAnnotation.start - offset, n.typeAnnotation.end - offset);\n }\n // Return type on functions\n if (n.returnType && n.returnType.start != null) {\n s.remove(n.returnType.start - offset, n.returnType.end - offset);\n }\n // Type parameters (generics)\n if (n.typeParameters && n.typeParameters.start != null) {\n s.remove(n.typeParameters.start - offset, n.typeParameters.end - offset);\n }\n // Type arguments on calls\n if (n.typeArguments && n.typeArguments.start != null) {\n s.remove(n.typeArguments.start - offset, n.typeArguments.end - offset);\n }\n // `as` expressions: keep the expression, remove `as Type`\n if (n.type === \"TSAsExpression\" && n.expression) {\n s.remove(n.expression.end - offset, n.end - offset);\n }\n // Non-null assertion: `x!` → `x`\n if (n.type === \"TSNonNullExpression\" && n.expression) {\n s.remove(n.expression.end - offset, n.end - offset);\n }\n // Satisfies expression: `x satisfies Type` → `x`\n if (n.type === \"TSSatisfiesExpression\" && n.expression) {\n s.remove(n.expression.end - offset, n.end - offset);\n }\n}\n\n/**\n * Extract a clean JS source string from an AST node, stripping all\n * TypeScript annotations. Works on a copy so the main MagicString is\n * not mutated.\n */\nfunction extractCleanSource(s: MagicString, node: AcornNode): string {\n const offset = node.start;\n const source = new MagicString(s.slice(node.start, node.end));\n walk(node as any, {\n enter(n: any) {\n stripTypeAnnotationFromNode(source, n, offset);\n },\n });\n return source.toString();\n}\n\nfunction findLastNonEmptyNode(\n nodes: AcornNode[],\n s: MagicString,\n): AcornNode | null {\n for (let i = nodes.length - 1; i >= 0; i--) {\n const node = nodes[i];\n // Skip nodes that were fully removed\n const slice = s.slice(node.start, node.end).trim();\n if (slice === \"\" || slice === \";\") continue;\n return node;\n }\n return null;\n}\n\nfunction isExpression(node: AcornNode): boolean {\n return node.type === \"ExpressionStatement\";\n}\n","/**\n * Core REPL engine built on quickjs-emscripten (asyncify variant).\n *\n * Host async functions (backend I/O, PTC tools) are exposed as\n * promise-returning functions inside the QuickJS guest. Guest code\n * uses `await` to consume them, enabling real concurrency via\n * `Promise.all`, `Promise.race`, etc.\n *\n * We still use the asyncify WASM variant because `evalCodeAsync` is\n * required to drive promise resolution from the host side.\n *\n * ## Architecture\n *\n * `ReplSession` is a serializable handle that can live in LangGraph state.\n * It holds an `id` that keys into a static session map. The heavy QuickJS\n * runtime is lazily started on the first `.eval()` call, making the session\n * safe across graph interrupts and checkpointing.\n *\n * File writes inside the REPL are buffered (`pendingWrites`) and only\n * flushed to the backend after a script finishes executing. Call\n * `session.flushWrites(backend)` after eval to persist them.\n */\n\nimport { shouldInterruptAfterDeadline } from \"quickjs-emscripten\";\nimport type { QuickJSHandle } from \"quickjs-emscripten\";\nimport { newQuickJSAsyncWASMModuleFromVariant } from \"quickjs-emscripten-core\";\nimport type {\n QuickJSAsyncContext,\n QuickJSAsyncRuntime,\n} from \"quickjs-emscripten-core\";\nimport type { BackendProtocol } from \"deepagents\";\nimport type { StructuredToolInterface } from \"@langchain/core/tools\";\n\nimport type { ReplSessionOptions, ReplResult } from \"./types.js\";\nimport { toCamelCase } from \"./utils.js\";\nimport { transformForEval } from \"./transform.js\";\n\nexport const DEFAULT_MEMORY_LIMIT = 50 * 1024 * 1024;\nexport const DEFAULT_MAX_STACK_SIZE = 320 * 1024;\nexport const DEFAULT_EXECUTION_TIMEOUT = 30_000;\nexport const DEFAULT_SESSION_ID = \"__default__\";\n\nlet asyncModulePromise: Promise<any> | undefined;\n\nasync function getAsyncModule() {\n if (!asyncModulePromise) {\n asyncModulePromise = (async () => {\n const variant =\n await import(\"@jitl/quickjs-ng-wasmfile-release-asyncify\");\n return newQuickJSAsyncWASMModuleFromVariant(\n (variant.default ?? variant) as any,\n );\n })();\n }\n return asyncModulePromise;\n}\n\nexport interface PendingWrite {\n path: string;\n content: string;\n}\n\n/**\n * Sandboxed JavaScript REPL session backed by QuickJS WASM.\n *\n * Serializable — holds an `id` that keys into a static session map.\n * The QuickJS runtime is lazily started on the first `.eval()` call\n * and reconnected if a session with the same id already exists.\n * This makes it safe to store in LangGraph state across interrupts.\n *\n * File writes are buffered during execution and flushed via\n * `flushWrites(backend)` after eval completes.\n */\nexport class ReplSession {\n private static sessions = new Map<string, ReplSession>();\n\n readonly id: string;\n readonly pendingWrites: PendingWrite[] = [];\n\n private runtime: QuickJSAsyncRuntime | null = null;\n private context: QuickJSAsyncContext | null = null;\n private logs: string[] = [];\n private _options: ReplSessionOptions;\n\n private _backend: BackendProtocol | null = null;\n\n constructor(id: string, options: ReplSessionOptions = {}) {\n this.id = id;\n this._options = options;\n }\n\n get backend(): BackendProtocol | null {\n return this._backend;\n }\n\n set backend(b: BackendProtocol | null) {\n this._backend = b;\n }\n\n private async ensureStarted(): Promise<void> {\n if (this.runtime) return;\n\n const {\n memoryLimitBytes = DEFAULT_MEMORY_LIMIT,\n maxStackSizeBytes = DEFAULT_MAX_STACK_SIZE,\n backend,\n tools,\n } = this._options;\n\n const asyncModule = await getAsyncModule();\n const runtime: QuickJSAsyncRuntime = asyncModule.newRuntime();\n runtime.setMemoryLimit(memoryLimitBytes);\n runtime.setMaxStackSize(maxStackSizeBytes);\n\n const context: QuickJSAsyncContext = runtime.newContext();\n this.runtime = runtime;\n this.context = context;\n\n this.setupConsole();\n\n if (backend) {\n this._backend = backend;\n }\n this.injectVfs();\n if (tools && tools.length > 0) {\n this.injectTools(tools);\n }\n }\n\n /**\n * Get or create a session for the given id.\n *\n * Sessions are deduped by id — calling `getOrCreate` twice with the\n * same id returns the same instance. The QuickJS runtime is lazily\n * started on the first `.eval()` call.\n */\n static getOrCreate(\n id: string,\n options: ReplSessionOptions = {},\n ): ReplSession {\n const existing = ReplSession.sessions.get(id);\n if (existing) {\n if (options.backend) {\n existing._backend = options.backend;\n }\n return existing;\n }\n\n const session = new ReplSession(id, options);\n ReplSession.sessions.set(id, session);\n return session;\n }\n\n /**\n * Retrieve an existing session by id, or null if none exists.\n */\n static get(id: string): ReplSession | null {\n return ReplSession.sessions.get(id) ?? null;\n }\n\n /**\n * Evaluate code in this session.\n *\n * Lazily starts the QuickJS runtime on the first call. Code is\n * transformed via an AST pipeline that strips TypeScript syntax,\n * hoists top-level declarations to globalThis for cross-eval\n * persistence, auto-returns the last expression, and wraps in an\n * async IIFE.\n */\n async eval(code: string, timeoutMs: number): Promise<ReplResult> {\n await this.ensureStarted();\n const runtime = this.runtime!;\n const context = this.context!;\n\n this.logs.length = 0;\n\n if (timeoutMs >= 0) {\n runtime.setInterruptHandler(\n shouldInterruptAfterDeadline(Date.now() + timeoutMs),\n );\n } else {\n runtime.setInterruptHandler(() => false);\n }\n\n const transformed = transformForEval(code);\n const result = await context.evalCodeAsync(transformed);\n\n if (result.error) {\n const error = context.dump(result.error);\n result.error.dispose();\n return { ok: false, error, logs: [...this.logs] };\n }\n\n const promiseState = context.getPromiseState(result.value);\n\n if (promiseState.type === \"fulfilled\") {\n if (promiseState.notAPromise) {\n const value = context.dump(result.value);\n result.value.dispose();\n return { ok: true, value, logs: [...this.logs] };\n }\n const value = context.dump(promiseState.value);\n promiseState.value.dispose();\n result.value.dispose();\n return { ok: true, value, logs: [...this.logs] };\n }\n\n if (promiseState.type === \"rejected\") {\n const error = context.dump(promiseState.error);\n promiseState.error.dispose();\n result.value.dispose();\n return { ok: false, error, logs: [...this.logs] };\n }\n\n const noTimeout = timeoutMs < 0;\n const deadline = noTimeout ? Infinity : Date.now() + timeoutMs;\n while (noTimeout || Date.now() < deadline) {\n context.runtime.executePendingJobs();\n const state = context.getPromiseState(result.value);\n if (state.type === \"fulfilled\") {\n const value = context.dump(state.value);\n state.value.dispose();\n result.value.dispose();\n return { ok: true, value, logs: [...this.logs] };\n }\n if (state.type === \"rejected\") {\n const error = context.dump(state.error);\n state.error.dispose();\n result.value.dispose();\n return { ok: false, error, logs: [...this.logs] };\n }\n await new Promise((r) => setTimeout(r, 1));\n }\n\n result.value.dispose();\n return {\n ok: false,\n error: { message: \"Promise timed out — execution interrupted\" },\n logs: [...this.logs],\n };\n }\n\n async flushWrites(backend: BackendProtocol): Promise<void> {\n const writes = this.pendingWrites.splice(0);\n for (const { path, content } of writes) {\n await backend.write(path, content);\n }\n }\n\n dispose(): void {\n try {\n this.context?.dispose();\n } catch {\n /* may already be disposed */\n }\n try {\n this.runtime?.dispose();\n } catch {\n /* may already be disposed */\n }\n this.runtime = null;\n this.context = null;\n ReplSession.sessions.delete(this.id);\n }\n\n toJSON(): { id: string } {\n return { id: this.id };\n }\n\n static fromJSON(data: { id: string }): ReplSession {\n return ReplSession.sessions.get(data.id) ?? new ReplSession(data.id);\n }\n\n /**\n * Clear the static session cache. Useful for testing.\n * @internal\n */\n static clearCache(): void {\n for (const session of ReplSession.sessions.values()) {\n session.dispose();\n }\n ReplSession.sessions.clear();\n }\n\n private setupConsole(): void {\n const context = this.context!;\n const logs = this.logs;\n const consoleHandle = context.newObject();\n for (const method of [\"log\", \"warn\", \"error\", \"info\", \"debug\"] as const) {\n const fnHandle = context.newFunction(\n method,\n (...args: QuickJSHandle[]) => {\n const nativeArgs = args.map((a: QuickJSHandle) => context.dump(a));\n const formatted = nativeArgs\n .map((a: unknown) =>\n typeof a === \"object\" && a !== null\n ? JSON.stringify(a)\n : String(a),\n )\n .join(\" \");\n logs.push(\n method === \"log\" || method === \"info\" || method === \"debug\"\n ? formatted\n : `[${method}] ${formatted}`,\n );\n },\n );\n context.setProp(consoleHandle, method, fnHandle);\n fnHandle.dispose();\n }\n context.setProp(context.global, \"console\", consoleHandle);\n consoleHandle.dispose();\n }\n\n private injectVfs(): void {\n const context = this.context!;\n const getBackend = () => this._backend;\n const { pendingWrites } = this;\n\n const readFileHandle = context.newFunction(\n \"readFile\",\n (pathHandle: QuickJSHandle) => {\n const backend = getBackend();\n if (!backend) {\n const promise = context.newPromise();\n const err = context.newError(\"Backend not available\");\n promise.reject(err);\n err.dispose();\n promise.settled.then(context.runtime.executePendingJobs);\n return promise.handle;\n }\n const path = context.getString(pathHandle);\n const promise = context.newPromise();\n (async () => {\n try {\n const fileData = await backend.readRaw(path);\n const val = context.newString(fileData.content.join(\"\\n\"));\n promise.resolve(val);\n val.dispose();\n } catch {\n const err = context.newError(\n `ENOENT: no such file or directory '${path}'.`,\n );\n promise.reject(err);\n err.dispose();\n }\n promise.settled.then(context.runtime.executePendingJobs);\n })();\n return promise.handle;\n },\n );\n context.setProp(context.global, \"readFile\", readFileHandle);\n readFileHandle.dispose();\n\n const writeFileHandle = context.newFunction(\n \"writeFile\",\n (pathHandle: QuickJSHandle, contentHandle: QuickJSHandle) => {\n const path = context.getString(pathHandle);\n const content = context.getString(contentHandle);\n const promise = context.newPromise();\n pendingWrites.push({ path, content });\n promise.resolve(context.undefined);\n promise.settled.then(context.runtime.executePendingJobs);\n return promise.handle;\n },\n );\n context.setProp(context.global, \"writeFile\", writeFileHandle);\n writeFileHandle.dispose();\n }\n\n private injectTools(tools: StructuredToolInterface[]): void {\n const context = this.context!;\n const toolsNs = context.newObject();\n\n for (const t of tools) {\n const camelName = toCamelCase(t.name);\n const fnHandle = context.newFunction(\n camelName,\n (inputHandle: QuickJSHandle) => {\n const input = context.dump(inputHandle);\n const promise = context.newPromise();\n (async () => {\n try {\n const rawInput =\n typeof input === \"object\" && input !== null ? input : {};\n const result = await t.invoke(rawInput);\n const val = context.newString(\n typeof result === \"string\" ? result : JSON.stringify(result),\n );\n promise.resolve(val);\n val.dispose();\n } catch (e: unknown) {\n const msg =\n e != null && typeof (e as Error).message === \"string\"\n ? (e as Error).message\n : String(e);\n const err = context.newError(`Tool '${t.name}' failed: ${msg}`);\n promise.reject(err);\n err.dispose();\n }\n promise.settled.then(context.runtime.executePendingJobs);\n })();\n return promise.handle;\n },\n );\n context.setProp(toolsNs, camelName, fnHandle);\n fnHandle.dispose();\n }\n\n context.setProp(context.global, \"tools\", toolsNs);\n toolsNs.dispose();\n }\n}\n","/**\n * QuickJS REPL middleware for deepagents.\n *\n * Provides a `js_eval` tool that runs JavaScript in a WASM-sandboxed QuickJS\n * interpreter. Supports:\n * - Persistent state across evaluations (true REPL)\n * - VFS integration via readFile/writeFile\n * - Programmatic tool calling (PTC)\n */\n\nimport {\n createMiddleware,\n tool,\n type AgentMiddleware as _AgentMiddleware,\n} from \"langchain\";\nimport { z } from \"zod/v4\";\nimport type { StructuredToolInterface } from \"@langchain/core/tools\";\nimport { StateBackend, type BackendRuntime, resolveBackend } from \"deepagents\";\n\nimport dedent from \"dedent\";\nimport type { QuickJSMiddlewareOptions } from \"./types.js\";\nimport {\n ReplSession,\n DEFAULT_EXECUTION_TIMEOUT,\n DEFAULT_MEMORY_LIMIT,\n DEFAULT_MAX_STACK_SIZE,\n DEFAULT_SESSION_ID,\n} from \"./session.js\";\nimport {\n formatReplResult,\n toCamelCase,\n toolToTypeSignature,\n safeToJsonSchema,\n} from \"./utils.js\";\n\n/**\n * These type-only imports are required for TypeScript's type inference to work\n * correctly with the langchain/langgraph middleware system. Without them, certain\n * generic type parameters fail to resolve properly, causing runtime issues with\n * tool schemas and message types.\n */\nimport type * as _zodTypes from \"@langchain/core/utils/types\";\nimport type * as _zodMeta from \"@langchain/langgraph/zod\";\nimport type * as _messages from \"@langchain/core/messages\";\nimport {\n getCurrentTaskInput,\n LangGraphRunnableConfig,\n} from \"@langchain/langgraph\";\n\n/**\n * Backend-provided tools excluded from PTC by default.\n * These are redundant inside the REPL since VFS helpers (readFile/writeFile)\n * already cover file I/O against the agent's in-memory working set.\n */\nexport const DEFAULT_PTC_EXCLUDED_TOOLS = [\n \"ls\",\n \"read_file\",\n \"write_file\",\n \"edit_file\",\n \"glob\",\n \"grep\",\n \"execute\",\n] as const;\n\nconst REPL_SYSTEM_PROMPT = dedent`\n ## TypeScript/JavaScript REPL (\\`js_eval\\`)\n\n You have access to a sandboxed TypeScript/JavaScript REPL running in an isolated interpreter.\n TypeScript syntax (type annotations, interfaces, generics, \\`as\\` casts) is supported and stripped at evaluation time.\n Variables, functions, and closures persist across calls within the same session.\n\n ### Hard rules\n\n - **No network, no filesystem** — only the helpers below. Do not attempt \\`fetch\\`, \\`require\\`, or \\`import\\`.\n - **Cite your sources** — when reporting values from files, include the path and key/index so the user can verify.\n - **Use console.log()** for output — it is captured and returned. \\`console.warn()\\` and \\`console.error()\\` are also available.\n - **Reuse state from previous cells** — variables, functions, and results from earlier \\`js_eval\\` calls persist across calls. Reference them by name in follow-up cells instead of re-embedding data as inline JSON literals.\n\n ### First-time usage\n\n \\`\\`\\`typescript\n // Read a file from the agent's virtual filesystem\n const raw: string = await readFile(\"/data.json\");\n const data = JSON.parse(raw) as { n: number };\n console.log(data);\n\n // Write results back\n await writeFile(\"/output.txt\", JSON.stringify({ result: data.n }));\n \\`\\`\\`\n\n ### API Reference — built-in globals\n\n \\`\\`\\`typescript\n /**\n * Read a file from the agent's virtual filesystem. Throws if the file does not exist.\n */\n async readFile(path: string): Promise<string>\n\n /**\n * Write a file to the agent's virtual filesystem.\n */\n async writeFile(path: string, content: string): Promise<void>\n \\`\\`\\`\n\n ### Limitations\n\n - ES2023+ syntax with TypeScript support. No Node.js APIs, no \\`require\\`, no \\`import\\`.\n - Output is truncated beyond a fixed character limit — be selective about what you log.\n - Execution timeout per call (default 30 s).\n`;\n\n/**\n * Generate the PTC API Reference section for the system prompt.\n */\nexport async function generatePtcPrompt(\n tools: StructuredToolInterface[],\n): Promise<string> {\n if (tools.length === 0) return \"\";\n\n const signatures = await Promise.all(\n tools.map((t) => {\n const jsonSchema = t.schema ? safeToJsonSchema(t.schema) : undefined;\n return toolToTypeSignature(\n toCamelCase(t.name),\n t.description,\n jsonSchema,\n );\n }),\n );\n\n return dedent`\n\n ### API Reference — \\`tools\\` namespace\n\n The following agent tools are callable as async functions inside the REPL.\n Each takes a single object argument and returns a Promise that resolves to a string.\n Use \\`await\\` to call them. Promise APIs like \\`Promise.all\\` are also available.\n\n **Example usage:**\n \\`\\`\\`javascript\n // Call a tool\n const result = await tools.searchWeb({ query: \"QuickJS tutorial\" });\n console.log(result);\n\n // Concurrent calls\n const [a, b] = await Promise.all([\n tools.fetchData({ url: \"https://api.example.com/a\" }),\n tools.fetchData({ url: \"https://api.example.com/b\" }),\n ]);\n \\`\\`\\`\n\n **Available functions:**\n \\`\\`\\`typescript\n ${signatures.join(\"\\n\\n\")}\n \\`\\`\\`\n `;\n}\n\n/**\n * Create the QuickJS REPL middleware.\n */\nexport function createQuickJSMiddleware(\n options: QuickJSMiddlewareOptions = {},\n) {\n const {\n backend = (runtime: BackendRuntime) => new StateBackend(runtime),\n ptc = false,\n memoryLimitBytes = DEFAULT_MEMORY_LIMIT,\n maxStackSizeBytes = DEFAULT_MAX_STACK_SIZE,\n executionTimeoutMs = DEFAULT_EXECUTION_TIMEOUT,\n systemPrompt: customSystemPrompt = null,\n } = options;\n\n const usePtc = ptc !== false;\n const baseSystemPrompt = customSystemPrompt || REPL_SYSTEM_PROMPT;\n\n let cachedPtcPrompt: string | null = null;\n\n let ptcTools: StructuredToolInterface[] = [];\n\n function filterToolsForPtc(\n allTools: StructuredToolInterface[],\n ): StructuredToolInterface[] {\n if (ptc === false) return [];\n\n const candidates = allTools.filter((t) => t.name !== \"js_eval\");\n\n if (ptc === true) {\n const excluded = new Set<string>(DEFAULT_PTC_EXCLUDED_TOOLS);\n return candidates.filter((t) => !excluded.has(t.name));\n }\n\n if (Array.isArray(ptc)) {\n const included = new Set(ptc);\n return candidates.filter((t) => included.has(t.name));\n }\n\n if (\"include\" in ptc) {\n const included = new Set(ptc.include);\n return candidates.filter((t) => included.has(t.name));\n }\n\n if (\"exclude\" in ptc) {\n const excluded = new Set([...DEFAULT_PTC_EXCLUDED_TOOLS, ...ptc.exclude]);\n return candidates.filter((t) => !excluded.has(t.name));\n }\n\n return [];\n }\n\n const jsEvalTool = tool(\n async (input, config: LangGraphRunnableConfig) => {\n const threadId = config.configurable?.thread_id || DEFAULT_SESSION_ID;\n\n const runtime: BackendRuntime = {\n ...config,\n state: getCurrentTaskInput(config) || {},\n } as BackendRuntime;\n const resolvedBackend = await resolveBackend(backend, runtime);\n\n const session = ReplSession.getOrCreate(threadId, {\n memoryLimitBytes,\n maxStackSizeBytes,\n backend: resolvedBackend,\n tools: ptcTools,\n });\n\n const result = await session.eval(input.code, executionTimeoutMs);\n await session.flushWrites(resolvedBackend);\n\n return formatReplResult(result);\n },\n {\n name: \"js_eval\",\n description: dedent`\n Evaluate TypeScript/JavaScript code in a sandboxed REPL. State persists across calls.\n Use readFile(path) and writeFile(path, content) for file access.\n Use console.log() for output. Returns the result of the last expression.\n `,\n schema: z.object({\n code: z\n .string()\n .describe(\n \"TypeScript/JavaScript code to evaluate in the sandboxed REPL\",\n ),\n }),\n },\n );\n\n return createMiddleware({\n name: \"QuickJSMiddleware\",\n tools: [jsEvalTool],\n wrapModelCall: async (request, handler) => {\n const agentTools = (request.tools || []) as StructuredToolInterface[];\n ptcTools = usePtc ? filterToolsForPtc(agentTools) : [];\n\n if (ptcTools.length > 0 && !cachedPtcPrompt) {\n cachedPtcPrompt = await generatePtcPrompt(ptcTools);\n }\n\n const systemMessage = request.systemMessage\n .concat(baseSystemPrompt)\n .concat(cachedPtcPrompt || \"\");\n return handler({ ...request, systemMessage });\n },\n });\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.cjs","names":["Parser","MagicString","StateBackend","z"],"sources":["../src/utils.ts","../src/transform.ts","../src/session.ts","../src/middleware.ts"],"sourcesContent":["import { compile } from \"json-schema-to-typescript\";\nimport { toJsonSchema } from \"@langchain/core/utils/json_schema\";\nimport dedent from \"dedent\";\nimport type { ReplResult } from \"./types.js\";\n\n/**\n * Convert a snake_case or kebab-case string to camelCase.\n */\nexport function toCamelCase(name: string): string {\n return name.replace(/[-_]([a-z])/g, (_, c) => c.toUpperCase());\n}\n\n/**\n * Recursively collect all string values from an object, array, or primitive.\n */\nexport function collectStrings(obj: unknown): string[] {\n const result: string[] = [];\n function walk(val: unknown) {\n if (typeof val === \"string\") {\n result.push(val);\n } else if (Array.isArray(val)) {\n for (const item of val) walk(item);\n } else if (typeof val === \"object\" && val !== null) {\n for (const v of Object.values(val)) walk(v);\n }\n }\n walk(obj);\n return result;\n}\n\n/**\n * Format the result of a REPL evaluation for the agent.\n */\nexport function formatReplResult(result: ReplResult): string {\n const parts: string[] = [];\n\n if (result.logs.length > 0) {\n parts.push(result.logs.join(\"\\n\"));\n }\n\n if (result.ok) {\n if (result.value !== undefined) {\n const formatted =\n typeof result.value === \"string\"\n ? result.value\n : JSON.stringify(result.value, null, 2);\n parts.push(`→ ${formatted}`);\n }\n } else if (result.error) {\n const errName = result.error.name || \"Error\";\n const errMsg = result.error.message || \"Unknown error\";\n parts.push(`${errName}: ${errMsg}`);\n if (result.error.stack) {\n parts.push(result.error.stack);\n }\n }\n\n return parts.join(\"\\n\") || \"(no output)\";\n}\n\nexport function safeToJsonSchema(\n schema: unknown,\n): Record<string, unknown> | undefined {\n try {\n return toJsonSchema(schema as Parameters<typeof toJsonSchema>[0]) as Record<\n string,\n unknown\n >;\n } catch {\n return undefined;\n }\n}\n\nasync function schemaToInterface(\n jsonSchema: Record<string, unknown>,\n interfaceName: string,\n): Promise<string> {\n const compiled = await compile(\n { ...jsonSchema, additionalProperties: false },\n interfaceName,\n { bannerComment: \"\", additionalProperties: false },\n );\n return compiled.replace(/^export /, \"\").trimEnd();\n}\n\nexport function capitalize(s: string): string {\n return s.charAt(0).toUpperCase() + s.slice(1);\n}\n\nexport async function toolToTypeSignature(\n name: string,\n description: string,\n jsonSchema: Record<string, unknown> | undefined,\n): Promise<string> {\n const inputType = `${capitalize(name)}Input`;\n\n if (!jsonSchema || !jsonSchema.properties) {\n return dedent`\n /**\n * ${description}\n */\n async tools.${name}(input: Record<string, unknown>): Promise<string>\n `;\n }\n\n const iface = await schemaToInterface(jsonSchema, inputType);\n return dedent`\n ${iface}\n\n /**\n * ${description}\n */\n async tools.${name}(input: ${inputType}): Promise<string>\n `;\n}\n","/**\n * AST-based code transform pipeline for the REPL.\n *\n * Transforms TypeScript/JavaScript code into plain JS that can be\n * evaluated inside QuickJS with proper state persistence:\n *\n * 1. Parse with acorn + acorn-typescript (handles TS syntax)\n * 2. Strip TypeScript-only nodes (type annotations, interfaces, etc.)\n * 3. Hoist top-level declarations to globalThis for cross-eval persistence\n * 4. Auto-return the last expression\n * 5. Wrap in async IIFE so top-level await works\n */\n\nimport { Parser } from \"acorn\";\nimport { tsPlugin } from \"@sveltejs/acorn-typescript\";\nimport { walk } from \"estree-walker\";\nimport MagicString from \"magic-string\";\nimport type {\n Node,\n Identifier,\n VariableDeclaration as EstreeVariableDeclaration,\n VariableDeclarator as EstreeVariableDeclarator,\n} from \"estree\";\n\nconst TSParser = Parser.extend(tsPlugin());\n\ntype AcornNode = Node & { start: number; end: number };\ntype AcornExpressionStatement = AcornNode & {\n type: \"ExpressionStatement\";\n expression: AcornNode;\n};\ntype AcornVariableDeclaration = EstreeVariableDeclaration & {\n start: number;\n end: number;\n declarations: AcornVariableDeclarator[];\n};\ntype AcornVariableDeclarator = EstreeVariableDeclarator & {\n start: number;\n end: number;\n id: AcornNode;\n init: AcornNode | null;\n};\n\n/**\n * Transform code for REPL evaluation.\n *\n * - Strips TypeScript syntax\n * - Hoists top-level variable declarations to globalThis\n * - Auto-returns the last expression\n * - Wraps in async IIFE for top-level await support\n */\nexport function transformForEval(code: string): string {\n let ast: AcornNode;\n try {\n ast = TSParser.parse(code, {\n ecmaVersion: \"latest\" as any,\n sourceType: \"module\",\n locations: true,\n }) as unknown as AcornNode;\n } catch {\n // If parsing fails, return the code as-is and let QuickJS report the error\n return `(async () => {\\n${code}\\n})()`;\n }\n\n const s = new MagicString(code);\n const program = ast as unknown as { body: AcornNode[] };\n const topLevelNodes = program.body;\n for (let i = 0; i < topLevelNodes.length; i++) {\n const node = topLevelNodes[i];\n\n // Remove TypeScript-only top-level declarations\n if (isTSOnlyNode(node)) {\n s.remove(node.start, node.end);\n continue;\n }\n\n // Remove import/export declarations (not supported in QuickJS eval)\n if (\n node.type === \"ImportDeclaration\" ||\n node.type === \"ExportNamedDeclaration\" ||\n node.type === \"ExportDefaultDeclaration\" ||\n node.type === \"ExportAllDeclaration\"\n ) {\n s.remove(node.start, node.end);\n continue;\n }\n\n // Hoist top-level variable declarations\n if (node.type === \"VariableDeclaration\") {\n hoistDeclaration(s, node as unknown as AcornVariableDeclaration);\n continue;\n }\n\n // Hoist function/class declarations to globalThis for cross-eval persistence\n if (\n node.type === \"FunctionDeclaration\" ||\n node.type === \"ClassDeclaration\"\n ) {\n stripTypeAnnotations(s, node);\n const name = (node as any).id?.name;\n if (name) {\n s.appendRight(node.end, `\\nglobalThis.${name} = ${name};`);\n }\n continue;\n }\n }\n\n // Strip type annotations from within expressions/statements\n for (const node of topLevelNodes) {\n if (isTSOnlyNode(node)) continue;\n if (\n node.type === \"ImportDeclaration\" ||\n node.type === \"ExportNamedDeclaration\" ||\n node.type === \"ExportDefaultDeclaration\" ||\n node.type === \"ExportAllDeclaration\"\n )\n continue;\n if (node.type !== \"VariableDeclaration\") {\n walk(node as any, {\n enter(n: any) {\n stripTypeAnnotationFromNode(s, n);\n },\n });\n }\n }\n\n // Auto-return the last expression. We insert `return (` before the\n // ExpressionStatement (to preserve any grouping parens like `({...})`),\n // but close `)` after the inner expression — not after the statement —\n // so any trailing semicolon stays outside: `return (expr);` not `return (expr;)`.\n const lastNode = findLastNonEmptyNode(topLevelNodes, s);\n if (lastNode && isExpression(lastNode)) {\n const { expression } = lastNode as AcornExpressionStatement;\n s.prependLeft(lastNode.start, \"return (\");\n s.appendRight(expression.end, \")\");\n }\n\n // Wrap in async IIFE\n s.prepend(\"(async () => {\\n\");\n s.append(\"\\n})()\");\n\n return s.toString();\n}\n\nfunction isTSOnlyNode(node: AcornNode): boolean {\n const t = node.type as string;\n return (\n t === \"TSTypeAliasDeclaration\" ||\n t === \"TSInterfaceDeclaration\" ||\n t === \"TSEnumDeclaration\" ||\n t === \"TSModuleDeclaration\" ||\n t === \"TSDeclareFunction\" ||\n t.startsWith(\"TS\")\n );\n}\n\n/**\n * Rewrite a top-level VariableDeclaration to globalThis assignments.\n *\n * `const x = 1, y = 2` → `globalThis.x = 1; globalThis.y = 2`\n *\n */\nfunction hoistDeclaration(\n s: MagicString,\n decl: AcornVariableDeclaration,\n): void {\n const parts: string[] = [];\n\n for (const d of decl.declarations) {\n const id = d.id as AcornNode;\n if (id.type === \"Identifier\") {\n const initCode = d.init ? extractCleanInit(s, d) : \"undefined\";\n parts.push(\n `globalThis.${(id as unknown as Identifier).name} = ${initCode}`,\n );\n } else if (id.type === \"ObjectPattern\" || id.type === \"ArrayPattern\") {\n const bindings = extractBindingNames(d.id as any);\n const initCode = d.init ? extractCleanInit(s, d) : \"undefined\";\n const patternCode = extractCleanSource(s, d.id as AcornNode);\n parts.push(`var ${patternCode} = ${initCode}`);\n for (const name of bindings) {\n parts.push(`globalThis.${name} = ${name}`);\n }\n }\n }\n\n s.overwrite(decl.start, decl.end, parts.join(\"; \") + \";\");\n}\n\n/**\n * Extract the initializer code, stripping TypeScript annotations from\n * within the expression (e.g. `as Type`, generics, parameter types in\n * arrow functions).\n */\nfunction extractCleanInit(s: MagicString, d: AcornVariableDeclarator): string {\n if (!d.init) return \"undefined\";\n return extractCleanSource(s, d.init as AcornNode);\n}\n\nfunction extractBindingNames(pattern: any): string[] {\n const names: string[] = [];\n if (pattern.type === \"Identifier\") {\n if (pattern.name) names.push(pattern.name);\n } else if (pattern.type === \"ObjectPattern\") {\n for (const prop of pattern.properties || []) {\n if (prop.type === \"RestElement\") {\n names.push(...extractBindingNames(prop.argument));\n } else {\n names.push(...extractBindingNames(prop.value));\n }\n }\n } else if (pattern.type === \"ArrayPattern\") {\n for (const el of pattern.elements || []) {\n if (el) names.push(...extractBindingNames(el));\n }\n } else if (pattern.type === \"RestElement\") {\n names.push(...extractBindingNames(pattern.argument));\n } else if (pattern.type === \"AssignmentPattern\") {\n names.push(...extractBindingNames(pattern.left));\n }\n return names;\n}\n\nfunction stripTypeAnnotations(s: MagicString, node: AcornNode): void {\n walk(node as any, {\n enter(n: any) {\n stripTypeAnnotationFromNode(s, n);\n },\n });\n}\n\nfunction stripTypeAnnotationFromNode(s: MagicString, n: any, offset = 0): void {\n // Type annotations on parameters, variables, return types\n if (n.typeAnnotation && n.typeAnnotation.start != null) {\n s.remove(n.typeAnnotation.start - offset, n.typeAnnotation.end - offset);\n }\n // Return type on functions\n if (n.returnType && n.returnType.start != null) {\n s.remove(n.returnType.start - offset, n.returnType.end - offset);\n }\n // Type parameters (generics)\n if (n.typeParameters && n.typeParameters.start != null) {\n s.remove(n.typeParameters.start - offset, n.typeParameters.end - offset);\n }\n // Type arguments on calls\n if (n.typeArguments && n.typeArguments.start != null) {\n s.remove(n.typeArguments.start - offset, n.typeArguments.end - offset);\n }\n // `as` expressions: keep the expression, remove `as Type`\n if (n.type === \"TSAsExpression\" && n.expression) {\n s.remove(n.expression.end - offset, n.end - offset);\n }\n // Non-null assertion: `x!` → `x`\n if (n.type === \"TSNonNullExpression\" && n.expression) {\n s.remove(n.expression.end - offset, n.end - offset);\n }\n // Satisfies expression: `x satisfies Type` → `x`\n if (n.type === \"TSSatisfiesExpression\" && n.expression) {\n s.remove(n.expression.end - offset, n.end - offset);\n }\n}\n\n/**\n * Extract a clean JS source string from an AST node, stripping all\n * TypeScript annotations. Works on a copy so the main MagicString is\n * not mutated.\n */\nfunction extractCleanSource(s: MagicString, node: AcornNode): string {\n const offset = node.start;\n const source = new MagicString(s.slice(node.start, node.end));\n walk(node as any, {\n enter(n: any) {\n stripTypeAnnotationFromNode(source, n, offset);\n },\n });\n return source.toString();\n}\n\nfunction findLastNonEmptyNode(\n nodes: AcornNode[],\n s: MagicString,\n): AcornNode | null {\n for (let i = nodes.length - 1; i >= 0; i--) {\n const node = nodes[i];\n // Skip nodes that were fully removed\n const slice = s.slice(node.start, node.end).trim();\n if (slice === \"\" || slice === \";\") continue;\n return node;\n }\n return null;\n}\n\nfunction isExpression(node: AcornNode): boolean {\n return node.type === \"ExpressionStatement\";\n}\n","/**\n * Core REPL engine built on quickjs-emscripten (asyncify variant).\n *\n * Host async functions (backend I/O, PTC tools) are exposed as\n * promise-returning functions inside the QuickJS guest. Guest code\n * uses `await` to consume them, enabling real concurrency via\n * `Promise.all`, `Promise.race`, etc.\n *\n * We still use the asyncify WASM variant because `evalCodeAsync` is\n * required to drive promise resolution from the host side.\n *\n * ## Architecture\n *\n * `ReplSession` is a serializable handle that can live in LangGraph state.\n * It holds an `id` that keys into a static session map. The heavy QuickJS\n * runtime is lazily started on the first `.eval()` call, making the session\n * safe across graph interrupts and checkpointing.\n *\n * File writes inside the REPL are buffered (`pendingWrites`) and only\n * flushed to the backend after a script finishes executing. Call\n * `session.flushWrites(backend)` after eval to persist them.\n */\n\nimport { shouldInterruptAfterDeadline } from \"quickjs-emscripten\";\nimport type { QuickJSHandle } from \"quickjs-emscripten\";\nimport { newQuickJSAsyncWASMModuleFromVariant } from \"quickjs-emscripten-core\";\nimport type {\n QuickJSAsyncContext,\n QuickJSAsyncRuntime,\n} from \"quickjs-emscripten-core\";\nimport type { AnyBackendProtocol, BackendProtocolV2 } from \"deepagents\";\nimport { adaptBackendProtocol } from \"deepagents\";\nimport type { StructuredToolInterface } from \"@langchain/core/tools\";\n\nimport type { ReplSessionOptions, ReplResult } from \"./types.js\";\nimport { toCamelCase } from \"./utils.js\";\nimport { transformForEval } from \"./transform.js\";\n\nexport const DEFAULT_MEMORY_LIMIT = 50 * 1024 * 1024;\nexport const DEFAULT_MAX_STACK_SIZE = 320 * 1024;\nexport const DEFAULT_EXECUTION_TIMEOUT = 30_000;\nexport const DEFAULT_SESSION_ID = \"__default__\";\n\nlet asyncModulePromise: Promise<any> | undefined;\n\nasync function getAsyncModule() {\n if (!asyncModulePromise) {\n asyncModulePromise = (async () => {\n const variant =\n await import(\"@jitl/quickjs-ng-wasmfile-release-asyncify\");\n return newQuickJSAsyncWASMModuleFromVariant(\n (variant.default ?? variant) as any,\n );\n })();\n }\n return asyncModulePromise;\n}\n\nexport interface PendingWrite {\n path: string;\n content: string;\n}\n\n/**\n * Sandboxed JavaScript REPL session backed by QuickJS WASM.\n *\n * Serializable — holds an `id` that keys into a static session map.\n * The QuickJS runtime is lazily started on the first `.eval()` call\n * and reconnected if a session with the same id already exists.\n * This makes it safe to store in LangGraph state across interrupts.\n *\n * File writes are buffered during execution and flushed via\n * `flushWrites(backend)` after eval completes.\n */\nexport class ReplSession {\n private static sessions = new Map<string, ReplSession>();\n\n readonly id: string;\n readonly pendingWrites: PendingWrite[] = [];\n\n private runtime: QuickJSAsyncRuntime | null = null;\n private context: QuickJSAsyncContext | null = null;\n private logs: string[] = [];\n private _options: ReplSessionOptions;\n\n private _backend: BackendProtocolV2 | null = null;\n\n constructor(id: string, options: ReplSessionOptions = {}) {\n this.id = id;\n this._options = options;\n }\n\n get backend(): BackendProtocolV2 | null {\n return this._backend;\n }\n\n set backend(b: AnyBackendProtocol | null) {\n this._backend = b ? adaptBackendProtocol(b) : null;\n }\n\n private async ensureStarted(): Promise<void> {\n if (this.runtime) return;\n\n const {\n memoryLimitBytes = DEFAULT_MEMORY_LIMIT,\n maxStackSizeBytes = DEFAULT_MAX_STACK_SIZE,\n backend,\n tools,\n } = this._options;\n\n const asyncModule = await getAsyncModule();\n const runtime: QuickJSAsyncRuntime = asyncModule.newRuntime();\n runtime.setMemoryLimit(memoryLimitBytes);\n runtime.setMaxStackSize(maxStackSizeBytes);\n\n const context: QuickJSAsyncContext = runtime.newContext();\n this.runtime = runtime;\n this.context = context;\n\n this.setupConsole();\n\n if (backend) {\n this._backend = adaptBackendProtocol(backend);\n }\n this.injectVfs();\n if (tools && tools.length > 0) {\n this.injectTools(tools);\n }\n }\n\n /**\n * Get or create a session for the given id.\n *\n * Sessions are deduped by id — calling `getOrCreate` twice with the\n * same id returns the same instance. The QuickJS runtime is lazily\n * started on the first `.eval()` call.\n */\n static getOrCreate(\n id: string,\n options: ReplSessionOptions = {},\n ): ReplSession {\n const existing = ReplSession.sessions.get(id);\n if (existing) {\n if (options.backend) {\n existing._backend = adaptBackendProtocol(options.backend);\n }\n return existing;\n }\n\n const session = new ReplSession(id, options);\n ReplSession.sessions.set(id, session);\n return session;\n }\n\n /**\n * Retrieve an existing session by id, or null if none exists.\n */\n static get(id: string): ReplSession | null {\n return ReplSession.sessions.get(id) ?? null;\n }\n\n /**\n * Evaluate code in this session.\n *\n * Lazily starts the QuickJS runtime on the first call. Code is\n * transformed via an AST pipeline that strips TypeScript syntax,\n * hoists top-level declarations to globalThis for cross-eval\n * persistence, auto-returns the last expression, and wraps in an\n * async IIFE.\n */\n async eval(code: string, timeoutMs: number): Promise<ReplResult> {\n await this.ensureStarted();\n const runtime = this.runtime!;\n const context = this.context!;\n\n this.logs.length = 0;\n\n if (timeoutMs >= 0) {\n runtime.setInterruptHandler(\n shouldInterruptAfterDeadline(Date.now() + timeoutMs),\n );\n } else {\n runtime.setInterruptHandler(() => false);\n }\n\n const transformed = transformForEval(code);\n const result = await context.evalCodeAsync(transformed);\n\n if (result.error) {\n const error = context.dump(result.error);\n result.error.dispose();\n return { ok: false, error, logs: [...this.logs] };\n }\n\n const promiseState = context.getPromiseState(result.value);\n\n if (promiseState.type === \"fulfilled\") {\n if (promiseState.notAPromise) {\n const value = context.dump(result.value);\n result.value.dispose();\n return { ok: true, value, logs: [...this.logs] };\n }\n const value = context.dump(promiseState.value);\n promiseState.value.dispose();\n result.value.dispose();\n return { ok: true, value, logs: [...this.logs] };\n }\n\n if (promiseState.type === \"rejected\") {\n const error = context.dump(promiseState.error);\n promiseState.error.dispose();\n result.value.dispose();\n return { ok: false, error, logs: [...this.logs] };\n }\n\n const noTimeout = timeoutMs < 0;\n const deadline = noTimeout ? Infinity : Date.now() + timeoutMs;\n while (noTimeout || Date.now() < deadline) {\n context.runtime.executePendingJobs();\n const state = context.getPromiseState(result.value);\n if (state.type === \"fulfilled\") {\n const value = context.dump(state.value);\n state.value.dispose();\n result.value.dispose();\n return { ok: true, value, logs: [...this.logs] };\n }\n if (state.type === \"rejected\") {\n const error = context.dump(state.error);\n state.error.dispose();\n result.value.dispose();\n return { ok: false, error, logs: [...this.logs] };\n }\n await new Promise((r) => setTimeout(r, 1));\n }\n\n result.value.dispose();\n return {\n ok: false,\n error: { message: \"Promise timed out — execution interrupted\" },\n logs: [...this.logs],\n };\n }\n\n async flushWrites(backend: AnyBackendProtocol): Promise<void> {\n const adapted = adaptBackendProtocol(backend);\n const writes = this.pendingWrites.splice(0);\n for (const { path, content } of writes) {\n await adapted.write(path, content);\n }\n }\n\n dispose(): void {\n try {\n this.context?.dispose();\n } catch {\n /* may already be disposed */\n }\n try {\n this.runtime?.dispose();\n } catch {\n /* may already be disposed */\n }\n this.runtime = null;\n this.context = null;\n ReplSession.sessions.delete(this.id);\n }\n\n toJSON(): { id: string } {\n return { id: this.id };\n }\n\n static fromJSON(data: { id: string }): ReplSession {\n return ReplSession.sessions.get(data.id) ?? new ReplSession(data.id);\n }\n\n /**\n * Clear the static session cache. Useful for testing.\n * @internal\n */\n static clearCache(): void {\n for (const session of ReplSession.sessions.values()) {\n session.dispose();\n }\n ReplSession.sessions.clear();\n }\n\n private setupConsole(): void {\n const context = this.context!;\n const logs = this.logs;\n const consoleHandle = context.newObject();\n for (const method of [\"log\", \"warn\", \"error\", \"info\", \"debug\"] as const) {\n const fnHandle = context.newFunction(\n method,\n (...args: QuickJSHandle[]) => {\n const nativeArgs = args.map((a: QuickJSHandle) => context.dump(a));\n const formatted = nativeArgs\n .map((a: unknown) =>\n typeof a === \"object\" && a !== null\n ? JSON.stringify(a)\n : String(a),\n )\n .join(\" \");\n logs.push(\n method === \"log\" || method === \"info\" || method === \"debug\"\n ? formatted\n : `[${method}] ${formatted}`,\n );\n },\n );\n context.setProp(consoleHandle, method, fnHandle);\n fnHandle.dispose();\n }\n context.setProp(context.global, \"console\", consoleHandle);\n consoleHandle.dispose();\n }\n\n private injectVfs(): void {\n const context = this.context!;\n const getBackend = () => this._backend;\n const { pendingWrites } = this;\n\n const readFileHandle = context.newFunction(\n \"readFile\",\n (pathHandle: QuickJSHandle) => {\n const backend = getBackend();\n if (!backend) {\n const promise = context.newPromise();\n const err = context.newError(\"Backend not available\");\n promise.reject(err);\n err.dispose();\n promise.settled.then(context.runtime.executePendingJobs);\n return promise.handle;\n }\n const path = context.getString(pathHandle);\n const promise = context.newPromise();\n (async () => {\n try {\n const result = await backend.readRaw(path);\n if (result.error || !result.data) {\n const err = context.newError(\n `ENOENT: no such file or directory '${path}'.`,\n );\n promise.reject(err);\n err.dispose();\n } else {\n const content = Array.isArray(result.data.content)\n ? result.data.content.join(\"\\n\")\n : typeof result.data.content === \"string\"\n ? result.data.content\n : null;\n if (content === null) {\n const err = context.newError(\n `Cannot read binary file '${path}' as text.`,\n );\n promise.reject(err);\n err.dispose();\n return;\n }\n const val = context.newString(content);\n promise.resolve(val);\n val.dispose();\n }\n } catch {\n const err = context.newError(\n `ENOENT: no such file or directory '${path}'.`,\n );\n promise.reject(err);\n err.dispose();\n }\n promise.settled.then(context.runtime.executePendingJobs);\n })();\n return promise.handle;\n },\n );\n context.setProp(context.global, \"readFile\", readFileHandle);\n readFileHandle.dispose();\n\n const writeFileHandle = context.newFunction(\n \"writeFile\",\n (pathHandle: QuickJSHandle, contentHandle: QuickJSHandle) => {\n const path = context.getString(pathHandle);\n const content = context.getString(contentHandle);\n const promise = context.newPromise();\n pendingWrites.push({ path, content });\n promise.resolve(context.undefined);\n promise.settled.then(context.runtime.executePendingJobs);\n return promise.handle;\n },\n );\n context.setProp(context.global, \"writeFile\", writeFileHandle);\n writeFileHandle.dispose();\n }\n\n private injectTools(tools: StructuredToolInterface[]): void {\n const context = this.context!;\n const toolsNs = context.newObject();\n\n for (const t of tools) {\n const camelName = toCamelCase(t.name);\n const fnHandle = context.newFunction(\n camelName,\n (inputHandle: QuickJSHandle) => {\n const input = context.dump(inputHandle);\n const promise = context.newPromise();\n (async () => {\n try {\n const rawInput =\n typeof input === \"object\" && input !== null ? input : {};\n const result = await t.invoke(rawInput);\n const val = context.newString(\n typeof result === \"string\" ? result : JSON.stringify(result),\n );\n promise.resolve(val);\n val.dispose();\n } catch (e: unknown) {\n const msg =\n e != null && typeof (e as Error).message === \"string\"\n ? (e as Error).message\n : String(e);\n const err = context.newError(`Tool '${t.name}' failed: ${msg}`);\n promise.reject(err);\n err.dispose();\n }\n promise.settled.then(context.runtime.executePendingJobs);\n })();\n return promise.handle;\n },\n );\n context.setProp(toolsNs, camelName, fnHandle);\n fnHandle.dispose();\n }\n\n context.setProp(context.global, \"tools\", toolsNs);\n toolsNs.dispose();\n }\n}\n","/**\n * QuickJS REPL middleware for deepagents.\n *\n * Provides a `js_eval` tool that runs JavaScript in a WASM-sandboxed QuickJS\n * interpreter. Supports:\n * - Persistent state across evaluations (true REPL)\n * - VFS integration via readFile/writeFile\n * - Programmatic tool calling (PTC)\n */\n\nimport {\n createMiddleware,\n tool,\n type AgentMiddleware as _AgentMiddleware,\n} from \"langchain\";\nimport { z } from \"zod/v4\";\nimport type { StructuredToolInterface } from \"@langchain/core/tools\";\nimport { StateBackend, type BackendRuntime, resolveBackend } from \"deepagents\";\n\nimport dedent from \"dedent\";\nimport type { QuickJSMiddlewareOptions } from \"./types.js\";\nimport {\n ReplSession,\n DEFAULT_EXECUTION_TIMEOUT,\n DEFAULT_MEMORY_LIMIT,\n DEFAULT_MAX_STACK_SIZE,\n DEFAULT_SESSION_ID,\n} from \"./session.js\";\nimport {\n formatReplResult,\n toCamelCase,\n toolToTypeSignature,\n safeToJsonSchema,\n} from \"./utils.js\";\n\n/**\n * These type-only imports are required for TypeScript's type inference to work\n * correctly with the langchain/langgraph middleware system. Without them, certain\n * generic type parameters fail to resolve properly, causing runtime issues with\n * tool schemas and message types.\n */\nimport type * as _zodTypes from \"@langchain/core/utils/types\";\nimport type * as _zodMeta from \"@langchain/langgraph/zod\";\nimport type * as _messages from \"@langchain/core/messages\";\nimport {\n getCurrentTaskInput,\n LangGraphRunnableConfig,\n} from \"@langchain/langgraph\";\n\n/**\n * Backend-provided tools excluded from PTC by default.\n * These are redundant inside the REPL since VFS helpers (readFile/writeFile)\n * already cover file I/O against the agent's in-memory working set.\n */\nexport const DEFAULT_PTC_EXCLUDED_TOOLS = [\n \"ls\",\n \"read_file\",\n \"write_file\",\n \"edit_file\",\n \"glob\",\n \"grep\",\n \"execute\",\n] as const;\n\nconst REPL_SYSTEM_PROMPT = dedent`\n ## TypeScript/JavaScript REPL (\\`js_eval\\`)\n\n You have access to a sandboxed TypeScript/JavaScript REPL running in an isolated interpreter.\n TypeScript syntax (type annotations, interfaces, generics, \\`as\\` casts) is supported and stripped at evaluation time.\n Variables, functions, and closures persist across calls within the same session.\n\n ### Hard rules\n\n - **No network, no filesystem** — only the helpers below. Do not attempt \\`fetch\\`, \\`require\\`, or \\`import\\`.\n - **Cite your sources** — when reporting values from files, include the path and key/index so the user can verify.\n - **Use console.log()** for output — it is captured and returned. \\`console.warn()\\` and \\`console.error()\\` are also available.\n - **Reuse state from previous cells** — variables, functions, and results from earlier \\`js_eval\\` calls persist across calls. Reference them by name in follow-up cells instead of re-embedding data as inline JSON literals.\n\n ### First-time usage\n\n \\`\\`\\`typescript\n // Read a file from the agent's virtual filesystem\n const raw: string = await readFile(\"/data.json\");\n const data = JSON.parse(raw) as { n: number };\n console.log(data);\n\n // Write results back\n await writeFile(\"/output.txt\", JSON.stringify({ result: data.n }));\n \\`\\`\\`\n\n ### API Reference — built-in globals\n\n \\`\\`\\`typescript\n /**\n * Read a file from the agent's virtual filesystem. Throws if the file does not exist.\n */\n async readFile(path: string): Promise<string>\n\n /**\n * Write a file to the agent's virtual filesystem.\n */\n async writeFile(path: string, content: string): Promise<void>\n \\`\\`\\`\n\n ### Limitations\n\n - ES2023+ syntax with TypeScript support. No Node.js APIs, no \\`require\\`, no \\`import\\`.\n - Output is truncated beyond a fixed character limit — be selective about what you log.\n - Execution timeout per call (default 30 s).\n`;\n\n/**\n * Generate the PTC API Reference section for the system prompt.\n */\nexport async function generatePtcPrompt(\n tools: StructuredToolInterface[],\n): Promise<string> {\n if (tools.length === 0) return \"\";\n\n const signatures = await Promise.all(\n tools.map((t) => {\n const jsonSchema = t.schema ? safeToJsonSchema(t.schema) : undefined;\n return toolToTypeSignature(\n toCamelCase(t.name),\n t.description,\n jsonSchema,\n );\n }),\n );\n\n return dedent`\n\n ### API Reference — \\`tools\\` namespace\n\n The following agent tools are callable as async functions inside the REPL.\n Each takes a single object argument and returns a Promise that resolves to a string.\n Use \\`await\\` to call them. Promise APIs like \\`Promise.all\\` are also available.\n\n **Example usage:**\n \\`\\`\\`javascript\n // Call a tool\n const result = await tools.searchWeb({ query: \"QuickJS tutorial\" });\n console.log(result);\n\n // Concurrent calls\n const [a, b] = await Promise.all([\n tools.fetchData({ url: \"https://api.example.com/a\" }),\n tools.fetchData({ url: \"https://api.example.com/b\" }),\n ]);\n \\`\\`\\`\n\n **Available functions:**\n \\`\\`\\`typescript\n ${signatures.join(\"\\n\\n\")}\n \\`\\`\\`\n `;\n}\n\n/**\n * Create the QuickJS REPL middleware.\n */\nexport function createQuickJSMiddleware(\n options: QuickJSMiddlewareOptions = {},\n) {\n const {\n backend = (runtime: BackendRuntime) => new StateBackend(runtime),\n ptc = false,\n memoryLimitBytes = DEFAULT_MEMORY_LIMIT,\n maxStackSizeBytes = DEFAULT_MAX_STACK_SIZE,\n executionTimeoutMs = DEFAULT_EXECUTION_TIMEOUT,\n systemPrompt: customSystemPrompt = null,\n } = options;\n\n const usePtc = ptc !== false;\n const baseSystemPrompt = customSystemPrompt || REPL_SYSTEM_PROMPT;\n\n let cachedPtcPrompt: string | null = null;\n\n let ptcTools: StructuredToolInterface[] = [];\n\n function filterToolsForPtc(\n allTools: StructuredToolInterface[],\n ): StructuredToolInterface[] {\n if (ptc === false) return [];\n\n const candidates = allTools.filter((t) => t.name !== \"js_eval\");\n\n if (ptc === true) {\n const excluded = new Set<string>(DEFAULT_PTC_EXCLUDED_TOOLS);\n return candidates.filter((t) => !excluded.has(t.name));\n }\n\n if (Array.isArray(ptc)) {\n const included = new Set(ptc);\n return candidates.filter((t) => included.has(t.name));\n }\n\n if (\"include\" in ptc) {\n const included = new Set(ptc.include);\n return candidates.filter((t) => included.has(t.name));\n }\n\n if (\"exclude\" in ptc) {\n const excluded = new Set([...DEFAULT_PTC_EXCLUDED_TOOLS, ...ptc.exclude]);\n return candidates.filter((t) => !excluded.has(t.name));\n }\n\n return [];\n }\n\n const jsEvalTool = tool(\n async (input, config: LangGraphRunnableConfig) => {\n const threadId = config.configurable?.thread_id || DEFAULT_SESSION_ID;\n\n const runtime: BackendRuntime = {\n ...config,\n state: getCurrentTaskInput(config) || {},\n } as BackendRuntime;\n const resolvedBackend = await resolveBackend(backend, runtime);\n\n const session = ReplSession.getOrCreate(threadId, {\n memoryLimitBytes,\n maxStackSizeBytes,\n backend: resolvedBackend,\n tools: ptcTools,\n });\n\n const result = await session.eval(input.code, executionTimeoutMs);\n await session.flushWrites(resolvedBackend);\n\n return formatReplResult(result);\n },\n {\n name: \"js_eval\",\n description: dedent`\n Evaluate TypeScript/JavaScript code in a sandboxed REPL. State persists across calls.\n Use readFile(path) and writeFile(path, content) for file access.\n Use console.log() for output. Returns the result of the last expression.\n `,\n schema: z.object({\n code: z\n .string()\n .describe(\n \"TypeScript/JavaScript code to evaluate in the sandboxed REPL\",\n ),\n }),\n },\n );\n\n return createMiddleware({\n name: \"QuickJSMiddleware\",\n tools: [jsEvalTool],\n wrapModelCall: async (request, handler) => {\n const agentTools = (request.tools || []) as StructuredToolInterface[];\n ptcTools = usePtc ? filterToolsForPtc(agentTools) : [];\n\n if (ptcTools.length > 0 && !cachedPtcPrompt) {\n cachedPtcPrompt = await generatePtcPrompt(ptcTools);\n }\n\n const systemMessage = request.systemMessage\n .concat(baseSystemPrompt)\n .concat(cachedPtcPrompt || \"\");\n return handler({ ...request, systemMessage });\n },\n });\n}\n"],"mappings":"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"}
package/dist/index.d.cts CHANGED
@@ -1,8 +1,8 @@
1
- import * as langchain from "langchain";
1
+ import * as _$langchain from "langchain";
2
2
  import { AgentMiddleware } from "langchain";
3
3
  import { z } from "zod/v4";
4
4
  import { StructuredToolInterface } from "@langchain/core/tools";
5
- import { BackendFactory, BackendProtocol } from "deepagents";
5
+ import { AnyBackendProtocol, BackendFactory, BackendProtocolV2 } from "deepagents";
6
6
 
7
7
  //#region src/types.d.ts
8
8
  /**
@@ -11,11 +11,11 @@ import { BackendFactory, BackendProtocol } from "deepagents";
11
11
  interface QuickJSMiddlewareOptions {
12
12
  /**
13
13
  * Backend for file I/O (readFile/writeFile) inside the REPL.
14
- * Accepts a BackendProtocol instance or a BackendFactory function.
14
+ * Accepts a AnyBackendProtocol instance or a BackendFactory function.
15
15
  * Defaults to StateBackend (reads/writes LangGraph checkpoint state).
16
16
  * @default StateBackend
17
17
  */
18
- backend?: BackendProtocol | BackendFactory;
18
+ backend?: AnyBackendProtocol | BackendFactory;
19
19
  /**
20
20
  * Enable programmatic tool calling from within the REPL.
21
21
  *
@@ -60,7 +60,7 @@ interface QuickJSMiddlewareOptions {
60
60
  interface ReplSessionOptions {
61
61
  memoryLimitBytes?: number;
62
62
  maxStackSizeBytes?: number;
63
- backend?: BackendProtocol;
63
+ backend?: AnyBackendProtocol;
64
64
  tools?: StructuredToolInterface[];
65
65
  }
66
66
  /**
@@ -87,7 +87,7 @@ declare const DEFAULT_PTC_EXCLUDED_TOOLS: readonly ["ls", "read_file", "write_fi
87
87
  /**
88
88
  * Create the QuickJS REPL middleware.
89
89
  */
90
- declare function createQuickJSMiddleware(options?: QuickJSMiddlewareOptions): AgentMiddleware<undefined, undefined, unknown, readonly [langchain.DynamicStructuredTool<z.ZodObject<{
90
+ declare function createQuickJSMiddleware(options?: QuickJSMiddlewareOptions): AgentMiddleware<undefined, undefined, unknown, readonly [_$langchain.DynamicStructuredTool<z.ZodObject<{
91
91
  code: z.ZodString;
92
92
  }, z.core.$strip>, {
93
93
  code: string;
@@ -124,8 +124,8 @@ declare class ReplSession {
124
124
  private _options;
125
125
  private _backend;
126
126
  constructor(id: string, options?: ReplSessionOptions);
127
- get backend(): BackendProtocol | null;
128
- set backend(b: BackendProtocol | null);
127
+ get backend(): BackendProtocolV2 | null;
128
+ set backend(b: AnyBackendProtocol | null);
129
129
  private ensureStarted;
130
130
  /**
131
131
  * Get or create a session for the given id.
@@ -149,7 +149,7 @@ declare class ReplSession {
149
149
  * async IIFE.
150
150
  */
151
151
  eval(code: string, timeoutMs: number): Promise<ReplResult>;
152
- flushWrites(backend: BackendProtocol): Promise<void>;
152
+ flushWrites(backend: AnyBackendProtocol): Promise<void>;
153
153
  dispose(): void;
154
154
  toJSON(): {
155
155
  id: string;
package/dist/index.d.ts CHANGED
@@ -1,7 +1,7 @@
1
- import * as langchain from "langchain";
1
+ import * as _$langchain from "langchain";
2
2
  import { AgentMiddleware } from "langchain";
3
3
  import { z } from "zod/v4";
4
- import { BackendFactory, BackendProtocol } from "deepagents";
4
+ import { AnyBackendProtocol, BackendFactory, BackendProtocolV2 } from "deepagents";
5
5
  import { StructuredToolInterface } from "@langchain/core/tools";
6
6
 
7
7
  //#region src/types.d.ts
@@ -11,11 +11,11 @@ import { StructuredToolInterface } from "@langchain/core/tools";
11
11
  interface QuickJSMiddlewareOptions {
12
12
  /**
13
13
  * Backend for file I/O (readFile/writeFile) inside the REPL.
14
- * Accepts a BackendProtocol instance or a BackendFactory function.
14
+ * Accepts a AnyBackendProtocol instance or a BackendFactory function.
15
15
  * Defaults to StateBackend (reads/writes LangGraph checkpoint state).
16
16
  * @default StateBackend
17
17
  */
18
- backend?: BackendProtocol | BackendFactory;
18
+ backend?: AnyBackendProtocol | BackendFactory;
19
19
  /**
20
20
  * Enable programmatic tool calling from within the REPL.
21
21
  *
@@ -60,7 +60,7 @@ interface QuickJSMiddlewareOptions {
60
60
  interface ReplSessionOptions {
61
61
  memoryLimitBytes?: number;
62
62
  maxStackSizeBytes?: number;
63
- backend?: BackendProtocol;
63
+ backend?: AnyBackendProtocol;
64
64
  tools?: StructuredToolInterface[];
65
65
  }
66
66
  /**
@@ -87,7 +87,7 @@ declare const DEFAULT_PTC_EXCLUDED_TOOLS: readonly ["ls", "read_file", "write_fi
87
87
  /**
88
88
  * Create the QuickJS REPL middleware.
89
89
  */
90
- declare function createQuickJSMiddleware(options?: QuickJSMiddlewareOptions): AgentMiddleware<undefined, undefined, unknown, readonly [langchain.DynamicStructuredTool<z.ZodObject<{
90
+ declare function createQuickJSMiddleware(options?: QuickJSMiddlewareOptions): AgentMiddleware<undefined, undefined, unknown, readonly [_$langchain.DynamicStructuredTool<z.ZodObject<{
91
91
  code: z.ZodString;
92
92
  }, z.core.$strip>, {
93
93
  code: string;
@@ -124,8 +124,8 @@ declare class ReplSession {
124
124
  private _options;
125
125
  private _backend;
126
126
  constructor(id: string, options?: ReplSessionOptions);
127
- get backend(): BackendProtocol | null;
128
- set backend(b: BackendProtocol | null);
127
+ get backend(): BackendProtocolV2 | null;
128
+ set backend(b: AnyBackendProtocol | null);
129
129
  private ensureStarted;
130
130
  /**
131
131
  * Get or create a session for the given id.
@@ -149,7 +149,7 @@ declare class ReplSession {
149
149
  * async IIFE.
150
150
  */
151
151
  eval(code: string, timeoutMs: number): Promise<ReplResult>;
152
- flushWrites(backend: BackendProtocol): Promise<void>;
152
+ flushWrites(backend: AnyBackendProtocol): Promise<void>;
153
153
  dispose(): void;
154
154
  toJSON(): {
155
155
  id: string;
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { createMiddleware, tool } from "langchain";
2
2
  import { z } from "zod/v4";
3
- import { StateBackend, resolveBackend } from "deepagents";
3
+ import { StateBackend, adaptBackendProtocol, resolveBackend } from "deepagents";
4
4
  import dedent from "dedent";
5
5
  import { shouldInterruptAfterDeadline } from "quickjs-emscripten";
6
6
  import { newQuickJSAsyncWASMModuleFromVariant } from "quickjs-emscripten-core";
@@ -297,7 +297,7 @@ var ReplSession = class ReplSession {
297
297
  return this._backend;
298
298
  }
299
299
  set backend(b) {
300
- this._backend = b;
300
+ this._backend = b ? adaptBackendProtocol(b) : null;
301
301
  }
302
302
  async ensureStarted() {
303
303
  if (this.runtime) return;
@@ -309,7 +309,7 @@ var ReplSession = class ReplSession {
309
309
  this.runtime = runtime;
310
310
  this.context = context;
311
311
  this.setupConsole();
312
- if (backend) this._backend = backend;
312
+ if (backend) this._backend = adaptBackendProtocol(backend);
313
313
  this.injectVfs();
314
314
  if (tools && tools.length > 0) this.injectTools(tools);
315
315
  }
@@ -323,7 +323,7 @@ var ReplSession = class ReplSession {
323
323
  static getOrCreate(id, options = {}) {
324
324
  const existing = ReplSession.sessions.get(id);
325
325
  if (existing) {
326
- if (options.backend) existing._backend = options.backend;
326
+ if (options.backend) existing._backend = adaptBackendProtocol(options.backend);
327
327
  return existing;
328
328
  }
329
329
  const session = new ReplSession(id, options);
@@ -428,8 +428,9 @@ var ReplSession = class ReplSession {
428
428
  };
429
429
  }
430
430
  async flushWrites(backend) {
431
+ const adapted = adaptBackendProtocol(backend);
431
432
  const writes = this.pendingWrites.splice(0);
432
- for (const { path, content } of writes) await backend.write(path, content);
433
+ for (const { path, content } of writes) await adapted.write(path, content);
433
434
  }
434
435
  dispose() {
435
436
  try {
@@ -495,10 +496,23 @@ var ReplSession = class ReplSession {
495
496
  const promise = context.newPromise();
496
497
  (async () => {
497
498
  try {
498
- const fileData = await backend.readRaw(path);
499
- const val = context.newString(fileData.content.join("\n"));
500
- promise.resolve(val);
501
- val.dispose();
499
+ const result = await backend.readRaw(path);
500
+ if (result.error || !result.data) {
501
+ const err = context.newError(`ENOENT: no such file or directory '${path}'.`);
502
+ promise.reject(err);
503
+ err.dispose();
504
+ } else {
505
+ const content = Array.isArray(result.data.content) ? result.data.content.join("\n") : typeof result.data.content === "string" ? result.data.content : null;
506
+ if (content === null) {
507
+ const err = context.newError(`Cannot read binary file '${path}' as text.`);
508
+ promise.reject(err);
509
+ err.dispose();
510
+ return;
511
+ }
512
+ const val = context.newString(content);
513
+ promise.resolve(val);
514
+ val.dispose();
515
+ }
502
516
  } catch {
503
517
  const err = context.newError(`ENOENT: no such file or directory '${path}'.`);
504
518
  promise.reject(err);
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../src/utils.ts","../src/transform.ts","../src/session.ts","../src/middleware.ts"],"sourcesContent":["import { compile } from \"json-schema-to-typescript\";\nimport { toJsonSchema } from \"@langchain/core/utils/json_schema\";\nimport dedent from \"dedent\";\nimport type { ReplResult } from \"./types.js\";\n\n/**\n * Convert a snake_case or kebab-case string to camelCase.\n */\nexport function toCamelCase(name: string): string {\n return name.replace(/[-_]([a-z])/g, (_, c) => c.toUpperCase());\n}\n\n/**\n * Recursively collect all string values from an object, array, or primitive.\n */\nexport function collectStrings(obj: unknown): string[] {\n const result: string[] = [];\n function walk(val: unknown) {\n if (typeof val === \"string\") {\n result.push(val);\n } else if (Array.isArray(val)) {\n for (const item of val) walk(item);\n } else if (typeof val === \"object\" && val !== null) {\n for (const v of Object.values(val)) walk(v);\n }\n }\n walk(obj);\n return result;\n}\n\n/**\n * Format the result of a REPL evaluation for the agent.\n */\nexport function formatReplResult(result: ReplResult): string {\n const parts: string[] = [];\n\n if (result.logs.length > 0) {\n parts.push(result.logs.join(\"\\n\"));\n }\n\n if (result.ok) {\n if (result.value !== undefined) {\n const formatted =\n typeof result.value === \"string\"\n ? result.value\n : JSON.stringify(result.value, null, 2);\n parts.push(`→ ${formatted}`);\n }\n } else if (result.error) {\n const errName = result.error.name || \"Error\";\n const errMsg = result.error.message || \"Unknown error\";\n parts.push(`${errName}: ${errMsg}`);\n if (result.error.stack) {\n parts.push(result.error.stack);\n }\n }\n\n return parts.join(\"\\n\") || \"(no output)\";\n}\n\nexport function safeToJsonSchema(\n schema: unknown,\n): Record<string, unknown> | undefined {\n try {\n return toJsonSchema(schema as Parameters<typeof toJsonSchema>[0]) as Record<\n string,\n unknown\n >;\n } catch {\n return undefined;\n }\n}\n\nasync function schemaToInterface(\n jsonSchema: Record<string, unknown>,\n interfaceName: string,\n): Promise<string> {\n const compiled = await compile(\n { ...jsonSchema, additionalProperties: false },\n interfaceName,\n { bannerComment: \"\", additionalProperties: false },\n );\n return compiled.replace(/^export /, \"\").trimEnd();\n}\n\nexport function capitalize(s: string): string {\n return s.charAt(0).toUpperCase() + s.slice(1);\n}\n\nexport async function toolToTypeSignature(\n name: string,\n description: string,\n jsonSchema: Record<string, unknown> | undefined,\n): Promise<string> {\n const inputType = `${capitalize(name)}Input`;\n\n if (!jsonSchema || !jsonSchema.properties) {\n return dedent`\n /**\n * ${description}\n */\n async tools.${name}(input: Record<string, unknown>): Promise<string>\n `;\n }\n\n const iface = await schemaToInterface(jsonSchema, inputType);\n return dedent`\n ${iface}\n\n /**\n * ${description}\n */\n async tools.${name}(input: ${inputType}): Promise<string>\n `;\n}\n","/**\n * AST-based code transform pipeline for the REPL.\n *\n * Transforms TypeScript/JavaScript code into plain JS that can be\n * evaluated inside QuickJS with proper state persistence:\n *\n * 1. Parse with acorn + acorn-typescript (handles TS syntax)\n * 2. Strip TypeScript-only nodes (type annotations, interfaces, etc.)\n * 3. Hoist top-level declarations to globalThis for cross-eval persistence\n * 4. Auto-return the last expression\n * 5. Wrap in async IIFE so top-level await works\n */\n\nimport { Parser } from \"acorn\";\nimport { tsPlugin } from \"@sveltejs/acorn-typescript\";\nimport { walk } from \"estree-walker\";\nimport MagicString from \"magic-string\";\nimport type {\n Node,\n Identifier,\n VariableDeclaration as EstreeVariableDeclaration,\n VariableDeclarator as EstreeVariableDeclarator,\n} from \"estree\";\n\nconst TSParser = Parser.extend(tsPlugin());\n\ntype AcornNode = Node & { start: number; end: number };\ntype AcornExpressionStatement = AcornNode & {\n type: \"ExpressionStatement\";\n expression: AcornNode;\n};\ntype AcornVariableDeclaration = EstreeVariableDeclaration & {\n start: number;\n end: number;\n declarations: AcornVariableDeclarator[];\n};\ntype AcornVariableDeclarator = EstreeVariableDeclarator & {\n start: number;\n end: number;\n id: AcornNode;\n init: AcornNode | null;\n};\n\n/**\n * Transform code for REPL evaluation.\n *\n * - Strips TypeScript syntax\n * - Hoists top-level variable declarations to globalThis\n * - Auto-returns the last expression\n * - Wraps in async IIFE for top-level await support\n */\nexport function transformForEval(code: string): string {\n let ast: AcornNode;\n try {\n ast = TSParser.parse(code, {\n ecmaVersion: \"latest\" as any,\n sourceType: \"module\",\n locations: true,\n }) as unknown as AcornNode;\n } catch {\n // If parsing fails, return the code as-is and let QuickJS report the error\n return `(async () => {\\n${code}\\n})()`;\n }\n\n const s = new MagicString(code);\n const program = ast as unknown as { body: AcornNode[] };\n const topLevelNodes = program.body;\n for (let i = 0; i < topLevelNodes.length; i++) {\n const node = topLevelNodes[i];\n\n // Remove TypeScript-only top-level declarations\n if (isTSOnlyNode(node)) {\n s.remove(node.start, node.end);\n continue;\n }\n\n // Remove import/export declarations (not supported in QuickJS eval)\n if (\n node.type === \"ImportDeclaration\" ||\n node.type === \"ExportNamedDeclaration\" ||\n node.type === \"ExportDefaultDeclaration\" ||\n node.type === \"ExportAllDeclaration\"\n ) {\n s.remove(node.start, node.end);\n continue;\n }\n\n // Hoist top-level variable declarations\n if (node.type === \"VariableDeclaration\") {\n hoistDeclaration(s, node as unknown as AcornVariableDeclaration);\n continue;\n }\n\n // Hoist function/class declarations to globalThis for cross-eval persistence\n if (\n node.type === \"FunctionDeclaration\" ||\n node.type === \"ClassDeclaration\"\n ) {\n stripTypeAnnotations(s, node);\n const name = (node as any).id?.name;\n if (name) {\n s.appendRight(node.end, `\\nglobalThis.${name} = ${name};`);\n }\n continue;\n }\n }\n\n // Strip type annotations from within expressions/statements\n for (const node of topLevelNodes) {\n if (isTSOnlyNode(node)) continue;\n if (\n node.type === \"ImportDeclaration\" ||\n node.type === \"ExportNamedDeclaration\" ||\n node.type === \"ExportDefaultDeclaration\" ||\n node.type === \"ExportAllDeclaration\"\n )\n continue;\n if (node.type !== \"VariableDeclaration\") {\n walk(node as any, {\n enter(n: any) {\n stripTypeAnnotationFromNode(s, n);\n },\n });\n }\n }\n\n // Auto-return the last expression. We insert `return (` before the\n // ExpressionStatement (to preserve any grouping parens like `({...})`),\n // but close `)` after the inner expression — not after the statement —\n // so any trailing semicolon stays outside: `return (expr);` not `return (expr;)`.\n const lastNode = findLastNonEmptyNode(topLevelNodes, s);\n if (lastNode && isExpression(lastNode)) {\n const { expression } = lastNode as AcornExpressionStatement;\n s.prependLeft(lastNode.start, \"return (\");\n s.appendRight(expression.end, \")\");\n }\n\n // Wrap in async IIFE\n s.prepend(\"(async () => {\\n\");\n s.append(\"\\n})()\");\n\n return s.toString();\n}\n\nfunction isTSOnlyNode(node: AcornNode): boolean {\n const t = node.type as string;\n return (\n t === \"TSTypeAliasDeclaration\" ||\n t === \"TSInterfaceDeclaration\" ||\n t === \"TSEnumDeclaration\" ||\n t === \"TSModuleDeclaration\" ||\n t === \"TSDeclareFunction\" ||\n t.startsWith(\"TS\")\n );\n}\n\n/**\n * Rewrite a top-level VariableDeclaration to globalThis assignments.\n *\n * `const x = 1, y = 2` → `globalThis.x = 1; globalThis.y = 2`\n *\n */\nfunction hoistDeclaration(\n s: MagicString,\n decl: AcornVariableDeclaration,\n): void {\n const parts: string[] = [];\n\n for (const d of decl.declarations) {\n const id = d.id as AcornNode;\n if (id.type === \"Identifier\") {\n const initCode = d.init ? extractCleanInit(s, d) : \"undefined\";\n parts.push(\n `globalThis.${(id as unknown as Identifier).name} = ${initCode}`,\n );\n } else if (id.type === \"ObjectPattern\" || id.type === \"ArrayPattern\") {\n const bindings = extractBindingNames(d.id as any);\n const initCode = d.init ? extractCleanInit(s, d) : \"undefined\";\n const patternCode = extractCleanSource(s, d.id as AcornNode);\n parts.push(`var ${patternCode} = ${initCode}`);\n for (const name of bindings) {\n parts.push(`globalThis.${name} = ${name}`);\n }\n }\n }\n\n s.overwrite(decl.start, decl.end, parts.join(\"; \") + \";\");\n}\n\n/**\n * Extract the initializer code, stripping TypeScript annotations from\n * within the expression (e.g. `as Type`, generics, parameter types in\n * arrow functions).\n */\nfunction extractCleanInit(s: MagicString, d: AcornVariableDeclarator): string {\n if (!d.init) return \"undefined\";\n return extractCleanSource(s, d.init as AcornNode);\n}\n\nfunction extractBindingNames(pattern: any): string[] {\n const names: string[] = [];\n if (pattern.type === \"Identifier\") {\n if (pattern.name) names.push(pattern.name);\n } else if (pattern.type === \"ObjectPattern\") {\n for (const prop of pattern.properties || []) {\n if (prop.type === \"RestElement\") {\n names.push(...extractBindingNames(prop.argument));\n } else {\n names.push(...extractBindingNames(prop.value));\n }\n }\n } else if (pattern.type === \"ArrayPattern\") {\n for (const el of pattern.elements || []) {\n if (el) names.push(...extractBindingNames(el));\n }\n } else if (pattern.type === \"RestElement\") {\n names.push(...extractBindingNames(pattern.argument));\n } else if (pattern.type === \"AssignmentPattern\") {\n names.push(...extractBindingNames(pattern.left));\n }\n return names;\n}\n\nfunction stripTypeAnnotations(s: MagicString, node: AcornNode): void {\n walk(node as any, {\n enter(n: any) {\n stripTypeAnnotationFromNode(s, n);\n },\n });\n}\n\nfunction stripTypeAnnotationFromNode(s: MagicString, n: any, offset = 0): void {\n // Type annotations on parameters, variables, return types\n if (n.typeAnnotation && n.typeAnnotation.start != null) {\n s.remove(n.typeAnnotation.start - offset, n.typeAnnotation.end - offset);\n }\n // Return type on functions\n if (n.returnType && n.returnType.start != null) {\n s.remove(n.returnType.start - offset, n.returnType.end - offset);\n }\n // Type parameters (generics)\n if (n.typeParameters && n.typeParameters.start != null) {\n s.remove(n.typeParameters.start - offset, n.typeParameters.end - offset);\n }\n // Type arguments on calls\n if (n.typeArguments && n.typeArguments.start != null) {\n s.remove(n.typeArguments.start - offset, n.typeArguments.end - offset);\n }\n // `as` expressions: keep the expression, remove `as Type`\n if (n.type === \"TSAsExpression\" && n.expression) {\n s.remove(n.expression.end - offset, n.end - offset);\n }\n // Non-null assertion: `x!` → `x`\n if (n.type === \"TSNonNullExpression\" && n.expression) {\n s.remove(n.expression.end - offset, n.end - offset);\n }\n // Satisfies expression: `x satisfies Type` → `x`\n if (n.type === \"TSSatisfiesExpression\" && n.expression) {\n s.remove(n.expression.end - offset, n.end - offset);\n }\n}\n\n/**\n * Extract a clean JS source string from an AST node, stripping all\n * TypeScript annotations. Works on a copy so the main MagicString is\n * not mutated.\n */\nfunction extractCleanSource(s: MagicString, node: AcornNode): string {\n const offset = node.start;\n const source = new MagicString(s.slice(node.start, node.end));\n walk(node as any, {\n enter(n: any) {\n stripTypeAnnotationFromNode(source, n, offset);\n },\n });\n return source.toString();\n}\n\nfunction findLastNonEmptyNode(\n nodes: AcornNode[],\n s: MagicString,\n): AcornNode | null {\n for (let i = nodes.length - 1; i >= 0; i--) {\n const node = nodes[i];\n // Skip nodes that were fully removed\n const slice = s.slice(node.start, node.end).trim();\n if (slice === \"\" || slice === \";\") continue;\n return node;\n }\n return null;\n}\n\nfunction isExpression(node: AcornNode): boolean {\n return node.type === \"ExpressionStatement\";\n}\n","/**\n * Core REPL engine built on quickjs-emscripten (asyncify variant).\n *\n * Host async functions (backend I/O, PTC tools) are exposed as\n * promise-returning functions inside the QuickJS guest. Guest code\n * uses `await` to consume them, enabling real concurrency via\n * `Promise.all`, `Promise.race`, etc.\n *\n * We still use the asyncify WASM variant because `evalCodeAsync` is\n * required to drive promise resolution from the host side.\n *\n * ## Architecture\n *\n * `ReplSession` is a serializable handle that can live in LangGraph state.\n * It holds an `id` that keys into a static session map. The heavy QuickJS\n * runtime is lazily started on the first `.eval()` call, making the session\n * safe across graph interrupts and checkpointing.\n *\n * File writes inside the REPL are buffered (`pendingWrites`) and only\n * flushed to the backend after a script finishes executing. Call\n * `session.flushWrites(backend)` after eval to persist them.\n */\n\nimport { shouldInterruptAfterDeadline } from \"quickjs-emscripten\";\nimport type { QuickJSHandle } from \"quickjs-emscripten\";\nimport { newQuickJSAsyncWASMModuleFromVariant } from \"quickjs-emscripten-core\";\nimport type {\n QuickJSAsyncContext,\n QuickJSAsyncRuntime,\n} from \"quickjs-emscripten-core\";\nimport type { BackendProtocol } from \"deepagents\";\nimport type { StructuredToolInterface } from \"@langchain/core/tools\";\n\nimport type { ReplSessionOptions, ReplResult } from \"./types.js\";\nimport { toCamelCase } from \"./utils.js\";\nimport { transformForEval } from \"./transform.js\";\n\nexport const DEFAULT_MEMORY_LIMIT = 50 * 1024 * 1024;\nexport const DEFAULT_MAX_STACK_SIZE = 320 * 1024;\nexport const DEFAULT_EXECUTION_TIMEOUT = 30_000;\nexport const DEFAULT_SESSION_ID = \"__default__\";\n\nlet asyncModulePromise: Promise<any> | undefined;\n\nasync function getAsyncModule() {\n if (!asyncModulePromise) {\n asyncModulePromise = (async () => {\n const variant =\n await import(\"@jitl/quickjs-ng-wasmfile-release-asyncify\");\n return newQuickJSAsyncWASMModuleFromVariant(\n (variant.default ?? variant) as any,\n );\n })();\n }\n return asyncModulePromise;\n}\n\nexport interface PendingWrite {\n path: string;\n content: string;\n}\n\n/**\n * Sandboxed JavaScript REPL session backed by QuickJS WASM.\n *\n * Serializable — holds an `id` that keys into a static session map.\n * The QuickJS runtime is lazily started on the first `.eval()` call\n * and reconnected if a session with the same id already exists.\n * This makes it safe to store in LangGraph state across interrupts.\n *\n * File writes are buffered during execution and flushed via\n * `flushWrites(backend)` after eval completes.\n */\nexport class ReplSession {\n private static sessions = new Map<string, ReplSession>();\n\n readonly id: string;\n readonly pendingWrites: PendingWrite[] = [];\n\n private runtime: QuickJSAsyncRuntime | null = null;\n private context: QuickJSAsyncContext | null = null;\n private logs: string[] = [];\n private _options: ReplSessionOptions;\n\n private _backend: BackendProtocol | null = null;\n\n constructor(id: string, options: ReplSessionOptions = {}) {\n this.id = id;\n this._options = options;\n }\n\n get backend(): BackendProtocol | null {\n return this._backend;\n }\n\n set backend(b: BackendProtocol | null) {\n this._backend = b;\n }\n\n private async ensureStarted(): Promise<void> {\n if (this.runtime) return;\n\n const {\n memoryLimitBytes = DEFAULT_MEMORY_LIMIT,\n maxStackSizeBytes = DEFAULT_MAX_STACK_SIZE,\n backend,\n tools,\n } = this._options;\n\n const asyncModule = await getAsyncModule();\n const runtime: QuickJSAsyncRuntime = asyncModule.newRuntime();\n runtime.setMemoryLimit(memoryLimitBytes);\n runtime.setMaxStackSize(maxStackSizeBytes);\n\n const context: QuickJSAsyncContext = runtime.newContext();\n this.runtime = runtime;\n this.context = context;\n\n this.setupConsole();\n\n if (backend) {\n this._backend = backend;\n }\n this.injectVfs();\n if (tools && tools.length > 0) {\n this.injectTools(tools);\n }\n }\n\n /**\n * Get or create a session for the given id.\n *\n * Sessions are deduped by id — calling `getOrCreate` twice with the\n * same id returns the same instance. The QuickJS runtime is lazily\n * started on the first `.eval()` call.\n */\n static getOrCreate(\n id: string,\n options: ReplSessionOptions = {},\n ): ReplSession {\n const existing = ReplSession.sessions.get(id);\n if (existing) {\n if (options.backend) {\n existing._backend = options.backend;\n }\n return existing;\n }\n\n const session = new ReplSession(id, options);\n ReplSession.sessions.set(id, session);\n return session;\n }\n\n /**\n * Retrieve an existing session by id, or null if none exists.\n */\n static get(id: string): ReplSession | null {\n return ReplSession.sessions.get(id) ?? null;\n }\n\n /**\n * Evaluate code in this session.\n *\n * Lazily starts the QuickJS runtime on the first call. Code is\n * transformed via an AST pipeline that strips TypeScript syntax,\n * hoists top-level declarations to globalThis for cross-eval\n * persistence, auto-returns the last expression, and wraps in an\n * async IIFE.\n */\n async eval(code: string, timeoutMs: number): Promise<ReplResult> {\n await this.ensureStarted();\n const runtime = this.runtime!;\n const context = this.context!;\n\n this.logs.length = 0;\n\n if (timeoutMs >= 0) {\n runtime.setInterruptHandler(\n shouldInterruptAfterDeadline(Date.now() + timeoutMs),\n );\n } else {\n runtime.setInterruptHandler(() => false);\n }\n\n const transformed = transformForEval(code);\n const result = await context.evalCodeAsync(transformed);\n\n if (result.error) {\n const error = context.dump(result.error);\n result.error.dispose();\n return { ok: false, error, logs: [...this.logs] };\n }\n\n const promiseState = context.getPromiseState(result.value);\n\n if (promiseState.type === \"fulfilled\") {\n if (promiseState.notAPromise) {\n const value = context.dump(result.value);\n result.value.dispose();\n return { ok: true, value, logs: [...this.logs] };\n }\n const value = context.dump(promiseState.value);\n promiseState.value.dispose();\n result.value.dispose();\n return { ok: true, value, logs: [...this.logs] };\n }\n\n if (promiseState.type === \"rejected\") {\n const error = context.dump(promiseState.error);\n promiseState.error.dispose();\n result.value.dispose();\n return { ok: false, error, logs: [...this.logs] };\n }\n\n const noTimeout = timeoutMs < 0;\n const deadline = noTimeout ? Infinity : Date.now() + timeoutMs;\n while (noTimeout || Date.now() < deadline) {\n context.runtime.executePendingJobs();\n const state = context.getPromiseState(result.value);\n if (state.type === \"fulfilled\") {\n const value = context.dump(state.value);\n state.value.dispose();\n result.value.dispose();\n return { ok: true, value, logs: [...this.logs] };\n }\n if (state.type === \"rejected\") {\n const error = context.dump(state.error);\n state.error.dispose();\n result.value.dispose();\n return { ok: false, error, logs: [...this.logs] };\n }\n await new Promise((r) => setTimeout(r, 1));\n }\n\n result.value.dispose();\n return {\n ok: false,\n error: { message: \"Promise timed out — execution interrupted\" },\n logs: [...this.logs],\n };\n }\n\n async flushWrites(backend: BackendProtocol): Promise<void> {\n const writes = this.pendingWrites.splice(0);\n for (const { path, content } of writes) {\n await backend.write(path, content);\n }\n }\n\n dispose(): void {\n try {\n this.context?.dispose();\n } catch {\n /* may already be disposed */\n }\n try {\n this.runtime?.dispose();\n } catch {\n /* may already be disposed */\n }\n this.runtime = null;\n this.context = null;\n ReplSession.sessions.delete(this.id);\n }\n\n toJSON(): { id: string } {\n return { id: this.id };\n }\n\n static fromJSON(data: { id: string }): ReplSession {\n return ReplSession.sessions.get(data.id) ?? new ReplSession(data.id);\n }\n\n /**\n * Clear the static session cache. Useful for testing.\n * @internal\n */\n static clearCache(): void {\n for (const session of ReplSession.sessions.values()) {\n session.dispose();\n }\n ReplSession.sessions.clear();\n }\n\n private setupConsole(): void {\n const context = this.context!;\n const logs = this.logs;\n const consoleHandle = context.newObject();\n for (const method of [\"log\", \"warn\", \"error\", \"info\", \"debug\"] as const) {\n const fnHandle = context.newFunction(\n method,\n (...args: QuickJSHandle[]) => {\n const nativeArgs = args.map((a: QuickJSHandle) => context.dump(a));\n const formatted = nativeArgs\n .map((a: unknown) =>\n typeof a === \"object\" && a !== null\n ? JSON.stringify(a)\n : String(a),\n )\n .join(\" \");\n logs.push(\n method === \"log\" || method === \"info\" || method === \"debug\"\n ? formatted\n : `[${method}] ${formatted}`,\n );\n },\n );\n context.setProp(consoleHandle, method, fnHandle);\n fnHandle.dispose();\n }\n context.setProp(context.global, \"console\", consoleHandle);\n consoleHandle.dispose();\n }\n\n private injectVfs(): void {\n const context = this.context!;\n const getBackend = () => this._backend;\n const { pendingWrites } = this;\n\n const readFileHandle = context.newFunction(\n \"readFile\",\n (pathHandle: QuickJSHandle) => {\n const backend = getBackend();\n if (!backend) {\n const promise = context.newPromise();\n const err = context.newError(\"Backend not available\");\n promise.reject(err);\n err.dispose();\n promise.settled.then(context.runtime.executePendingJobs);\n return promise.handle;\n }\n const path = context.getString(pathHandle);\n const promise = context.newPromise();\n (async () => {\n try {\n const fileData = await backend.readRaw(path);\n const val = context.newString(fileData.content.join(\"\\n\"));\n promise.resolve(val);\n val.dispose();\n } catch {\n const err = context.newError(\n `ENOENT: no such file or directory '${path}'.`,\n );\n promise.reject(err);\n err.dispose();\n }\n promise.settled.then(context.runtime.executePendingJobs);\n })();\n return promise.handle;\n },\n );\n context.setProp(context.global, \"readFile\", readFileHandle);\n readFileHandle.dispose();\n\n const writeFileHandle = context.newFunction(\n \"writeFile\",\n (pathHandle: QuickJSHandle, contentHandle: QuickJSHandle) => {\n const path = context.getString(pathHandle);\n const content = context.getString(contentHandle);\n const promise = context.newPromise();\n pendingWrites.push({ path, content });\n promise.resolve(context.undefined);\n promise.settled.then(context.runtime.executePendingJobs);\n return promise.handle;\n },\n );\n context.setProp(context.global, \"writeFile\", writeFileHandle);\n writeFileHandle.dispose();\n }\n\n private injectTools(tools: StructuredToolInterface[]): void {\n const context = this.context!;\n const toolsNs = context.newObject();\n\n for (const t of tools) {\n const camelName = toCamelCase(t.name);\n const fnHandle = context.newFunction(\n camelName,\n (inputHandle: QuickJSHandle) => {\n const input = context.dump(inputHandle);\n const promise = context.newPromise();\n (async () => {\n try {\n const rawInput =\n typeof input === \"object\" && input !== null ? input : {};\n const result = await t.invoke(rawInput);\n const val = context.newString(\n typeof result === \"string\" ? result : JSON.stringify(result),\n );\n promise.resolve(val);\n val.dispose();\n } catch (e: unknown) {\n const msg =\n e != null && typeof (e as Error).message === \"string\"\n ? (e as Error).message\n : String(e);\n const err = context.newError(`Tool '${t.name}' failed: ${msg}`);\n promise.reject(err);\n err.dispose();\n }\n promise.settled.then(context.runtime.executePendingJobs);\n })();\n return promise.handle;\n },\n );\n context.setProp(toolsNs, camelName, fnHandle);\n fnHandle.dispose();\n }\n\n context.setProp(context.global, \"tools\", toolsNs);\n toolsNs.dispose();\n }\n}\n","/**\n * QuickJS REPL middleware for deepagents.\n *\n * Provides a `js_eval` tool that runs JavaScript in a WASM-sandboxed QuickJS\n * interpreter. Supports:\n * - Persistent state across evaluations (true REPL)\n * - VFS integration via readFile/writeFile\n * - Programmatic tool calling (PTC)\n */\n\nimport {\n createMiddleware,\n tool,\n type AgentMiddleware as _AgentMiddleware,\n} from \"langchain\";\nimport { z } from \"zod/v4\";\nimport type { StructuredToolInterface } from \"@langchain/core/tools\";\nimport { StateBackend, type BackendRuntime, resolveBackend } from \"deepagents\";\n\nimport dedent from \"dedent\";\nimport type { QuickJSMiddlewareOptions } from \"./types.js\";\nimport {\n ReplSession,\n DEFAULT_EXECUTION_TIMEOUT,\n DEFAULT_MEMORY_LIMIT,\n DEFAULT_MAX_STACK_SIZE,\n DEFAULT_SESSION_ID,\n} from \"./session.js\";\nimport {\n formatReplResult,\n toCamelCase,\n toolToTypeSignature,\n safeToJsonSchema,\n} from \"./utils.js\";\n\n/**\n * These type-only imports are required for TypeScript's type inference to work\n * correctly with the langchain/langgraph middleware system. Without them, certain\n * generic type parameters fail to resolve properly, causing runtime issues with\n * tool schemas and message types.\n */\nimport type * as _zodTypes from \"@langchain/core/utils/types\";\nimport type * as _zodMeta from \"@langchain/langgraph/zod\";\nimport type * as _messages from \"@langchain/core/messages\";\nimport {\n getCurrentTaskInput,\n LangGraphRunnableConfig,\n} from \"@langchain/langgraph\";\n\n/**\n * Backend-provided tools excluded from PTC by default.\n * These are redundant inside the REPL since VFS helpers (readFile/writeFile)\n * already cover file I/O against the agent's in-memory working set.\n */\nexport const DEFAULT_PTC_EXCLUDED_TOOLS = [\n \"ls\",\n \"read_file\",\n \"write_file\",\n \"edit_file\",\n \"glob\",\n \"grep\",\n \"execute\",\n] as const;\n\nconst REPL_SYSTEM_PROMPT = dedent`\n ## TypeScript/JavaScript REPL (\\`js_eval\\`)\n\n You have access to a sandboxed TypeScript/JavaScript REPL running in an isolated interpreter.\n TypeScript syntax (type annotations, interfaces, generics, \\`as\\` casts) is supported and stripped at evaluation time.\n Variables, functions, and closures persist across calls within the same session.\n\n ### Hard rules\n\n - **No network, no filesystem** — only the helpers below. Do not attempt \\`fetch\\`, \\`require\\`, or \\`import\\`.\n - **Cite your sources** — when reporting values from files, include the path and key/index so the user can verify.\n - **Use console.log()** for output — it is captured and returned. \\`console.warn()\\` and \\`console.error()\\` are also available.\n - **Reuse state from previous cells** — variables, functions, and results from earlier \\`js_eval\\` calls persist across calls. Reference them by name in follow-up cells instead of re-embedding data as inline JSON literals.\n\n ### First-time usage\n\n \\`\\`\\`typescript\n // Read a file from the agent's virtual filesystem\n const raw: string = await readFile(\"/data.json\");\n const data = JSON.parse(raw) as { n: number };\n console.log(data);\n\n // Write results back\n await writeFile(\"/output.txt\", JSON.stringify({ result: data.n }));\n \\`\\`\\`\n\n ### API Reference — built-in globals\n\n \\`\\`\\`typescript\n /**\n * Read a file from the agent's virtual filesystem. Throws if the file does not exist.\n */\n async readFile(path: string): Promise<string>\n\n /**\n * Write a file to the agent's virtual filesystem.\n */\n async writeFile(path: string, content: string): Promise<void>\n \\`\\`\\`\n\n ### Limitations\n\n - ES2023+ syntax with TypeScript support. No Node.js APIs, no \\`require\\`, no \\`import\\`.\n - Output is truncated beyond a fixed character limit — be selective about what you log.\n - Execution timeout per call (default 30 s).\n`;\n\n/**\n * Generate the PTC API Reference section for the system prompt.\n */\nexport async function generatePtcPrompt(\n tools: StructuredToolInterface[],\n): Promise<string> {\n if (tools.length === 0) return \"\";\n\n const signatures = await Promise.all(\n tools.map((t) => {\n const jsonSchema = t.schema ? safeToJsonSchema(t.schema) : undefined;\n return toolToTypeSignature(\n toCamelCase(t.name),\n t.description,\n jsonSchema,\n );\n }),\n );\n\n return dedent`\n\n ### API Reference — \\`tools\\` namespace\n\n The following agent tools are callable as async functions inside the REPL.\n Each takes a single object argument and returns a Promise that resolves to a string.\n Use \\`await\\` to call them. Promise APIs like \\`Promise.all\\` are also available.\n\n **Example usage:**\n \\`\\`\\`javascript\n // Call a tool\n const result = await tools.searchWeb({ query: \"QuickJS tutorial\" });\n console.log(result);\n\n // Concurrent calls\n const [a, b] = await Promise.all([\n tools.fetchData({ url: \"https://api.example.com/a\" }),\n tools.fetchData({ url: \"https://api.example.com/b\" }),\n ]);\n \\`\\`\\`\n\n **Available functions:**\n \\`\\`\\`typescript\n ${signatures.join(\"\\n\\n\")}\n \\`\\`\\`\n `;\n}\n\n/**\n * Create the QuickJS REPL middleware.\n */\nexport function createQuickJSMiddleware(\n options: QuickJSMiddlewareOptions = {},\n) {\n const {\n backend = (runtime: BackendRuntime) => new StateBackend(runtime),\n ptc = false,\n memoryLimitBytes = DEFAULT_MEMORY_LIMIT,\n maxStackSizeBytes = DEFAULT_MAX_STACK_SIZE,\n executionTimeoutMs = DEFAULT_EXECUTION_TIMEOUT,\n systemPrompt: customSystemPrompt = null,\n } = options;\n\n const usePtc = ptc !== false;\n const baseSystemPrompt = customSystemPrompt || REPL_SYSTEM_PROMPT;\n\n let cachedPtcPrompt: string | null = null;\n\n let ptcTools: StructuredToolInterface[] = [];\n\n function filterToolsForPtc(\n allTools: StructuredToolInterface[],\n ): StructuredToolInterface[] {\n if (ptc === false) return [];\n\n const candidates = allTools.filter((t) => t.name !== \"js_eval\");\n\n if (ptc === true) {\n const excluded = new Set<string>(DEFAULT_PTC_EXCLUDED_TOOLS);\n return candidates.filter((t) => !excluded.has(t.name));\n }\n\n if (Array.isArray(ptc)) {\n const included = new Set(ptc);\n return candidates.filter((t) => included.has(t.name));\n }\n\n if (\"include\" in ptc) {\n const included = new Set(ptc.include);\n return candidates.filter((t) => included.has(t.name));\n }\n\n if (\"exclude\" in ptc) {\n const excluded = new Set([...DEFAULT_PTC_EXCLUDED_TOOLS, ...ptc.exclude]);\n return candidates.filter((t) => !excluded.has(t.name));\n }\n\n return [];\n }\n\n const jsEvalTool = tool(\n async (input, config: LangGraphRunnableConfig) => {\n const threadId = config.configurable?.thread_id || DEFAULT_SESSION_ID;\n\n const runtime: BackendRuntime = {\n ...config,\n state: getCurrentTaskInput(config) || {},\n } as BackendRuntime;\n const resolvedBackend = await resolveBackend(backend, runtime);\n\n const session = ReplSession.getOrCreate(threadId, {\n memoryLimitBytes,\n maxStackSizeBytes,\n backend: resolvedBackend,\n tools: ptcTools,\n });\n\n const result = await session.eval(input.code, executionTimeoutMs);\n await session.flushWrites(resolvedBackend);\n\n return formatReplResult(result);\n },\n {\n name: \"js_eval\",\n description: dedent`\n Evaluate TypeScript/JavaScript code in a sandboxed REPL. State persists across calls.\n Use readFile(path) and writeFile(path, content) for file access.\n Use console.log() for output. Returns the result of the last expression.\n `,\n schema: z.object({\n code: z\n .string()\n .describe(\n \"TypeScript/JavaScript code to evaluate in the sandboxed REPL\",\n ),\n }),\n },\n );\n\n return createMiddleware({\n name: \"QuickJSMiddleware\",\n tools: [jsEvalTool],\n wrapModelCall: async (request, handler) => {\n const agentTools = (request.tools || []) as StructuredToolInterface[];\n ptcTools = usePtc ? filterToolsForPtc(agentTools) : [];\n\n if (ptcTools.length > 0 && !cachedPtcPrompt) {\n cachedPtcPrompt = await generatePtcPrompt(ptcTools);\n }\n\n const systemMessage = request.systemMessage\n .concat(baseSystemPrompt)\n .concat(cachedPtcPrompt || \"\");\n return handler({ ...request, systemMessage });\n },\n });\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../src/utils.ts","../src/transform.ts","../src/session.ts","../src/middleware.ts"],"sourcesContent":["import { compile } from \"json-schema-to-typescript\";\nimport { toJsonSchema } from \"@langchain/core/utils/json_schema\";\nimport dedent from \"dedent\";\nimport type { ReplResult } from \"./types.js\";\n\n/**\n * Convert a snake_case or kebab-case string to camelCase.\n */\nexport function toCamelCase(name: string): string {\n return name.replace(/[-_]([a-z])/g, (_, c) => c.toUpperCase());\n}\n\n/**\n * Recursively collect all string values from an object, array, or primitive.\n */\nexport function collectStrings(obj: unknown): string[] {\n const result: string[] = [];\n function walk(val: unknown) {\n if (typeof val === \"string\") {\n result.push(val);\n } else if (Array.isArray(val)) {\n for (const item of val) walk(item);\n } else if (typeof val === \"object\" && val !== null) {\n for (const v of Object.values(val)) walk(v);\n }\n }\n walk(obj);\n return result;\n}\n\n/**\n * Format the result of a REPL evaluation for the agent.\n */\nexport function formatReplResult(result: ReplResult): string {\n const parts: string[] = [];\n\n if (result.logs.length > 0) {\n parts.push(result.logs.join(\"\\n\"));\n }\n\n if (result.ok) {\n if (result.value !== undefined) {\n const formatted =\n typeof result.value === \"string\"\n ? result.value\n : JSON.stringify(result.value, null, 2);\n parts.push(`→ ${formatted}`);\n }\n } else if (result.error) {\n const errName = result.error.name || \"Error\";\n const errMsg = result.error.message || \"Unknown error\";\n parts.push(`${errName}: ${errMsg}`);\n if (result.error.stack) {\n parts.push(result.error.stack);\n }\n }\n\n return parts.join(\"\\n\") || \"(no output)\";\n}\n\nexport function safeToJsonSchema(\n schema: unknown,\n): Record<string, unknown> | undefined {\n try {\n return toJsonSchema(schema as Parameters<typeof toJsonSchema>[0]) as Record<\n string,\n unknown\n >;\n } catch {\n return undefined;\n }\n}\n\nasync function schemaToInterface(\n jsonSchema: Record<string, unknown>,\n interfaceName: string,\n): Promise<string> {\n const compiled = await compile(\n { ...jsonSchema, additionalProperties: false },\n interfaceName,\n { bannerComment: \"\", additionalProperties: false },\n );\n return compiled.replace(/^export /, \"\").trimEnd();\n}\n\nexport function capitalize(s: string): string {\n return s.charAt(0).toUpperCase() + s.slice(1);\n}\n\nexport async function toolToTypeSignature(\n name: string,\n description: string,\n jsonSchema: Record<string, unknown> | undefined,\n): Promise<string> {\n const inputType = `${capitalize(name)}Input`;\n\n if (!jsonSchema || !jsonSchema.properties) {\n return dedent`\n /**\n * ${description}\n */\n async tools.${name}(input: Record<string, unknown>): Promise<string>\n `;\n }\n\n const iface = await schemaToInterface(jsonSchema, inputType);\n return dedent`\n ${iface}\n\n /**\n * ${description}\n */\n async tools.${name}(input: ${inputType}): Promise<string>\n `;\n}\n","/**\n * AST-based code transform pipeline for the REPL.\n *\n * Transforms TypeScript/JavaScript code into plain JS that can be\n * evaluated inside QuickJS with proper state persistence:\n *\n * 1. Parse with acorn + acorn-typescript (handles TS syntax)\n * 2. Strip TypeScript-only nodes (type annotations, interfaces, etc.)\n * 3. Hoist top-level declarations to globalThis for cross-eval persistence\n * 4. Auto-return the last expression\n * 5. Wrap in async IIFE so top-level await works\n */\n\nimport { Parser } from \"acorn\";\nimport { tsPlugin } from \"@sveltejs/acorn-typescript\";\nimport { walk } from \"estree-walker\";\nimport MagicString from \"magic-string\";\nimport type {\n Node,\n Identifier,\n VariableDeclaration as EstreeVariableDeclaration,\n VariableDeclarator as EstreeVariableDeclarator,\n} from \"estree\";\n\nconst TSParser = Parser.extend(tsPlugin());\n\ntype AcornNode = Node & { start: number; end: number };\ntype AcornExpressionStatement = AcornNode & {\n type: \"ExpressionStatement\";\n expression: AcornNode;\n};\ntype AcornVariableDeclaration = EstreeVariableDeclaration & {\n start: number;\n end: number;\n declarations: AcornVariableDeclarator[];\n};\ntype AcornVariableDeclarator = EstreeVariableDeclarator & {\n start: number;\n end: number;\n id: AcornNode;\n init: AcornNode | null;\n};\n\n/**\n * Transform code for REPL evaluation.\n *\n * - Strips TypeScript syntax\n * - Hoists top-level variable declarations to globalThis\n * - Auto-returns the last expression\n * - Wraps in async IIFE for top-level await support\n */\nexport function transformForEval(code: string): string {\n let ast: AcornNode;\n try {\n ast = TSParser.parse(code, {\n ecmaVersion: \"latest\" as any,\n sourceType: \"module\",\n locations: true,\n }) as unknown as AcornNode;\n } catch {\n // If parsing fails, return the code as-is and let QuickJS report the error\n return `(async () => {\\n${code}\\n})()`;\n }\n\n const s = new MagicString(code);\n const program = ast as unknown as { body: AcornNode[] };\n const topLevelNodes = program.body;\n for (let i = 0; i < topLevelNodes.length; i++) {\n const node = topLevelNodes[i];\n\n // Remove TypeScript-only top-level declarations\n if (isTSOnlyNode(node)) {\n s.remove(node.start, node.end);\n continue;\n }\n\n // Remove import/export declarations (not supported in QuickJS eval)\n if (\n node.type === \"ImportDeclaration\" ||\n node.type === \"ExportNamedDeclaration\" ||\n node.type === \"ExportDefaultDeclaration\" ||\n node.type === \"ExportAllDeclaration\"\n ) {\n s.remove(node.start, node.end);\n continue;\n }\n\n // Hoist top-level variable declarations\n if (node.type === \"VariableDeclaration\") {\n hoistDeclaration(s, node as unknown as AcornVariableDeclaration);\n continue;\n }\n\n // Hoist function/class declarations to globalThis for cross-eval persistence\n if (\n node.type === \"FunctionDeclaration\" ||\n node.type === \"ClassDeclaration\"\n ) {\n stripTypeAnnotations(s, node);\n const name = (node as any).id?.name;\n if (name) {\n s.appendRight(node.end, `\\nglobalThis.${name} = ${name};`);\n }\n continue;\n }\n }\n\n // Strip type annotations from within expressions/statements\n for (const node of topLevelNodes) {\n if (isTSOnlyNode(node)) continue;\n if (\n node.type === \"ImportDeclaration\" ||\n node.type === \"ExportNamedDeclaration\" ||\n node.type === \"ExportDefaultDeclaration\" ||\n node.type === \"ExportAllDeclaration\"\n )\n continue;\n if (node.type !== \"VariableDeclaration\") {\n walk(node as any, {\n enter(n: any) {\n stripTypeAnnotationFromNode(s, n);\n },\n });\n }\n }\n\n // Auto-return the last expression. We insert `return (` before the\n // ExpressionStatement (to preserve any grouping parens like `({...})`),\n // but close `)` after the inner expression — not after the statement —\n // so any trailing semicolon stays outside: `return (expr);` not `return (expr;)`.\n const lastNode = findLastNonEmptyNode(topLevelNodes, s);\n if (lastNode && isExpression(lastNode)) {\n const { expression } = lastNode as AcornExpressionStatement;\n s.prependLeft(lastNode.start, \"return (\");\n s.appendRight(expression.end, \")\");\n }\n\n // Wrap in async IIFE\n s.prepend(\"(async () => {\\n\");\n s.append(\"\\n})()\");\n\n return s.toString();\n}\n\nfunction isTSOnlyNode(node: AcornNode): boolean {\n const t = node.type as string;\n return (\n t === \"TSTypeAliasDeclaration\" ||\n t === \"TSInterfaceDeclaration\" ||\n t === \"TSEnumDeclaration\" ||\n t === \"TSModuleDeclaration\" ||\n t === \"TSDeclareFunction\" ||\n t.startsWith(\"TS\")\n );\n}\n\n/**\n * Rewrite a top-level VariableDeclaration to globalThis assignments.\n *\n * `const x = 1, y = 2` → `globalThis.x = 1; globalThis.y = 2`\n *\n */\nfunction hoistDeclaration(\n s: MagicString,\n decl: AcornVariableDeclaration,\n): void {\n const parts: string[] = [];\n\n for (const d of decl.declarations) {\n const id = d.id as AcornNode;\n if (id.type === \"Identifier\") {\n const initCode = d.init ? extractCleanInit(s, d) : \"undefined\";\n parts.push(\n `globalThis.${(id as unknown as Identifier).name} = ${initCode}`,\n );\n } else if (id.type === \"ObjectPattern\" || id.type === \"ArrayPattern\") {\n const bindings = extractBindingNames(d.id as any);\n const initCode = d.init ? extractCleanInit(s, d) : \"undefined\";\n const patternCode = extractCleanSource(s, d.id as AcornNode);\n parts.push(`var ${patternCode} = ${initCode}`);\n for (const name of bindings) {\n parts.push(`globalThis.${name} = ${name}`);\n }\n }\n }\n\n s.overwrite(decl.start, decl.end, parts.join(\"; \") + \";\");\n}\n\n/**\n * Extract the initializer code, stripping TypeScript annotations from\n * within the expression (e.g. `as Type`, generics, parameter types in\n * arrow functions).\n */\nfunction extractCleanInit(s: MagicString, d: AcornVariableDeclarator): string {\n if (!d.init) return \"undefined\";\n return extractCleanSource(s, d.init as AcornNode);\n}\n\nfunction extractBindingNames(pattern: any): string[] {\n const names: string[] = [];\n if (pattern.type === \"Identifier\") {\n if (pattern.name) names.push(pattern.name);\n } else if (pattern.type === \"ObjectPattern\") {\n for (const prop of pattern.properties || []) {\n if (prop.type === \"RestElement\") {\n names.push(...extractBindingNames(prop.argument));\n } else {\n names.push(...extractBindingNames(prop.value));\n }\n }\n } else if (pattern.type === \"ArrayPattern\") {\n for (const el of pattern.elements || []) {\n if (el) names.push(...extractBindingNames(el));\n }\n } else if (pattern.type === \"RestElement\") {\n names.push(...extractBindingNames(pattern.argument));\n } else if (pattern.type === \"AssignmentPattern\") {\n names.push(...extractBindingNames(pattern.left));\n }\n return names;\n}\n\nfunction stripTypeAnnotations(s: MagicString, node: AcornNode): void {\n walk(node as any, {\n enter(n: any) {\n stripTypeAnnotationFromNode(s, n);\n },\n });\n}\n\nfunction stripTypeAnnotationFromNode(s: MagicString, n: any, offset = 0): void {\n // Type annotations on parameters, variables, return types\n if (n.typeAnnotation && n.typeAnnotation.start != null) {\n s.remove(n.typeAnnotation.start - offset, n.typeAnnotation.end - offset);\n }\n // Return type on functions\n if (n.returnType && n.returnType.start != null) {\n s.remove(n.returnType.start - offset, n.returnType.end - offset);\n }\n // Type parameters (generics)\n if (n.typeParameters && n.typeParameters.start != null) {\n s.remove(n.typeParameters.start - offset, n.typeParameters.end - offset);\n }\n // Type arguments on calls\n if (n.typeArguments && n.typeArguments.start != null) {\n s.remove(n.typeArguments.start - offset, n.typeArguments.end - offset);\n }\n // `as` expressions: keep the expression, remove `as Type`\n if (n.type === \"TSAsExpression\" && n.expression) {\n s.remove(n.expression.end - offset, n.end - offset);\n }\n // Non-null assertion: `x!` → `x`\n if (n.type === \"TSNonNullExpression\" && n.expression) {\n s.remove(n.expression.end - offset, n.end - offset);\n }\n // Satisfies expression: `x satisfies Type` → `x`\n if (n.type === \"TSSatisfiesExpression\" && n.expression) {\n s.remove(n.expression.end - offset, n.end - offset);\n }\n}\n\n/**\n * Extract a clean JS source string from an AST node, stripping all\n * TypeScript annotations. Works on a copy so the main MagicString is\n * not mutated.\n */\nfunction extractCleanSource(s: MagicString, node: AcornNode): string {\n const offset = node.start;\n const source = new MagicString(s.slice(node.start, node.end));\n walk(node as any, {\n enter(n: any) {\n stripTypeAnnotationFromNode(source, n, offset);\n },\n });\n return source.toString();\n}\n\nfunction findLastNonEmptyNode(\n nodes: AcornNode[],\n s: MagicString,\n): AcornNode | null {\n for (let i = nodes.length - 1; i >= 0; i--) {\n const node = nodes[i];\n // Skip nodes that were fully removed\n const slice = s.slice(node.start, node.end).trim();\n if (slice === \"\" || slice === \";\") continue;\n return node;\n }\n return null;\n}\n\nfunction isExpression(node: AcornNode): boolean {\n return node.type === \"ExpressionStatement\";\n}\n","/**\n * Core REPL engine built on quickjs-emscripten (asyncify variant).\n *\n * Host async functions (backend I/O, PTC tools) are exposed as\n * promise-returning functions inside the QuickJS guest. Guest code\n * uses `await` to consume them, enabling real concurrency via\n * `Promise.all`, `Promise.race`, etc.\n *\n * We still use the asyncify WASM variant because `evalCodeAsync` is\n * required to drive promise resolution from the host side.\n *\n * ## Architecture\n *\n * `ReplSession` is a serializable handle that can live in LangGraph state.\n * It holds an `id` that keys into a static session map. The heavy QuickJS\n * runtime is lazily started on the first `.eval()` call, making the session\n * safe across graph interrupts and checkpointing.\n *\n * File writes inside the REPL are buffered (`pendingWrites`) and only\n * flushed to the backend after a script finishes executing. Call\n * `session.flushWrites(backend)` after eval to persist them.\n */\n\nimport { shouldInterruptAfterDeadline } from \"quickjs-emscripten\";\nimport type { QuickJSHandle } from \"quickjs-emscripten\";\nimport { newQuickJSAsyncWASMModuleFromVariant } from \"quickjs-emscripten-core\";\nimport type {\n QuickJSAsyncContext,\n QuickJSAsyncRuntime,\n} from \"quickjs-emscripten-core\";\nimport type { AnyBackendProtocol, BackendProtocolV2 } from \"deepagents\";\nimport { adaptBackendProtocol } from \"deepagents\";\nimport type { StructuredToolInterface } from \"@langchain/core/tools\";\n\nimport type { ReplSessionOptions, ReplResult } from \"./types.js\";\nimport { toCamelCase } from \"./utils.js\";\nimport { transformForEval } from \"./transform.js\";\n\nexport const DEFAULT_MEMORY_LIMIT = 50 * 1024 * 1024;\nexport const DEFAULT_MAX_STACK_SIZE = 320 * 1024;\nexport const DEFAULT_EXECUTION_TIMEOUT = 30_000;\nexport const DEFAULT_SESSION_ID = \"__default__\";\n\nlet asyncModulePromise: Promise<any> | undefined;\n\nasync function getAsyncModule() {\n if (!asyncModulePromise) {\n asyncModulePromise = (async () => {\n const variant =\n await import(\"@jitl/quickjs-ng-wasmfile-release-asyncify\");\n return newQuickJSAsyncWASMModuleFromVariant(\n (variant.default ?? variant) as any,\n );\n })();\n }\n return asyncModulePromise;\n}\n\nexport interface PendingWrite {\n path: string;\n content: string;\n}\n\n/**\n * Sandboxed JavaScript REPL session backed by QuickJS WASM.\n *\n * Serializable — holds an `id` that keys into a static session map.\n * The QuickJS runtime is lazily started on the first `.eval()` call\n * and reconnected if a session with the same id already exists.\n * This makes it safe to store in LangGraph state across interrupts.\n *\n * File writes are buffered during execution and flushed via\n * `flushWrites(backend)` after eval completes.\n */\nexport class ReplSession {\n private static sessions = new Map<string, ReplSession>();\n\n readonly id: string;\n readonly pendingWrites: PendingWrite[] = [];\n\n private runtime: QuickJSAsyncRuntime | null = null;\n private context: QuickJSAsyncContext | null = null;\n private logs: string[] = [];\n private _options: ReplSessionOptions;\n\n private _backend: BackendProtocolV2 | null = null;\n\n constructor(id: string, options: ReplSessionOptions = {}) {\n this.id = id;\n this._options = options;\n }\n\n get backend(): BackendProtocolV2 | null {\n return this._backend;\n }\n\n set backend(b: AnyBackendProtocol | null) {\n this._backend = b ? adaptBackendProtocol(b) : null;\n }\n\n private async ensureStarted(): Promise<void> {\n if (this.runtime) return;\n\n const {\n memoryLimitBytes = DEFAULT_MEMORY_LIMIT,\n maxStackSizeBytes = DEFAULT_MAX_STACK_SIZE,\n backend,\n tools,\n } = this._options;\n\n const asyncModule = await getAsyncModule();\n const runtime: QuickJSAsyncRuntime = asyncModule.newRuntime();\n runtime.setMemoryLimit(memoryLimitBytes);\n runtime.setMaxStackSize(maxStackSizeBytes);\n\n const context: QuickJSAsyncContext = runtime.newContext();\n this.runtime = runtime;\n this.context = context;\n\n this.setupConsole();\n\n if (backend) {\n this._backend = adaptBackendProtocol(backend);\n }\n this.injectVfs();\n if (tools && tools.length > 0) {\n this.injectTools(tools);\n }\n }\n\n /**\n * Get or create a session for the given id.\n *\n * Sessions are deduped by id — calling `getOrCreate` twice with the\n * same id returns the same instance. The QuickJS runtime is lazily\n * started on the first `.eval()` call.\n */\n static getOrCreate(\n id: string,\n options: ReplSessionOptions = {},\n ): ReplSession {\n const existing = ReplSession.sessions.get(id);\n if (existing) {\n if (options.backend) {\n existing._backend = adaptBackendProtocol(options.backend);\n }\n return existing;\n }\n\n const session = new ReplSession(id, options);\n ReplSession.sessions.set(id, session);\n return session;\n }\n\n /**\n * Retrieve an existing session by id, or null if none exists.\n */\n static get(id: string): ReplSession | null {\n return ReplSession.sessions.get(id) ?? null;\n }\n\n /**\n * Evaluate code in this session.\n *\n * Lazily starts the QuickJS runtime on the first call. Code is\n * transformed via an AST pipeline that strips TypeScript syntax,\n * hoists top-level declarations to globalThis for cross-eval\n * persistence, auto-returns the last expression, and wraps in an\n * async IIFE.\n */\n async eval(code: string, timeoutMs: number): Promise<ReplResult> {\n await this.ensureStarted();\n const runtime = this.runtime!;\n const context = this.context!;\n\n this.logs.length = 0;\n\n if (timeoutMs >= 0) {\n runtime.setInterruptHandler(\n shouldInterruptAfterDeadline(Date.now() + timeoutMs),\n );\n } else {\n runtime.setInterruptHandler(() => false);\n }\n\n const transformed = transformForEval(code);\n const result = await context.evalCodeAsync(transformed);\n\n if (result.error) {\n const error = context.dump(result.error);\n result.error.dispose();\n return { ok: false, error, logs: [...this.logs] };\n }\n\n const promiseState = context.getPromiseState(result.value);\n\n if (promiseState.type === \"fulfilled\") {\n if (promiseState.notAPromise) {\n const value = context.dump(result.value);\n result.value.dispose();\n return { ok: true, value, logs: [...this.logs] };\n }\n const value = context.dump(promiseState.value);\n promiseState.value.dispose();\n result.value.dispose();\n return { ok: true, value, logs: [...this.logs] };\n }\n\n if (promiseState.type === \"rejected\") {\n const error = context.dump(promiseState.error);\n promiseState.error.dispose();\n result.value.dispose();\n return { ok: false, error, logs: [...this.logs] };\n }\n\n const noTimeout = timeoutMs < 0;\n const deadline = noTimeout ? Infinity : Date.now() + timeoutMs;\n while (noTimeout || Date.now() < deadline) {\n context.runtime.executePendingJobs();\n const state = context.getPromiseState(result.value);\n if (state.type === \"fulfilled\") {\n const value = context.dump(state.value);\n state.value.dispose();\n result.value.dispose();\n return { ok: true, value, logs: [...this.logs] };\n }\n if (state.type === \"rejected\") {\n const error = context.dump(state.error);\n state.error.dispose();\n result.value.dispose();\n return { ok: false, error, logs: [...this.logs] };\n }\n await new Promise((r) => setTimeout(r, 1));\n }\n\n result.value.dispose();\n return {\n ok: false,\n error: { message: \"Promise timed out — execution interrupted\" },\n logs: [...this.logs],\n };\n }\n\n async flushWrites(backend: AnyBackendProtocol): Promise<void> {\n const adapted = adaptBackendProtocol(backend);\n const writes = this.pendingWrites.splice(0);\n for (const { path, content } of writes) {\n await adapted.write(path, content);\n }\n }\n\n dispose(): void {\n try {\n this.context?.dispose();\n } catch {\n /* may already be disposed */\n }\n try {\n this.runtime?.dispose();\n } catch {\n /* may already be disposed */\n }\n this.runtime = null;\n this.context = null;\n ReplSession.sessions.delete(this.id);\n }\n\n toJSON(): { id: string } {\n return { id: this.id };\n }\n\n static fromJSON(data: { id: string }): ReplSession {\n return ReplSession.sessions.get(data.id) ?? new ReplSession(data.id);\n }\n\n /**\n * Clear the static session cache. Useful for testing.\n * @internal\n */\n static clearCache(): void {\n for (const session of ReplSession.sessions.values()) {\n session.dispose();\n }\n ReplSession.sessions.clear();\n }\n\n private setupConsole(): void {\n const context = this.context!;\n const logs = this.logs;\n const consoleHandle = context.newObject();\n for (const method of [\"log\", \"warn\", \"error\", \"info\", \"debug\"] as const) {\n const fnHandle = context.newFunction(\n method,\n (...args: QuickJSHandle[]) => {\n const nativeArgs = args.map((a: QuickJSHandle) => context.dump(a));\n const formatted = nativeArgs\n .map((a: unknown) =>\n typeof a === \"object\" && a !== null\n ? JSON.stringify(a)\n : String(a),\n )\n .join(\" \");\n logs.push(\n method === \"log\" || method === \"info\" || method === \"debug\"\n ? formatted\n : `[${method}] ${formatted}`,\n );\n },\n );\n context.setProp(consoleHandle, method, fnHandle);\n fnHandle.dispose();\n }\n context.setProp(context.global, \"console\", consoleHandle);\n consoleHandle.dispose();\n }\n\n private injectVfs(): void {\n const context = this.context!;\n const getBackend = () => this._backend;\n const { pendingWrites } = this;\n\n const readFileHandle = context.newFunction(\n \"readFile\",\n (pathHandle: QuickJSHandle) => {\n const backend = getBackend();\n if (!backend) {\n const promise = context.newPromise();\n const err = context.newError(\"Backend not available\");\n promise.reject(err);\n err.dispose();\n promise.settled.then(context.runtime.executePendingJobs);\n return promise.handle;\n }\n const path = context.getString(pathHandle);\n const promise = context.newPromise();\n (async () => {\n try {\n const result = await backend.readRaw(path);\n if (result.error || !result.data) {\n const err = context.newError(\n `ENOENT: no such file or directory '${path}'.`,\n );\n promise.reject(err);\n err.dispose();\n } else {\n const content = Array.isArray(result.data.content)\n ? result.data.content.join(\"\\n\")\n : typeof result.data.content === \"string\"\n ? result.data.content\n : null;\n if (content === null) {\n const err = context.newError(\n `Cannot read binary file '${path}' as text.`,\n );\n promise.reject(err);\n err.dispose();\n return;\n }\n const val = context.newString(content);\n promise.resolve(val);\n val.dispose();\n }\n } catch {\n const err = context.newError(\n `ENOENT: no such file or directory '${path}'.`,\n );\n promise.reject(err);\n err.dispose();\n }\n promise.settled.then(context.runtime.executePendingJobs);\n })();\n return promise.handle;\n },\n );\n context.setProp(context.global, \"readFile\", readFileHandle);\n readFileHandle.dispose();\n\n const writeFileHandle = context.newFunction(\n \"writeFile\",\n (pathHandle: QuickJSHandle, contentHandle: QuickJSHandle) => {\n const path = context.getString(pathHandle);\n const content = context.getString(contentHandle);\n const promise = context.newPromise();\n pendingWrites.push({ path, content });\n promise.resolve(context.undefined);\n promise.settled.then(context.runtime.executePendingJobs);\n return promise.handle;\n },\n );\n context.setProp(context.global, \"writeFile\", writeFileHandle);\n writeFileHandle.dispose();\n }\n\n private injectTools(tools: StructuredToolInterface[]): void {\n const context = this.context!;\n const toolsNs = context.newObject();\n\n for (const t of tools) {\n const camelName = toCamelCase(t.name);\n const fnHandle = context.newFunction(\n camelName,\n (inputHandle: QuickJSHandle) => {\n const input = context.dump(inputHandle);\n const promise = context.newPromise();\n (async () => {\n try {\n const rawInput =\n typeof input === \"object\" && input !== null ? input : {};\n const result = await t.invoke(rawInput);\n const val = context.newString(\n typeof result === \"string\" ? result : JSON.stringify(result),\n );\n promise.resolve(val);\n val.dispose();\n } catch (e: unknown) {\n const msg =\n e != null && typeof (e as Error).message === \"string\"\n ? (e as Error).message\n : String(e);\n const err = context.newError(`Tool '${t.name}' failed: ${msg}`);\n promise.reject(err);\n err.dispose();\n }\n promise.settled.then(context.runtime.executePendingJobs);\n })();\n return promise.handle;\n },\n );\n context.setProp(toolsNs, camelName, fnHandle);\n fnHandle.dispose();\n }\n\n context.setProp(context.global, \"tools\", toolsNs);\n toolsNs.dispose();\n }\n}\n","/**\n * QuickJS REPL middleware for deepagents.\n *\n * Provides a `js_eval` tool that runs JavaScript in a WASM-sandboxed QuickJS\n * interpreter. Supports:\n * - Persistent state across evaluations (true REPL)\n * - VFS integration via readFile/writeFile\n * - Programmatic tool calling (PTC)\n */\n\nimport {\n createMiddleware,\n tool,\n type AgentMiddleware as _AgentMiddleware,\n} from \"langchain\";\nimport { z } from \"zod/v4\";\nimport type { StructuredToolInterface } from \"@langchain/core/tools\";\nimport { StateBackend, type BackendRuntime, resolveBackend } from \"deepagents\";\n\nimport dedent from \"dedent\";\nimport type { QuickJSMiddlewareOptions } from \"./types.js\";\nimport {\n ReplSession,\n DEFAULT_EXECUTION_TIMEOUT,\n DEFAULT_MEMORY_LIMIT,\n DEFAULT_MAX_STACK_SIZE,\n DEFAULT_SESSION_ID,\n} from \"./session.js\";\nimport {\n formatReplResult,\n toCamelCase,\n toolToTypeSignature,\n safeToJsonSchema,\n} from \"./utils.js\";\n\n/**\n * These type-only imports are required for TypeScript's type inference to work\n * correctly with the langchain/langgraph middleware system. Without them, certain\n * generic type parameters fail to resolve properly, causing runtime issues with\n * tool schemas and message types.\n */\nimport type * as _zodTypes from \"@langchain/core/utils/types\";\nimport type * as _zodMeta from \"@langchain/langgraph/zod\";\nimport type * as _messages from \"@langchain/core/messages\";\nimport {\n getCurrentTaskInput,\n LangGraphRunnableConfig,\n} from \"@langchain/langgraph\";\n\n/**\n * Backend-provided tools excluded from PTC by default.\n * These are redundant inside the REPL since VFS helpers (readFile/writeFile)\n * already cover file I/O against the agent's in-memory working set.\n */\nexport const DEFAULT_PTC_EXCLUDED_TOOLS = [\n \"ls\",\n \"read_file\",\n \"write_file\",\n \"edit_file\",\n \"glob\",\n \"grep\",\n \"execute\",\n] as const;\n\nconst REPL_SYSTEM_PROMPT = dedent`\n ## TypeScript/JavaScript REPL (\\`js_eval\\`)\n\n You have access to a sandboxed TypeScript/JavaScript REPL running in an isolated interpreter.\n TypeScript syntax (type annotations, interfaces, generics, \\`as\\` casts) is supported and stripped at evaluation time.\n Variables, functions, and closures persist across calls within the same session.\n\n ### Hard rules\n\n - **No network, no filesystem** — only the helpers below. Do not attempt \\`fetch\\`, \\`require\\`, or \\`import\\`.\n - **Cite your sources** — when reporting values from files, include the path and key/index so the user can verify.\n - **Use console.log()** for output — it is captured and returned. \\`console.warn()\\` and \\`console.error()\\` are also available.\n - **Reuse state from previous cells** — variables, functions, and results from earlier \\`js_eval\\` calls persist across calls. Reference them by name in follow-up cells instead of re-embedding data as inline JSON literals.\n\n ### First-time usage\n\n \\`\\`\\`typescript\n // Read a file from the agent's virtual filesystem\n const raw: string = await readFile(\"/data.json\");\n const data = JSON.parse(raw) as { n: number };\n console.log(data);\n\n // Write results back\n await writeFile(\"/output.txt\", JSON.stringify({ result: data.n }));\n \\`\\`\\`\n\n ### API Reference — built-in globals\n\n \\`\\`\\`typescript\n /**\n * Read a file from the agent's virtual filesystem. Throws if the file does not exist.\n */\n async readFile(path: string): Promise<string>\n\n /**\n * Write a file to the agent's virtual filesystem.\n */\n async writeFile(path: string, content: string): Promise<void>\n \\`\\`\\`\n\n ### Limitations\n\n - ES2023+ syntax with TypeScript support. No Node.js APIs, no \\`require\\`, no \\`import\\`.\n - Output is truncated beyond a fixed character limit — be selective about what you log.\n - Execution timeout per call (default 30 s).\n`;\n\n/**\n * Generate the PTC API Reference section for the system prompt.\n */\nexport async function generatePtcPrompt(\n tools: StructuredToolInterface[],\n): Promise<string> {\n if (tools.length === 0) return \"\";\n\n const signatures = await Promise.all(\n tools.map((t) => {\n const jsonSchema = t.schema ? safeToJsonSchema(t.schema) : undefined;\n return toolToTypeSignature(\n toCamelCase(t.name),\n t.description,\n jsonSchema,\n );\n }),\n );\n\n return dedent`\n\n ### API Reference — \\`tools\\` namespace\n\n The following agent tools are callable as async functions inside the REPL.\n Each takes a single object argument and returns a Promise that resolves to a string.\n Use \\`await\\` to call them. Promise APIs like \\`Promise.all\\` are also available.\n\n **Example usage:**\n \\`\\`\\`javascript\n // Call a tool\n const result = await tools.searchWeb({ query: \"QuickJS tutorial\" });\n console.log(result);\n\n // Concurrent calls\n const [a, b] = await Promise.all([\n tools.fetchData({ url: \"https://api.example.com/a\" }),\n tools.fetchData({ url: \"https://api.example.com/b\" }),\n ]);\n \\`\\`\\`\n\n **Available functions:**\n \\`\\`\\`typescript\n ${signatures.join(\"\\n\\n\")}\n \\`\\`\\`\n `;\n}\n\n/**\n * Create the QuickJS REPL middleware.\n */\nexport function createQuickJSMiddleware(\n options: QuickJSMiddlewareOptions = {},\n) {\n const {\n backend = (runtime: BackendRuntime) => new StateBackend(runtime),\n ptc = false,\n memoryLimitBytes = DEFAULT_MEMORY_LIMIT,\n maxStackSizeBytes = DEFAULT_MAX_STACK_SIZE,\n executionTimeoutMs = DEFAULT_EXECUTION_TIMEOUT,\n systemPrompt: customSystemPrompt = null,\n } = options;\n\n const usePtc = ptc !== false;\n const baseSystemPrompt = customSystemPrompt || REPL_SYSTEM_PROMPT;\n\n let cachedPtcPrompt: string | null = null;\n\n let ptcTools: StructuredToolInterface[] = [];\n\n function filterToolsForPtc(\n allTools: StructuredToolInterface[],\n ): StructuredToolInterface[] {\n if (ptc === false) return [];\n\n const candidates = allTools.filter((t) => t.name !== \"js_eval\");\n\n if (ptc === true) {\n const excluded = new Set<string>(DEFAULT_PTC_EXCLUDED_TOOLS);\n return candidates.filter((t) => !excluded.has(t.name));\n }\n\n if (Array.isArray(ptc)) {\n const included = new Set(ptc);\n return candidates.filter((t) => included.has(t.name));\n }\n\n if (\"include\" in ptc) {\n const included = new Set(ptc.include);\n return candidates.filter((t) => included.has(t.name));\n }\n\n if (\"exclude\" in ptc) {\n const excluded = new Set([...DEFAULT_PTC_EXCLUDED_TOOLS, ...ptc.exclude]);\n return candidates.filter((t) => !excluded.has(t.name));\n }\n\n return [];\n }\n\n const jsEvalTool = tool(\n async (input, config: LangGraphRunnableConfig) => {\n const threadId = config.configurable?.thread_id || DEFAULT_SESSION_ID;\n\n const runtime: BackendRuntime = {\n ...config,\n state: getCurrentTaskInput(config) || {},\n } as BackendRuntime;\n const resolvedBackend = await resolveBackend(backend, runtime);\n\n const session = ReplSession.getOrCreate(threadId, {\n memoryLimitBytes,\n maxStackSizeBytes,\n backend: resolvedBackend,\n tools: ptcTools,\n });\n\n const result = await session.eval(input.code, executionTimeoutMs);\n await session.flushWrites(resolvedBackend);\n\n return formatReplResult(result);\n },\n {\n name: \"js_eval\",\n description: dedent`\n Evaluate TypeScript/JavaScript code in a sandboxed REPL. State persists across calls.\n Use readFile(path) and writeFile(path, content) for file access.\n Use console.log() for output. Returns the result of the last expression.\n `,\n schema: z.object({\n code: z\n .string()\n .describe(\n \"TypeScript/JavaScript code to evaluate in the sandboxed REPL\",\n ),\n }),\n },\n );\n\n return createMiddleware({\n name: \"QuickJSMiddleware\",\n tools: [jsEvalTool],\n wrapModelCall: async (request, handler) => {\n const agentTools = (request.tools || []) as StructuredToolInterface[];\n ptcTools = usePtc ? filterToolsForPtc(agentTools) : [];\n\n if (ptcTools.length > 0 && !cachedPtcPrompt) {\n cachedPtcPrompt = await generatePtcPrompt(ptcTools);\n }\n\n const systemMessage = request.systemMessage\n .concat(baseSystemPrompt)\n .concat(cachedPtcPrompt || \"\");\n return handler({ ...request, systemMessage });\n },\n });\n}\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@langchain/quickjs",
3
- "version": "0.2.3",
3
+ "version": "0.2.5-alpha.0",
4
4
  "description": "Sandboxed JavaScript REPL for deepagents using QuickJS (WASM)",
5
5
  "main": "./dist/index.cjs",
6
6
  "module": "./dist/index.js",
@@ -39,10 +39,10 @@
39
39
  "quickjs-emscripten-core": "^0.32.0"
40
40
  },
41
41
  "peerDependencies": {
42
- "deepagents": ">=1.6.0"
42
+ "deepagents": ">=1.9.0-alpha.0"
43
43
  },
44
44
  "devDependencies": {
45
- "@langchain/core": "^1.1.37",
45
+ "@langchain/core": "^1.1.38",
46
46
  "@langchain/langgraph": "^1.1.4",
47
47
  "@tsconfig/recommended": "^1.0.13",
48
48
  "@types/dedent": "^0.7.2",
@@ -50,13 +50,13 @@
50
50
  "@types/node": "^25.2.3",
51
51
  "@vitest/coverage-v8": "^4.0.18",
52
52
  "dotenv": "^17.2.3",
53
- "langchain": "1.2.38",
53
+ "langchain": "^1.2.39",
54
54
  "tsdown": "^0.21.4",
55
55
  "tsx": "^4.21.0",
56
- "typescript": "^5.9.3",
56
+ "typescript": "^6.0.2",
57
57
  "vitest": "^4.0.18",
58
58
  "zod": "^4.3.6",
59
- "deepagents": "1.8.7"
59
+ "deepagents": "1.9.0-alpha.1"
60
60
  },
61
61
  "exports": {
62
62
  ".": {