@langchain/quickjs 0.2.6 → 0.4.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.d.ts CHANGED
@@ -6,9 +6,9 @@ import { StructuredToolInterface } from "@langchain/core/tools";
6
6
 
7
7
  //#region src/types.d.ts
8
8
  /**
9
- * Configuration options for the QuickJS REPL middleware.
9
+ * Configuration options for the Code Interpreter middleware.
10
10
  */
11
- interface QuickJSMiddlewareOptions {
11
+ interface CodeInterpreterMiddlewareOptions {
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 52428800 (50MB)
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 30000 (30s)
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 QuickJS REPL middleware.
124
+ * Create the Code Interpreter middleware.
112
125
  */
113
- declare function createQuickJSMiddleware(options?: QuickJSMiddlewareOptions): AgentMiddleware<undefined, undefined, unknown, readonly [_$langchain.DynamicStructuredTool<z.ZodObject<{
126
+ declare function createCodeInterpreterMiddleware(options?: CodeInterpreterMiddlewareOptions): 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, "js_eval">]>;
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 = 30000;
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.
@@ -171,12 +184,35 @@ declare class ReplSession {
171
184
  private skillsFailed;
172
185
  private readonly maxPtcCalls;
173
186
  private ptcCallsRemaining;
187
+ /**
188
+ * Reset the shared WASM module. Forces the next session to instantiate
189
+ * a fresh module. Only needed in tests where module state must be
190
+ * isolated between test files.
191
+ *
192
+ * @internal
193
+ */
194
+ static resetSharedModule(): void;
174
195
  constructor(id: string, options?: ReplSessionOptions);
175
196
  private ensureStarted;
176
197
  /**
177
198
  * Load the skill into cache on first access and replay cached errors.
178
199
  */
179
200
  private ensureSkillLoaded;
201
+ /**
202
+ * Pre-load all skills referenced in source code into the in-memory
203
+ * cache. Must be called before `evalCodeAsync` so the module loader
204
+ * can resolve synchronously. An async loader would cause asyncify
205
+ * suspensions on each import, which is incompatible with the shared
206
+ * WASM module used by all sessions.
207
+ */
208
+ preloadReferencedSkills(code: string): Promise<void>;
209
+ /**
210
+ * Resolve a module specifier to source code. Strictly synchronous —
211
+ * only reads from the in-memory skill cache populated by
212
+ * `preloadReferencedSkills`. Returns error source (not a thrown
213
+ * exception) for missing or failed skills so QuickJS reports the
214
+ * error inside the VM.
215
+ */
180
216
  private resolveSpecifier;
181
217
  /**
182
218
  * Canonicalize an `import` specifier. Bare specifiers pass through;
@@ -186,6 +222,12 @@ declare class ReplSession {
186
222
  private normalizeSpecifier;
187
223
  /**
188
224
  * Wire the QuickJS module loader and normalizer on this session's runtime.
225
+ *
226
+ * The loader is strictly synchronous — it reads from the in-memory skill
227
+ * cache populated by `preloadReferencedSkills`. This is critical: an async
228
+ * module loader causes asyncify suspensions on each import, and disposing
229
+ * a runtime after multi-file imports corrupts the shared module's asyncify
230
+ * state, silently breaking the loader for all subsequent sessions.
189
231
  */
190
232
  private installModuleLoader;
191
233
  /**
@@ -221,7 +263,7 @@ declare class ReplSession {
221
263
  static deleteSession(key: string): void;
222
264
  /**
223
265
  * Push the current skills metadata + backend into the session.
224
- * Called by the middleware once per `js_eval` invocation, before eval runs.
266
+ * Called by the middleware once per `eval` invocation, before eval runs.
225
267
  * Pass `undefined` to clear the context (no skill imports will resolve).
226
268
  */
227
269
  setSkillsContext(ctx?: SkillsContext): void;
@@ -343,5 +385,5 @@ declare function loadSkill(metadata: SkillMetadata, backend: AnyBackendProtocol)
343
385
  */
344
386
  declare function scanSkillReferences(source: string): Set<string>;
345
387
  //#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 QuickJSMiddlewareOptions, type ReplResult, ReplSession, type ReplSessionOptions, SKILL_MODULE_EXTENSIONS, createQuickJSMiddleware, formatReplResult, formatSkillNotAvailable, loadSkill, scanSkillReferences, stripTypeSyntax, toCamelCase, transformForEval };
388
+ export { type CodeInterpreterMiddlewareOptions, DEFAULT_EXECUTION_TIMEOUT, DEFAULT_MAX_PTC_CALLS, DEFAULT_MAX_STACK_SIZE, DEFAULT_MEMORY_LIMIT, type LoadedSkill, MAX_SKILL_BUNDLE_BYTES, PTCCallBudgetExceededError, type ReplResult, ReplSession, type ReplSessionOptions, SKILL_MODULE_EXTENSIONS, createCodeInterpreterMiddleware, formatReplResult, formatSkillNotAvailable, loadSkill, scanSkillReferences, stripTypeSyntax, toCamelCase, transformForEval };
347
389
  //# sourceMappingURL=index.d.ts.map
package/dist/index.js CHANGED
@@ -427,6 +427,38 @@ function formatSkillNotAvailable(missing) {
427
427
  return `Skills unavailable: ${[...missing].sort().join(", ")}`;
428
428
  }
429
429
  //#endregion
430
+ //#region src/eval-queue.ts
431
+ /**
432
+ * Serializes async operations on a shared WASM module.
433
+ *
434
+ * The quickjs-emscripten asyncify variant allows only one concurrent
435
+ * async call per module instance. This queue enforces that constraint
436
+ * by chaining operations into a promise queue — each caller waits for
437
+ * the previous one to finish before executing.
438
+ */
439
+ var AsyncEvalQueue = class {
440
+ tail = Promise.resolve();
441
+ /**
442
+ * Enqueue an async operation. The operation will not start until all
443
+ * previously enqueued operations have completed.
444
+ */
445
+ async enqueue(fn) {
446
+ let release;
447
+ const gate = new Promise((r) => {
448
+ release = r;
449
+ });
450
+ const prev = this.tail;
451
+ this.tail = gate;
452
+ return prev.then(async () => {
453
+ try {
454
+ return await fn();
455
+ } finally {
456
+ release();
457
+ }
458
+ });
459
+ }
460
+ };
461
+ //#endregion
430
462
  //#region src/session.ts
431
463
  /**
432
464
  * Core REPL engine built on quickjs-emscripten (asyncify variant).
@@ -446,15 +478,41 @@ function formatSkillNotAvailable(missing) {
446
478
  * runtime is lazily started on the first `.eval()` call, making the session
447
479
  * safe across graph interrupts and checkpointing.
448
480
  */
449
- const DEFAULT_MEMORY_LIMIT = 50 * 1024 * 1024;
481
+ const DEFAULT_MEMORY_LIMIT = 64 * 1024 * 1024;
450
482
  const DEFAULT_MAX_STACK_SIZE = 320 * 1024;
451
- const DEFAULT_EXECUTION_TIMEOUT = 3e4;
483
+ const DEFAULT_EXECUTION_TIMEOUT = 5e3;
452
484
  const DEFAULT_MAX_PTC_CALLS = 256;
453
485
  const DEFAULT_MAX_RESULTS_CHARS = 4e3;
454
486
  const variantImport = import("@jitl/quickjs-ng-wasmfile-release-asyncify");
455
- async function newAsyncModule() {
456
- const variant = await variantImport;
457
- return newQuickJSAsyncWASMModuleFromVariant(variant.default ?? variant);
487
+ /**
488
+ * Process-global eval queue. Serializes all evalCodeAsync calls across
489
+ * sessions to enforce the asyncify one-at-a-time constraint.
490
+ */
491
+ const sharedEvalQueue = new AsyncEvalQueue();
492
+ /**
493
+ * Process-global WASM module shared by all sessions.
494
+ *
495
+ * Each session creates its own runtime and context on this module,
496
+ * providing full isolation for globals, heap, and stack. The module
497
+ * itself is stateless between runtimes — only the compiled WASM code
498
+ * and Emscripten infrastructure are shared.
499
+ *
500
+ * This is safe because:
501
+ * - The module loader is synchronous (preloaded skill cache), so
502
+ * imports don't cause asyncify suspensions.
503
+ * - Tool injection uses the promise-based pattern (newFunction +
504
+ * newPromise), not newAsyncifiedFunction, so tool calls don't
505
+ * cause asyncify suspensions.
506
+ * - The eval queue serializes evalCodeAsync calls to satisfy the
507
+ * one-concurrent-async-call-per-module constraint.
508
+ */
509
+ let sharedModulePromise;
510
+ function getSharedModule() {
511
+ if (!sharedModulePromise) sharedModulePromise = (async () => {
512
+ const variant = await variantImport;
513
+ return newQuickJSAsyncWASMModuleFromVariant(variant.default ?? variant);
514
+ })();
515
+ return sharedModulePromise;
458
516
  }
459
517
  function makeErrorSource(message) {
460
518
  return `throw { name: "Error", message: ${JSON.stringify(message)} };`;
@@ -575,6 +633,16 @@ var ReplSession = class ReplSession {
575
633
  skillsFailed = /* @__PURE__ */ new Map();
576
634
  maxPtcCalls;
577
635
  ptcCallsRemaining = null;
636
+ /**
637
+ * Reset the shared WASM module. Forces the next session to instantiate
638
+ * a fresh module. Only needed in tests where module state must be
639
+ * isolated between test files.
640
+ *
641
+ * @internal
642
+ */
643
+ static resetSharedModule() {
644
+ sharedModulePromise = void 0;
645
+ }
578
646
  constructor(id, options = {}) {
579
647
  this.id = id;
580
648
  this.options = options;
@@ -582,15 +650,15 @@ var ReplSession = class ReplSession {
582
650
  }
583
651
  async ensureStarted() {
584
652
  if (this.runtime) return;
585
- const { memoryLimitBytes = DEFAULT_MEMORY_LIMIT, maxStackSizeBytes = DEFAULT_MAX_STACK_SIZE, tools, skillsEnabled = false, maxResultChars = DEFAULT_MAX_RESULTS_CHARS } = this.options;
586
- const runtime = (await newAsyncModule()).newRuntime();
653
+ const { memoryLimitBytes = DEFAULT_MEMORY_LIMIT, maxStackSizeBytes = DEFAULT_MAX_STACK_SIZE, tools, skillsEnabled = false, maxResultChars = DEFAULT_MAX_RESULTS_CHARS, captureConsole = true } = this.options;
654
+ const runtime = (await getSharedModule()).newRuntime();
587
655
  runtime.setMemoryLimit(memoryLimitBytes);
588
656
  runtime.setMaxStackSize(maxStackSizeBytes);
589
657
  const context = runtime.newContext();
590
658
  this.runtime = runtime;
591
659
  this.context = context;
592
660
  this.consoleBuffer = new ConsoleBuffer(maxResultChars);
593
- this.setupConsole();
661
+ if (captureConsole) this.setupConsole();
594
662
  if (tools !== void 0 && tools.length > 0) this.injectTools(tools);
595
663
  if (skillsEnabled) this.installModuleLoader();
596
664
  }
@@ -615,21 +683,45 @@ var ReplSession = class ReplSession {
615
683
  throw err;
616
684
  }
617
685
  }
618
- async resolveSpecifier(specifier) {
686
+ /**
687
+ * Pre-load all skills referenced in source code into the in-memory
688
+ * cache. Must be called before `evalCodeAsync` so the module loader
689
+ * can resolve synchronously. An async loader would cause asyncify
690
+ * suspensions on each import, which is incompatible with the shared
691
+ * WASM module used by all sessions.
692
+ */
693
+ async preloadReferencedSkills(code) {
694
+ const refs = scanSkillReferences(code);
695
+ for (const name of refs) {
696
+ if (this.skillsLoaded.has(name) || this.skillsFailed.has(name)) continue;
697
+ try {
698
+ await this.ensureSkillLoaded(name);
699
+ } catch (err) {
700
+ if (!this.skillsFailed.has(name)) this.skillsFailed.set(name, err);
701
+ }
702
+ }
703
+ }
704
+ /**
705
+ * Resolve a module specifier to source code. Strictly synchronous —
706
+ * only reads from the in-memory skill cache populated by
707
+ * `preloadReferencedSkills`. Returns error source (not a thrown
708
+ * exception) for missing or failed skills so QuickJS reports the
709
+ * error inside the VM.
710
+ */
711
+ resolveSpecifier(specifier) {
619
712
  const parsed = parseSkillSpecifier(specifier);
620
713
  if (parsed === void 0) return makeErrorSource(`Module not found: ${specifier}`);
621
- let loaded;
622
- try {
623
- loaded = await this.ensureSkillLoaded(parsed.name);
624
- } catch (err) {
625
- return makeErrorSource(err.message ?? String(err));
626
- }
714
+ const cachedError = this.skillsFailed.get(parsed.name);
715
+ if (cachedError !== void 0) return makeErrorSource(cachedError.message ?? String(cachedError));
716
+ const loaded = this.skillsLoaded.get(parsed.name);
717
+ if (loaded === void 0) return makeErrorSource(`Skill '${parsed.name}' was not preloaded. Ensure the import specifier is a static string literal (dynamic specifiers like \`import("@/skills/" + name)\` are not supported).`);
627
718
  if (parsed.rel === void 0) {
628
719
  const source = loaded.files.get(loaded.entryRel);
629
720
  if (source === void 0) return makeErrorSource(`Skill '${parsed.name}': entrypoint '${loaded.entryRel}' missing from bundle`);
630
721
  return source;
631
722
  }
632
- const source = loaded.files.get(parsed.rel);
723
+ let source = loaded.files.get(parsed.rel);
724
+ if (source === void 0 && parsed.rel.endsWith(".js")) source = loaded.files.get(parsed.rel.slice(0, -3) + ".ts");
633
725
  if (source === void 0) return makeErrorSource(`Skill '${parsed.name}': '${parsed.rel}' not found in bundle`);
634
726
  return source;
635
727
  }
@@ -649,10 +741,16 @@ var ReplSession = class ReplSession {
649
741
  }
650
742
  /**
651
743
  * Wire the QuickJS module loader and normalizer on this session's runtime.
744
+ *
745
+ * The loader is strictly synchronous — it reads from the in-memory skill
746
+ * cache populated by `preloadReferencedSkills`. This is critical: an async
747
+ * module loader causes asyncify suspensions on each import, and disposing
748
+ * a runtime after multi-file imports corrupts the shared module's asyncify
749
+ * state, silently breaking the loader for all subsequent sessions.
652
750
  */
653
751
  installModuleLoader() {
654
752
  if (this.runtime === null) return;
655
- this.runtime.setModuleLoader(async (specifier) => this.resolveSpecifier(specifier), (base, requested) => this.normalizeSpecifier(base, requested));
753
+ this.runtime.setModuleLoader((specifier) => this.resolveSpecifier(specifier), (base, requested) => this.normalizeSpecifier(base, requested));
656
754
  }
657
755
  /**
658
756
  * Initialise the per-eval PTC counter. Called at the top of every `eval()`.
@@ -716,7 +814,7 @@ var ReplSession = class ReplSession {
716
814
  }
717
815
  /**
718
816
  * Push the current skills metadata + backend into the session.
719
- * Called by the middleware once per `js_eval` invocation, before eval runs.
817
+ * Called by the middleware once per `eval` invocation, before eval runs.
720
818
  * Pass `undefined` to clear the context (no skill imports will resolve).
721
819
  */
722
820
  setSkillsContext(ctx) {
@@ -735,6 +833,7 @@ var ReplSession = class ReplSession {
735
833
  await this.ensureStarted();
736
834
  const runtime = this.runtime;
737
835
  const context = this.context;
836
+ await this.preloadReferencedSkills(code);
738
837
  const drainLogs = () => {
739
838
  const [raw, dropped] = this.consoleBuffer.drain();
740
839
  return {
@@ -747,7 +846,7 @@ var ReplSession = class ReplSession {
747
846
  if (timeoutMs >= 0) runtime.setInterruptHandler(shouldInterruptAfterDeadline(Date.now() + timeoutMs));
748
847
  else runtime.setInterruptHandler(() => false);
749
848
  const transformed = transformForEval(code);
750
- const result = await context.evalCodeAsync(transformed);
849
+ const result = await sharedEvalQueue.enqueue(() => context.evalCodeAsync(transformed));
751
850
  if (result.error) {
752
851
  const error = context.dump(result.error);
753
852
  result.error.dispose();
@@ -906,33 +1005,26 @@ var ReplSession = class ReplSession {
906
1005
  //#endregion
907
1006
  //#region src/middleware.ts
908
1007
  /**
909
- * QuickJS REPL middleware for deepagents.
1008
+ * Code Interpreter middleware for deepagents.
910
1009
  *
911
- * Provides a `js_eval` tool that runs JavaScript in a WASM-sandboxed QuickJS
1010
+ * Provides an `eval` tool that runs JavaScript in a WASM-sandboxed QuickJS
912
1011
  * interpreter. Supports:
913
1012
  * - Persistent state across evaluations (true REPL)
914
1013
  * - Programmatic tool calling (PTC) — expose agent or custom tools inside the REPL
915
1014
  */
916
- const REPL_SYSTEM_PROMPT = dedent`
917
- ## TypeScript/JavaScript REPL (\`js_eval\`)
918
-
919
- You have access to a sandboxed TypeScript/JavaScript REPL running in an isolated interpreter.
920
- TypeScript syntax (type annotations, interfaces, generics, \`as\` casts) is supported and stripped at evaluation time.
921
- Variables, functions, and closures persist across calls within the same session.
922
-
923
- ### Hard rules
924
-
925
- - **No network, no direct filesystem** — only through tools provided in the \`tools\` namespace below.
926
- - **Cite your sources** — when reporting values from files, include the path and key/index so the user can verify.
927
- - **Use console.log()** for output — it is captured and returned. \`console.warn()\` and \`console.error()\` are also available.
928
- - **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.
929
-
930
- ### Limitations
1015
+ const DEFAULT_TOOL_NAME = "eval";
1016
+ function renderReplSystemPrompt(opts) {
1017
+ return dedent`
1018
+ ### Interpreter
931
1019
 
932
- - ES2023+ syntax with TypeScript support. No Node.js APIs, no \`require\`, no \`import\`.
933
- - Output is truncated beyond a fixed character limit be selective about what you log.
934
- - Execution timeout per call (default 30 s).
935
- `;
1020
+ An \`${opts.toolName}\` tool is available. It runs JavaScript in a persistent REPL.
1021
+ - State (variables, functions) persists across tool calls within a single turn of conversation. They DO NOT persist across multiple turns.
1022
+ - Top-level \`await\` works; Promises resolve before the call returns.
1023
+ - Sandboxed: no filesystem, no stdlib, no network, no real clock, no \`fetch\`, no \`require\`.
1024
+ - Timeout: ${opts.timeout}s per call. Memory: ${opts.memoryLimitMb} MB total.
1025
+ - \`console.log\` output is captured and returned alongside the result.
1026
+ `;
1027
+ }
936
1028
  /**
937
1029
  * Generate the PTC API Reference section for the system prompt.
938
1030
  */
@@ -1009,21 +1101,25 @@ async function prepareSkillsForEval(session, skillsBackend, code) {
1009
1101
  });
1010
1102
  }
1011
1103
  /**
1012
- * Create the QuickJS REPL middleware.
1104
+ * Create the Code Interpreter middleware.
1013
1105
  */
1014
- function createQuickJSMiddleware(options = {}) {
1015
- 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;
1106
+ function createCodeInterpreterMiddleware(options = {}) {
1107
+ 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;
1016
1108
  if (maxPtcCalls !== null && maxPtcCalls !== void 0 && maxPtcCalls < 1) throw new Error("`maxPtcCalls` must be >= 1 or null");
1017
- const baseSystemPrompt = customSystemPrompt || REPL_SYSTEM_PROMPT;
1109
+ const baseSystemPrompt = customSystemPrompt || renderReplSystemPrompt({
1110
+ toolName,
1111
+ timeout: executionTimeoutMs / 1e3,
1112
+ memoryLimitMb: Math.floor(memoryLimitBytes / (1024 * 1024))
1113
+ });
1018
1114
  const middlewareId = crypto.randomUUID();
1019
1115
  let cachedPtcPrompt = null;
1020
1116
  let ptcTools = [];
1021
1117
  function filterToolsForPtc(allTools) {
1022
1118
  if (!ptc) return [];
1023
- return resolveToolList(ptc, allTools.filter((t) => t.name !== "js_eval"));
1119
+ return resolveToolList(ptc, allTools.filter((t) => t.name !== toolName));
1024
1120
  }
1025
1121
  return createMiddleware({
1026
- name: "QuickJSMiddleware",
1122
+ name: "CodeInterpreterMiddleware",
1027
1123
  tools: [tool(async (input, config) => {
1028
1124
  const sessionKey = `${config.configurable?.thread_id || "__default__"}:${middlewareId}`;
1029
1125
  const session = ReplSession.getOrCreate(sessionKey, {
@@ -1032,7 +1128,8 @@ function createQuickJSMiddleware(options = {}) {
1032
1128
  maxPtcCalls,
1033
1129
  tools: ptcTools,
1034
1130
  skillsEnabled: skillsBackend !== void 0,
1035
- maxResultChars
1131
+ maxResultChars,
1132
+ captureConsole
1036
1133
  });
1037
1134
  if (skillsBackend !== void 0) {
1038
1135
  const setupError = await prepareSkillsForEval(session, skillsBackend, input.code);
@@ -1040,7 +1137,7 @@ function createQuickJSMiddleware(options = {}) {
1040
1137
  }
1041
1138
  return formatReplResult(await session.eval(input.code, executionTimeoutMs));
1042
1139
  }, {
1043
- name: "js_eval",
1140
+ name: toolName,
1044
1141
  description: dedent`
1045
1142
  Evaluate TypeScript/JavaScript code in a sandboxed REPL. State persists across calls.
1046
1143
  Use console.log() for output. Returns the result of the last expression.
@@ -1066,6 +1163,6 @@ function createQuickJSMiddleware(options = {}) {
1066
1163
  });
1067
1164
  }
1068
1165
  //#endregion
1069
- export { DEFAULT_EXECUTION_TIMEOUT, DEFAULT_MAX_PTC_CALLS, DEFAULT_MAX_STACK_SIZE, DEFAULT_MEMORY_LIMIT, MAX_SKILL_BUNDLE_BYTES, PTCCallBudgetExceededError, ReplSession, SKILL_MODULE_EXTENSIONS, createQuickJSMiddleware, formatReplResult, formatSkillNotAvailable, loadSkill, scanSkillReferences, stripTypeSyntax, toCamelCase, transformForEval };
1166
+ export { DEFAULT_EXECUTION_TIMEOUT, DEFAULT_MAX_PTC_CALLS, DEFAULT_MAX_STACK_SIZE, DEFAULT_MEMORY_LIMIT, MAX_SKILL_BUNDLE_BYTES, PTCCallBudgetExceededError, ReplSession, SKILL_MODULE_EXTENSIONS, createCodeInterpreterMiddleware, formatReplResult, formatSkillNotAvailable, loadSkill, scanSkillReferences, stripTypeSyntax, toCamelCase, transformForEval };
1070
1167
 
1071
1168
  //# sourceMappingURL=index.js.map