@langchain/quickjs 0.2.6 → 0.3.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 +36 -38
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +23 -10
- package/dist/index.d.ts +23 -10
- package/dist/index.js +33 -35
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -24,18 +24,18 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
24
24
|
let langchain = require("langchain");
|
|
25
25
|
let zod_v4 = require("zod/v4");
|
|
26
26
|
let dedent = require("dedent");
|
|
27
|
-
dedent = __toESM(dedent);
|
|
27
|
+
dedent = __toESM(dedent, 1);
|
|
28
28
|
let _langchain_langgraph = require("@langchain/langgraph");
|
|
29
29
|
let deepagents = require("deepagents");
|
|
30
30
|
let quickjs_emscripten = require("quickjs-emscripten");
|
|
31
31
|
let quickjs_emscripten_core = require("quickjs-emscripten-core");
|
|
32
32
|
let node_path_posix = require("node:path/posix");
|
|
33
|
-
node_path_posix = __toESM(node_path_posix);
|
|
33
|
+
node_path_posix = __toESM(node_path_posix, 1);
|
|
34
34
|
let acorn = require("acorn");
|
|
35
35
|
let _sveltejs_acorn_typescript = require("@sveltejs/acorn-typescript");
|
|
36
36
|
let estree_walker = require("estree-walker");
|
|
37
37
|
let magic_string = require("magic-string");
|
|
38
|
-
magic_string = __toESM(magic_string);
|
|
38
|
+
magic_string = __toESM(magic_string, 1);
|
|
39
39
|
let json_schema_to_typescript = require("json-schema-to-typescript");
|
|
40
40
|
let _langchain_core_utils_json_schema = require("@langchain/core/utils/json_schema");
|
|
41
41
|
//#region src/transform.ts
|
|
@@ -472,9 +472,9 @@ function formatSkillNotAvailable(missing) {
|
|
|
472
472
|
* runtime is lazily started on the first `.eval()` call, making the session
|
|
473
473
|
* safe across graph interrupts and checkpointing.
|
|
474
474
|
*/
|
|
475
|
-
const DEFAULT_MEMORY_LIMIT =
|
|
475
|
+
const DEFAULT_MEMORY_LIMIT = 64 * 1024 * 1024;
|
|
476
476
|
const DEFAULT_MAX_STACK_SIZE = 320 * 1024;
|
|
477
|
-
const DEFAULT_EXECUTION_TIMEOUT =
|
|
477
|
+
const DEFAULT_EXECUTION_TIMEOUT = 5e3;
|
|
478
478
|
const DEFAULT_MAX_PTC_CALLS = 256;
|
|
479
479
|
const DEFAULT_MAX_RESULTS_CHARS = 4e3;
|
|
480
480
|
const variantImport = import("@jitl/quickjs-ng-wasmfile-release-asyncify");
|
|
@@ -608,7 +608,7 @@ var ReplSession = class ReplSession {
|
|
|
608
608
|
}
|
|
609
609
|
async ensureStarted() {
|
|
610
610
|
if (this.runtime) return;
|
|
611
|
-
const { memoryLimitBytes = DEFAULT_MEMORY_LIMIT, maxStackSizeBytes = DEFAULT_MAX_STACK_SIZE, tools, skillsEnabled = false, maxResultChars = DEFAULT_MAX_RESULTS_CHARS } = this.options;
|
|
611
|
+
const { memoryLimitBytes = DEFAULT_MEMORY_LIMIT, maxStackSizeBytes = DEFAULT_MAX_STACK_SIZE, tools, skillsEnabled = false, maxResultChars = DEFAULT_MAX_RESULTS_CHARS, captureConsole = true } = this.options;
|
|
612
612
|
const runtime = (await newAsyncModule()).newRuntime();
|
|
613
613
|
runtime.setMemoryLimit(memoryLimitBytes);
|
|
614
614
|
runtime.setMaxStackSize(maxStackSizeBytes);
|
|
@@ -616,7 +616,7 @@ var ReplSession = class ReplSession {
|
|
|
616
616
|
this.runtime = runtime;
|
|
617
617
|
this.context = context;
|
|
618
618
|
this.consoleBuffer = new ConsoleBuffer(maxResultChars);
|
|
619
|
-
this.setupConsole();
|
|
619
|
+
if (captureConsole) this.setupConsole();
|
|
620
620
|
if (tools !== void 0 && tools.length > 0) this.injectTools(tools);
|
|
621
621
|
if (skillsEnabled) this.installModuleLoader();
|
|
622
622
|
}
|
|
@@ -742,7 +742,7 @@ var ReplSession = class ReplSession {
|
|
|
742
742
|
}
|
|
743
743
|
/**
|
|
744
744
|
* Push the current skills metadata + backend into the session.
|
|
745
|
-
* Called by the middleware once per `
|
|
745
|
+
* Called by the middleware once per `eval` invocation, before eval runs.
|
|
746
746
|
* Pass `undefined` to clear the context (no skill imports will resolve).
|
|
747
747
|
*/
|
|
748
748
|
setSkillsContext(ctx) {
|
|
@@ -932,33 +932,26 @@ var ReplSession = class ReplSession {
|
|
|
932
932
|
//#endregion
|
|
933
933
|
//#region src/middleware.ts
|
|
934
934
|
/**
|
|
935
|
-
*
|
|
935
|
+
* REPL middleware for deepagents.
|
|
936
936
|
*
|
|
937
|
-
* Provides
|
|
937
|
+
* Provides an `eval` tool that runs JavaScript in a WASM-sandboxed QuickJS
|
|
938
938
|
* interpreter. Supports:
|
|
939
939
|
* - Persistent state across evaluations (true REPL)
|
|
940
940
|
* - Programmatic tool calling (PTC) — expose agent or custom tools inside the REPL
|
|
941
941
|
*/
|
|
942
|
-
const
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
TypeScript syntax (type annotations, interfaces, generics, \`as\` casts) is supported and stripped at evaluation time.
|
|
947
|
-
Variables, functions, and closures persist across calls within the same session.
|
|
948
|
-
|
|
949
|
-
### Hard rules
|
|
950
|
-
|
|
951
|
-
- **No network, no direct filesystem** — only through tools provided in the \`tools\` namespace below.
|
|
952
|
-
- **Cite your sources** — when reporting values from files, include the path and key/index so the user can verify.
|
|
953
|
-
- **Use console.log()** for output — it is captured and returned. \`console.warn()\` and \`console.error()\` are also available.
|
|
954
|
-
- **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.
|
|
955
|
-
|
|
956
|
-
### Limitations
|
|
942
|
+
const DEFAULT_TOOL_NAME = "eval";
|
|
943
|
+
function renderReplSystemPrompt(opts) {
|
|
944
|
+
return dedent.default`
|
|
945
|
+
### Interpreter
|
|
957
946
|
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
947
|
+
An \`${opts.toolName}\` tool is available. It runs JavaScript in a persistent REPL.
|
|
948
|
+
- State (variables, functions) persists across tool calls within a single turn of conversation. They DO NOT persist across multiple turns.
|
|
949
|
+
- Top-level \`await\` works; Promises resolve before the call returns.
|
|
950
|
+
- Sandboxed: no filesystem, no stdlib, no network, no real clock, no \`fetch\`, no \`require\`.
|
|
951
|
+
- Timeout: ${opts.timeout}s per call. Memory: ${opts.memoryLimitMb} MB total.
|
|
952
|
+
- \`console.log\` output is captured and returned alongside the result.
|
|
953
|
+
`;
|
|
954
|
+
}
|
|
962
955
|
/**
|
|
963
956
|
* Generate the PTC API Reference section for the system prompt.
|
|
964
957
|
*/
|
|
@@ -1035,21 +1028,25 @@ async function prepareSkillsForEval(session, skillsBackend, code) {
|
|
|
1035
1028
|
});
|
|
1036
1029
|
}
|
|
1037
1030
|
/**
|
|
1038
|
-
* Create the
|
|
1031
|
+
* Create the REPL middleware.
|
|
1039
1032
|
*/
|
|
1040
|
-
function
|
|
1041
|
-
const { ptc, memoryLimitBytes = DEFAULT_MEMORY_LIMIT, maxStackSizeBytes = DEFAULT_MAX_STACK_SIZE, executionTimeoutMs = DEFAULT_EXECUTION_TIMEOUT, systemPrompt: customSystemPrompt = null, skillsBackend, maxPtcCalls = 256, maxResultChars = DEFAULT_MAX_RESULTS_CHARS } = options;
|
|
1033
|
+
function createREPLMiddleware(options = {}) {
|
|
1034
|
+
const { ptc, memoryLimitBytes = DEFAULT_MEMORY_LIMIT, maxStackSizeBytes = DEFAULT_MAX_STACK_SIZE, executionTimeoutMs = DEFAULT_EXECUTION_TIMEOUT, systemPrompt: customSystemPrompt = null, skillsBackend, maxPtcCalls = 256, maxResultChars = DEFAULT_MAX_RESULTS_CHARS, toolName = DEFAULT_TOOL_NAME, captureConsole = true } = options;
|
|
1042
1035
|
if (maxPtcCalls !== null && maxPtcCalls !== void 0 && maxPtcCalls < 1) throw new Error("`maxPtcCalls` must be >= 1 or null");
|
|
1043
|
-
const baseSystemPrompt = customSystemPrompt ||
|
|
1036
|
+
const baseSystemPrompt = customSystemPrompt || renderReplSystemPrompt({
|
|
1037
|
+
toolName,
|
|
1038
|
+
timeout: executionTimeoutMs / 1e3,
|
|
1039
|
+
memoryLimitMb: Math.floor(memoryLimitBytes / (1024 * 1024))
|
|
1040
|
+
});
|
|
1044
1041
|
const middlewareId = crypto.randomUUID();
|
|
1045
1042
|
let cachedPtcPrompt = null;
|
|
1046
1043
|
let ptcTools = [];
|
|
1047
1044
|
function filterToolsForPtc(allTools) {
|
|
1048
1045
|
if (!ptc) return [];
|
|
1049
|
-
return resolveToolList(ptc, allTools.filter((t) => t.name !==
|
|
1046
|
+
return resolveToolList(ptc, allTools.filter((t) => t.name !== toolName));
|
|
1050
1047
|
}
|
|
1051
1048
|
return (0, langchain.createMiddleware)({
|
|
1052
|
-
name: "
|
|
1049
|
+
name: "REPLMiddleware",
|
|
1053
1050
|
tools: [(0, langchain.tool)(async (input, config) => {
|
|
1054
1051
|
const sessionKey = `${config.configurable?.thread_id || "__default__"}:${middlewareId}`;
|
|
1055
1052
|
const session = ReplSession.getOrCreate(sessionKey, {
|
|
@@ -1058,7 +1055,8 @@ function createQuickJSMiddleware(options = {}) {
|
|
|
1058
1055
|
maxPtcCalls,
|
|
1059
1056
|
tools: ptcTools,
|
|
1060
1057
|
skillsEnabled: skillsBackend !== void 0,
|
|
1061
|
-
maxResultChars
|
|
1058
|
+
maxResultChars,
|
|
1059
|
+
captureConsole
|
|
1062
1060
|
});
|
|
1063
1061
|
if (skillsBackend !== void 0) {
|
|
1064
1062
|
const setupError = await prepareSkillsForEval(session, skillsBackend, input.code);
|
|
@@ -1066,7 +1064,7 @@ function createQuickJSMiddleware(options = {}) {
|
|
|
1066
1064
|
}
|
|
1067
1065
|
return formatReplResult(await session.eval(input.code, executionTimeoutMs));
|
|
1068
1066
|
}, {
|
|
1069
|
-
name:
|
|
1067
|
+
name: toolName,
|
|
1070
1068
|
description: dedent.default`
|
|
1071
1069
|
Evaluate TypeScript/JavaScript code in a sandboxed REPL. State persists across calls.
|
|
1072
1070
|
Use console.log() for output. Returns the result of the last expression.
|
|
@@ -1100,7 +1098,7 @@ exports.MAX_SKILL_BUNDLE_BYTES = MAX_SKILL_BUNDLE_BYTES;
|
|
|
1100
1098
|
exports.PTCCallBudgetExceededError = PTCCallBudgetExceededError;
|
|
1101
1099
|
exports.ReplSession = ReplSession;
|
|
1102
1100
|
exports.SKILL_MODULE_EXTENSIONS = SKILL_MODULE_EXTENSIONS;
|
|
1103
|
-
exports.
|
|
1101
|
+
exports.createREPLMiddleware = createREPLMiddleware;
|
|
1104
1102
|
exports.formatReplResult = formatReplResult;
|
|
1105
1103
|
exports.formatSkillNotAvailable = formatSkillNotAvailable;
|
|
1106
1104
|
exports.loadSkill = loadSkill;
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","names":["Parser","MagicString","posix","z"],"sources":["../src/transform.ts","../src/skills.ts","../src/errors.ts","../src/utils.ts","../src/session.ts","../src/middleware.ts"],"sourcesContent":["/**\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/**\n * Strip TypeScript type syntax from an ES-module source so QuickJS can\n * evaluate it as a standard JS module.\n *\n * Unlike `transformForEval`, this keeps `import`/`export` declarations,\n * does not hoist to `globalThis`, and does not wrap in an IIFE.\n * On parse failure the original source is returned unchanged.\n */\nexport function stripTypeSyntax(code: string): string {\n let ast: AcornNode;\n try {\n ast = TSParser.parse(code, {\n ecmaVersion: \"latest\",\n sourceType: \"module\",\n locations: true,\n }) as unknown as AcornNode;\n } catch {\n // Return the original source unchanged rather than throwing or returning an empty string.\n // We don't know why the parse failed - it could be a valid plain-JS file that hit an\n // acorn-typescript incompatibility, in which case returning it unchanged lets QuickJS\n // evaluate it correctly. If it's genuinely broken TS, QuickJS will surface the parse error\n // at evaluation time with a useful line/column.\n return code;\n }\n\n const magicString = new MagicString(code);\n const program = ast as unknown as { body: AcornNode[] };\n\n for (const node of program.body) {\n if (isTSOnlyNode(node)) {\n magicString.remove(node.start, node.end);\n continue;\n }\n\n walk(node as any, {\n enter(n: any) {\n stripTypeAnnotationFromNode(magicString, n);\n },\n });\n }\n\n return magicString.toString();\n}\n","import * as posix from \"node:path/posix\";\n\nimport {\n adaptBackendProtocol,\n BackendProtocolV2,\n type AnyBackendProtocol,\n type FileDownloadResponse,\n type FileInfo,\n type SkillMetadata,\n} from \"deepagents\";\n\nimport { stripTypeSyntax } from \"./transform.js\";\n\n/**\n * File extensions the loader will enumerate from a skill directory.\n */\nexport const SKILL_MODULE_EXTENSIONS = [\n \".js\",\n \".mjs\",\n \".cjs\",\n \".ts\",\n \".mts\",\n \".cts\",\n \".jsx\",\n \".tsx\",\n];\n\n/**\n * Hard cap on total bytes pulled for one skill's bundle (1 MiB).\n */\nexport const MAX_SKILL_BUNDLE_BYTES = 1 * 1024 * 1024;\n\n/**\n * Validates a skill name against the spec's kebab-case rule.\n */\nconst SKILL_NAME_RE = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;\n\n/**\n * Matches `\"@/skills/<name>\"` or `'@/skills/<name>'` references in source.\n * Template literals and computed specifiers are not caught.\n */\nconst SKILL_SPECIFIER_RE = /[\"']@\\/skills\\/([a-z0-9]+(?:-[a-z0-9]+)*)[\"']/g;\n\n/**\n * Install-ready state for a single skill, produced by `loadSkill`.\n */\nexport interface LoadedSkill {\n /**\n * Spec-validated kebab-case skill name.\n */\n name: string;\n\n /**\n * Bare specifier the skill installs under: `\"@/skills/<name>\"`.\n */\n specifier: string;\n\n /**\n * Relative POSIX path of the entrypoint file (e.g. `\"index.ts\"`).\n */\n entryRel: string;\n\n /**\n * File contents keyed by relative POSIX path, with TS syntax stripped.\n */\n files: Map<string, string>;\n}\n\n/**\n * List every code-extension file under `skillDir` (recursive).\n */\nasync function enumerateCodeFiles(\n backend: BackendProtocolV2,\n skillDir: string,\n skillName: string,\n): Promise<string[]> {\n const seen = new Set<string>();\n for (const ext of SKILL_MODULE_EXTENSIONS) {\n const result = await backend.glob(`**/*${ext}`, skillDir);\n if (result.error !== undefined) {\n throw new Error(\n `Skill '${skillName}': failed to list '${skillDir}': ${result.error}`,\n );\n }\n\n const matches: FileInfo[] = result.files ?? [];\n for (const match of matches) {\n seen.add(match.path);\n }\n }\n\n return [...seen].sort();\n}\n\n/**\n * Decode download responses into [path, source] pairs.\n */\nfunction decodeFiles(\n responses: FileDownloadResponse[],\n skillName: string,\n): Array<[string, string]> {\n const decoder = new TextDecoder(\"utf-8\", { fatal: true });\n\n const pairs: Array<[string, string]> = [];\n for (const response of responses) {\n if (response.error !== null || response.content === null) {\n throw new Error(\n `Skill '${skillName}': failed to download '${response.path}': ${response.error ?? \"no content\"}`,\n );\n }\n\n let source: string;\n try {\n source = decoder.decode(response.content);\n } catch {\n throw new Error(\n `Skill '${skillName}': file '${response.path}' is not valid UTF-8`,\n );\n }\n\n pairs.push([response.path, source]);\n }\n\n return pairs;\n}\n\n/**\n * Throws an Error when the total decoded size of all files exceeds\n * `MAX_SKILL_BUNDLE_BYTES`. Counts characters rather than bytes, which\n * over-counts multi-byte UTF-8. Intentionally errs toward rejection.\n */\nfunction validateBundleSize(\n pairs: Array<[string, string]>,\n skillName: string,\n): void {\n let total = 0;\n for (const [, source] of pairs) {\n total += source.length;\n }\n\n if (total > MAX_SKILL_BUNDLE_BYTES) {\n throw new Error(\n `Skill '${skillName}': bundle exceeds ${MAX_SKILL_BUNDLE_BYTES} bytes (total ${total})`,\n );\n }\n}\n\n/**\n * Express `absolutePath` as a POSIX-relative path under `skillDir`.\n * Throws an Error if the path escapes the skill directory which indicates\n * a backend bug, not a user error.\n */\nfunction relativeUnder(\n skillDir: string,\n absolutePath: string,\n skillName: string,\n): string {\n const rel = posix.relative(skillDir, absolutePath);\n if (rel === \"\" || rel.startsWith(\"..\")) {\n throw new Error(\n `Skill '${skillName}': file ${absolutePath} is not under '${skillDir}'`,\n );\n }\n return rel;\n}\n\n/**\n * Build the relative-path → source map, applying `stripTypeSyntax` to each file.\n */\nfunction buildFilesMap(\n skillDir: string,\n entryRel: string,\n pairs: Array<[string, string]>,\n skillName: string,\n): Map<string, string> {\n const files = new Map<string, string>();\n let entryPresent = false;\n\n for (const [absPath, source] of pairs) {\n const rel = relativeUnder(skillDir, absPath, skillName);\n files.set(rel, stripTypeSyntax(source));\n if (rel === entryRel) {\n entryPresent = true;\n }\n }\n\n if (!entryPresent) {\n throw new Error(\n `Skill '${skillName}': module path '${entryRel}' did not match any file in the skill directory`,\n );\n }\n\n return files;\n}\n\n/**\n * Build a `LoadedSkill` from a skill's metadata and a backend handle.\n *\n * Enumerates code files under the skill directory, downloads them,\n * strips TypeScript syntax, and validates the entrypoint is present.\n */\nexport async function loadSkill(\n metadata: SkillMetadata,\n backend: AnyBackendProtocol,\n): Promise<LoadedSkill> {\n const name = metadata.name;\n\n if (!SKILL_NAME_RE.test(name)) {\n throw new Error(\n `Skill name '${name}' is not a valid kebab-case identifier`,\n );\n }\n\n const entryRel = metadata.module;\n if (entryRel === undefined || entryRel === \"\") {\n throw new Error(\n `Skill '${name}' has no 'module' frontmatter key - only skills with a declared entrypoint are installable`,\n );\n }\n\n const adapted = adaptBackendProtocol(backend);\n if (adapted.downloadFiles === undefined) {\n throw new Error(\n `Skill '${name}': backend does not implement downloadFiles`,\n );\n }\n\n const skillDir = posix.dirname(metadata.path);\n const codeFiles = await enumerateCodeFiles(adapted, skillDir, name);\n if (codeFiles.length === 0) {\n throw new Error(`Skill '${name}': no JS/TS files under '${skillDir}'`);\n }\n\n const responses = await adapted.downloadFiles(codeFiles);\n const filePairs = decodeFiles(responses, name);\n validateBundleSize(filePairs, name);\n\n const files = buildFilesMap(skillDir, entryRel, filePairs, name);\n return {\n name,\n specifier: `@/skills/${name}`,\n entryRel,\n files,\n };\n}\n\n/**\n * Extract skill names referenced by `\"@/skills/<name>\"` literals in source.\n *\n * Used as a pre-eval scan so the middleware can surface `SkillNotAvailable`\n * before evaluation starts. Dynamic imports with computed specifiers are\n * not detected.\n */\nexport function scanSkillReferences(source: string): Set<string> {\n const names = new Set<string>();\n\n const matches = source.matchAll(SKILL_SPECIFIER_RE);\n for (const match of matches) {\n names.add(match[1]);\n }\n\n return names;\n}\n","/**\n * Options for constructing a {@link PTCCallBudgetExceededError}.\n */\ninterface PTCCallBudgetExceededOptions {\n /**\n * The configured per-eval PTC call limit.\n */\n limit: number;\n\n /**\n * The call number that triggered the violation (always `limit + 1`).\n */\n attempted: number;\n\n /**\n * The name of the tool function that was called over budget.\n */\n functionName: string;\n}\n\n/**\n * Thrown when a single eval exhausts its configured PTC call budget.\n */\nexport class PTCCallBudgetExceededError extends Error {\n readonly limit: number;\n readonly attempted: number;\n readonly functionName: string;\n\n constructor(options: PTCCallBudgetExceededOptions) {\n super(\n `PTC call budget exceeded (limit=${options.limit}, attempted=${options.attempted}, function=${options.functionName})`,\n );\n this.name = \"PTCCallBudgetExceededError\";\n this.limit = options.limit;\n this.attempted = options.attempted;\n this.functionName = options.functionName;\n }\n}\n","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 let logsText = result.logs.join(\"\\n\");\n if (result.logsDroppedChars > 0) {\n logsText += `\\n[truncated ${result.logsDroppedChars} chars]`;\n }\n parts.push(logsText);\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/**\n * Render a pre-eval error when referenced skills are not available on the agent.\n */\nexport function formatSkillNotAvailable(missing: readonly string[]): string {\n const list = [...missing].sort().join(\", \");\n return `Skills unavailable: ${list}`;\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\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 { StructuredToolInterface } from \"@langchain/core/tools\";\n\nimport { loadSkill, type LoadedSkill } from \"./skills.js\";\nimport { PTCCallBudgetExceededError } from \"./errors.js\";\nimport type { ReplSessionOptions, ReplResult, SkillsContext } 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__\";\nexport const DEFAULT_MAX_PTC_CALLS = 256;\nexport const DEFAULT_MAX_RESULTS_CHARS = 4000;\n\n// The variant descriptor (WASM binary + glue) is safe to share across sessions;\n// only the instantiated module carries asyncify state. Import once, instantiate per session.\nconst variantImport = import(\"@jitl/quickjs-ng-wasmfile-release-asyncify\");\n\n// Each ReplSession needs its own WASM module. The asyncify WASM variant allows only one\n// concurrent async call per module instance, and multi-file skill imports (2+ unwind/rewind\n// cycles inside a single evalCodeAsync) leave the module's asyncify state corrupted after\n// the owning runtime is disposed — new runtimes on the same module silently skip module\n// loader callbacks. A fresh instantiation per session gives each session clean asyncify state.\nasync function newAsyncModule() {\n const variant = await variantImport;\n return newQuickJSAsyncWASMModuleFromVariant(\n (variant.default ?? variant) as any,\n );\n}\n\n// After a successful asyncify unwind/rewind cycle, a rejected module loader\n// Promise causes a WASM crash (\"memory access out of bounds\"). The rejection\n// path in quickjs-emscripten's `maybeAsyncFn` catch block calls\n// `context.throw(error)` — a WASM FFI call while the asyncify stack is still\n// unwound — which corrupts memory. To avoid this, the module loader must never\n// reject. This helper returns source code that throws at evaluation time inside\n// the VM instead.\n//\n// The thrown value is a plain object (not `new Error()`) because QuickJS stores\n// Error's `name` and `message` as non-enumerable properties (per spec), which\n// causes `context.dump()` (JSON.stringify) to return `{}`.\nfunction makeErrorSource(message: string): string {\n return `throw { name: \"Error\", message: ${JSON.stringify(message)} };`;\n}\n\n/**\n * Parse a canonicalized skill specifier into `{ name, rel }`.\n * Returns `undefined` for anything that isn't a valid `@/skills/<name>` or\n * `@/skills/<name>/<rel>` shape. `rel` is absent for the bare form.\n */\nfunction parseSkillSpecifier(\n specifier: string,\n): { name: string; rel?: string } | undefined {\n const prefix = \"@/skills/\";\n if (!specifier.startsWith(prefix)) {\n return;\n }\n\n const tail = specifier.slice(prefix.length);\n const slashIdx = tail.indexOf(\"/\");\n const name = slashIdx === -1 ? tail : tail.slice(0, slashIdx);\n if (!/^[a-z0-9]+(?:-[a-z0-9]+)*$/.test(name)) {\n return;\n }\n\n const rel = slashIdx === -1 ? undefined : tail.slice(slashIdx + 1);\n if (rel !== undefined && rel === \"\") {\n return;\n }\n\n return { name, rel };\n}\n\n/**\n * Return the `@/skills/<name>` prefix for the skill that owns `base`, or `undefined`.\n */\nfunction matchSkillPrefix(base: string): string | undefined {\n const parsed = parseSkillSpecifier(base);\n if (parsed === undefined) {\n return;\n }\n return `@/skills/${parsed.name}`;\n}\n\n/**\n * Return the directory portion of a slash-separated specifier path.\n */\nfunction posixDirname(p: string): string {\n const idx = p.lastIndexOf(\"/\");\n if (idx === -1) {\n return \"\";\n }\n return p.slice(0, idx);\n}\n\n/**\n * POSIX join for slash-separated specifiers. Avoids `node:path/posix`\n * since session.ts is consumed in browser bundles.\n */\nfunction posixJoin(base: string, rel: string): string {\n const out: string[] = [];\n\n const segments = `${base}/${rel}`.split(\"/\");\n for (const segment of segments) {\n if (segment === \"\" || segment === \".\") {\n continue;\n }\n\n if (segment === \"..\") {\n out.pop();\n continue;\n }\n\n out.push(segment);\n }\n\n return out.join(\"/\");\n}\n\n/**\n * Fixed-size character buffer for capturing console output from the QuickJS VM.\n *\n * Lines are accumulated up to `maxChars`. Once the cap is reached, excess\n * characters are counted as dropped rather than silently discarded without\n * attribution, so callers can surface a truncation notice to the user.\n */\nclass ConsoleBuffer {\n private readonly maxChars: number;\n private buffer: string = \"\";\n private droppedChars: number = 0;\n\n constructor(maxChars: number) {\n this.maxChars = Math.max(maxChars, 0);\n }\n\n /**\n * Append `line` to the buffer.\n *\n * If the buffer is already full the entire line is counted as dropped.\n * If `line` partially fits, the fitting prefix is stored and the remainder\n * is counted as dropped.\n */\n append(line: string): void {\n const remaining = this.maxChars - this.buffer.length;\n if (remaining <= 0) {\n this.droppedChars += line.length;\n return;\n }\n\n if (line.length <= remaining) {\n this.buffer += line;\n } else {\n this.buffer += line.slice(0, remaining);\n this.droppedChars += line.length - remaining;\n }\n }\n\n /**\n * Return the buffered output and dropped-character count as `[buffered,\n * droppedChars]`, then reset both to zero.\n */\n drain(): [string, number] {\n const out = this.buffer;\n const dropped = this.droppedChars;\n\n this.buffer = \"\";\n this.droppedChars = 0;\n\n return [out, dropped];\n }\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 */\nexport class ReplSession {\n private static sessions = new Map<string, ReplSession>();\n\n readonly id: string;\n\n private runtime: QuickJSAsyncRuntime | null = null;\n private context: QuickJSAsyncContext | null = null;\n private consoleBuffer: ConsoleBuffer = new ConsoleBuffer(\n DEFAULT_MAX_RESULTS_CHARS,\n );\n private options: ReplSessionOptions;\n private skillsContext: SkillsContext | undefined;\n private skillsLoaded: Map<string, LoadedSkill> = new Map();\n private skillsFailed: Map<string, Error> = new Map();\n private readonly maxPtcCalls: number | null;\n private ptcCallsRemaining: number | null = null;\n\n constructor(id: string, options: ReplSessionOptions = {}) {\n this.id = id;\n this.options = options;\n this.maxPtcCalls =\n options.maxPtcCalls !== undefined\n ? options.maxPtcCalls\n : DEFAULT_MAX_PTC_CALLS;\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 tools,\n skillsEnabled = false,\n maxResultChars = DEFAULT_MAX_RESULTS_CHARS,\n } = this.options;\n\n const asyncModule = await newAsyncModule();\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.consoleBuffer = new ConsoleBuffer(maxResultChars);\n this.setupConsole();\n\n if (tools !== undefined && tools.length > 0) {\n this.injectTools(tools);\n }\n\n if (skillsEnabled) {\n this.installModuleLoader();\n }\n }\n\n /**\n * Load the skill into cache on first access and replay cached errors.\n */\n private async ensureSkillLoaded(name: string): Promise<LoadedSkill> {\n const cached = this.skillsLoaded.get(name);\n if (cached !== undefined) {\n return cached;\n }\n\n const cachedError = this.skillsFailed.get(name);\n if (cachedError !== undefined) {\n throw cachedError;\n }\n\n const ctx = this.skillsContext;\n if (ctx === undefined) {\n throw new Error(\n `Skill '${name}' referenced but skills are not configured for this session`,\n );\n }\n\n const metadata = ctx.metadata.find((m) => m.name === name);\n if (metadata === undefined) {\n throw new Error(\n `Skill '${name}' referenced but not available on this agent`,\n );\n }\n\n try {\n const loaded = await loadSkill(metadata, ctx.backend);\n this.skillsLoaded.set(name, loaded);\n return loaded;\n } catch (err) {\n this.skillsFailed.set(name, err as Error);\n throw err;\n }\n }\n\n private async resolveSpecifier(specifier: string): Promise<string> {\n const parsed = parseSkillSpecifier(specifier);\n if (parsed === undefined) {\n return makeErrorSource(`Module not found: ${specifier}`);\n }\n\n let loaded: LoadedSkill;\n try {\n loaded = await this.ensureSkillLoaded(parsed.name);\n } catch (err) {\n return makeErrorSource((err as Error).message ?? String(err));\n }\n\n if (parsed.rel === undefined) {\n const source = loaded.files.get(loaded.entryRel);\n if (source === undefined) {\n return makeErrorSource(\n `Skill '${parsed.name}': entrypoint '${loaded.entryRel}' missing from bundle`,\n );\n }\n return source;\n }\n\n const source = loaded.files.get(parsed.rel);\n if (source === undefined) {\n return makeErrorSource(\n `Skill '${parsed.name}': '${parsed.rel}' not found in bundle`,\n );\n }\n\n return source;\n }\n\n /**\n * Canonicalize an `import` specifier. Bare specifiers pass through;\n * relative specifiers are resolved against the importing module's path.\n * Traversal out of a skill's `@/skills/<name>/` namespace is rejected.\n */\n private normalizeSpecifier(base: string, requested: string): string {\n const isRelative =\n requested.startsWith(\"./\") || requested.startsWith(\"../\");\n if (!isRelative) {\n return requested;\n }\n\n // A bare skill specifier like \"@/skills/my-skill\" has no file component, so\n // posixDirname would return \"@/skills\". Treat the bare specifier itself as\n // the directory so that \"./lib/math.js\" resolves to \"@/skills/my-skill/lib/math.js\".\n const parsed = parseSkillSpecifier(base);\n const baseDir =\n parsed !== undefined && parsed.rel === undefined\n ? base\n : posixDirname(base);\n const resolved = posixJoin(baseDir, requested);\n\n const skillPrefix = matchSkillPrefix(base);\n if (skillPrefix === undefined) {\n return resolved;\n }\n\n if (!resolved.startsWith(`${skillPrefix}/`)) {\n return `__resolve_error__:${requested} escapes ${skillPrefix}`;\n }\n\n return resolved;\n }\n\n /**\n * Wire the QuickJS module loader and normalizer on this session's runtime.\n */\n private installModuleLoader(): void {\n if (this.runtime === null) {\n return;\n }\n\n this.runtime.setModuleLoader(\n async (specifier: string) => this.resolveSpecifier(specifier),\n (base: string, requested: string) =>\n this.normalizeSpecifier(base, requested),\n );\n }\n\n /**\n * Initialise the per-eval PTC counter. Called at the top of every `eval()`.\n */\n private resetPtcBudget(): void {\n this.ptcCallsRemaining =\n this.maxPtcCalls === null ? null : this.maxPtcCalls;\n }\n\n /**\n * Decrement the PTC call counter and throw if the budget is exhausted.\n * `null` budget means unlimited — returns immediately without decrementing.\n */\n private consumePtcBudget(functionName: string): void {\n if (this.ptcCallsRemaining === null) {\n return;\n }\n\n if (this.ptcCallsRemaining > 0) {\n this.ptcCallsRemaining--;\n return;\n }\n\n const limit = this.maxPtcCalls ?? 0;\n throw new PTCCallBudgetExceededError({\n limit,\n attempted: limit + 1,\n functionName,\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 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 * Returns true if any session exists whose key equals `threadId` or starts\n * with `threadId:`. Useful for tests that need to confirm a session was\n * created without knowing the full `threadId:middlewareId` key.\n */\n static hasAnyForThread(threadId: string): boolean {\n const prefix = `${threadId}:`;\n for (const key of ReplSession.sessions.keys()) {\n if (key === threadId || key.startsWith(prefix)) {\n return true;\n }\n }\n return false;\n }\n\n /**\n * Dispose and remove the session with the given key, if it exists.\n */\n static deleteSession(key: string): void {\n const session = ReplSession.sessions.get(key);\n if (session) {\n session.dispose();\n }\n }\n\n /**\n * Push the current skills metadata + backend into the session.\n * Called by the middleware once per `js_eval` invocation, before eval runs.\n * Pass `undefined` to clear the context (no skill imports will resolve).\n */\n setSkillsContext(ctx?: SkillsContext): void {\n this.skillsContext = ctx;\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 const drainLogs = (): { logs: string[]; logsDroppedChars: number } => {\n const [raw, dropped] = this.consoleBuffer.drain();\n return {\n logs: raw.length > 0 ? raw.split(\"\\n\").filter((l) => l.length > 0) : [],\n logsDroppedChars: dropped,\n };\n };\n\n this.resetPtcBudget();\n try {\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, ...drainLogs() };\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, ...drainLogs() };\n }\n const value = context.dump(promiseState.value);\n promiseState.value.dispose();\n result.value.dispose();\n return { ok: true, value, ...drainLogs() };\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, ...drainLogs() };\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, ...drainLogs() };\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, ...drainLogs() };\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 ...drainLogs(),\n };\n } finally {\n this.ptcCallsRemaining = null;\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 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 const line =\n method === \"log\" || method === \"info\" || method === \"debug\"\n ? formatted\n : `[${method}] ${formatted}`;\n this.consoleBuffer.append(line + \"\\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 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 this.consumePtcBudget(camelName);\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 * - Programmatic tool calling (PTC) — expose agent or custom tools inside the REPL\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\";\n\nimport dedent from \"dedent\";\nimport { getCurrentTaskInput } from \"@langchain/langgraph\";\nimport {\n resolveBackend,\n type AnyBackendProtocol,\n type BackendFactory,\n type SkillMetadata,\n} from \"deepagents\";\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 DEFAULT_MAX_PTC_CALLS,\n DEFAULT_MAX_RESULTS_CHARS,\n} from \"./session.js\";\nimport {\n formatReplResult,\n formatSkillNotAvailable,\n toCamelCase,\n toolToTypeSignature,\n safeToJsonSchema,\n} from \"./utils.js\";\nimport { scanSkillReferences } from \"./skills.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 { LangGraphRunnableConfig } from \"@langchain/langgraph\";\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 direct filesystem** — only through tools provided in the \\`tools\\` namespace below.\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 ### 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 * Resolves a mixed list of tool names and tool instances into a flat list of\n * StructuredToolInterface objects. Strings are looked up by name in agentTools;\n * instances are included directly without requiring agent registration. Strings\n * that don't match any agent tool are silently omitted.\n */\nexport function resolveToolList(\n items: (string | StructuredToolInterface)[],\n agentTools: StructuredToolInterface[],\n): StructuredToolInterface[] {\n const agentByName = new Map(agentTools.map((t) => [t.name, t]));\n return items.flatMap((item) => {\n if (typeof item === \"string\") {\n const found = agentByName.get(item);\n return found ? [found] : [];\n }\n return [item];\n });\n}\n\n/**\n * Pull `skillsMetadata` from the task input, resolve the backend, and push\n * both into the session. Short-circuits with a `SkillNotAvailable` error if\n * the source references skills the agent doesn't have.\n */\nasync function prepareSkillsForEval(\n session: ReplSession,\n skillsBackend: AnyBackendProtocol | BackendFactory,\n code: string,\n): Promise<string | undefined> {\n const taskInput = getCurrentTaskInput<{ skillsMetadata?: SkillMetadata[] }>();\n const metadata: SkillMetadata[] = taskInput?.skillsMetadata ?? [];\n\n const referenced = scanSkillReferences(code);\n if (referenced.size > 0) {\n const known = new Set(metadata.map((m) => m.name));\n const missing: string[] = [];\n for (const name of referenced) {\n if (!known.has(name)) {\n missing.push(name);\n }\n }\n if (missing.length > 0) {\n session.setSkillsContext(undefined);\n return formatSkillNotAvailable(missing);\n }\n }\n\n const resolved = await resolveBackend(skillsBackend, { state: taskInput });\n session.setSkillsContext({ metadata, backend: resolved });\n return undefined;\n}\n\n/**\n * Create the QuickJS REPL middleware.\n */\nexport function createQuickJSMiddleware(\n options: QuickJSMiddlewareOptions = {},\n) {\n const {\n ptc,\n memoryLimitBytes = DEFAULT_MEMORY_LIMIT,\n maxStackSizeBytes = DEFAULT_MAX_STACK_SIZE,\n executionTimeoutMs = DEFAULT_EXECUTION_TIMEOUT,\n systemPrompt: customSystemPrompt = null,\n skillsBackend,\n maxPtcCalls = DEFAULT_MAX_PTC_CALLS,\n maxResultChars = DEFAULT_MAX_RESULTS_CHARS,\n } = options;\n\n if (maxPtcCalls !== null && maxPtcCalls !== undefined && maxPtcCalls < 1) {\n throw new Error(\"`maxPtcCalls` must be >= 1 or null\");\n }\n\n const baseSystemPrompt = customSystemPrompt || REPL_SYSTEM_PROMPT;\n\n const middlewareId = crypto.randomUUID();\n\n let cachedPtcPrompt: string | null = null;\n\n let ptcTools: StructuredToolInterface[] = [];\n\n function filterToolsForPtc(\n allTools: StructuredToolInterface[],\n ): StructuredToolInterface[] {\n if (!ptc) return [];\n\n const candidates = allTools.filter((t) => t.name !== \"js_eval\");\n\n return resolveToolList(ptc, candidates);\n }\n\n const jsEvalTool = tool(\n async (input, config: LangGraphRunnableConfig) => {\n const threadId = config.configurable?.thread_id || DEFAULT_SESSION_ID;\n const sessionKey = `${threadId}:${middlewareId}`;\n\n const session = ReplSession.getOrCreate(sessionKey, {\n memoryLimitBytes,\n maxStackSizeBytes,\n maxPtcCalls,\n tools: ptcTools,\n skillsEnabled: skillsBackend !== undefined,\n maxResultChars,\n });\n\n if (skillsBackend !== undefined) {\n const setupError = await prepareSkillsForEval(\n session,\n skillsBackend,\n input.code,\n );\n if (setupError !== undefined) {\n return setupError;\n }\n }\n\n const result = await session.eval(input.code, executionTimeoutMs);\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 console.log() for output. Returns the result of the last expression.\n If file or other tools are available, call them via the tools namespace: await tools.readFile({ path }).\n If skills are configured, dynamically import them: await import(\"@/skills/<name>\").\n `,\n metadata: { ls_code_input_language: \"javascript\" },\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 = 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 afterAgent: async (_state, runtime) => {\n const threadId = runtime.configurable?.thread_id ?? DEFAULT_SESSION_ID;\n const sessionKey = `${threadId}:${middlewareId}`;\n ReplSession.deleteSession(sessionKey);\n },\n });\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAwBA,MAAM,WAAWA,MAAAA,OAAO,QAAA,GAAA,2BAAA,WAAiB,CAAC;;;;;;;;;AA2B1C,SAAgB,iBAAiB,MAAsB;CACrD,IAAI;AACJ,KAAI;AACF,QAAM,SAAS,MAAM,MAAM;GACzB,aAAa;GACb,YAAY;GACZ,WAAW;GACZ,CAAC;SACI;AAEN,SAAO,mBAAmB,KAAK;;CAGjC,MAAM,IAAI,IAAIC,aAAAA,QAAY,KAAK;CAE/B,MAAM,gBADU,IACc;AAC9B,MAAK,IAAI,IAAI,GAAG,IAAI,cAAc,QAAQ,KAAK;EAC7C,MAAM,OAAO,cAAc;AAG3B,MAAI,aAAa,KAAK,EAAE;AACtB,KAAE,OAAO,KAAK,OAAO,KAAK,IAAI;AAC9B;;AAIF,MACE,KAAK,SAAS,uBACd,KAAK,SAAS,4BACd,KAAK,SAAS,8BACd,KAAK,SAAS,wBACd;AACA,KAAE,OAAO,KAAK,OAAO,KAAK,IAAI;AAC9B;;AAIF,MAAI,KAAK,SAAS,uBAAuB;AACvC,oBAAiB,GAAG,KAA4C;AAChE;;AAIF,MACE,KAAK,SAAS,yBACd,KAAK,SAAS,oBACd;AACA,wBAAqB,GAAG,KAAK;GAC7B,MAAM,OAAQ,KAAa,IAAI;AAC/B,OAAI,KACF,GAAE,YAAY,KAAK,KAAK,gBAAgB,KAAK,KAAK,KAAK,GAAG;AAE5D;;;AAKJ,MAAK,MAAM,QAAQ,eAAe;AAChC,MAAI,aAAa,KAAK,CAAE;AACxB,MACE,KAAK,SAAS,uBACd,KAAK,SAAS,4BACd,KAAK,SAAS,8BACd,KAAK,SAAS,uBAEd;AACF,MAAI,KAAK,SAAS,sBAChB,EAAA,GAAA,cAAA,MAAK,MAAa,EAChB,MAAM,GAAQ;AACZ,+BAA4B,GAAG,EAAE;KAEpC,CAAC;;CAQN,MAAM,WAAW,qBAAqB,eAAe,EAAE;AACvD,KAAI,YAAY,aAAa,SAAS,EAAE;EACtC,MAAM,EAAE,eAAe;AACvB,IAAE,YAAY,SAAS,OAAO,WAAW;AACzC,IAAE,YAAY,WAAW,KAAK,IAAI;;AAIpC,GAAE,QAAQ,mBAAmB;AAC7B,GAAE,OAAO,SAAS;AAElB,QAAO,EAAE,UAAU;;AAGrB,SAAS,aAAa,MAA0B;CAC9C,MAAM,IAAI,KAAK;AACf,QACE,MAAM,4BACN,MAAM,4BACN,MAAM,uBACN,MAAM,yBACN,MAAM,uBACN,EAAE,WAAW,KAAK;;;;;;;;AAUtB,SAAS,iBACP,GACA,MACM;CACN,MAAM,QAAkB,EAAE;AAE1B,MAAK,MAAM,KAAK,KAAK,cAAc;EACjC,MAAM,KAAK,EAAE;AACb,MAAI,GAAG,SAAS,cAAc;GAC5B,MAAM,WAAW,EAAE,OAAO,iBAAiB,GAAG,EAAE,GAAG;AACnD,SAAM,KACJ,cAAe,GAA6B,KAAK,KAAK,WACvD;aACQ,GAAG,SAAS,mBAAmB,GAAG,SAAS,gBAAgB;GACpE,MAAM,WAAW,oBAAoB,EAAE,GAAU;GACjD,MAAM,WAAW,EAAE,OAAO,iBAAiB,GAAG,EAAE,GAAG;GACnD,MAAM,cAAc,mBAAmB,GAAG,EAAE,GAAgB;AAC5D,SAAM,KAAK,OAAO,YAAY,KAAK,WAAW;AAC9C,QAAK,MAAM,QAAQ,SACjB,OAAM,KAAK,cAAc,KAAK,KAAK,OAAO;;;AAKhD,GAAE,UAAU,KAAK,OAAO,KAAK,KAAK,MAAM,KAAK,KAAK,GAAG,IAAI;;;;;;;AAQ3D,SAAS,iBAAiB,GAAgB,GAAoC;AAC5E,KAAI,CAAC,EAAE,KAAM,QAAO;AACpB,QAAO,mBAAmB,GAAG,EAAE,KAAkB;;AAGnD,SAAS,oBAAoB,SAAwB;CACnD,MAAM,QAAkB,EAAE;AAC1B,KAAI,QAAQ,SAAS;MACf,QAAQ,KAAM,OAAM,KAAK,QAAQ,KAAK;YACjC,QAAQ,SAAS,gBAC1B,MAAK,MAAM,QAAQ,QAAQ,cAAc,EAAE,CACzC,KAAI,KAAK,SAAS,cAChB,OAAM,KAAK,GAAG,oBAAoB,KAAK,SAAS,CAAC;KAEjD,OAAM,KAAK,GAAG,oBAAoB,KAAK,MAAM,CAAC;UAGzC,QAAQ,SAAS;OACrB,MAAM,MAAM,QAAQ,YAAY,EAAE,CACrC,KAAI,GAAI,OAAM,KAAK,GAAG,oBAAoB,GAAG,CAAC;YAEvC,QAAQ,SAAS,cAC1B,OAAM,KAAK,GAAG,oBAAoB,QAAQ,SAAS,CAAC;UAC3C,QAAQ,SAAS,oBAC1B,OAAM,KAAK,GAAG,oBAAoB,QAAQ,KAAK,CAAC;AAElD,QAAO;;AAGT,SAAS,qBAAqB,GAAgB,MAAuB;AACnE,EAAA,GAAA,cAAA,MAAK,MAAa,EAChB,MAAM,GAAQ;AACZ,8BAA4B,GAAG,EAAE;IAEpC,CAAC;;AAGJ,SAAS,4BAA4B,GAAgB,GAAQ,SAAS,GAAS;AAE7E,KAAI,EAAE,kBAAkB,EAAE,eAAe,SAAS,KAChD,GAAE,OAAO,EAAE,eAAe,QAAQ,QAAQ,EAAE,eAAe,MAAM,OAAO;AAG1E,KAAI,EAAE,cAAc,EAAE,WAAW,SAAS,KACxC,GAAE,OAAO,EAAE,WAAW,QAAQ,QAAQ,EAAE,WAAW,MAAM,OAAO;AAGlE,KAAI,EAAE,kBAAkB,EAAE,eAAe,SAAS,KAChD,GAAE,OAAO,EAAE,eAAe,QAAQ,QAAQ,EAAE,eAAe,MAAM,OAAO;AAG1E,KAAI,EAAE,iBAAiB,EAAE,cAAc,SAAS,KAC9C,GAAE,OAAO,EAAE,cAAc,QAAQ,QAAQ,EAAE,cAAc,MAAM,OAAO;AAGxE,KAAI,EAAE,SAAS,oBAAoB,EAAE,WACnC,GAAE,OAAO,EAAE,WAAW,MAAM,QAAQ,EAAE,MAAM,OAAO;AAGrD,KAAI,EAAE,SAAS,yBAAyB,EAAE,WACxC,GAAE,OAAO,EAAE,WAAW,MAAM,QAAQ,EAAE,MAAM,OAAO;AAGrD,KAAI,EAAE,SAAS,2BAA2B,EAAE,WAC1C,GAAE,OAAO,EAAE,WAAW,MAAM,QAAQ,EAAE,MAAM,OAAO;;;;;;;AASvD,SAAS,mBAAmB,GAAgB,MAAyB;CACnE,MAAM,SAAS,KAAK;CACpB,MAAM,SAAS,IAAIA,aAAAA,QAAY,EAAE,MAAM,KAAK,OAAO,KAAK,IAAI,CAAC;AAC7D,EAAA,GAAA,cAAA,MAAK,MAAa,EAChB,MAAM,GAAQ;AACZ,8BAA4B,QAAQ,GAAG,OAAO;IAEjD,CAAC;AACF,QAAO,OAAO,UAAU;;AAG1B,SAAS,qBACP,OACA,GACkB;AAClB,MAAK,IAAI,IAAI,MAAM,SAAS,GAAG,KAAK,GAAG,KAAK;EAC1C,MAAM,OAAO,MAAM;EAEnB,MAAM,QAAQ,EAAE,MAAM,KAAK,OAAO,KAAK,IAAI,CAAC,MAAM;AAClD,MAAI,UAAU,MAAM,UAAU,IAAK;AACnC,SAAO;;AAET,QAAO;;AAGT,SAAS,aAAa,MAA0B;AAC9C,QAAO,KAAK,SAAS;;;;;;;;;;AAWvB,SAAgB,gBAAgB,MAAsB;CACpD,IAAI;AACJ,KAAI;AACF,QAAM,SAAS,MAAM,MAAM;GACzB,aAAa;GACb,YAAY;GACZ,WAAW;GACZ,CAAC;SACI;AAMN,SAAO;;CAGT,MAAM,cAAc,IAAIA,aAAAA,QAAY,KAAK;CACzC,MAAM,UAAU;AAEhB,MAAK,MAAM,QAAQ,QAAQ,MAAM;AAC/B,MAAI,aAAa,KAAK,EAAE;AACtB,eAAY,OAAO,KAAK,OAAO,KAAK,IAAI;AACxC;;AAGF,GAAA,GAAA,cAAA,MAAK,MAAa,EAChB,MAAM,GAAQ;AACZ,+BAA4B,aAAa,EAAE;KAE9C,CAAC;;AAGJ,QAAO,YAAY,UAAU;;;;;;;ACjU/B,MAAa,0BAA0B;CACrC;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACD;;;;AAKD,MAAa,yBAAyB,IAAI,OAAO;;;;AAKjD,MAAM,gBAAgB;;;;;AAMtB,MAAM,qBAAqB;;;;AA8B3B,eAAe,mBACb,SACA,UACA,WACmB;CACnB,MAAM,uBAAO,IAAI,KAAa;AAC9B,MAAK,MAAM,OAAO,yBAAyB;EACzC,MAAM,SAAS,MAAM,QAAQ,KAAK,OAAO,OAAO,SAAS;AACzD,MAAI,OAAO,UAAU,KAAA,EACnB,OAAM,IAAI,MACR,UAAU,UAAU,qBAAqB,SAAS,KAAK,OAAO,QAC/D;EAGH,MAAM,UAAsB,OAAO,SAAS,EAAE;AAC9C,OAAK,MAAM,SAAS,QAClB,MAAK,IAAI,MAAM,KAAK;;AAIxB,QAAO,CAAC,GAAG,KAAK,CAAC,MAAM;;;;;AAMzB,SAAS,YACP,WACA,WACyB;CACzB,MAAM,UAAU,IAAI,YAAY,SAAS,EAAE,OAAO,MAAM,CAAC;CAEzD,MAAM,QAAiC,EAAE;AACzC,MAAK,MAAM,YAAY,WAAW;AAChC,MAAI,SAAS,UAAU,QAAQ,SAAS,YAAY,KAClD,OAAM,IAAI,MACR,UAAU,UAAU,yBAAyB,SAAS,KAAK,KAAK,SAAS,SAAS,eACnF;EAGH,IAAI;AACJ,MAAI;AACF,YAAS,QAAQ,OAAO,SAAS,QAAQ;UACnC;AACN,SAAM,IAAI,MACR,UAAU,UAAU,WAAW,SAAS,KAAK,sBAC9C;;AAGH,QAAM,KAAK,CAAC,SAAS,MAAM,OAAO,CAAC;;AAGrC,QAAO;;;;;;;AAQT,SAAS,mBACP,OACA,WACM;CACN,IAAI,QAAQ;AACZ,MAAK,MAAM,GAAG,WAAW,MACvB,UAAS,OAAO;AAGlB,KAAI,QAAA,QACF,OAAM,IAAI,MACR,UAAU,UAAU,oBAAoB,uBAAuB,gBAAgB,MAAM,GACtF;;;;;;;AASL,SAAS,cACP,UACA,cACA,WACQ;CACR,MAAM,MAAMC,gBAAM,SAAS,UAAU,aAAa;AAClD,KAAI,QAAQ,MAAM,IAAI,WAAW,KAAK,CACpC,OAAM,IAAI,MACR,UAAU,UAAU,UAAU,aAAa,iBAAiB,SAAS,GACtE;AAEH,QAAO;;;;;AAMT,SAAS,cACP,UACA,UACA,OACA,WACqB;CACrB,MAAM,wBAAQ,IAAI,KAAqB;CACvC,IAAI,eAAe;AAEnB,MAAK,MAAM,CAAC,SAAS,WAAW,OAAO;EACrC,MAAM,MAAM,cAAc,UAAU,SAAS,UAAU;AACvD,QAAM,IAAI,KAAK,gBAAgB,OAAO,CAAC;AACvC,MAAI,QAAQ,SACV,gBAAe;;AAInB,KAAI,CAAC,aACH,OAAM,IAAI,MACR,UAAU,UAAU,kBAAkB,SAAS,iDAChD;AAGH,QAAO;;;;;;;;AAST,eAAsB,UACpB,UACA,SACsB;CACtB,MAAM,OAAO,SAAS;AAEtB,KAAI,CAAC,cAAc,KAAK,KAAK,CAC3B,OAAM,IAAI,MACR,eAAe,KAAK,wCACrB;CAGH,MAAM,WAAW,SAAS;AAC1B,KAAI,aAAa,KAAA,KAAa,aAAa,GACzC,OAAM,IAAI,MACR,UAAU,KAAK,4FAChB;CAGH,MAAM,WAAA,GAAA,WAAA,sBAA+B,QAAQ;AAC7C,KAAI,QAAQ,kBAAkB,KAAA,EAC5B,OAAM,IAAI,MACR,UAAU,KAAK,6CAChB;CAGH,MAAM,WAAWA,gBAAM,QAAQ,SAAS,KAAK;CAC7C,MAAM,YAAY,MAAM,mBAAmB,SAAS,UAAU,KAAK;AACnE,KAAI,UAAU,WAAW,EACvB,OAAM,IAAI,MAAM,UAAU,KAAK,2BAA2B,SAAS,GAAG;CAIxE,MAAM,YAAY,YADA,MAAM,QAAQ,cAAc,UAAU,EACf,KAAK;AAC9C,oBAAmB,WAAW,KAAK;CAEnC,MAAM,QAAQ,cAAc,UAAU,UAAU,WAAW,KAAK;AAChE,QAAO;EACL;EACA,WAAW,YAAY;EACvB;EACA;EACD;;;;;;;;;AAUH,SAAgB,oBAAoB,QAA6B;CAC/D,MAAM,wBAAQ,IAAI,KAAa;CAE/B,MAAM,UAAU,OAAO,SAAS,mBAAmB;AACnD,MAAK,MAAM,SAAS,QAClB,OAAM,IAAI,MAAM,GAAG;AAGrB,QAAO;;;;;;;AC9OT,IAAa,6BAAb,cAAgD,MAAM;CACpD;CACA;CACA;CAEA,YAAY,SAAuC;AACjD,QACE,mCAAmC,QAAQ,MAAM,cAAc,QAAQ,UAAU,aAAa,QAAQ,aAAa,GACpH;AACD,OAAK,OAAO;AACZ,OAAK,QAAQ,QAAQ;AACrB,OAAK,YAAY,QAAQ;AACzB,OAAK,eAAe,QAAQ;;;;;;;;AC3BhC,SAAgB,YAAY,MAAsB;AAChD,QAAO,KAAK,QAAQ,iBAAiB,GAAG,MAAM,EAAE,aAAa,CAAC;;;;;AAwBhE,SAAgB,iBAAiB,QAA4B;CAC3D,MAAM,QAAkB,EAAE;AAE1B,KAAI,OAAO,KAAK,SAAS,GAAG;EAC1B,IAAI,WAAW,OAAO,KAAK,KAAK,KAAK;AACrC,MAAI,OAAO,mBAAmB,EAC5B,aAAY,gBAAgB,OAAO,iBAAiB;AAEtD,QAAM,KAAK,SAAS;;AAGtB,KAAI,OAAO;MACL,OAAO,UAAU,KAAA,GAAW;GAC9B,MAAM,YACJ,OAAO,OAAO,UAAU,WACpB,OAAO,QACP,KAAK,UAAU,OAAO,OAAO,MAAM,EAAE;AAC3C,SAAM,KAAK,KAAK,YAAY;;YAErB,OAAO,OAAO;EACvB,MAAM,UAAU,OAAO,MAAM,QAAQ;EACrC,MAAM,SAAS,OAAO,MAAM,WAAW;AACvC,QAAM,KAAK,GAAG,QAAQ,IAAI,SAAS;AACnC,MAAI,OAAO,MAAM,MACf,OAAM,KAAK,OAAO,MAAM,MAAM;;AAIlC,QAAO,MAAM,KAAK,KAAK,IAAI;;AAG7B,SAAgB,iBACd,QACqC;AACrC,KAAI;AACF,UAAA,GAAA,kCAAA,cAAoB,OAA6C;SAI3D;AACN;;;AAIJ,eAAe,kBACb,YACA,eACiB;AAMjB,SALiB,OAAA,GAAA,0BAAA,SACf;EAAE,GAAG;EAAY,sBAAsB;EAAO,EAC9C,eACA;EAAE,eAAe;EAAI,sBAAsB;EAAO,CACnD,EACe,QAAQ,YAAY,GAAG,CAAC,SAAS;;AAGnD,SAAgB,WAAW,GAAmB;AAC5C,QAAO,EAAE,OAAO,EAAE,CAAC,aAAa,GAAG,EAAE,MAAM,EAAE;;AAG/C,eAAsB,oBACpB,MACA,aACA,YACiB;CACjB,MAAM,YAAY,GAAG,WAAW,KAAK,CAAC;AAEtC,KAAI,CAAC,cAAc,CAAC,WAAW,WAC7B,QAAO,OAAA,OAAM;;WAEN,YAAY;;oBAEH,KAAK;;AAKvB,QAAO,OAAA,OAAM;MADC,MAAM,kBAAkB,YAAY,UAAU,CAElD;;;SAGH,YAAY;;kBAEH,KAAK,UAAU,UAAU;;;;;;AAO3C,SAAgB,wBAAwB,SAAoC;AAE1E,QAAO,uBADM,CAAC,GAAG,QAAQ,CAAC,MAAM,CAAC,KAAK,KAAK;;;;;;;;;;;;;;;;;;;;;;AC1F7C,MAAa,uBAAuB,KAAK,OAAO;AAChD,MAAa,yBAAyB,MAAM;AAC5C,MAAa,4BAA4B;AAEzC,MAAa,wBAAwB;AACrC,MAAa,4BAA4B;AAIzC,MAAM,gBAAgB,OAAO;AAO7B,eAAe,iBAAiB;CAC9B,MAAM,UAAU,MAAM;AACtB,SAAA,GAAA,wBAAA,sCACG,QAAQ,WAAW,QACrB;;AAcH,SAAS,gBAAgB,SAAyB;AAChD,QAAO,mCAAmC,KAAK,UAAU,QAAQ,CAAC;;;;;;;AAQpE,SAAS,oBACP,WAC4C;AAE5C,KAAI,CAAC,UAAU,WADA,YACkB,CAC/B;CAGF,MAAM,OAAO,UAAU,MAAM,EAAc;CAC3C,MAAM,WAAW,KAAK,QAAQ,IAAI;CAClC,MAAM,OAAO,aAAa,KAAK,OAAO,KAAK,MAAM,GAAG,SAAS;AAC7D,KAAI,CAAC,6BAA6B,KAAK,KAAK,CAC1C;CAGF,MAAM,MAAM,aAAa,KAAK,KAAA,IAAY,KAAK,MAAM,WAAW,EAAE;AAClE,KAAI,QAAQ,KAAA,KAAa,QAAQ,GAC/B;AAGF,QAAO;EAAE;EAAM;EAAK;;;;;AAMtB,SAAS,iBAAiB,MAAkC;CAC1D,MAAM,SAAS,oBAAoB,KAAK;AACxC,KAAI,WAAW,KAAA,EACb;AAEF,QAAO,YAAY,OAAO;;;;;AAM5B,SAAS,aAAa,GAAmB;CACvC,MAAM,MAAM,EAAE,YAAY,IAAI;AAC9B,KAAI,QAAQ,GACV,QAAO;AAET,QAAO,EAAE,MAAM,GAAG,IAAI;;;;;;AAOxB,SAAS,UAAU,MAAc,KAAqB;CACpD,MAAM,MAAgB,EAAE;CAExB,MAAM,WAAW,GAAG,KAAK,GAAG,MAAM,MAAM,IAAI;AAC5C,MAAK,MAAM,WAAW,UAAU;AAC9B,MAAI,YAAY,MAAM,YAAY,IAChC;AAGF,MAAI,YAAY,MAAM;AACpB,OAAI,KAAK;AACT;;AAGF,MAAI,KAAK,QAAQ;;AAGnB,QAAO,IAAI,KAAK,IAAI;;;;;;;;;AAUtB,IAAM,gBAAN,MAAoB;CAClB;CACA,SAAyB;CACzB,eAA+B;CAE/B,YAAY,UAAkB;AAC5B,OAAK,WAAW,KAAK,IAAI,UAAU,EAAE;;;;;;;;;CAUvC,OAAO,MAAoB;EACzB,MAAM,YAAY,KAAK,WAAW,KAAK,OAAO;AAC9C,MAAI,aAAa,GAAG;AAClB,QAAK,gBAAgB,KAAK;AAC1B;;AAGF,MAAI,KAAK,UAAU,UACjB,MAAK,UAAU;OACV;AACL,QAAK,UAAU,KAAK,MAAM,GAAG,UAAU;AACvC,QAAK,gBAAgB,KAAK,SAAS;;;;;;;CAQvC,QAA0B;EACxB,MAAM,MAAM,KAAK;EACjB,MAAM,UAAU,KAAK;AAErB,OAAK,SAAS;AACd,OAAK,eAAe;AAEpB,SAAO,CAAC,KAAK,QAAQ;;;;;;;;;;;AAYzB,IAAa,cAAb,MAAa,YAAY;CACvB,OAAe,2BAAW,IAAI,KAA0B;CAExD;CAEA,UAA8C;CAC9C,UAA8C;CAC9C,gBAAuC,IAAI,cACzC,0BACD;CACD;CACA;CACA,+BAAiD,IAAI,KAAK;CAC1D,+BAA2C,IAAI,KAAK;CACpD;CACA,oBAA2C;CAE3C,YAAY,IAAY,UAA8B,EAAE,EAAE;AACxD,OAAK,KAAK;AACV,OAAK,UAAU;AACf,OAAK,cACH,QAAQ,gBAAgB,KAAA,IACpB,QAAQ,cAAA;;CAIhB,MAAc,gBAA+B;AAC3C,MAAI,KAAK,QAAS;EAElB,MAAM,EACJ,mBAAmB,sBACnB,oBAAoB,wBACpB,OACA,gBAAgB,OAChB,iBAAiB,8BACf,KAAK;EAGT,MAAM,WADc,MAAM,gBAAgB,EACO,YAAY;AAC7D,UAAQ,eAAe,iBAAiB;AACxC,UAAQ,gBAAgB,kBAAkB;EAE1C,MAAM,UAA+B,QAAQ,YAAY;AACzD,OAAK,UAAU;AACf,OAAK,UAAU;AAEf,OAAK,gBAAgB,IAAI,cAAc,eAAe;AACtD,OAAK,cAAc;AAEnB,MAAI,UAAU,KAAA,KAAa,MAAM,SAAS,EACxC,MAAK,YAAY,MAAM;AAGzB,MAAI,cACF,MAAK,qBAAqB;;;;;CAO9B,MAAc,kBAAkB,MAAoC;EAClE,MAAM,SAAS,KAAK,aAAa,IAAI,KAAK;AAC1C,MAAI,WAAW,KAAA,EACb,QAAO;EAGT,MAAM,cAAc,KAAK,aAAa,IAAI,KAAK;AAC/C,MAAI,gBAAgB,KAAA,EAClB,OAAM;EAGR,MAAM,MAAM,KAAK;AACjB,MAAI,QAAQ,KAAA,EACV,OAAM,IAAI,MACR,UAAU,KAAK,6DAChB;EAGH,MAAM,WAAW,IAAI,SAAS,MAAM,MAAM,EAAE,SAAS,KAAK;AAC1D,MAAI,aAAa,KAAA,EACf,OAAM,IAAI,MACR,UAAU,KAAK,8CAChB;AAGH,MAAI;GACF,MAAM,SAAS,MAAM,UAAU,UAAU,IAAI,QAAQ;AACrD,QAAK,aAAa,IAAI,MAAM,OAAO;AACnC,UAAO;WACA,KAAK;AACZ,QAAK,aAAa,IAAI,MAAM,IAAa;AACzC,SAAM;;;CAIV,MAAc,iBAAiB,WAAoC;EACjE,MAAM,SAAS,oBAAoB,UAAU;AAC7C,MAAI,WAAW,KAAA,EACb,QAAO,gBAAgB,qBAAqB,YAAY;EAG1D,IAAI;AACJ,MAAI;AACF,YAAS,MAAM,KAAK,kBAAkB,OAAO,KAAK;WAC3C,KAAK;AACZ,UAAO,gBAAiB,IAAc,WAAW,OAAO,IAAI,CAAC;;AAG/D,MAAI,OAAO,QAAQ,KAAA,GAAW;GAC5B,MAAM,SAAS,OAAO,MAAM,IAAI,OAAO,SAAS;AAChD,OAAI,WAAW,KAAA,EACb,QAAO,gBACL,UAAU,OAAO,KAAK,iBAAiB,OAAO,SAAS,uBACxD;AAEH,UAAO;;EAGT,MAAM,SAAS,OAAO,MAAM,IAAI,OAAO,IAAI;AAC3C,MAAI,WAAW,KAAA,EACb,QAAO,gBACL,UAAU,OAAO,KAAK,MAAM,OAAO,IAAI,uBACxC;AAGH,SAAO;;;;;;;CAQT,mBAA2B,MAAc,WAA2B;AAGlE,MAAI,EADF,UAAU,WAAW,KAAK,IAAI,UAAU,WAAW,MAAM,EAEzD,QAAO;EAMT,MAAM,SAAS,oBAAoB,KAAK;EAKxC,MAAM,WAAW,UAHf,WAAW,KAAA,KAAa,OAAO,QAAQ,KAAA,IACnC,OACA,aAAa,KAAK,EACY,UAAU;EAE9C,MAAM,cAAc,iBAAiB,KAAK;AAC1C,MAAI,gBAAgB,KAAA,EAClB,QAAO;AAGT,MAAI,CAAC,SAAS,WAAW,GAAG,YAAY,GAAG,CACzC,QAAO,qBAAqB,UAAU,WAAW;AAGnD,SAAO;;;;;CAMT,sBAAoC;AAClC,MAAI,KAAK,YAAY,KACnB;AAGF,OAAK,QAAQ,gBACX,OAAO,cAAsB,KAAK,iBAAiB,UAAU,GAC5D,MAAc,cACb,KAAK,mBAAmB,MAAM,UAAU,CAC3C;;;;;CAMH,iBAA+B;AAC7B,OAAK,oBACH,KAAK,gBAAgB,OAAO,OAAO,KAAK;;;;;;CAO5C,iBAAyB,cAA4B;AACnD,MAAI,KAAK,sBAAsB,KAC7B;AAGF,MAAI,KAAK,oBAAoB,GAAG;AAC9B,QAAK;AACL;;EAGF,MAAM,QAAQ,KAAK,eAAe;AAClC,QAAM,IAAI,2BAA2B;GACnC;GACA,WAAW,QAAQ;GACnB;GACD,CAAC;;;;;;;;;CAUJ,OAAO,YACL,IACA,UAA8B,EAAE,EACnB;EACb,MAAM,WAAW,YAAY,SAAS,IAAI,GAAG;AAC7C,MAAI,SACF,QAAO;EAGT,MAAM,UAAU,IAAI,YAAY,IAAI,QAAQ;AAC5C,cAAY,SAAS,IAAI,IAAI,QAAQ;AACrC,SAAO;;;;;CAMT,OAAO,IAAI,IAAgC;AACzC,SAAO,YAAY,SAAS,IAAI,GAAG,IAAI;;;;;;;CAQzC,OAAO,gBAAgB,UAA2B;EAChD,MAAM,SAAS,GAAG,SAAS;AAC3B,OAAK,MAAM,OAAO,YAAY,SAAS,MAAM,CAC3C,KAAI,QAAQ,YAAY,IAAI,WAAW,OAAO,CAC5C,QAAO;AAGX,SAAO;;;;;CAMT,OAAO,cAAc,KAAmB;EACtC,MAAM,UAAU,YAAY,SAAS,IAAI,IAAI;AAC7C,MAAI,QACF,SAAQ,SAAS;;;;;;;CASrB,iBAAiB,KAA2B;AAC1C,OAAK,gBAAgB;;;;;;;;;;;CAYvB,MAAM,KAAK,MAAc,WAAwC;AAC/D,QAAM,KAAK,eAAe;EAC1B,MAAM,UAAU,KAAK;EACrB,MAAM,UAAU,KAAK;EAErB,MAAM,kBAAgE;GACpE,MAAM,CAAC,KAAK,WAAW,KAAK,cAAc,OAAO;AACjD,UAAO;IACL,MAAM,IAAI,SAAS,IAAI,IAAI,MAAM,KAAK,CAAC,QAAQ,MAAM,EAAE,SAAS,EAAE,GAAG,EAAE;IACvE,kBAAkB;IACnB;;AAGH,OAAK,gBAAgB;AACrB,MAAI;AACF,OAAI,aAAa,EACf,SAAQ,qBAAA,GAAA,mBAAA,8BACuB,KAAK,KAAK,GAAG,UAAU,CACrD;OAED,SAAQ,0BAA0B,MAAM;GAG1C,MAAM,cAAc,iBAAiB,KAAK;GAC1C,MAAM,SAAS,MAAM,QAAQ,cAAc,YAAY;AAEvD,OAAI,OAAO,OAAO;IAChB,MAAM,QAAQ,QAAQ,KAAK,OAAO,MAAM;AACxC,WAAO,MAAM,SAAS;AACtB,WAAO;KAAE,IAAI;KAAO;KAAO,GAAG,WAAW;KAAE;;GAG7C,MAAM,eAAe,QAAQ,gBAAgB,OAAO,MAAM;AAE1D,OAAI,aAAa,SAAS,aAAa;AACrC,QAAI,aAAa,aAAa;KAC5B,MAAM,QAAQ,QAAQ,KAAK,OAAO,MAAM;AACxC,YAAO,MAAM,SAAS;AACtB,YAAO;MAAE,IAAI;MAAM;MAAO,GAAG,WAAW;MAAE;;IAE5C,MAAM,QAAQ,QAAQ,KAAK,aAAa,MAAM;AAC9C,iBAAa,MAAM,SAAS;AAC5B,WAAO,MAAM,SAAS;AACtB,WAAO;KAAE,IAAI;KAAM;KAAO,GAAG,WAAW;KAAE;;AAG5C,OAAI,aAAa,SAAS,YAAY;IACpC,MAAM,QAAQ,QAAQ,KAAK,aAAa,MAAM;AAC9C,iBAAa,MAAM,SAAS;AAC5B,WAAO,MAAM,SAAS;AACtB,WAAO;KAAE,IAAI;KAAO;KAAO,GAAG,WAAW;KAAE;;GAG7C,MAAM,YAAY,YAAY;GAC9B,MAAM,WAAW,YAAY,WAAW,KAAK,KAAK,GAAG;AACrD,UAAO,aAAa,KAAK,KAAK,GAAG,UAAU;AACzC,YAAQ,QAAQ,oBAAoB;IACpC,MAAM,QAAQ,QAAQ,gBAAgB,OAAO,MAAM;AACnD,QAAI,MAAM,SAAS,aAAa;KAC9B,MAAM,QAAQ,QAAQ,KAAK,MAAM,MAAM;AACvC,WAAM,MAAM,SAAS;AACrB,YAAO,MAAM,SAAS;AACtB,YAAO;MAAE,IAAI;MAAM;MAAO,GAAG,WAAW;MAAE;;AAE5C,QAAI,MAAM,SAAS,YAAY;KAC7B,MAAM,QAAQ,QAAQ,KAAK,MAAM,MAAM;AACvC,WAAM,MAAM,SAAS;AACrB,YAAO,MAAM,SAAS;AACtB,YAAO;MAAE,IAAI;MAAO;MAAO,GAAG,WAAW;MAAE;;AAE7C,UAAM,IAAI,SAAS,MAAM,WAAW,GAAG,EAAE,CAAC;;AAG5C,UAAO,MAAM,SAAS;AACtB,UAAO;IACL,IAAI;IACJ,OAAO,EAAE,SAAS,6CAA6C;IAC/D,GAAG,WAAW;IACf;YACO;AACR,QAAK,oBAAoB;;;CAI7B,UAAgB;AACd,MAAI;AACF,QAAK,SAAS,SAAS;UACjB;AAGR,MAAI;AACF,QAAK,SAAS,SAAS;UACjB;AAGR,OAAK,UAAU;AACf,OAAK,UAAU;AACf,cAAY,SAAS,OAAO,KAAK,GAAG;;CAGtC,SAAyB;AACvB,SAAO,EAAE,IAAI,KAAK,IAAI;;CAGxB,OAAO,SAAS,MAAmC;AACjD,SAAO,YAAY,SAAS,IAAI,KAAK,GAAG,IAAI,IAAI,YAAY,KAAK,GAAG;;;;;;CAOtE,OAAO,aAAmB;AACxB,OAAK,MAAM,WAAW,YAAY,SAAS,QAAQ,CACjD,SAAQ,SAAS;AAEnB,cAAY,SAAS,OAAO;;CAG9B,eAA6B;EAC3B,MAAM,UAAU,KAAK;EACrB,MAAM,gBAAgB,QAAQ,WAAW;AACzC,OAAK,MAAM,UAAU;GAAC;GAAO;GAAQ;GAAS;GAAQ;GAAQ,EAAW;GACvE,MAAM,WAAW,QAAQ,YACvB,SACC,GAAG,SAA0B;IAE5B,MAAM,YADa,KAAK,KAAK,MAAqB,QAAQ,KAAK,EAAE,CAAC,CAE/D,KAAK,MACJ,OAAO,MAAM,YAAY,MAAM,OAC3B,KAAK,UAAU,EAAE,GACjB,OAAO,EAAE,CACd,CACA,KAAK,IAAI;IACZ,MAAM,OACJ,WAAW,SAAS,WAAW,UAAU,WAAW,UAChD,YACA,IAAI,OAAO,IAAI;AACrB,SAAK,cAAc,OAAO,OAAO,KAAK;KAEzC;AACD,WAAQ,QAAQ,eAAe,QAAQ,SAAS;AAChD,YAAS,SAAS;;AAEpB,UAAQ,QAAQ,QAAQ,QAAQ,WAAW,cAAc;AACzD,gBAAc,SAAS;;CAGzB,YAAoB,OAAwC;EAC1D,MAAM,UAAU,KAAK;EACrB,MAAM,UAAU,QAAQ,WAAW;AAEnC,OAAK,MAAM,KAAK,OAAO;GACrB,MAAM,YAAY,YAAY,EAAE,KAAK;GACrC,MAAM,WAAW,QAAQ,YACvB,YACC,gBAA+B;IAC9B,MAAM,QAAQ,QAAQ,KAAK,YAAY;IACvC,MAAM,UAAU,QAAQ,YAAY;AACpC,KAAC,YAAY;AACX,SAAI;AACF,WAAK,iBAAiB,UAAU;MAChC,MAAM,WACJ,OAAO,UAAU,YAAY,UAAU,OAAO,QAAQ,EAAE;MAC1D,MAAM,SAAS,MAAM,EAAE,OAAO,SAAS;MACvC,MAAM,MAAM,QAAQ,UAClB,OAAO,WAAW,WAAW,SAAS,KAAK,UAAU,OAAO,CAC7D;AACD,cAAQ,QAAQ,IAAI;AACpB,UAAI,SAAS;cACN,GAAY;MACnB,MAAM,MACJ,KAAK,QAAQ,OAAQ,EAAY,YAAY,WACxC,EAAY,UACb,OAAO,EAAE;MACf,MAAM,MAAM,QAAQ,SAAS,SAAS,EAAE,KAAK,YAAY,MAAM;AAC/D,cAAQ,OAAO,IAAI;AACnB,UAAI,SAAS;;AAEf,aAAQ,QAAQ,KAAK,QAAQ,QAAQ,mBAAmB;QACtD;AACJ,WAAO,QAAQ;KAElB;AACD,WAAQ,QAAQ,SAAS,WAAW,SAAS;AAC7C,YAAS,SAAS;;AAGpB,UAAQ,QAAQ,QAAQ,QAAQ,SAAS,QAAQ;AACjD,UAAQ,SAAS;;;;;;;;;;;;;AC5mBrB,MAAM,qBAAqB,OAAA,OAAM;;;;;;;;;;;;;;;;;;;;;;;AAwBjC,eAAsB,kBACpB,OACiB;AACjB,KAAI,MAAM,WAAW,EAAG,QAAO;AAa/B,QAAO,OAAA,OAAM;;;;;;;;;;;;;;;;;;;;;;;OAXM,MAAM,QAAQ,IAC/B,MAAM,KAAK,MAAM;EACf,MAAM,aAAa,EAAE,SAAS,iBAAiB,EAAE,OAAO,GAAG,KAAA;AAC3D,SAAO,oBACL,YAAY,EAAE,KAAK,EACnB,EAAE,aACF,WACD;GACD,CACH,EAyBc,KAAK,OAAO,CAAC;;;;;;;;;;AAW9B,SAAgB,gBACd,OACA,YAC2B;CAC3B,MAAM,cAAc,IAAI,IAAI,WAAW,KAAK,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC;AAC/D,QAAO,MAAM,SAAS,SAAS;AAC7B,MAAI,OAAO,SAAS,UAAU;GAC5B,MAAM,QAAQ,YAAY,IAAI,KAAK;AACnC,UAAO,QAAQ,CAAC,MAAM,GAAG,EAAE;;AAE7B,SAAO,CAAC,KAAK;GACb;;;;;;;AAQJ,eAAe,qBACb,SACA,eACA,MAC6B;CAC7B,MAAM,aAAA,GAAA,qBAAA,sBAAuE;CAC7E,MAAM,WAA4B,WAAW,kBAAkB,EAAE;CAEjE,MAAM,aAAa,oBAAoB,KAAK;AAC5C,KAAI,WAAW,OAAO,GAAG;EACvB,MAAM,QAAQ,IAAI,IAAI,SAAS,KAAK,MAAM,EAAE,KAAK,CAAC;EAClD,MAAM,UAAoB,EAAE;AAC5B,OAAK,MAAM,QAAQ,WACjB,KAAI,CAAC,MAAM,IAAI,KAAK,CAClB,SAAQ,KAAK,KAAK;AAGtB,MAAI,QAAQ,SAAS,GAAG;AACtB,WAAQ,iBAAiB,KAAA,EAAU;AACnC,UAAO,wBAAwB,QAAQ;;;CAI3C,MAAM,WAAW,OAAA,GAAA,WAAA,gBAAqB,eAAe,EAAE,OAAO,WAAW,CAAC;AAC1E,SAAQ,iBAAiB;EAAE;EAAU,SAAS;EAAU,CAAC;;;;;AAO3D,SAAgB,wBACd,UAAoC,EAAE,EACtC;CACA,MAAM,EACJ,KACA,mBAAmB,sBACnB,oBAAoB,wBACpB,qBAAqB,2BACrB,cAAc,qBAAqB,MACnC,eACA,cAAA,KACA,iBAAiB,8BACf;AAEJ,KAAI,gBAAgB,QAAQ,gBAAgB,KAAA,KAAa,cAAc,EACrE,OAAM,IAAI,MAAM,qCAAqC;CAGvD,MAAM,mBAAmB,sBAAsB;CAE/C,MAAM,eAAe,OAAO,YAAY;CAExC,IAAI,kBAAiC;CAErC,IAAI,WAAsC,EAAE;CAE5C,SAAS,kBACP,UAC2B;AAC3B,MAAI,CAAC,IAAK,QAAO,EAAE;AAInB,SAAO,gBAAgB,KAFJ,SAAS,QAAQ,MAAM,EAAE,SAAS,UAAU,CAExB;;AAkDzC,SAAA,GAAA,UAAA,kBAAwB;EACtB,MAAM;EACN,OAAO,EAAA,GAAA,UAAA,MAhDP,OAAO,OAAO,WAAoC;GAEhD,MAAM,aAAa,GADF,OAAO,cAAc,aAAA,cACP,GAAG;GAElC,MAAM,UAAU,YAAY,YAAY,YAAY;IAClD;IACA;IACA;IACA,OAAO;IACP,eAAe,kBAAkB,KAAA;IACjC;IACD,CAAC;AAEF,OAAI,kBAAkB,KAAA,GAAW;IAC/B,MAAM,aAAa,MAAM,qBACvB,SACA,eACA,MAAM,KACP;AACD,QAAI,eAAe,KAAA,EACjB,QAAO;;AAKX,UAAO,iBADQ,MAAM,QAAQ,KAAK,MAAM,MAAM,mBAAmB,CAClC;KAEjC;GACE,MAAM;GACN,aAAa,OAAA,OAAM;;;;;;GAMnB,UAAU,EAAE,wBAAwB,cAAc;GAClD,QAAQC,OAAAA,EAAE,OAAO,EACf,MAAMA,OAAAA,EACH,QAAQ,CACR,SACC,+DACD,EACJ,CAAC;GACH,CACF,CAIoB;EACnB,eAAe,OAAO,SAAS,YAAY;AAEzC,cAAW,kBADS,QAAQ,SAAS,EAAE,CACC;AAExC,OAAI,SAAS,SAAS,KAAK,CAAC,gBAC1B,mBAAkB,MAAM,kBAAkB,SAAS;GAGrD,MAAM,gBAAgB,QAAQ,cAC3B,OAAO,iBAAiB,CACxB,OAAO,mBAAmB,GAAG;AAChC,UAAO,QAAQ;IAAE,GAAG;IAAS;IAAe,CAAC;;EAE/C,YAAY,OAAO,QAAQ,YAAY;GAErC,MAAM,aAAa,GADF,QAAQ,cAAc,aAAA,cACR,GAAG;AAClC,eAAY,cAAc,WAAW;;EAExC,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.cjs","names":["Parser","MagicString","program","posix","z"],"sources":["../src/transform.ts","../src/skills.ts","../src/errors.ts","../src/utils.ts","../src/session.ts","../src/middleware.ts"],"sourcesContent":["/**\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/**\n * Strip TypeScript type syntax from an ES-module source so QuickJS can\n * evaluate it as a standard JS module.\n *\n * Unlike `transformForEval`, this keeps `import`/`export` declarations,\n * does not hoist to `globalThis`, and does not wrap in an IIFE.\n * On parse failure the original source is returned unchanged.\n */\nexport function stripTypeSyntax(code: string): string {\n let ast: AcornNode;\n try {\n ast = TSParser.parse(code, {\n ecmaVersion: \"latest\",\n sourceType: \"module\",\n locations: true,\n }) as unknown as AcornNode;\n } catch {\n // Return the original source unchanged rather than throwing or returning an empty string.\n // We don't know why the parse failed - it could be a valid plain-JS file that hit an\n // acorn-typescript incompatibility, in which case returning it unchanged lets QuickJS\n // evaluate it correctly. If it's genuinely broken TS, QuickJS will surface the parse error\n // at evaluation time with a useful line/column.\n return code;\n }\n\n const magicString = new MagicString(code);\n const program = ast as unknown as { body: AcornNode[] };\n\n for (const node of program.body) {\n if (isTSOnlyNode(node)) {\n magicString.remove(node.start, node.end);\n continue;\n }\n\n walk(node as any, {\n enter(n: any) {\n stripTypeAnnotationFromNode(magicString, n);\n },\n });\n }\n\n return magicString.toString();\n}\n","import * as posix from \"node:path/posix\";\n\nimport {\n adaptBackendProtocol,\n BackendProtocolV2,\n type AnyBackendProtocol,\n type FileDownloadResponse,\n type FileInfo,\n type SkillMetadata,\n} from \"deepagents\";\n\nimport { stripTypeSyntax } from \"./transform.js\";\n\n/**\n * File extensions the loader will enumerate from a skill directory.\n */\nexport const SKILL_MODULE_EXTENSIONS = [\n \".js\",\n \".mjs\",\n \".cjs\",\n \".ts\",\n \".mts\",\n \".cts\",\n \".jsx\",\n \".tsx\",\n];\n\n/**\n * Hard cap on total bytes pulled for one skill's bundle (1 MiB).\n */\nexport const MAX_SKILL_BUNDLE_BYTES = 1 * 1024 * 1024;\n\n/**\n * Validates a skill name against the spec's kebab-case rule.\n */\nconst SKILL_NAME_RE = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;\n\n/**\n * Matches `\"@/skills/<name>\"` or `'@/skills/<name>'` references in source.\n * Template literals and computed specifiers are not caught.\n */\nconst SKILL_SPECIFIER_RE = /[\"']@\\/skills\\/([a-z0-9]+(?:-[a-z0-9]+)*)[\"']/g;\n\n/**\n * Install-ready state for a single skill, produced by `loadSkill`.\n */\nexport interface LoadedSkill {\n /**\n * Spec-validated kebab-case skill name.\n */\n name: string;\n\n /**\n * Bare specifier the skill installs under: `\"@/skills/<name>\"`.\n */\n specifier: string;\n\n /**\n * Relative POSIX path of the entrypoint file (e.g. `\"index.ts\"`).\n */\n entryRel: string;\n\n /**\n * File contents keyed by relative POSIX path, with TS syntax stripped.\n */\n files: Map<string, string>;\n}\n\n/**\n * List every code-extension file under `skillDir` (recursive).\n */\nasync function enumerateCodeFiles(\n backend: BackendProtocolV2,\n skillDir: string,\n skillName: string,\n): Promise<string[]> {\n const seen = new Set<string>();\n for (const ext of SKILL_MODULE_EXTENSIONS) {\n const result = await backend.glob(`**/*${ext}`, skillDir);\n if (result.error !== undefined) {\n throw new Error(\n `Skill '${skillName}': failed to list '${skillDir}': ${result.error}`,\n );\n }\n\n const matches: FileInfo[] = result.files ?? [];\n for (const match of matches) {\n seen.add(match.path);\n }\n }\n\n return [...seen].sort();\n}\n\n/**\n * Decode download responses into [path, source] pairs.\n */\nfunction decodeFiles(\n responses: FileDownloadResponse[],\n skillName: string,\n): Array<[string, string]> {\n const decoder = new TextDecoder(\"utf-8\", { fatal: true });\n\n const pairs: Array<[string, string]> = [];\n for (const response of responses) {\n if (response.error !== null || response.content === null) {\n throw new Error(\n `Skill '${skillName}': failed to download '${response.path}': ${response.error ?? \"no content\"}`,\n );\n }\n\n let source: string;\n try {\n source = decoder.decode(response.content);\n } catch {\n throw new Error(\n `Skill '${skillName}': file '${response.path}' is not valid UTF-8`,\n );\n }\n\n pairs.push([response.path, source]);\n }\n\n return pairs;\n}\n\n/**\n * Throws an Error when the total decoded size of all files exceeds\n * `MAX_SKILL_BUNDLE_BYTES`. Counts characters rather than bytes, which\n * over-counts multi-byte UTF-8. Intentionally errs toward rejection.\n */\nfunction validateBundleSize(\n pairs: Array<[string, string]>,\n skillName: string,\n): void {\n let total = 0;\n for (const [, source] of pairs) {\n total += source.length;\n }\n\n if (total > MAX_SKILL_BUNDLE_BYTES) {\n throw new Error(\n `Skill '${skillName}': bundle exceeds ${MAX_SKILL_BUNDLE_BYTES} bytes (total ${total})`,\n );\n }\n}\n\n/**\n * Express `absolutePath` as a POSIX-relative path under `skillDir`.\n * Throws an Error if the path escapes the skill directory which indicates\n * a backend bug, not a user error.\n */\nfunction relativeUnder(\n skillDir: string,\n absolutePath: string,\n skillName: string,\n): string {\n const rel = posix.relative(skillDir, absolutePath);\n if (rel === \"\" || rel.startsWith(\"..\")) {\n throw new Error(\n `Skill '${skillName}': file ${absolutePath} is not under '${skillDir}'`,\n );\n }\n return rel;\n}\n\n/**\n * Build the relative-path → source map, applying `stripTypeSyntax` to each file.\n */\nfunction buildFilesMap(\n skillDir: string,\n entryRel: string,\n pairs: Array<[string, string]>,\n skillName: string,\n): Map<string, string> {\n const files = new Map<string, string>();\n let entryPresent = false;\n\n for (const [absPath, source] of pairs) {\n const rel = relativeUnder(skillDir, absPath, skillName);\n files.set(rel, stripTypeSyntax(source));\n if (rel === entryRel) {\n entryPresent = true;\n }\n }\n\n if (!entryPresent) {\n throw new Error(\n `Skill '${skillName}': module path '${entryRel}' did not match any file in the skill directory`,\n );\n }\n\n return files;\n}\n\n/**\n * Build a `LoadedSkill` from a skill's metadata and a backend handle.\n *\n * Enumerates code files under the skill directory, downloads them,\n * strips TypeScript syntax, and validates the entrypoint is present.\n */\nexport async function loadSkill(\n metadata: SkillMetadata,\n backend: AnyBackendProtocol,\n): Promise<LoadedSkill> {\n const name = metadata.name;\n\n if (!SKILL_NAME_RE.test(name)) {\n throw new Error(\n `Skill name '${name}' is not a valid kebab-case identifier`,\n );\n }\n\n const entryRel = metadata.module;\n if (entryRel === undefined || entryRel === \"\") {\n throw new Error(\n `Skill '${name}' has no 'module' frontmatter key - only skills with a declared entrypoint are installable`,\n );\n }\n\n const adapted = adaptBackendProtocol(backend);\n if (adapted.downloadFiles === undefined) {\n throw new Error(\n `Skill '${name}': backend does not implement downloadFiles`,\n );\n }\n\n const skillDir = posix.dirname(metadata.path);\n const codeFiles = await enumerateCodeFiles(adapted, skillDir, name);\n if (codeFiles.length === 0) {\n throw new Error(`Skill '${name}': no JS/TS files under '${skillDir}'`);\n }\n\n const responses = await adapted.downloadFiles(codeFiles);\n const filePairs = decodeFiles(responses, name);\n validateBundleSize(filePairs, name);\n\n const files = buildFilesMap(skillDir, entryRel, filePairs, name);\n return {\n name,\n specifier: `@/skills/${name}`,\n entryRel,\n files,\n };\n}\n\n/**\n * Extract skill names referenced by `\"@/skills/<name>\"` literals in source.\n *\n * Used as a pre-eval scan so the middleware can surface `SkillNotAvailable`\n * before evaluation starts. Dynamic imports with computed specifiers are\n * not detected.\n */\nexport function scanSkillReferences(source: string): Set<string> {\n const names = new Set<string>();\n\n const matches = source.matchAll(SKILL_SPECIFIER_RE);\n for (const match of matches) {\n names.add(match[1]);\n }\n\n return names;\n}\n","/**\n * Options for constructing a {@link PTCCallBudgetExceededError}.\n */\ninterface PTCCallBudgetExceededOptions {\n /**\n * The configured per-eval PTC call limit.\n */\n limit: number;\n\n /**\n * The call number that triggered the violation (always `limit + 1`).\n */\n attempted: number;\n\n /**\n * The name of the tool function that was called over budget.\n */\n functionName: string;\n}\n\n/**\n * Thrown when a single eval exhausts its configured PTC call budget.\n */\nexport class PTCCallBudgetExceededError extends Error {\n readonly limit: number;\n readonly attempted: number;\n readonly functionName: string;\n\n constructor(options: PTCCallBudgetExceededOptions) {\n super(\n `PTC call budget exceeded (limit=${options.limit}, attempted=${options.attempted}, function=${options.functionName})`,\n );\n this.name = \"PTCCallBudgetExceededError\";\n this.limit = options.limit;\n this.attempted = options.attempted;\n this.functionName = options.functionName;\n }\n}\n","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 let logsText = result.logs.join(\"\\n\");\n if (result.logsDroppedChars > 0) {\n logsText += `\\n[truncated ${result.logsDroppedChars} chars]`;\n }\n parts.push(logsText);\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/**\n * Render a pre-eval error when referenced skills are not available on the agent.\n */\nexport function formatSkillNotAvailable(missing: readonly string[]): string {\n const list = [...missing].sort().join(\", \");\n return `Skills unavailable: ${list}`;\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\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 { StructuredToolInterface } from \"@langchain/core/tools\";\n\nimport { loadSkill, type LoadedSkill } from \"./skills.js\";\nimport { PTCCallBudgetExceededError } from \"./errors.js\";\nimport type { ReplSessionOptions, ReplResult, SkillsContext } from \"./types.js\";\nimport { toCamelCase } from \"./utils.js\";\nimport { transformForEval } from \"./transform.js\";\n\nexport const DEFAULT_MEMORY_LIMIT = 64 * 1024 * 1024;\nexport const DEFAULT_MAX_STACK_SIZE = 320 * 1024;\nexport const DEFAULT_EXECUTION_TIMEOUT = 5_000;\nexport const DEFAULT_SESSION_ID = \"__default__\";\nexport const DEFAULT_MAX_PTC_CALLS = 256;\nexport const DEFAULT_MAX_RESULTS_CHARS = 4000;\n\n// The variant descriptor (WASM binary + glue) is safe to share across sessions;\n// only the instantiated module carries asyncify state. Import once, instantiate per session.\nconst variantImport = import(\"@jitl/quickjs-ng-wasmfile-release-asyncify\");\n\n// Each ReplSession needs its own WASM module. The asyncify WASM variant allows only one\n// concurrent async call per module instance, and multi-file skill imports (2+ unwind/rewind\n// cycles inside a single evalCodeAsync) leave the module's asyncify state corrupted after\n// the owning runtime is disposed — new runtimes on the same module silently skip module\n// loader callbacks. A fresh instantiation per session gives each session clean asyncify state.\nasync function newAsyncModule() {\n const variant = await variantImport;\n return newQuickJSAsyncWASMModuleFromVariant(\n (variant.default ?? variant) as any,\n );\n}\n\n// After a successful asyncify unwind/rewind cycle, a rejected module loader\n// Promise causes a WASM crash (\"memory access out of bounds\"). The rejection\n// path in quickjs-emscripten's `maybeAsyncFn` catch block calls\n// `context.throw(error)` — a WASM FFI call while the asyncify stack is still\n// unwound — which corrupts memory. To avoid this, the module loader must never\n// reject. This helper returns source code that throws at evaluation time inside\n// the VM instead.\n//\n// The thrown value is a plain object (not `new Error()`) because QuickJS stores\n// Error's `name` and `message` as non-enumerable properties (per spec), which\n// causes `context.dump()` (JSON.stringify) to return `{}`.\nfunction makeErrorSource(message: string): string {\n return `throw { name: \"Error\", message: ${JSON.stringify(message)} };`;\n}\n\n/**\n * Parse a canonicalized skill specifier into `{ name, rel }`.\n * Returns `undefined` for anything that isn't a valid `@/skills/<name>` or\n * `@/skills/<name>/<rel>` shape. `rel` is absent for the bare form.\n */\nfunction parseSkillSpecifier(\n specifier: string,\n): { name: string; rel?: string } | undefined {\n const prefix = \"@/skills/\";\n if (!specifier.startsWith(prefix)) {\n return;\n }\n\n const tail = specifier.slice(prefix.length);\n const slashIdx = tail.indexOf(\"/\");\n const name = slashIdx === -1 ? tail : tail.slice(0, slashIdx);\n if (!/^[a-z0-9]+(?:-[a-z0-9]+)*$/.test(name)) {\n return;\n }\n\n const rel = slashIdx === -1 ? undefined : tail.slice(slashIdx + 1);\n if (rel !== undefined && rel === \"\") {\n return;\n }\n\n return { name, rel };\n}\n\n/**\n * Return the `@/skills/<name>` prefix for the skill that owns `base`, or `undefined`.\n */\nfunction matchSkillPrefix(base: string): string | undefined {\n const parsed = parseSkillSpecifier(base);\n if (parsed === undefined) {\n return;\n }\n return `@/skills/${parsed.name}`;\n}\n\n/**\n * Return the directory portion of a slash-separated specifier path.\n */\nfunction posixDirname(p: string): string {\n const idx = p.lastIndexOf(\"/\");\n if (idx === -1) {\n return \"\";\n }\n return p.slice(0, idx);\n}\n\n/**\n * POSIX join for slash-separated specifiers. Avoids `node:path/posix`\n * since session.ts is consumed in browser bundles.\n */\nfunction posixJoin(base: string, rel: string): string {\n const out: string[] = [];\n\n const segments = `${base}/${rel}`.split(\"/\");\n for (const segment of segments) {\n if (segment === \"\" || segment === \".\") {\n continue;\n }\n\n if (segment === \"..\") {\n out.pop();\n continue;\n }\n\n out.push(segment);\n }\n\n return out.join(\"/\");\n}\n\n/**\n * Fixed-size character buffer for capturing console output from the QuickJS VM.\n *\n * Lines are accumulated up to `maxChars`. Once the cap is reached, excess\n * characters are counted as dropped rather than silently discarded without\n * attribution, so callers can surface a truncation notice to the user.\n */\nclass ConsoleBuffer {\n private readonly maxChars: number;\n private buffer: string = \"\";\n private droppedChars: number = 0;\n\n constructor(maxChars: number) {\n this.maxChars = Math.max(maxChars, 0);\n }\n\n /**\n * Append `line` to the buffer.\n *\n * If the buffer is already full the entire line is counted as dropped.\n * If `line` partially fits, the fitting prefix is stored and the remainder\n * is counted as dropped.\n */\n append(line: string): void {\n const remaining = this.maxChars - this.buffer.length;\n if (remaining <= 0) {\n this.droppedChars += line.length;\n return;\n }\n\n if (line.length <= remaining) {\n this.buffer += line;\n } else {\n this.buffer += line.slice(0, remaining);\n this.droppedChars += line.length - remaining;\n }\n }\n\n /**\n * Return the buffered output and dropped-character count as `[buffered,\n * droppedChars]`, then reset both to zero.\n */\n drain(): [string, number] {\n const out = this.buffer;\n const dropped = this.droppedChars;\n\n this.buffer = \"\";\n this.droppedChars = 0;\n\n return [out, dropped];\n }\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 */\nexport class ReplSession {\n private static sessions = new Map<string, ReplSession>();\n\n readonly id: string;\n\n private runtime: QuickJSAsyncRuntime | null = null;\n private context: QuickJSAsyncContext | null = null;\n private consoleBuffer: ConsoleBuffer = new ConsoleBuffer(\n DEFAULT_MAX_RESULTS_CHARS,\n );\n private options: ReplSessionOptions;\n private skillsContext: SkillsContext | undefined;\n private skillsLoaded: Map<string, LoadedSkill> = new Map();\n private skillsFailed: Map<string, Error> = new Map();\n private readonly maxPtcCalls: number | null;\n private ptcCallsRemaining: number | null = null;\n\n constructor(id: string, options: ReplSessionOptions = {}) {\n this.id = id;\n this.options = options;\n this.maxPtcCalls =\n options.maxPtcCalls !== undefined\n ? options.maxPtcCalls\n : DEFAULT_MAX_PTC_CALLS;\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 tools,\n skillsEnabled = false,\n maxResultChars = DEFAULT_MAX_RESULTS_CHARS,\n captureConsole = true,\n } = this.options;\n\n const asyncModule = await newAsyncModule();\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.consoleBuffer = new ConsoleBuffer(maxResultChars);\n if (captureConsole) {\n this.setupConsole();\n }\n\n if (tools !== undefined && tools.length > 0) {\n this.injectTools(tools);\n }\n\n if (skillsEnabled) {\n this.installModuleLoader();\n }\n }\n\n /**\n * Load the skill into cache on first access and replay cached errors.\n */\n private async ensureSkillLoaded(name: string): Promise<LoadedSkill> {\n const cached = this.skillsLoaded.get(name);\n if (cached !== undefined) {\n return cached;\n }\n\n const cachedError = this.skillsFailed.get(name);\n if (cachedError !== undefined) {\n throw cachedError;\n }\n\n const ctx = this.skillsContext;\n if (ctx === undefined) {\n throw new Error(\n `Skill '${name}' referenced but skills are not configured for this session`,\n );\n }\n\n const metadata = ctx.metadata.find((m) => m.name === name);\n if (metadata === undefined) {\n throw new Error(\n `Skill '${name}' referenced but not available on this agent`,\n );\n }\n\n try {\n const loaded = await loadSkill(metadata, ctx.backend);\n this.skillsLoaded.set(name, loaded);\n return loaded;\n } catch (err) {\n this.skillsFailed.set(name, err as Error);\n throw err;\n }\n }\n\n private async resolveSpecifier(specifier: string): Promise<string> {\n const parsed = parseSkillSpecifier(specifier);\n if (parsed === undefined) {\n return makeErrorSource(`Module not found: ${specifier}`);\n }\n\n let loaded: LoadedSkill;\n try {\n loaded = await this.ensureSkillLoaded(parsed.name);\n } catch (err) {\n return makeErrorSource((err as Error).message ?? String(err));\n }\n\n if (parsed.rel === undefined) {\n const source = loaded.files.get(loaded.entryRel);\n if (source === undefined) {\n return makeErrorSource(\n `Skill '${parsed.name}': entrypoint '${loaded.entryRel}' missing from bundle`,\n );\n }\n return source;\n }\n\n const source = loaded.files.get(parsed.rel);\n if (source === undefined) {\n return makeErrorSource(\n `Skill '${parsed.name}': '${parsed.rel}' not found in bundle`,\n );\n }\n\n return source;\n }\n\n /**\n * Canonicalize an `import` specifier. Bare specifiers pass through;\n * relative specifiers are resolved against the importing module's path.\n * Traversal out of a skill's `@/skills/<name>/` namespace is rejected.\n */\n private normalizeSpecifier(base: string, requested: string): string {\n const isRelative =\n requested.startsWith(\"./\") || requested.startsWith(\"../\");\n if (!isRelative) {\n return requested;\n }\n\n // A bare skill specifier like \"@/skills/my-skill\" has no file component, so\n // posixDirname would return \"@/skills\". Treat the bare specifier itself as\n // the directory so that \"./lib/math.js\" resolves to \"@/skills/my-skill/lib/math.js\".\n const parsed = parseSkillSpecifier(base);\n const baseDir =\n parsed !== undefined && parsed.rel === undefined\n ? base\n : posixDirname(base);\n const resolved = posixJoin(baseDir, requested);\n\n const skillPrefix = matchSkillPrefix(base);\n if (skillPrefix === undefined) {\n return resolved;\n }\n\n if (!resolved.startsWith(`${skillPrefix}/`)) {\n return `__resolve_error__:${requested} escapes ${skillPrefix}`;\n }\n\n return resolved;\n }\n\n /**\n * Wire the QuickJS module loader and normalizer on this session's runtime.\n */\n private installModuleLoader(): void {\n if (this.runtime === null) {\n return;\n }\n\n this.runtime.setModuleLoader(\n async (specifier: string) => this.resolveSpecifier(specifier),\n (base: string, requested: string) =>\n this.normalizeSpecifier(base, requested),\n );\n }\n\n /**\n * Initialise the per-eval PTC counter. Called at the top of every `eval()`.\n */\n private resetPtcBudget(): void {\n this.ptcCallsRemaining =\n this.maxPtcCalls === null ? null : this.maxPtcCalls;\n }\n\n /**\n * Decrement the PTC call counter and throw if the budget is exhausted.\n * `null` budget means unlimited — returns immediately without decrementing.\n */\n private consumePtcBudget(functionName: string): void {\n if (this.ptcCallsRemaining === null) {\n return;\n }\n\n if (this.ptcCallsRemaining > 0) {\n this.ptcCallsRemaining--;\n return;\n }\n\n const limit = this.maxPtcCalls ?? 0;\n throw new PTCCallBudgetExceededError({\n limit,\n attempted: limit + 1,\n functionName,\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 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 * Returns true if any session exists whose key equals `threadId` or starts\n * with `threadId:`. Useful for tests that need to confirm a session was\n * created without knowing the full `threadId:middlewareId` key.\n */\n static hasAnyForThread(threadId: string): boolean {\n const prefix = `${threadId}:`;\n for (const key of ReplSession.sessions.keys()) {\n if (key === threadId || key.startsWith(prefix)) {\n return true;\n }\n }\n return false;\n }\n\n /**\n * Dispose and remove the session with the given key, if it exists.\n */\n static deleteSession(key: string): void {\n const session = ReplSession.sessions.get(key);\n if (session) {\n session.dispose();\n }\n }\n\n /**\n * Push the current skills metadata + backend into the session.\n * Called by the middleware once per `eval` invocation, before eval runs.\n * Pass `undefined` to clear the context (no skill imports will resolve).\n */\n setSkillsContext(ctx?: SkillsContext): void {\n this.skillsContext = ctx;\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 const drainLogs = (): { logs: string[]; logsDroppedChars: number } => {\n const [raw, dropped] = this.consoleBuffer.drain();\n return {\n logs: raw.length > 0 ? raw.split(\"\\n\").filter((l) => l.length > 0) : [],\n logsDroppedChars: dropped,\n };\n };\n\n this.resetPtcBudget();\n try {\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, ...drainLogs() };\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, ...drainLogs() };\n }\n const value = context.dump(promiseState.value);\n promiseState.value.dispose();\n result.value.dispose();\n return { ok: true, value, ...drainLogs() };\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, ...drainLogs() };\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, ...drainLogs() };\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, ...drainLogs() };\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 ...drainLogs(),\n };\n } finally {\n this.ptcCallsRemaining = null;\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 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 const line =\n method === \"log\" || method === \"info\" || method === \"debug\"\n ? formatted\n : `[${method}] ${formatted}`;\n this.consoleBuffer.append(line + \"\\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 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 this.consumePtcBudget(camelName);\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 * REPL middleware for deepagents.\n *\n * Provides an `eval` tool that runs JavaScript in a WASM-sandboxed QuickJS\n * interpreter. Supports:\n * - Persistent state across evaluations (true REPL)\n * - Programmatic tool calling (PTC) — expose agent or custom tools inside the REPL\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\";\n\nimport dedent from \"dedent\";\nimport { getCurrentTaskInput } from \"@langchain/langgraph\";\nimport {\n resolveBackend,\n type AnyBackendProtocol,\n type BackendFactory,\n type SkillMetadata,\n} from \"deepagents\";\nimport type { REPLMiddlewareOptions } from \"./types.js\";\nimport {\n ReplSession,\n DEFAULT_EXECUTION_TIMEOUT,\n DEFAULT_MEMORY_LIMIT,\n DEFAULT_MAX_STACK_SIZE,\n DEFAULT_SESSION_ID,\n DEFAULT_MAX_PTC_CALLS,\n DEFAULT_MAX_RESULTS_CHARS,\n} from \"./session.js\";\nimport {\n formatReplResult,\n formatSkillNotAvailable,\n toCamelCase,\n toolToTypeSignature,\n safeToJsonSchema,\n} from \"./utils.js\";\nimport { scanSkillReferences } from \"./skills.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 { LangGraphRunnableConfig } from \"@langchain/langgraph\";\n\nconst DEFAULT_TOOL_NAME = \"eval\";\n\nfunction renderReplSystemPrompt(opts: {\n toolName: string;\n timeout: number;\n memoryLimitMb: number;\n}): string {\n return dedent`\n ### Interpreter\n\n An \\`${opts.toolName}\\` tool is available. It runs JavaScript in a persistent REPL.\n - State (variables, functions) persists across tool calls within a single turn of conversation. They DO NOT persist across multiple turns.\n - Top-level \\`await\\` works; Promises resolve before the call returns.\n - Sandboxed: no filesystem, no stdlib, no network, no real clock, no \\`fetch\\`, no \\`require\\`.\n - Timeout: ${opts.timeout}s per call. Memory: ${opts.memoryLimitMb} MB total.\n - \\`console.log\\` output is captured and returned alongside the result.\n `;\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 * Resolves a mixed list of tool names and tool instances into a flat list of\n * StructuredToolInterface objects. Strings are looked up by name in agentTools;\n * instances are included directly without requiring agent registration. Strings\n * that don't match any agent tool are silently omitted.\n */\nexport function resolveToolList(\n items: (string | StructuredToolInterface)[],\n agentTools: StructuredToolInterface[],\n): StructuredToolInterface[] {\n const agentByName = new Map(agentTools.map((t) => [t.name, t]));\n return items.flatMap((item) => {\n if (typeof item === \"string\") {\n const found = agentByName.get(item);\n return found ? [found] : [];\n }\n return [item];\n });\n}\n\n/**\n * Pull `skillsMetadata` from the task input, resolve the backend, and push\n * both into the session. Short-circuits with a `SkillNotAvailable` error if\n * the source references skills the agent doesn't have.\n */\nasync function prepareSkillsForEval(\n session: ReplSession,\n skillsBackend: AnyBackendProtocol | BackendFactory,\n code: string,\n): Promise<string | undefined> {\n const taskInput = getCurrentTaskInput<{ skillsMetadata?: SkillMetadata[] }>();\n const metadata: SkillMetadata[] = taskInput?.skillsMetadata ?? [];\n\n const referenced = scanSkillReferences(code);\n if (referenced.size > 0) {\n const known = new Set(metadata.map((m) => m.name));\n const missing: string[] = [];\n for (const name of referenced) {\n if (!known.has(name)) {\n missing.push(name);\n }\n }\n if (missing.length > 0) {\n session.setSkillsContext(undefined);\n return formatSkillNotAvailable(missing);\n }\n }\n\n const resolved = await resolveBackend(skillsBackend, { state: taskInput });\n session.setSkillsContext({ metadata, backend: resolved });\n return undefined;\n}\n\n/**\n * Create the REPL middleware.\n */\nexport function createREPLMiddleware(options: REPLMiddlewareOptions = {}) {\n const {\n ptc,\n memoryLimitBytes = DEFAULT_MEMORY_LIMIT,\n maxStackSizeBytes = DEFAULT_MAX_STACK_SIZE,\n executionTimeoutMs = DEFAULT_EXECUTION_TIMEOUT,\n systemPrompt: customSystemPrompt = null,\n skillsBackend,\n maxPtcCalls = DEFAULT_MAX_PTC_CALLS,\n maxResultChars = DEFAULT_MAX_RESULTS_CHARS,\n toolName = DEFAULT_TOOL_NAME,\n captureConsole = true,\n } = options;\n\n if (maxPtcCalls !== null && maxPtcCalls !== undefined && maxPtcCalls < 1) {\n throw new Error(\"`maxPtcCalls` must be >= 1 or null\");\n }\n\n const baseSystemPrompt =\n customSystemPrompt ||\n renderReplSystemPrompt({\n toolName,\n timeout: executionTimeoutMs / 1000,\n memoryLimitMb: Math.floor(memoryLimitBytes / (1024 * 1024)),\n });\n\n const middlewareId = crypto.randomUUID();\n\n let cachedPtcPrompt: string | null = null;\n\n let ptcTools: StructuredToolInterface[] = [];\n\n function filterToolsForPtc(\n allTools: StructuredToolInterface[],\n ): StructuredToolInterface[] {\n if (!ptc) return [];\n\n const candidates = allTools.filter((t) => t.name !== toolName);\n\n return resolveToolList(ptc, candidates);\n }\n\n const evalTool = tool(\n async (input, config: LangGraphRunnableConfig) => {\n const threadId = config.configurable?.thread_id || DEFAULT_SESSION_ID;\n const sessionKey = `${threadId}:${middlewareId}`;\n\n const session = ReplSession.getOrCreate(sessionKey, {\n memoryLimitBytes,\n maxStackSizeBytes,\n maxPtcCalls,\n tools: ptcTools,\n skillsEnabled: skillsBackend !== undefined,\n maxResultChars,\n captureConsole,\n });\n\n if (skillsBackend !== undefined) {\n const setupError = await prepareSkillsForEval(\n session,\n skillsBackend,\n input.code,\n );\n if (setupError !== undefined) {\n return setupError;\n }\n }\n\n const result = await session.eval(input.code, executionTimeoutMs);\n return formatReplResult(result);\n },\n {\n name: toolName,\n description: dedent`\n Evaluate TypeScript/JavaScript code in a sandboxed REPL. State persists across calls.\n Use console.log() for output. Returns the result of the last expression.\n If file or other tools are available, call them via the tools namespace: await tools.readFile({ path }).\n If skills are configured, dynamically import them: await import(\"@/skills/<name>\").\n `,\n metadata: { ls_code_input_language: \"javascript\" },\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: \"REPLMiddleware\",\n tools: [evalTool],\n wrapModelCall: async (request, handler) => {\n const agentTools = (request.tools || []) as StructuredToolInterface[];\n ptcTools = 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 afterAgent: async (_state, runtime) => {\n const threadId = runtime.configurable?.thread_id ?? DEFAULT_SESSION_ID;\n const sessionKey = `${threadId}:${middlewareId}`;\n ReplSession.deleteSession(sessionKey);\n },\n });\n}\n"],"mappings":"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"}
|
package/dist/index.d.cts
CHANGED
|
@@ -6,9 +6,9 @@ import { AnyBackendProtocol, BackendFactory, SkillMetadata } from "deepagents";
|
|
|
6
6
|
|
|
7
7
|
//#region src/types.d.ts
|
|
8
8
|
/**
|
|
9
|
-
* Configuration options for the
|
|
9
|
+
* Configuration options for the REPL middleware.
|
|
10
10
|
*/
|
|
11
|
-
interface
|
|
11
|
+
interface REPLMiddlewareOptions {
|
|
12
12
|
/**
|
|
13
13
|
* Enable programmatic tool calling from within the REPL.
|
|
14
14
|
*
|
|
@@ -20,7 +20,7 @@ interface QuickJSMiddlewareOptions {
|
|
|
20
20
|
ptc?: (string | StructuredToolInterface)[];
|
|
21
21
|
/**
|
|
22
22
|
* Memory limit in bytes.
|
|
23
|
-
* @default
|
|
23
|
+
* @default 67108864 (64MB)
|
|
24
24
|
*/
|
|
25
25
|
memoryLimitBytes?: number;
|
|
26
26
|
/**
|
|
@@ -31,7 +31,7 @@ interface QuickJSMiddlewareOptions {
|
|
|
31
31
|
/**
|
|
32
32
|
* Execution timeout in milliseconds per evaluation.
|
|
33
33
|
* Set to a negative value to disable the timeout entirely.
|
|
34
|
-
* @default
|
|
34
|
+
* @default 5000 (5s)
|
|
35
35
|
*/
|
|
36
36
|
executionTimeoutMs?: number;
|
|
37
37
|
/**
|
|
@@ -66,6 +66,18 @@ interface QuickJSMiddlewareOptions {
|
|
|
66
66
|
* @default 4000
|
|
67
67
|
*/
|
|
68
68
|
maxResultChars?: number;
|
|
69
|
+
/**
|
|
70
|
+
* Name of the tool exposed to the model.
|
|
71
|
+
* @default "eval"
|
|
72
|
+
*/
|
|
73
|
+
toolName?: string;
|
|
74
|
+
/**
|
|
75
|
+
* If true, install a `console` object that buffers `console.log/warn/error`
|
|
76
|
+
* calls and emits them alongside the result. If false, console output is
|
|
77
|
+
* silently discarded.
|
|
78
|
+
* @default true
|
|
79
|
+
*/
|
|
80
|
+
captureConsole?: boolean;
|
|
69
81
|
}
|
|
70
82
|
/**
|
|
71
83
|
* Options for creating a ReplSession.
|
|
@@ -77,6 +89,7 @@ interface ReplSessionOptions {
|
|
|
77
89
|
skillsEnabled?: boolean;
|
|
78
90
|
maxPtcCalls?: number | null;
|
|
79
91
|
maxResultChars?: number;
|
|
92
|
+
captureConsole?: boolean;
|
|
80
93
|
}
|
|
81
94
|
/**
|
|
82
95
|
* Result of a single REPL evaluation.
|
|
@@ -108,15 +121,15 @@ interface SkillsContext {
|
|
|
108
121
|
//#endregion
|
|
109
122
|
//#region src/middleware.d.ts
|
|
110
123
|
/**
|
|
111
|
-
* Create the
|
|
124
|
+
* Create the REPL middleware.
|
|
112
125
|
*/
|
|
113
|
-
declare function
|
|
126
|
+
declare function createREPLMiddleware(options?: REPLMiddlewareOptions): AgentMiddleware<undefined, undefined, unknown, readonly [_$langchain.DynamicStructuredTool<z.ZodObject<{
|
|
114
127
|
code: z.ZodString;
|
|
115
128
|
}, z.core.$strip>, {
|
|
116
129
|
code: string;
|
|
117
130
|
}, {
|
|
118
131
|
code: string;
|
|
119
|
-
}, string, unknown,
|
|
132
|
+
}, string, unknown, string>]>;
|
|
120
133
|
//#endregion
|
|
121
134
|
//#region src/errors.d.ts
|
|
122
135
|
/**
|
|
@@ -149,7 +162,7 @@ declare class PTCCallBudgetExceededError extends Error {
|
|
|
149
162
|
//#region src/session.d.ts
|
|
150
163
|
declare const DEFAULT_MEMORY_LIMIT: number;
|
|
151
164
|
declare const DEFAULT_MAX_STACK_SIZE: number;
|
|
152
|
-
declare const DEFAULT_EXECUTION_TIMEOUT =
|
|
165
|
+
declare const DEFAULT_EXECUTION_TIMEOUT = 5000;
|
|
153
166
|
declare const DEFAULT_MAX_PTC_CALLS = 256;
|
|
154
167
|
/**
|
|
155
168
|
* Sandboxed JavaScript REPL session backed by QuickJS WASM.
|
|
@@ -221,7 +234,7 @@ declare class ReplSession {
|
|
|
221
234
|
static deleteSession(key: string): void;
|
|
222
235
|
/**
|
|
223
236
|
* Push the current skills metadata + backend into the session.
|
|
224
|
-
* Called by the middleware once per `
|
|
237
|
+
* Called by the middleware once per `eval` invocation, before eval runs.
|
|
225
238
|
* Pass `undefined` to clear the context (no skill imports will resolve).
|
|
226
239
|
*/
|
|
227
240
|
setSkillsContext(ctx?: SkillsContext): void;
|
|
@@ -343,5 +356,5 @@ declare function loadSkill(metadata: SkillMetadata, backend: AnyBackendProtocol)
|
|
|
343
356
|
*/
|
|
344
357
|
declare function scanSkillReferences(source: string): Set<string>;
|
|
345
358
|
//#endregion
|
|
346
|
-
export { DEFAULT_EXECUTION_TIMEOUT, DEFAULT_MAX_PTC_CALLS, DEFAULT_MAX_STACK_SIZE, DEFAULT_MEMORY_LIMIT, type LoadedSkill, MAX_SKILL_BUNDLE_BYTES, PTCCallBudgetExceededError, type
|
|
359
|
+
export { DEFAULT_EXECUTION_TIMEOUT, DEFAULT_MAX_PTC_CALLS, DEFAULT_MAX_STACK_SIZE, DEFAULT_MEMORY_LIMIT, type LoadedSkill, MAX_SKILL_BUNDLE_BYTES, PTCCallBudgetExceededError, type REPLMiddlewareOptions, type ReplResult, ReplSession, type ReplSessionOptions, SKILL_MODULE_EXTENSIONS, createREPLMiddleware, formatReplResult, formatSkillNotAvailable, loadSkill, scanSkillReferences, stripTypeSyntax, toCamelCase, transformForEval };
|
|
347
360
|
//# sourceMappingURL=index.d.cts.map
|