@dreb/coding-agent 2.55.6 → 2.57.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/README.md +1 -1
- package/agents/developers-advocate.md +39 -0
- package/agents/devils-advocate.md +39 -0
- package/agents/independent-assessor.md +32 -43
- package/dist/core/tools/subagent.d.ts +10 -1
- package/dist/core/tools/subagent.d.ts.map +1 -1
- package/dist/core/tools/subagent.js +152 -14
- package/dist/core/tools/subagent.js.map +1 -1
- package/dist/modes/rpc/rpc-client.d.ts +7 -0
- package/dist/modes/rpc/rpc-client.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-client.js +10 -0
- package/dist/modes/rpc/rpc-client.js.map +1 -1
- package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-mode.js +36 -2
- package/dist/modes/rpc/rpc-mode.js.map +1 -1
- package/dist/modes/rpc/rpc-types.d.ts +23 -0
- package/dist/modes/rpc/rpc-types.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-types.js.map +1 -1
- package/docs/dashboard.md +2 -2
- package/docs/mach6.md +27 -21
- package/docs/rpc.md +18 -0
- package/docs/skills.md +1 -1
- package/package.json +1 -1
- package/skills/mach6-implement/SKILL.md +1 -1
- package/skills/mach6-publish/SKILL.md +12 -8
- package/skills/mach6-review/SKILL.md +65 -161
|
@@ -8,7 +8,7 @@ import { Text } from "@dreb/tui";
|
|
|
8
8
|
import { Type } from "@sinclair/typebox";
|
|
9
9
|
import { CONFIG_DIR_NAME, getPackageDir, getSubagentSessionsDir } from "../../config.js";
|
|
10
10
|
import { keyHint } from "../../modes/interactive/components/keybinding-hints.js";
|
|
11
|
-
import { attachJsonlLineReader } from "../../modes/rpc/jsonl.js";
|
|
11
|
+
import { attachJsonlLineReader, serializeJsonLine } from "../../modes/rpc/jsonl.js";
|
|
12
12
|
import { log } from "../logger.js";
|
|
13
13
|
import { resolveCliModel } from "../model-resolver.js";
|
|
14
14
|
import { resolveEffectiveThinkingLevel, thinkingLevelToReasoning, validateThinkingLevelForModel } from "../thinking.js";
|
|
@@ -226,7 +226,7 @@ export function handleChildJsonlLine(line, sinks) {
|
|
|
226
226
|
sinks.onProgress(`${sinks.toolNameRef.current} done`);
|
|
227
227
|
}
|
|
228
228
|
}
|
|
229
|
-
async function spawnSubagent(agentConfig, task, cwd, signal, onProgress, parentProvider, sessionDir, parentSessionFile, onChildEvent, thinkingOverride) {
|
|
229
|
+
async function spawnSubagent(agentConfig, task, cwd, signal, onProgress, parentProvider, sessionDir, parentSessionFile, onChildEvent, thinkingOverride, onControlAvailable) {
|
|
230
230
|
const drebBin = findDrebBinary();
|
|
231
231
|
log.debug(`[subagent] spawn: agent=${agentConfig.name} cwd=${cwd}`);
|
|
232
232
|
// Validate cwd exists — spawn() throws a misleading ENOENT blaming the
|
|
@@ -276,6 +276,12 @@ async function spawnSubagent(agentConfig, task, cwd, signal, onProgress, parentP
|
|
|
276
276
|
args.push("--parent-session", parentSessionFile);
|
|
277
277
|
}
|
|
278
278
|
args.push("-p", task);
|
|
279
|
+
if (onControlAvailable) {
|
|
280
|
+
const rpcModeIndex = args.indexOf("json");
|
|
281
|
+
if (rpcModeIndex !== -1)
|
|
282
|
+
args[rpcModeIndex] = "rpc";
|
|
283
|
+
args.splice(args.length - 2, 2);
|
|
284
|
+
}
|
|
279
285
|
// Early abort check — if the signal is already aborted (e.g. queued task whose
|
|
280
286
|
// AbortController was aborted while waiting on bgAcquire), bail out before
|
|
281
287
|
// spawning a child process that can never be killed. addEventListener("abort")
|
|
@@ -295,7 +301,7 @@ async function spawnSubagent(agentConfig, task, cwd, signal, onProgress, parentP
|
|
|
295
301
|
try {
|
|
296
302
|
proc = spawn(NODE_EXEC, [drebBin, ...args], {
|
|
297
303
|
cwd,
|
|
298
|
-
stdio: ["ignore", "pipe", "pipe"],
|
|
304
|
+
stdio: [onControlAvailable ? "pipe" : "ignore", "pipe", "pipe"],
|
|
299
305
|
env: { ...process.env },
|
|
300
306
|
});
|
|
301
307
|
}
|
|
@@ -313,6 +319,56 @@ async function spawnSubagent(agentConfig, task, cwd, signal, onProgress, parentP
|
|
|
313
319
|
const toolNameRef = { current: "" };
|
|
314
320
|
let resolvedModel;
|
|
315
321
|
let resolvedThinking;
|
|
322
|
+
let rpcRequestId = 0;
|
|
323
|
+
let rpcCompleted = false;
|
|
324
|
+
let controlError;
|
|
325
|
+
const pendingRpc = new Map();
|
|
326
|
+
const sendRpc = (command) => {
|
|
327
|
+
if (!proc.stdin?.writable)
|
|
328
|
+
return Promise.reject(new Error("Subagent control channel is unavailable."));
|
|
329
|
+
const id = `subagent-${++rpcRequestId}`;
|
|
330
|
+
proc.stdin.write(serializeJsonLine({ ...command, id }));
|
|
331
|
+
return new Promise((resolve, reject) => pendingRpc.set(id, { resolve, reject }));
|
|
332
|
+
};
|
|
333
|
+
const controlClient = onControlAvailable
|
|
334
|
+
? {
|
|
335
|
+
steer: async (message) => {
|
|
336
|
+
await sendRpc({ type: "steer", message });
|
|
337
|
+
},
|
|
338
|
+
getPendingMessages: async () => sendRpc({ type: "get_pending_messages" }),
|
|
339
|
+
getState: async () => sendRpc({ type: "get_state" }),
|
|
340
|
+
}
|
|
341
|
+
: undefined;
|
|
342
|
+
// Terminally fail a controlled child: remember the first failure, reject all
|
|
343
|
+
// in-flight control requests, and stop the process (with the same SIGKILL
|
|
344
|
+
// backstop as the abort path) so the close handler settles instead of the
|
|
345
|
+
// child idling in RPC mode forever.
|
|
346
|
+
const failControlledChild = (err) => {
|
|
347
|
+
if (!controlError)
|
|
348
|
+
controlError = err;
|
|
349
|
+
for (const request of pendingRpc.values())
|
|
350
|
+
request.reject(err);
|
|
351
|
+
pendingRpc.clear();
|
|
352
|
+
try {
|
|
353
|
+
proc.kill("SIGTERM");
|
|
354
|
+
}
|
|
355
|
+
catch {
|
|
356
|
+
/* process already exited */
|
|
357
|
+
}
|
|
358
|
+
killTimer ??= setTimeout(() => {
|
|
359
|
+
try {
|
|
360
|
+
if (!proc.killed)
|
|
361
|
+
proc.kill("SIGKILL");
|
|
362
|
+
}
|
|
363
|
+
catch {
|
|
364
|
+
/* process already exited */
|
|
365
|
+
}
|
|
366
|
+
}, 5000);
|
|
367
|
+
};
|
|
368
|
+
proc.stdin?.on("error", (err) => {
|
|
369
|
+
log.warn(`[subagent] stdin stream error (agent=${agentConfig.name}): ${err.message}`);
|
|
370
|
+
failControlledChild(err);
|
|
371
|
+
});
|
|
316
372
|
// Drain stderr concurrently to avoid pipe deadlock (capped to prevent OOM from verbose subagents)
|
|
317
373
|
proc.stderr?.on("data", (chunk) => {
|
|
318
374
|
if (stderrSize < MAX_STDERR_BYTES) {
|
|
@@ -330,6 +386,36 @@ async function spawnSubagent(agentConfig, task, cwd, signal, onProgress, parentP
|
|
|
330
386
|
log.warn(`[subagent] stdout stream error (agent=${agentConfig.name}): ${err.message}`);
|
|
331
387
|
});
|
|
332
388
|
attachJsonlLineReader(proc.stdout, (line) => {
|
|
389
|
+
if (onControlAvailable) {
|
|
390
|
+
try {
|
|
391
|
+
const message = JSON.parse(line);
|
|
392
|
+
if (message?.type === "agent_end" && !rpcCompleted) {
|
|
393
|
+
rpcCompleted = true;
|
|
394
|
+
setImmediate(() => proc.kill("SIGTERM"));
|
|
395
|
+
}
|
|
396
|
+
if (message?.type === "response" && typeof message.id === "string") {
|
|
397
|
+
const pending = pendingRpc.get(message.id);
|
|
398
|
+
if (pending) {
|
|
399
|
+
pendingRpc.delete(message.id);
|
|
400
|
+
if (message.success)
|
|
401
|
+
pending.resolve(message.data);
|
|
402
|
+
else
|
|
403
|
+
pending.reject(new Error(message.error ?? "Subagent RPC command failed."));
|
|
404
|
+
}
|
|
405
|
+
else if (message.command === "prompt" && message.success === false && !rpcCompleted) {
|
|
406
|
+
// Late failure of the initial prompt: the child acknowledged the
|
|
407
|
+
// command synchronously, then failed before the agent loop started
|
|
408
|
+
// (e.g. model/API-key validation, or the task was consumed without
|
|
409
|
+
// starting the loop), so no agent_end will ever settle this process.
|
|
410
|
+
failControlledChild(new Error(typeof message.error === "string" ? message.error : "Subagent prompt failed."));
|
|
411
|
+
}
|
|
412
|
+
return;
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
catch {
|
|
416
|
+
// The normal line handler preserves non-JSON diagnostics.
|
|
417
|
+
}
|
|
418
|
+
}
|
|
333
419
|
handleChildJsonlLine(line, {
|
|
334
420
|
onEvent: onChildEvent,
|
|
335
421
|
onAssistantMessage: (message) => collectedMessages.push(message),
|
|
@@ -345,6 +431,16 @@ async function spawnSubagent(agentConfig, task, cwd, signal, onProgress, parentP
|
|
|
345
431
|
});
|
|
346
432
|
});
|
|
347
433
|
}
|
|
434
|
+
if (onControlAvailable && controlClient) {
|
|
435
|
+
onControlAvailable(controlClient);
|
|
436
|
+
void sendRpc({ type: "prompt", message: task }).catch((err) => {
|
|
437
|
+
const error = err instanceof Error ? err : new Error(String(err));
|
|
438
|
+
log.warn(`[subagent] initial RPC prompt failed (agent=${agentConfig.name}): ${error.message}`);
|
|
439
|
+
// A rejected initial prompt means the agent loop never starts and the
|
|
440
|
+
// child would idle in RPC mode forever — terminate it and fail loudly.
|
|
441
|
+
failControlledChild(error);
|
|
442
|
+
});
|
|
443
|
+
}
|
|
348
444
|
// Handle abort signal (guard kill() against ESRCH race if process already exited)
|
|
349
445
|
const onAbort = () => {
|
|
350
446
|
try {
|
|
@@ -368,6 +464,10 @@ async function spawnSubagent(agentConfig, task, cwd, signal, onProgress, parentP
|
|
|
368
464
|
if (settled)
|
|
369
465
|
return;
|
|
370
466
|
settled = true;
|
|
467
|
+
onControlAvailable?.(undefined);
|
|
468
|
+
for (const request of pendingRpc.values())
|
|
469
|
+
request.reject(err);
|
|
470
|
+
pendingRpc.clear();
|
|
371
471
|
if (killTimer)
|
|
372
472
|
clearTimeout(killTimer);
|
|
373
473
|
signal?.removeEventListener("abort", onAbort);
|
|
@@ -377,10 +477,14 @@ async function spawnSubagent(agentConfig, task, cwd, signal, onProgress, parentP
|
|
|
377
477
|
if (settled)
|
|
378
478
|
return;
|
|
379
479
|
settled = true;
|
|
480
|
+
onControlAvailable?.(undefined);
|
|
481
|
+
for (const request of pendingRpc.values())
|
|
482
|
+
request.reject(new Error("Subagent process exited."));
|
|
483
|
+
pendingRpc.clear();
|
|
380
484
|
if (killTimer)
|
|
381
485
|
clearTimeout(killTimer);
|
|
382
486
|
signal?.removeEventListener("abort", onAbort);
|
|
383
|
-
const exitCode = code ?? 1;
|
|
487
|
+
const exitCode = rpcCompleted ? 0 : (code ?? 1);
|
|
384
488
|
const stderr = stderrChunks.join("");
|
|
385
489
|
log.debug(`[subagent] close: agent=${agentConfig.name} exit=${exitCode} messages=${collectedMessages.length}${exitCode !== 0 ? ` stderr=${stderr.slice(0, 200)} stdout=${plainStdoutLines.join("|").slice(0, 200)}` : ""}`);
|
|
386
490
|
// Extract final text output from collected assistant messages
|
|
@@ -407,7 +511,10 @@ async function spawnSubagent(agentConfig, task, cwd, signal, onProgress, parentP
|
|
|
407
511
|
const stderrTrimmed = stderr.trim();
|
|
408
512
|
const plainOutput = plainStdoutLines.join("\n").trim();
|
|
409
513
|
errorMessage =
|
|
410
|
-
|
|
514
|
+
controlError?.message.slice(0, 500) ||
|
|
515
|
+
stderrTrimmed.slice(0, 500) ||
|
|
516
|
+
plainOutput.slice(0, 500) ||
|
|
517
|
+
`Subagent exited with code ${exitCode}`;
|
|
411
518
|
}
|
|
412
519
|
else if (output.trim() === "") {
|
|
413
520
|
// Clean exit but no output — surface why instead of returning a silent empty result.
|
|
@@ -853,7 +960,7 @@ function clampCwd(defaultCwd, itemCwd) {
|
|
|
853
960
|
}
|
|
854
961
|
return { ok: true, cwd: resolved };
|
|
855
962
|
}
|
|
856
|
-
export async function executeSingle(agents, agentName, task, cwd, signal, onProgress, modelOverride, parentProvider, registry, sessionDir, parentModel, agentModels, parentSessionFile, onChildEvent, thinkingOverride, arbitration) {
|
|
963
|
+
export async function executeSingle(agents, agentName, task, cwd, signal, onProgress, modelOverride, parentProvider, registry, sessionDir, parentModel, agentModels, parentSessionFile, onChildEvent, thinkingOverride, arbitration, onControlAvailable) {
|
|
857
964
|
let name = agentName || DEFAULT_AGENT;
|
|
858
965
|
let config = agents.get(name);
|
|
859
966
|
if (!config) {
|
|
@@ -1086,7 +1193,7 @@ export async function executeSingle(agents, agentName, task, cwd, signal, onProg
|
|
|
1086
1193
|
}
|
|
1087
1194
|
const usedModel = effectiveConfig.model?.toString();
|
|
1088
1195
|
onProgress?.(`Running ${name} agent${usedModel ? ` (${usedModel})` : ""}...`);
|
|
1089
|
-
const result = await spawnSubagent(effectiveConfig, task, cwd, signal, onProgress, resolvedProvider, sessionDir, parentSessionFile, onChildEvent, finalThinking);
|
|
1196
|
+
const result = await spawnSubagent(effectiveConfig, task, cwd, signal, onProgress, resolvedProvider, sessionDir, parentSessionFile, onChildEvent, finalThinking, onControlAvailable);
|
|
1090
1197
|
const finalSelectedModel = result.model ?? (usedModel ? canonicalModelRef(resolvedProvider, usedModel) : undefined);
|
|
1091
1198
|
result.output = prependModelFallbackSummary(result.output, skippedModels, arbitrationEnabled ? proposalSelectedModel : finalSelectedModel, arbitrationEnabled ? finalSelectedModel : undefined);
|
|
1092
1199
|
if (warning) {
|
|
@@ -1095,7 +1202,7 @@ export async function executeSingle(agents, agentName, task, cwd, signal, onProg
|
|
|
1095
1202
|
}
|
|
1096
1203
|
return result;
|
|
1097
1204
|
}
|
|
1098
|
-
async function executeChain(agents, chain, defaultCwd, signal, onProgress, parentProvider, registry, sessionBaseDir, defaultAgent, defaultModel, defaultThinking, parentModel, getAgentModelsForAgentFn, parentSessionFile, onChildEvent, arbitration) {
|
|
1205
|
+
async function executeChain(agents, chain, defaultCwd, signal, onProgress, parentProvider, registry, sessionBaseDir, defaultAgent, defaultModel, defaultThinking, parentModel, getAgentModelsForAgentFn, parentSessionFile, onChildEvent, arbitration, onControlAvailable) {
|
|
1099
1206
|
const results = [];
|
|
1100
1207
|
let previousOutput = "";
|
|
1101
1208
|
for (let i = 0; i < chain.length; i++) {
|
|
@@ -1132,7 +1239,7 @@ async function executeChain(agents, chain, defaultCwd, signal, onProgress, paren
|
|
|
1132
1239
|
const stepSessionDir = sessionBaseDir ? join(sessionBaseDir, `step-${i + 1}`) : undefined;
|
|
1133
1240
|
const stepAgentName = step.agent || defaultAgent || DEFAULT_AGENT;
|
|
1134
1241
|
const stepMach6Models = getAgentModelsForAgentFn?.(stepAgentName);
|
|
1135
|
-
const result = await executeSingle(agents, step.agent || defaultAgent, task, cwdResult.cwd, signal, onProgress, step.model || defaultModel, parentProvider, registry, stepSessionDir, parentModel, stepMach6Models, parentSessionFile, onChildEvent, resolveSubagentThinkingOverride(step.thinking, defaultThinking), arbitration ? { ...arbitration, step: i + 1 } : undefined);
|
|
1242
|
+
const result = await executeSingle(agents, step.agent || defaultAgent, task, cwdResult.cwd, signal, onProgress, step.model || defaultModel, parentProvider, registry, stepSessionDir, parentModel, stepMach6Models, parentSessionFile, onChildEvent, resolveSubagentThinkingOverride(step.thinking, defaultThinking), arbitration ? { ...arbitration, step: i + 1 } : undefined, onControlAvailable);
|
|
1136
1243
|
results.push(result);
|
|
1137
1244
|
if (result.exitCode !== 0) {
|
|
1138
1245
|
break; // stop chain on error
|
|
@@ -1149,6 +1256,7 @@ function generateAgentId() {
|
|
|
1149
1256
|
}
|
|
1150
1257
|
const backgroundAgentRegistry = new Map();
|
|
1151
1258
|
const backgroundAbortControllers = new Map();
|
|
1259
|
+
const backgroundControlClients = new Map();
|
|
1152
1260
|
const REHYDRATED_AGENT_ID_PREFIX = "rehydrated-";
|
|
1153
1261
|
const HEADER_READ_CHUNK_BYTES = 8192;
|
|
1154
1262
|
const MAX_HEADER_READ_BYTES = 256 * 1024;
|
|
@@ -1440,6 +1548,27 @@ export function getBackgroundAgents() {
|
|
|
1440
1548
|
export function getRunningBackgroundAgents() {
|
|
1441
1549
|
return [...backgroundAgentRegistry.values()].filter((a) => a.status === "running").map(cloneBackgroundAgentInfo);
|
|
1442
1550
|
}
|
|
1551
|
+
function getBackgroundControlClient(agentId) {
|
|
1552
|
+
const info = backgroundAgentRegistry.get(agentId);
|
|
1553
|
+
if (!info)
|
|
1554
|
+
throw new Error(`Unknown background agent "${agentId}".`);
|
|
1555
|
+
if (info.status !== "running")
|
|
1556
|
+
throw new Error(`Background agent "${agentId}" is no longer running.`);
|
|
1557
|
+
const client = backgroundControlClients.get(agentId);
|
|
1558
|
+
if (!client)
|
|
1559
|
+
throw new Error(`Background agent "${agentId}" has not started a controllable child yet.`);
|
|
1560
|
+
return client;
|
|
1561
|
+
}
|
|
1562
|
+
/** Queue the user's message unchanged in the selected live child session. */
|
|
1563
|
+
export async function steerBackgroundAgent(agentId, message) {
|
|
1564
|
+
await getBackgroundControlClient(agentId).steer(message);
|
|
1565
|
+
}
|
|
1566
|
+
/** Read pending steering messages and the effective delivery mode from the selected live child. */
|
|
1567
|
+
export async function getBackgroundAgentPendingSteering(agentId) {
|
|
1568
|
+
const client = getBackgroundControlClient(agentId);
|
|
1569
|
+
const [state, pending] = await Promise.all([client.getState(), client.getPendingMessages()]);
|
|
1570
|
+
return { steeringMode: state.steeringMode, pending };
|
|
1571
|
+
}
|
|
1443
1572
|
/** Abort all running background agents. */
|
|
1444
1573
|
export function abortBackgroundAgents() {
|
|
1445
1574
|
for (const [id, controller] of backgroundAbortControllers) {
|
|
@@ -1450,6 +1579,7 @@ export function abortBackgroundAgents() {
|
|
|
1450
1579
|
}
|
|
1451
1580
|
}
|
|
1452
1581
|
backgroundAbortControllers.clear();
|
|
1582
|
+
backgroundControlClients.clear();
|
|
1453
1583
|
}
|
|
1454
1584
|
/** Remove completed/failed entries older than the given age (ms). Default: 5 minutes. */
|
|
1455
1585
|
export function pruneBackgroundAgents(maxAgeMs = 5 * 60 * 1000) {
|
|
@@ -1458,6 +1588,7 @@ export function pruneBackgroundAgents(maxAgeMs = 5 * 60 * 1000) {
|
|
|
1458
1588
|
if (info.status !== "running" && now - info.startedAt > maxAgeMs) {
|
|
1459
1589
|
backgroundAgentRegistry.delete(id);
|
|
1460
1590
|
backgroundAbortControllers.delete(id);
|
|
1591
|
+
backgroundControlClients.delete(id);
|
|
1461
1592
|
}
|
|
1462
1593
|
}
|
|
1463
1594
|
}
|
|
@@ -1732,6 +1863,12 @@ export function createSubagentToolDefinition(cwd, options) {
|
|
|
1732
1863
|
onArbitration?.({ type: "subagent_arbitration", agentId, ...record });
|
|
1733
1864
|
};
|
|
1734
1865
|
const bgSignal = bgAbort.signal;
|
|
1866
|
+
const onControlAvailable = (client) => {
|
|
1867
|
+
if (client)
|
|
1868
|
+
backgroundControlClients.set(agentId, client);
|
|
1869
|
+
else
|
|
1870
|
+
backgroundControlClients.delete(agentId);
|
|
1871
|
+
};
|
|
1735
1872
|
const safeNotify = (result) => {
|
|
1736
1873
|
try {
|
|
1737
1874
|
onBackgroundComplete(agentId, result, bgSignal.aborted);
|
|
@@ -1743,7 +1880,7 @@ export function createSubagentToolDefinition(cwd, options) {
|
|
|
1743
1880
|
const run = async () => {
|
|
1744
1881
|
await bgAcquire();
|
|
1745
1882
|
try {
|
|
1746
|
-
const result = await runFn(bgSignal, onChildEvent, onArbitrationRecord);
|
|
1883
|
+
const result = await runFn(bgSignal, onChildEvent, onArbitrationRecord, onControlAvailable);
|
|
1747
1884
|
const entry = backgroundAgentRegistry.get(agentId);
|
|
1748
1885
|
if (entry && !bgSignal.aborted)
|
|
1749
1886
|
entry.status = result.exitCode === 0 ? "completed" : "failed";
|
|
@@ -1767,6 +1904,7 @@ export function createSubagentToolDefinition(cwd, options) {
|
|
|
1767
1904
|
});
|
|
1768
1905
|
}
|
|
1769
1906
|
finally {
|
|
1907
|
+
backgroundControlClients.delete(agentId);
|
|
1770
1908
|
bgRelease();
|
|
1771
1909
|
}
|
|
1772
1910
|
};
|
|
@@ -1800,14 +1938,14 @@ export function createSubagentToolDefinition(cwd, options) {
|
|
|
1800
1938
|
const sessionId = generateAgentId();
|
|
1801
1939
|
const sessionDir = join(subagentSessionsBase, sessionId);
|
|
1802
1940
|
const agentModels = getAgentModelsForAgent?.(agentName || DEFAULT_AGENT);
|
|
1803
|
-
return launchBackgroundLifecycle(agentName, taskLabel, sessionDir, resolvedCwd, (signal, onChildEvent, onArbitrationRecord) => executeSingle(agents, agentName === DEFAULT_AGENT ? undefined : agentName, task, resolvedCwd, signal, undefined, modelOverride, getParentProvider(), modelRegistry, sessionDir, getParentModel(), agentModels, getParentSessionFile(), onChildEvent, thinkingOverride, arbitrate
|
|
1941
|
+
return launchBackgroundLifecycle(agentName, taskLabel, sessionDir, resolvedCwd, (signal, onChildEvent, onArbitrationRecord, onControlAvailable) => executeSingle(agents, agentName === DEFAULT_AGENT ? undefined : agentName, task, resolvedCwd, signal, undefined, modelOverride, getParentProvider(), modelRegistry, sessionDir, getParentModel(), agentModels, getParentSessionFile(), onChildEvent, thinkingOverride, arbitrate
|
|
1804
1942
|
? {
|
|
1805
1943
|
arbitrate,
|
|
1806
1944
|
onRecord: onArbitrationRecord,
|
|
1807
1945
|
defaultThinkingLevel: getDefaultThinkingLevel?.(),
|
|
1808
1946
|
getAgentModelsForAgent,
|
|
1809
1947
|
}
|
|
1810
|
-
: undefined));
|
|
1948
|
+
: undefined, onControlAvailable));
|
|
1811
1949
|
};
|
|
1812
1950
|
if (params.task) {
|
|
1813
1951
|
// Single background task
|
|
@@ -1872,7 +2010,7 @@ export function createSubagentToolDefinition(cwd, options) {
|
|
|
1872
2010
|
const taskSummary = `${params.chain.length}-step chain`;
|
|
1873
2011
|
const chainSteps = params.chain;
|
|
1874
2012
|
const chainSessionDir = join(subagentSessionsBase, `chain-${generateAgentId()}`);
|
|
1875
|
-
const agentId = launchBackgroundLifecycle(agentName, taskSummary, chainSessionDir, cwd, async (signal, onChildEvent, onArbitrationRecord) => {
|
|
2013
|
+
const agentId = launchBackgroundLifecycle(agentName, taskSummary, chainSessionDir, cwd, async (signal, onChildEvent, onArbitrationRecord, onControlAvailable) => {
|
|
1876
2014
|
const results = await executeChain(agents, chainSteps, cwd, signal, undefined, getParentProvider(), modelRegistry, chainSessionDir, params.agent, params.model, params.thinking, getParentModel(), getAgentModelsForAgent, getParentSessionFile(), onChildEvent, arbitrate
|
|
1877
2015
|
? {
|
|
1878
2016
|
arbitrate,
|
|
@@ -1880,7 +2018,7 @@ export function createSubagentToolDefinition(cwd, options) {
|
|
|
1880
2018
|
defaultThinkingLevel: getDefaultThinkingLevel?.(),
|
|
1881
2019
|
getAgentModelsForAgent,
|
|
1882
2020
|
}
|
|
1883
|
-
: undefined);
|
|
2021
|
+
: undefined, onControlAvailable);
|
|
1884
2022
|
const resultText = results
|
|
1885
2023
|
.map((r, i) => `### Step ${i + 1}\n${formatSingleResult(r)}`)
|
|
1886
2024
|
.join("\n\n---\n\n");
|