@langchain/quickjs 0.2.5-alpha.0 → 0.2.6

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
@@ -1,7 +1,7 @@
1
1
  import * as _$langchain from "langchain";
2
2
  import { AgentMiddleware } from "langchain";
3
3
  import { z } from "zod/v4";
4
- import { AnyBackendProtocol, BackendFactory, BackendProtocolV2 } from "deepagents";
4
+ import { AnyBackendProtocol, BackendFactory, SkillMetadata } from "deepagents";
5
5
  import { StructuredToolInterface } from "@langchain/core/tools";
6
6
 
7
7
  //#region src/types.d.ts
@@ -9,29 +9,15 @@ import { StructuredToolInterface } from "@langchain/core/tools";
9
9
  * Configuration options for the QuickJS REPL middleware.
10
10
  */
11
11
  interface QuickJSMiddlewareOptions {
12
- /**
13
- * Backend for file I/O (readFile/writeFile) inside the REPL.
14
- * Accepts a AnyBackendProtocol instance or a BackendFactory function.
15
- * Defaults to StateBackend (reads/writes LangGraph checkpoint state).
16
- * @default StateBackend
17
- */
18
- backend?: AnyBackendProtocol | BackendFactory;
19
12
  /**
20
13
  * Enable programmatic tool calling from within the REPL.
21
14
  *
22
- * - `false` disabled (default)
23
- * - `true` expose all agent tools except standard vfs tools
24
- * - `string[]` — expose only these tools (alias for `{ include }`)
25
- * - `{ include: string[] }` — expose only these tools
26
- * - `{ exclude: string[] }` — expose all agent tools except these
15
+ * Array of tools to expose; strings are resolved from agent tools, instances
16
+ * are injected directly without needing to be registered on the agent.
27
17
  *
28
- * @default false
18
+ * Omit to disable PTC entirely (default).
29
19
  */
30
- ptc?: boolean | string[] | {
31
- include: string[];
32
- } | {
33
- exclude: string[];
34
- };
20
+ ptc?: (string | StructuredToolInterface)[];
35
21
  /**
36
22
  * Memory limit in bytes.
37
23
  * @default 52428800 (50MB)
@@ -53,6 +39,33 @@ interface QuickJSMiddlewareOptions {
53
39
  * @default null (uses built-in prompt)
54
40
  */
55
41
  systemPrompt?: string | null;
42
+ /**
43
+ * Backend the REPL reads skill module sources from. When provided alongside
44
+ * `SkillsMiddleware`, skills with a `module:` key become dynamic-importable.
45
+ */
46
+ skillsBackend?: AnyBackendProtocol | BackendFactory;
47
+ /**
48
+ * Maximum number of `tools.*` bridge calls allowed per `eval()` invocation.
49
+ *
50
+ * Each call to any function in the `tools` namespace decrements the counter.
51
+ * Once exhausted the next call rejects with a `PTCCallBudgetExceeded` error.
52
+ * The budget resets to this value at the start of every new `eval()` call.
53
+ *
54
+ * Set to `null` to disable the limit entirely (unsafe — increases DoS risk).
55
+ * Must be >= 1 when provided as a number.
56
+ *
57
+ * @default 256
58
+ */
59
+ maxPtcCalls?: number | null;
60
+ /**
61
+ * Maximum characters to retain from console output per evaluation.
62
+ * Output exceeding this limit is dropped at capture time and a
63
+ * `[truncated N chars]` marker is appended to the tool response.
64
+ * The same limit also caps result and error strings in the formatted output.
65
+ *
66
+ * @default 4000
67
+ */
68
+ maxResultChars?: number;
56
69
  }
57
70
  /**
58
71
  * Options for creating a ReplSession.
@@ -60,8 +73,10 @@ interface QuickJSMiddlewareOptions {
60
73
  interface ReplSessionOptions {
61
74
  memoryLimitBytes?: number;
62
75
  maxStackSizeBytes?: number;
63
- backend?: AnyBackendProtocol;
64
76
  tools?: StructuredToolInterface[];
77
+ skillsEnabled?: boolean;
78
+ maxPtcCalls?: number | null;
79
+ maxResultChars?: number;
65
80
  }
66
81
  /**
67
82
  * Result of a single REPL evaluation.
@@ -75,15 +90,23 @@ interface ReplResult {
75
90
  stack?: string;
76
91
  };
77
92
  logs: string[];
93
+ logsDroppedChars: number;
78
94
  }
79
- //#endregion
80
- //#region src/middleware.d.ts
81
95
  /**
82
- * Backend-provided tools excluded from PTC by default.
83
- * These are redundant inside the REPL since VFS helpers (readFile/writeFile)
84
- * already cover file I/O against the agent's in-memory working set.
96
+ * Metadata + backend pair the session needs to resolve skill imports.
85
97
  */
86
- declare const DEFAULT_PTC_EXCLUDED_TOOLS: readonly ["ls", "read_file", "write_file", "edit_file", "glob", "grep", "execute"];
98
+ interface SkillsContext {
99
+ /**
100
+ * Per-eval snapshot of `state.skillsMetadata`.
101
+ */
102
+ metadata: SkillMetadata[];
103
+ /**
104
+ * Backend the session fetches skill source files from.
105
+ */
106
+ backend: AnyBackendProtocol;
107
+ }
108
+ //#endregion
109
+ //#region src/middleware.d.ts
87
110
  /**
88
111
  * Create the QuickJS REPL middleware.
89
112
  */
@@ -95,14 +118,39 @@ declare function createQuickJSMiddleware(options?: QuickJSMiddlewareOptions): Ag
95
118
  code: string;
96
119
  }, string, unknown, "js_eval">]>;
97
120
  //#endregion
121
+ //#region src/errors.d.ts
122
+ /**
123
+ * Options for constructing a {@link PTCCallBudgetExceededError}.
124
+ */
125
+ interface PTCCallBudgetExceededOptions {
126
+ /**
127
+ * The configured per-eval PTC call limit.
128
+ */
129
+ limit: number;
130
+ /**
131
+ * The call number that triggered the violation (always `limit + 1`).
132
+ */
133
+ attempted: number;
134
+ /**
135
+ * The name of the tool function that was called over budget.
136
+ */
137
+ functionName: string;
138
+ }
139
+ /**
140
+ * Thrown when a single eval exhausts its configured PTC call budget.
141
+ */
142
+ declare class PTCCallBudgetExceededError extends Error {
143
+ readonly limit: number;
144
+ readonly attempted: number;
145
+ readonly functionName: string;
146
+ constructor(options: PTCCallBudgetExceededOptions);
147
+ }
148
+ //#endregion
98
149
  //#region src/session.d.ts
99
150
  declare const DEFAULT_MEMORY_LIMIT: number;
100
151
  declare const DEFAULT_MAX_STACK_SIZE: number;
101
152
  declare const DEFAULT_EXECUTION_TIMEOUT = 30000;
102
- interface PendingWrite {
103
- path: string;
104
- content: string;
105
- }
153
+ declare const DEFAULT_MAX_PTC_CALLS = 256;
106
154
  /**
107
155
  * Sandboxed JavaScript REPL session backed by QuickJS WASM.
108
156
  *
@@ -110,23 +158,45 @@ interface PendingWrite {
110
158
  * The QuickJS runtime is lazily started on the first `.eval()` call
111
159
  * and reconnected if a session with the same id already exists.
112
160
  * This makes it safe to store in LangGraph state across interrupts.
113
- *
114
- * File writes are buffered during execution and flushed via
115
- * `flushWrites(backend)` after eval completes.
116
161
  */
117
162
  declare class ReplSession {
118
163
  private static sessions;
119
164
  readonly id: string;
120
- readonly pendingWrites: PendingWrite[];
121
165
  private runtime;
122
166
  private context;
123
- private logs;
124
- private _options;
125
- private _backend;
167
+ private consoleBuffer;
168
+ private options;
169
+ private skillsContext;
170
+ private skillsLoaded;
171
+ private skillsFailed;
172
+ private readonly maxPtcCalls;
173
+ private ptcCallsRemaining;
126
174
  constructor(id: string, options?: ReplSessionOptions);
127
- get backend(): BackendProtocolV2 | null;
128
- set backend(b: AnyBackendProtocol | null);
129
175
  private ensureStarted;
176
+ /**
177
+ * Load the skill into cache on first access and replay cached errors.
178
+ */
179
+ private ensureSkillLoaded;
180
+ private resolveSpecifier;
181
+ /**
182
+ * Canonicalize an `import` specifier. Bare specifiers pass through;
183
+ * relative specifiers are resolved against the importing module's path.
184
+ * Traversal out of a skill's `@/skills/<name>/` namespace is rejected.
185
+ */
186
+ private normalizeSpecifier;
187
+ /**
188
+ * Wire the QuickJS module loader and normalizer on this session's runtime.
189
+ */
190
+ private installModuleLoader;
191
+ /**
192
+ * Initialise the per-eval PTC counter. Called at the top of every `eval()`.
193
+ */
194
+ private resetPtcBudget;
195
+ /**
196
+ * Decrement the PTC call counter and throw if the budget is exhausted.
197
+ * `null` budget means unlimited — returns immediately without decrementing.
198
+ */
199
+ private consumePtcBudget;
130
200
  /**
131
201
  * Get or create a session for the given id.
132
202
  *
@@ -139,6 +209,22 @@ declare class ReplSession {
139
209
  * Retrieve an existing session by id, or null if none exists.
140
210
  */
141
211
  static get(id: string): ReplSession | null;
212
+ /**
213
+ * Returns true if any session exists whose key equals `threadId` or starts
214
+ * with `threadId:`. Useful for tests that need to confirm a session was
215
+ * created without knowing the full `threadId:middlewareId` key.
216
+ */
217
+ static hasAnyForThread(threadId: string): boolean;
218
+ /**
219
+ * Dispose and remove the session with the given key, if it exists.
220
+ */
221
+ static deleteSession(key: string): void;
222
+ /**
223
+ * Push the current skills metadata + backend into the session.
224
+ * Called by the middleware once per `js_eval` invocation, before eval runs.
225
+ * Pass `undefined` to clear the context (no skill imports will resolve).
226
+ */
227
+ setSkillsContext(ctx?: SkillsContext): void;
142
228
  /**
143
229
  * Evaluate code in this session.
144
230
  *
@@ -149,7 +235,6 @@ declare class ReplSession {
149
235
  * async IIFE.
150
236
  */
151
237
  eval(code: string, timeoutMs: number): Promise<ReplResult>;
152
- flushWrites(backend: AnyBackendProtocol): Promise<void>;
153
238
  dispose(): void;
154
239
  toJSON(): {
155
240
  id: string;
@@ -163,7 +248,6 @@ declare class ReplSession {
163
248
  */
164
249
  static clearCache(): void;
165
250
  private setupConsole;
166
- private injectVfs;
167
251
  private injectTools;
168
252
  }
169
253
  //#endregion
@@ -176,6 +260,10 @@ declare function toCamelCase(name: string): string;
176
260
  * Format the result of a REPL evaluation for the agent.
177
261
  */
178
262
  declare function formatReplResult(result: ReplResult): string;
263
+ /**
264
+ * Render a pre-eval error when referenced skills are not available on the agent.
265
+ */
266
+ declare function formatSkillNotAvailable(missing: readonly string[]): string;
179
267
  //#endregion
180
268
  //#region src/transform.d.ts
181
269
  /**
@@ -199,6 +287,61 @@ declare function formatReplResult(result: ReplResult): string;
199
287
  * - Wraps in async IIFE for top-level await support
200
288
  */
201
289
  declare function transformForEval(code: string): string;
290
+ /**
291
+ * Strip TypeScript type syntax from an ES-module source so QuickJS can
292
+ * evaluate it as a standard JS module.
293
+ *
294
+ * Unlike `transformForEval`, this keeps `import`/`export` declarations,
295
+ * does not hoist to `globalThis`, and does not wrap in an IIFE.
296
+ * On parse failure the original source is returned unchanged.
297
+ */
298
+ declare function stripTypeSyntax(code: string): string;
299
+ //#endregion
300
+ //#region src/skills.d.ts
301
+ /**
302
+ * File extensions the loader will enumerate from a skill directory.
303
+ */
304
+ declare const SKILL_MODULE_EXTENSIONS: string[];
305
+ /**
306
+ * Hard cap on total bytes pulled for one skill's bundle (1 MiB).
307
+ */
308
+ declare const MAX_SKILL_BUNDLE_BYTES: number;
309
+ /**
310
+ * Install-ready state for a single skill, produced by `loadSkill`.
311
+ */
312
+ interface LoadedSkill {
313
+ /**
314
+ * Spec-validated kebab-case skill name.
315
+ */
316
+ name: string;
317
+ /**
318
+ * Bare specifier the skill installs under: `"@/skills/<name>"`.
319
+ */
320
+ specifier: string;
321
+ /**
322
+ * Relative POSIX path of the entrypoint file (e.g. `"index.ts"`).
323
+ */
324
+ entryRel: string;
325
+ /**
326
+ * File contents keyed by relative POSIX path, with TS syntax stripped.
327
+ */
328
+ files: Map<string, string>;
329
+ }
330
+ /**
331
+ * Build a `LoadedSkill` from a skill's metadata and a backend handle.
332
+ *
333
+ * Enumerates code files under the skill directory, downloads them,
334
+ * strips TypeScript syntax, and validates the entrypoint is present.
335
+ */
336
+ declare function loadSkill(metadata: SkillMetadata, backend: AnyBackendProtocol): Promise<LoadedSkill>;
337
+ /**
338
+ * Extract skill names referenced by `"@/skills/<name>"` literals in source.
339
+ *
340
+ * Used as a pre-eval scan so the middleware can surface `SkillNotAvailable`
341
+ * before evaluation starts. Dynamic imports with computed specifiers are
342
+ * not detected.
343
+ */
344
+ declare function scanSkillReferences(source: string): Set<string>;
202
345
  //#endregion
203
- export { DEFAULT_EXECUTION_TIMEOUT, DEFAULT_MAX_STACK_SIZE, DEFAULT_MEMORY_LIMIT, DEFAULT_PTC_EXCLUDED_TOOLS, type PendingWrite, type QuickJSMiddlewareOptions, type ReplResult, ReplSession, type ReplSessionOptions, createQuickJSMiddleware, formatReplResult, toCamelCase, transformForEval };
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 };
204
347
  //# sourceMappingURL=index.d.ts.map