@humain/terminal 0.0.16 → 0.0.18

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.
@@ -1 +1 @@
1
- {"version":3,"file":"subagent.d.ts","sourceRoot":"","sources":["../../../src/core/tools/subagent.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAOH,OAAO,KAAK,EAAO,OAAO,EAAS,MAAM,uBAAuB,CAAC;AAGjE,OAAO,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAI/B,OAAO,KAAK,EAAoB,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAU/E,4FAA4F;AAC5F,eAAO,MAAM,kBAAkB,mCAAmC,CAAC;AAUnE,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG,SAAS,GAAG,MAAM,CAAC;AAErD,MAAM,WAAW,WAAW;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3B,QAAQ,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,oBAAoB;IACpC,MAAM,EAAE,WAAW,EAAE,CAAC;IACtB,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;CAChC;AAyED,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,GAAG,oBAAoB,CAmBnF;AAoGD,MAAM,WAAW,kBAAkB;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,aAAa,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,oBAAoB;IACpC,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,GAAG,SAAS,GAAG,SAAS,CAAC;IAC5C,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,kBAAkB,CAAC;IAC1B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,IAAI,CAAC,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,eAAe;IAC/B,IAAI,EAAE,QAAQ,GAAG,UAAU,GAAG,OAAO,CAAC;IACtC,UAAU,EAAE,UAAU,CAAC;IACvB,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,OAAO,EAAE,oBAAoB,EAAE,CAAC;CAChC;AAoTD,QAAA,MAAM,cAAc;;;;;;;;;;;;;;;;;;;EAelB,CAAC;AAEH,wBAAgB,4BAA4B,CAAC,GAAG,EAAE,MAAM,GAAG,cAAc,CAAC,OAAO,cAAc,EAAE,eAAe,CAAC,CAsoBhH;AAED,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,2EAE7C"}
1
+ {"version":3,"file":"subagent.d.ts","sourceRoot":"","sources":["../../../src/core/tools/subagent.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAOH,OAAO,KAAK,EAAO,OAAO,EAAS,MAAM,uBAAuB,CAAC;AAGjE,OAAO,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAI/B,OAAO,KAAK,EAAoB,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAG/E,OAAO,EAGN,KAAK,iBAAiB,EACtB,KAAK,oBAAoB,EAEzB,MAAM,wBAAwB,CAAC;AAQhC,4FAA4F;AAC5F,eAAO,MAAM,kBAAkB,mCAAmC,CAAC;AAUnE,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG,SAAS,GAAG,MAAM,CAAC;AAErD,MAAM,WAAW,WAAW;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3B,QAAQ,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,oBAAoB;IACpC,MAAM,EAAE,WAAW,EAAE,CAAC;IACtB,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;CAChC;AAyED,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,GAAG,oBAAoB,CAmBnF;AAoGD,MAAM,WAAW,kBAAkB;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,aAAa,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,oBAAoB;IACpC,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,GAAG,SAAS,GAAG,SAAS,CAAC;IAC5C,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,kBAAkB,CAAC;IAC1B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,iBAAiB,CAAC;IAC7B,uBAAuB,CAAC,EAAE,gBAAgB,CAAC;IAC3C,YAAY,CAAC,EAAE,oBAAoB,CAAC;IACpC,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,SAAS,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,eAAe;IAC/B,IAAI,EAAE,QAAQ,GAAG,UAAU,GAAG,OAAO,CAAC;IACtC,UAAU,EAAE,UAAU,CAAC;IACvB,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,OAAO,EAAE,oBAAoB,EAAE,CAAC;CAChC;AA0YD,QAAA,MAAM,cAAc;;;;;;;;;;;;;;;;;;;;;EAqBlB,CAAC;AAEH,wBAAgB,4BAA4B,CAAC,GAAG,EAAE,MAAM,GAAG,cAAc,CAAC,OAAO,cAAc,EAAE,eAAe,CAAC,CAopBhH;AAED,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,2EAE7C"}
@@ -23,6 +23,7 @@ import { getMarkdownTheme } from "../../modes/interactive/theme/theme.js";
23
23
  import { parseFrontmatter } from "../../utils/frontmatter.js";
24
24
  import { withFileMutationQueue } from "./file-mutation-queue.js";
25
25
  import { shortenPath } from "./render-utils.js";
26
+ import { createSubagentWorktree, isGitWorkTree, } from "./subagent-worktree.js";
26
27
  import { wrapToolDefinition } from "./tool-definition-wrapper.js";
27
28
  const MAX_PARALLEL_TASKS = 8;
28
29
  const MAX_CONCURRENCY = 4;
@@ -223,7 +224,10 @@ function getFinalOutput(messages) {
223
224
  return "";
224
225
  }
225
226
  function isFailedResult(result) {
226
- return result.exitCode !== 0 || result.stopReason === "error" || result.stopReason === "aborted";
227
+ return (Boolean(result.errorMessage) ||
228
+ result.exitCode !== 0 ||
229
+ result.stopReason === "error" ||
230
+ result.stopReason === "aborted");
227
231
  }
228
232
  function getResultOutput(result) {
229
233
  if (isFailedResult(result)) {
@@ -255,7 +259,7 @@ function getDisplayItems(messages) {
255
259
  }
256
260
  return items;
257
261
  }
258
- async function mapWithConcurrencyLimit(items, concurrency, fn, signal) {
262
+ async function mapWithConcurrencyLimit(items, concurrency, fn, signal, onAbort) {
259
263
  if (items.length === 0)
260
264
  return [];
261
265
  const limit = Math.max(1, Math.min(concurrency, items.length));
@@ -263,12 +267,14 @@ async function mapWithConcurrencyLimit(items, concurrency, fn, signal) {
263
267
  let nextIndex = 0;
264
268
  const workers = new Array(limit).fill(null).map(async () => {
265
269
  while (true) {
266
- // Don't spawn doomed children for tasks still queued after an abort.
267
- if (signal?.aborted)
268
- throw new Error("Subagent was aborted");
269
270
  const current = nextIndex++;
270
271
  if (current >= items.length)
271
272
  return;
273
+ if (signal?.aborted) {
274
+ if (onAbort)
275
+ results[current] = await onAbort(items[current], current);
276
+ continue;
277
+ }
272
278
  results[current] = await fn(items[current], current);
273
279
  }
274
280
  });
@@ -297,7 +303,7 @@ function getCliInvocation(args) {
297
303
  }
298
304
  return { command: "humain-terminal", args };
299
305
  }
300
- async function runSingleAgent(defaultCwd, agents, agentName, task, cwd, step, model, parentModel, signal, onUpdate, makeDetails) {
306
+ async function runSingleAgent(defaultCwd, agents, agentName, task, cwd, isolation, step, model, parentModel, signal, onUpdate, makeDetails, toolCallId, childIndex) {
301
307
  const agent = agents.find((a) => a.name === agentName);
302
308
  if (!agent) {
303
309
  const available = agents.map((a) => `"${a.name}"`).join(", ") || "none";
@@ -310,8 +316,13 @@ async function runSingleAgent(defaultCwd, agents, agentName, task, cwd, step, mo
310
316
  stderr: `Unknown agent: "${agentName}". Available agents: ${available}.`,
311
317
  usage: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, cost: 0, contextTokens: 0, turns: 0 },
312
318
  step,
319
+ isolation: "shared",
313
320
  };
314
321
  }
322
+ let worktree = null;
323
+ let isolationDegradedReason;
324
+ const parentCwd = cwd ?? defaultCwd;
325
+ let childCwd = parentCwd;
315
326
  const args = ["--mode", "json", "-p", "--no-session"];
316
327
  if (model) {
317
328
  // Canonical "provider/modelId" handle: split on the FIRST slash so
@@ -343,6 +354,7 @@ async function runSingleAgent(defaultCwd, agents, agentName, task, cwd, step, mo
343
354
  usage: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, cost: 0, contextTokens: 0, turns: 0 },
344
355
  model: model ?? `${parentModel.provider}/${parentModel.id}`,
345
356
  step,
357
+ isolation: "shared",
346
358
  };
347
359
  const emitUpdate = () => {
348
360
  if (onUpdate) {
@@ -352,7 +364,22 @@ async function runSingleAgent(defaultCwd, agents, agentName, task, cwd, step, mo
352
364
  });
353
365
  }
354
366
  };
367
+ let wasAborted = false;
355
368
  try {
369
+ if (isolation === "worktree") {
370
+ if (await isGitWorkTree(parentCwd)) {
371
+ worktree = await createSubagentWorktree({ parentCwd, label: `${toolCallId}-${childIndex}` });
372
+ childCwd = worktree.cwd;
373
+ currentResult.isolation = "worktree";
374
+ }
375
+ else {
376
+ isolationDegradedReason = "not-a-git-repo";
377
+ }
378
+ }
379
+ if (isolationDegradedReason)
380
+ currentResult.isolationDegradedReason = isolationDegradedReason;
381
+ if (signal?.aborted)
382
+ throw new Error("Subagent was aborted");
356
383
  if (agent.systemPrompt.trim()) {
357
384
  const tmp = await writePromptToTempFile(agent.name, agent.systemPrompt);
358
385
  tmpPromptDir = tmp.dir;
@@ -360,16 +387,16 @@ async function runSingleAgent(defaultCwd, agents, agentName, task, cwd, step, mo
360
387
  args.push("--append-system-prompt", tmpPromptPath);
361
388
  }
362
389
  args.push(`Task: ${task}`);
363
- let wasAborted = false;
364
390
  const exitCode = await new Promise((resolve) => {
365
391
  const invocation = getCliInvocation(args);
366
392
  const proc = spawn(invocation.command, invocation.args, {
367
- cwd: cwd ?? defaultCwd,
393
+ cwd: childCwd,
368
394
  shell: false,
369
395
  stdio: ["ignore", "pipe", "pipe"],
370
396
  env: { ...process.env, [SUBAGENT_DEPTH_ENV]: String(currentSubagentDepth() + 1) },
371
397
  });
372
398
  let buffer = "";
399
+ let settled = false;
373
400
  const processLine = (line) => {
374
401
  if (!line.trim())
375
402
  return;
@@ -418,23 +445,39 @@ async function runSingleAgent(defaultCwd, agents, agentName, task, cwd, step, mo
418
445
  proc.stderr.on("data", (data) => {
419
446
  currentResult.stderr += data.toString();
420
447
  });
448
+ let abortListener;
449
+ let killTimer;
450
+ const cleanupAbort = () => {
451
+ if (signal && abortListener)
452
+ signal.removeEventListener("abort", abortListener);
453
+ if (killTimer)
454
+ clearTimeout(killTimer);
455
+ };
421
456
  proc.on("close", (code) => {
457
+ settled = true;
458
+ cleanupAbort();
422
459
  if (buffer.trim())
423
460
  processLine(buffer);
424
461
  resolve(code ?? 0);
425
462
  });
426
463
  proc.on("error", () => {
464
+ settled = true;
465
+ cleanupAbort();
427
466
  resolve(1);
428
467
  });
429
468
  if (signal) {
430
469
  const killProc = () => {
470
+ if (settled)
471
+ return;
431
472
  wasAborted = true;
432
- proc.kill("SIGTERM");
433
- setTimeout(() => {
434
- if (!proc.killed)
473
+ killTimer = setTimeout(() => {
474
+ if (!settled)
435
475
  proc.kill("SIGKILL");
436
476
  }, 5000);
477
+ killTimer.unref?.();
478
+ proc.kill("SIGTERM");
437
479
  };
480
+ abortListener = killProc;
438
481
  if (signal.aborted)
439
482
  killProc();
440
483
  else
@@ -442,11 +485,53 @@ async function runSingleAgent(defaultCwd, agents, agentName, task, cwd, step, mo
442
485
  }
443
486
  });
444
487
  currentResult.exitCode = exitCode;
445
- if (wasAborted)
446
- throw new Error("Subagent was aborted");
447
- return currentResult;
488
+ if (wasAborted || signal?.aborted) {
489
+ currentResult.exitCode = 1;
490
+ currentResult.stopReason = "aborted";
491
+ currentResult.errorMessage = "Subagent was aborted";
492
+ }
493
+ }
494
+ catch (error) {
495
+ currentResult.exitCode = 1;
496
+ currentResult.errorMessage = error instanceof Error ? error.message : String(error);
497
+ if (wasAborted || signal?.aborted)
498
+ currentResult.stopReason = "aborted";
448
499
  }
449
500
  finally {
501
+ if (worktree) {
502
+ try {
503
+ if (isFailedResult(currentResult) || signal?.aborted) {
504
+ currentResult.mergeOutcome = "skipped";
505
+ }
506
+ else {
507
+ const merged = await worktree.mergeBack();
508
+ currentResult.mergeOutcome = merged.outcome;
509
+ currentResult.changedFiles = merged.changedFiles;
510
+ if (merged.patchPath)
511
+ currentResult.patchPath = merged.patchPath;
512
+ if (merged.outcome === "conflict") {
513
+ currentResult.errorMessage = `subagent merge conflict: ${merged.changedFiles.join(", ")} could not be applied to the parent workspace; patch kept at ${merged.patchPath}`;
514
+ }
515
+ }
516
+ }
517
+ catch (error) {
518
+ currentResult.exitCode = 1;
519
+ currentResult.mergeOutcome = "skipped";
520
+ currentResult.errorMessage = `subagent merge failed: ${error instanceof Error ? error.message : String(error)}`;
521
+ }
522
+ finally {
523
+ try {
524
+ await worktree.dispose();
525
+ }
526
+ catch (error) {
527
+ currentResult.exitCode = 1;
528
+ const cleanupError = `subagent worktree cleanup failed: ${error instanceof Error ? error.message : String(error)}`;
529
+ const primaryOutput = getResultOutput(currentResult);
530
+ currentResult.errorMessage =
531
+ primaryOutput === "(no output)" ? cleanupError : `${primaryOutput}\n${cleanupError}`;
532
+ }
533
+ }
534
+ }
450
535
  if (tmpPromptPath)
451
536
  try {
452
537
  fs.unlinkSync(tmpPromptPath);
@@ -462,6 +547,7 @@ async function runSingleAgent(defaultCwd, agents, agentName, task, cwd, step, mo
462
547
  /* ignore */
463
548
  }
464
549
  }
550
+ return currentResult;
465
551
  }
466
552
  const TaskItem = Type.Object({
467
553
  agent: Type.String({ description: "Name of the agent to invoke" }),
@@ -470,6 +556,9 @@ const TaskItem = Type.Object({
470
556
  description: "Optional canonical provider/model for this child. Defaults to the parent provider/model.",
471
557
  })),
472
558
  cwd: Type.Optional(Type.String({ description: "Working directory for the agent process" })),
559
+ isolation: Type.Optional(StringEnum(["shared", "worktree"], {
560
+ description: "Filesystem isolation for this child. 'worktree' runs it in a disposable git worktree and merges its changes back; the caller's policy sets this, not the model.",
561
+ })),
473
562
  });
474
563
  const ChainItem = Type.Object({
475
564
  agent: Type.String({ description: "Name of the agent to invoke" }),
@@ -494,6 +583,9 @@ const SubagentParams = Type.Object({
494
583
  agentScope: Type.Optional(AgentScopeSchema),
495
584
  confirmProjectAgents: Type.Optional(Type.Boolean({ description: "Prompt before running project-local agents. Default: true.", default: true })),
496
585
  cwd: Type.Optional(Type.String({ description: "Working directory for the agent process (single mode)" })),
586
+ isolation: Type.Optional(StringEnum(["shared", "worktree"], {
587
+ description: "Filesystem isolation for this child. 'worktree' runs it in a disposable git worktree and merges its changes back; the caller's policy sets this, not the model.",
588
+ })),
497
589
  });
498
590
  export function createSubagentToolDefinition(cwd) {
499
591
  return {
@@ -502,6 +594,7 @@ export function createSubagentToolDefinition(cwd) {
502
594
  description: [
503
595
  "Delegate tasks to specialized subagents with isolated context.",
504
596
  "Modes: single (agent + task), parallel (tasks array), chain (sequential with {previous} placeholder).",
597
+ "The optional isolation field is policy-set for each child.",
505
598
  `Default agent scope is "user" (from ${path.join(getAgentDir(), "agents")}).`,
506
599
  `To enable project-local agents in ${CONFIG_DIR_NAME}/agents, set agentScope: "both" (or "project").`,
507
600
  ].join(" "),
@@ -510,7 +603,7 @@ export function createSubagentToolDefinition(cwd) {
510
603
  "Use subagent to fan out independent work in parallel (tasks array) or run multi-step pipelines (chain). Subagents run with isolated context and cannot delegate further.",
511
604
  ],
512
605
  parameters: SubagentParams,
513
- async execute(_toolCallId, params, signal, onUpdate, ctx) {
606
+ async execute(toolCallId, params, signal, onUpdate, ctx) {
514
607
  const agentScope = params.agentScope ?? "user";
515
608
  const defaultCwd = ctx?.cwd ?? cwd;
516
609
  const parentModel = ctx?.model;
@@ -539,6 +632,7 @@ export function createSubagentToolDefinition(cwd) {
539
632
  usage: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, cost: 0, contextTokens: 0, turns: 0 },
540
633
  errorMessage,
541
634
  step: child.step,
635
+ isolation: "shared",
542
636
  });
543
637
  const stubAllChildren = (errorMessage) => requestedChildren().map((child) => stubResult(child, errorMessage));
544
638
  const makeDetails = (mode) => (results) => ({
@@ -631,7 +725,7 @@ export function createSubagentToolDefinition(cwd) {
631
725
  }
632
726
  }
633
727
  : undefined;
634
- const result = await runSingleAgent(defaultCwd, agents, step.agent, taskWithContext, step.cwd, i + 1, step.model, parentModel, signal, chainUpdate, makeDetails("chain"));
728
+ const result = await runSingleAgent(defaultCwd, agents, step.agent, taskWithContext, step.cwd, undefined, i + 1, step.model, parentModel, signal, chainUpdate, makeDetails("chain"), toolCallId, i);
635
729
  results.push(result);
636
730
  const isError = isFailedResult(result);
637
731
  if (isError) {
@@ -676,6 +770,7 @@ export function createSubagentToolDefinition(cwd) {
676
770
  messages: [],
677
771
  stderr: "",
678
772
  usage: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, cost: 0, contextTokens: 0, turns: 0 },
773
+ isolation: "shared",
679
774
  };
680
775
  }
681
776
  const emitParallelUpdate = () => {
@@ -691,18 +786,18 @@ export function createSubagentToolDefinition(cwd) {
691
786
  }
692
787
  };
693
788
  const results = await mapWithConcurrencyLimit(params.tasks, MAX_CONCURRENCY, async (t, index) => {
694
- const result = await runSingleAgent(defaultCwd, agents, t.agent, t.task, t.cwd, undefined, t.model, parentModel, signal,
789
+ const result = await runSingleAgent(defaultCwd, agents, t.agent, t.task, t.cwd, t.isolation, undefined, t.model, parentModel, signal,
695
790
  // Per-task update callback
696
791
  (partial) => {
697
792
  if (partial.details?.results[0]) {
698
793
  allResults[index] = partial.details.results[0];
699
794
  emitParallelUpdate();
700
795
  }
701
- }, makeDetails("parallel"));
796
+ }, makeDetails("parallel"), toolCallId, index);
702
797
  allResults[index] = result;
703
798
  emitParallelUpdate();
704
799
  return result;
705
- }, signal);
800
+ }, signal, (t) => stubResult({ agent: t.agent, task: t.task }, "not run: subagent was aborted"));
706
801
  const successCount = results.filter((r) => !isFailedResult(r)).length;
707
802
  const summaries = results.map((r) => {
708
803
  const output = truncateParallelOutput(getResultOutput(r));
@@ -719,10 +814,11 @@ export function createSubagentToolDefinition(cwd) {
719
814
  },
720
815
  ],
721
816
  details: makeDetails("parallel")(results),
817
+ isError: successCount !== results.length,
722
818
  };
723
819
  }
724
820
  if (params.agent && params.task) {
725
- const result = await runSingleAgent(defaultCwd, agents, params.agent, params.task, params.cwd, undefined, params.model, parentModel, signal, onUpdate, makeDetails("single"));
821
+ const result = await runSingleAgent(defaultCwd, agents, params.agent, params.task, params.cwd, params.isolation, undefined, params.model, parentModel, signal, onUpdate, makeDetails("single"), toolCallId, 0);
726
822
  const isError = isFailedResult(result);
727
823
  if (isError) {
728
824
  const errorMsg = getResultOutput(result);