agent.libx.js 0.93.28 → 0.93.30

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
@@ -314,7 +314,7 @@ declare const grepTool: AgentTool;
314
314
  * Compact map of a VFS — code signatures and/or doc outlines. Edge-safe (pure IFilesystem walk).
315
315
  * `mode`: "code" (default) = top-level signatures; "docs" = heading outlines; "all" = both.
316
316
  */
317
- declare function repoIndex(fs: IFilesystem, glob?: string, mode?: 'code' | 'docs' | 'all'): Promise<string>;
317
+ declare function repoIndex(fs: IFilesystem, glob?: string, mode?: 'code' | 'docs' | 'all', signal?: AbortSignal): Promise<string>;
318
318
  /** Compact map of the codebase or document workspace — orient in ONE call, not many. */
319
319
  declare const repoMapTool: AgentTool;
320
320
  /** Create or overwrite a file, creating parent directories as needed (mkdir -p). */
@@ -683,6 +683,11 @@ declare class DuplexAgentOptions {
683
683
  actModel: string;
684
684
  /** Premium reasoning model. Set to `false` to disable the Think tier entirely. */
685
685
  thinkModel: string | false;
686
+ /** Per-worker providerOptions, derived from the worker's actual model at spawn time (IoC — keeps duplex
687
+ * provider-agnostic). Workers override the reflex/main model, so provider-specific options (e.g. cursor's
688
+ * cwd/cursorSession) must be recomputed for the worker's model, never inherited from the main template —
689
+ * leaking cursor options to an anthropic worker is a hard 400. Returns undefined → no providerOptions. */
690
+ providerOptionsFor?: (model: string) => Record<string, unknown> | undefined;
686
691
  /** Escape hatches merged over the derived per-agent options. */
687
692
  reflexOptions?: Partial<AgentOptions>;
688
693
  actOptions?: Partial<AgentOptions>;
package/dist/index.js CHANGED
@@ -25,7 +25,10 @@ var init_redact = __esm({
25
25
  });
26
26
 
27
27
  // src/tools.structured.ts
28
- async function walkFiles(fs, dir, out = []) {
28
+ function ckAbort(signal) {
29
+ if (signal?.aborted) throw new Error("aborted");
30
+ }
31
+ async function walkFiles(fs, dir, signal, out = []) {
29
32
  let entries;
30
33
  try {
31
34
  entries = await fs.readDir(dir);
@@ -33,8 +36,9 @@ async function walkFiles(fs, dir, out = []) {
33
36
  return out;
34
37
  }
35
38
  for (const name of entries.sort()) {
39
+ ckAbort(signal);
36
40
  const p = dir === "/" ? `/${name}` : `${dir}/${name}`;
37
- if (await fs.isDirectory(p)) await walkFiles(fs, p, out);
41
+ if (await fs.isDirectory(p)) await walkFiles(fs, p, signal, out);
38
42
  else out.push(p);
39
43
  }
40
44
  return out;
@@ -91,13 +95,14 @@ function signaturesOf(content, cap = 40) {
91
95
  }
92
96
  return out;
93
97
  }
94
- async function repoIndex(fs, glob, mode = "code") {
98
+ async function repoIndex(fs, glob, mode = "code", signal) {
95
99
  const scope = glob ? anchoredGlob(fs, String(glob)) : null;
96
100
  const filter = mode === "code" ? isCode : mode === "docs" ? isDoc : (p) => isCode(p) || isDoc(p);
97
- const files = (await walkFiles(fs, fsCwd(fs))).filter((p) => scope ? scope.test(p) : filter(p));
101
+ const files = (await walkFiles(fs, fsCwd(fs), signal)).filter((p) => scope ? scope.test(p) : filter(p));
98
102
  const blocks = [];
99
103
  let shown = 0;
100
104
  for (const path of files) {
105
+ ckAbort(signal);
101
106
  let content;
102
107
  try {
103
108
  content = await fs.readFile(path);
@@ -217,7 +222,7 @@ var init_tools_structured = __esm({
217
222
  const include = pats.filter((p) => !p.startsWith("!")).map((p) => anchoredGlob(ctx.fs, p));
218
223
  const exclude = pats.filter((p) => p.startsWith("!")).map((p) => anchoredGlob(ctx.fs, p.slice(1)));
219
224
  const includes = include.length ? include : [anchoredGlob(ctx.fs, "**")];
220
- const hits = (await walkFiles(ctx.fs, fsCwd(ctx.fs))).filter(
225
+ const hits = (await walkFiles(ctx.fs, fsCwd(ctx.fs), ctx.signal)).filter(
221
226
  (p) => includes.some((re) => re.test(p)) && !exclude.some((re) => re.test(p))
222
227
  );
223
228
  return hits.length ? hits.join("\n") : "(no matches)";
@@ -244,11 +249,12 @@ var init_tools_structured = __esm({
244
249
  throw new Error(`invalid regex: ${String(e)}`);
245
250
  }
246
251
  const scope = glob ? anchoredGlob(ctx.fs, String(glob)) : null;
247
- const files = (await walkFiles(ctx.fs, fsCwd(ctx.fs))).filter((p) => !scope || scope.test(p));
252
+ const files = (await walkFiles(ctx.fs, fsCwd(ctx.fs), ctx.signal)).filter((p) => !scope || scope.test(p));
248
253
  const ctxN = Math.max(0, Number(context ?? 0));
249
254
  const out = [];
250
255
  const matched = [];
251
256
  for (const path of files) {
257
+ ckAbort(ctx.signal);
252
258
  let content;
253
259
  try {
254
260
  content = await ctx.fs.readFile(path);
@@ -284,7 +290,7 @@ var init_tools_structured = __esm({
284
290
  scope: { type: "string", enum: ["code", "docs", "all"], description: 'what to map: "code" (default), "docs", or "all"' }
285
291
  }
286
292
  },
287
- run: ({ glob, scope }, ctx) => repoIndex(ctx.fs, glob, scope || "code")
293
+ run: ({ glob, scope }, ctx) => repoIndex(ctx.fs, glob, scope || "code", ctx.signal)
288
294
  };
289
295
  writeTool = {
290
296
  name: "Write",
@@ -3004,6 +3010,7 @@ var Agent = class _Agent {
3004
3010
  toolCallsTotal += toolCalls.length;
3005
3011
  if (o.maxToolCalls && toolCallsTotal > o.maxToolCalls) return kill("max_tool_calls");
3006
3012
  for (const tc of toolCalls) {
3013
+ if (o.signal?.aborted) return kill("aborted");
3007
3014
  const raw = await this.dispatch(tc);
3008
3015
  let content;
3009
3016
  if (typeof raw === "string") {
@@ -3763,6 +3770,11 @@ var DuplexAgentOptions = class {
3763
3770
  actModel = "anthropic/claude-sonnet-4-6";
3764
3771
  /** Premium reasoning model. Set to `false` to disable the Think tier entirely. */
3765
3772
  thinkModel = "anthropic/claude-opus-4-8";
3773
+ /** Per-worker providerOptions, derived from the worker's actual model at spawn time (IoC — keeps duplex
3774
+ * provider-agnostic). Workers override the reflex/main model, so provider-specific options (e.g. cursor's
3775
+ * cwd/cursorSession) must be recomputed for the worker's model, never inherited from the main template —
3776
+ * leaking cursor options to an anthropic worker is a hard 400. Returns undefined → no providerOptions. */
3777
+ providerOptionsFor;
3766
3778
  /** Escape hatches merged over the derived per-agent options. */
3767
3779
  reflexOptions;
3768
3780
  actOptions;
@@ -4025,6 +4037,9 @@ ${recent}` : brief) + verify;
4025
4037
  model: tierModel,
4026
4038
  ...tier === "think" ? { reasoning: tierOpts?.reasoning ?? "high" } : {},
4027
4039
  ...tierOpts,
4040
+ // Recompute providerOptions for THIS worker's model (after tierOpts so it wins over any inherited
4041
+ // main-template value) — prevents cursor-only cwd/cursorSession leaking onto an anthropic worker.
4042
+ providerOptions: o.providerOptionsFor?.(tierModel),
4028
4043
  ...workerHost ? { host: workerHost } : {},
4029
4044
  ...hooks ? { hooks } : {},
4030
4045
  signal: controller.signal