@dreb/coding-agent 2.66.3 → 2.68.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 +4 -2
- package/dist/cli/args.d.ts.map +1 -1
- package/dist/cli/args.js +1 -1
- package/dist/cli/args.js.map +1 -1
- package/dist/config.d.ts +12 -2
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +27 -4
- package/dist/config.js.map +1 -1
- package/dist/core/agent-session.d.ts +5 -0
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +16 -1
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/daily-cost-tracker.d.ts +22 -6
- package/dist/core/daily-cost-tracker.d.ts.map +1 -1
- package/dist/core/daily-cost-tracker.js +117 -47
- package/dist/core/daily-cost-tracker.js.map +1 -1
- package/dist/core/footer-data-provider.d.ts +10 -2
- package/dist/core/footer-data-provider.d.ts.map +1 -1
- package/dist/core/footer-data-provider.js +17 -1
- package/dist/core/footer-data-provider.js.map +1 -1
- package/dist/core/sdk.d.ts.map +1 -1
- package/dist/core/sdk.js +2 -1
- package/dist/core/sdk.js.map +1 -1
- package/dist/core/session-manager.d.ts +32 -4
- package/dist/core/session-manager.d.ts.map +1 -1
- package/dist/core/session-manager.js +234 -108
- package/dist/core/session-manager.js.map +1 -1
- package/dist/core/settings-manager.d.ts +4 -0
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js +4 -0
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/core/subagent-session-cost-tracker.d.ts +22 -0
- package/dist/core/subagent-session-cost-tracker.d.ts.map +1 -0
- package/dist/core/subagent-session-cost-tracker.js +94 -0
- package/dist/core/subagent-session-cost-tracker.js.map +1 -0
- package/dist/core/tools/subagent.d.ts +14 -8
- package/dist/core/tools/subagent.d.ts.map +1 -1
- package/dist/core/tools/subagent.js +145 -71
- package/dist/core/tools/subagent.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +16 -7
- package/dist/main.js.map +1 -1
- package/dist/modes/interactive/components/footer.d.ts.map +1 -1
- package/dist/modes/interactive/components/footer.js +8 -2
- package/dist/modes/interactive/components/footer.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +5 -1
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/rpc/rpc-client.d.ts +7 -2
- package/dist/modes/rpc/rpc-client.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-client.js +3 -2
- package/dist/modes/rpc/rpc-client.js.map +1 -1
- package/dist/modes/rpc/rpc-mode.d.ts +2 -2
- package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-mode.js +34 -9
- package/dist/modes/rpc/rpc-mode.js.map +1 -1
- package/dist/modes/rpc/rpc-types.d.ts +2 -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 +27 -15
- package/docs/rpc.md +9 -5
- package/docs/session.md +16 -7
- package/docs/settings.md +17 -5
- package/docs/skills.md +1 -1
- package/package.json +1 -1
- package/skills/model-routing-guide/SKILL.md +10 -5
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { spawn } from "node:child_process";
|
|
2
2
|
import { randomBytes } from "node:crypto";
|
|
3
|
-
import { closeSync, existsSync, openSync, readdirSync, readFileSync, readSync, statSync } from "node:fs";
|
|
3
|
+
import { closeSync, existsSync, openSync, readdirSync, readFileSync, readSync, realpathSync, statSync, } from "node:fs";
|
|
4
4
|
import { homedir } from "node:os";
|
|
5
5
|
import { basename, join, resolve } from "node:path";
|
|
6
6
|
import { completeSimple } from "@dreb/ai";
|
|
@@ -559,7 +559,7 @@ async function spawnSubagent(agentConfig, task, cwd, signal, onProgress, parentP
|
|
|
559
559
|
});
|
|
560
560
|
}
|
|
561
561
|
const STEP_SESSION_DIR_RE = /^step-(\d+)$/;
|
|
562
|
-
function findNewestJsonlFileInDir(dir) {
|
|
562
|
+
function findNewestJsonlFileInDir(dir, throwOnOperationalError = false) {
|
|
563
563
|
let best;
|
|
564
564
|
for (const entry of readdirSync(dir, { withFileTypes: true })) {
|
|
565
565
|
if (!entry.name.endsWith(".jsonl"))
|
|
@@ -573,14 +573,14 @@ function findNewestJsonlFileInDir(dir) {
|
|
|
573
573
|
best = { path: fullPath, mtime };
|
|
574
574
|
}
|
|
575
575
|
catch (err) {
|
|
576
|
-
if (isExpectedFilesystemError(err))
|
|
576
|
+
if (isExpectedFilesystemError(err) && (!throwOnOperationalError || isMissingFilesystemError(err)))
|
|
577
577
|
continue;
|
|
578
578
|
throw err;
|
|
579
579
|
}
|
|
580
580
|
}
|
|
581
581
|
return best;
|
|
582
582
|
}
|
|
583
|
-
function discoverStepSessionFileCandidates(sessionDir) {
|
|
583
|
+
function discoverStepSessionFileCandidates(sessionDir, throwOnOperationalError = false) {
|
|
584
584
|
const steps = [];
|
|
585
585
|
for (const entry of readdirSync(sessionDir, { withFileTypes: true })) {
|
|
586
586
|
if (!entry.isDirectory())
|
|
@@ -594,12 +594,12 @@ function discoverStepSessionFileCandidates(sessionDir) {
|
|
|
594
594
|
const files = [];
|
|
595
595
|
for (const step of steps) {
|
|
596
596
|
try {
|
|
597
|
-
const candidate = findNewestJsonlFileInDir(join(sessionDir, step.name));
|
|
597
|
+
const candidate = findNewestJsonlFileInDir(join(sessionDir, step.name), throwOnOperationalError);
|
|
598
598
|
if (candidate)
|
|
599
599
|
files.push(candidate);
|
|
600
600
|
}
|
|
601
601
|
catch (err) {
|
|
602
|
-
if (isExpectedFilesystemError(err))
|
|
602
|
+
if (isExpectedFilesystemError(err) && (!throwOnOperationalError || isMissingFilesystemError(err)))
|
|
603
603
|
continue;
|
|
604
604
|
throw err;
|
|
605
605
|
}
|
|
@@ -615,22 +615,28 @@ function discoverStepSessionFileCandidates(sessionDir) {
|
|
|
615
615
|
* present this recurses one level into step-* directories and returns one file
|
|
616
616
|
* per step in numeric step order.
|
|
617
617
|
*/
|
|
618
|
-
export function discoverSessionFiles(sessionDir, agentName) {
|
|
618
|
+
export function discoverSessionFiles(sessionDir, agentName, options = {}) {
|
|
619
|
+
const throwOnOperationalError = options.throwOnOperationalError ?? false;
|
|
619
620
|
try {
|
|
620
|
-
if (!existsSync(sessionDir))
|
|
621
|
+
if (!throwOnOperationalError && !existsSync(sessionDir))
|
|
621
622
|
return [];
|
|
622
|
-
const flatFile = findNewestJsonlFileInDir(sessionDir);
|
|
623
|
+
const flatFile = findNewestJsonlFileInDir(sessionDir, throwOnOperationalError);
|
|
623
624
|
if (flatFile) {
|
|
624
625
|
log.debug(`[subagent] session file: ${flatFile.path} (agent=${agentName})`);
|
|
625
626
|
return [flatFile.path];
|
|
626
627
|
}
|
|
627
|
-
const stepFiles = discoverStepSessionFileCandidates(sessionDir);
|
|
628
|
+
const stepFiles = discoverStepSessionFileCandidates(sessionDir, throwOnOperationalError);
|
|
628
629
|
if (stepFiles.length > 0) {
|
|
629
630
|
log.debug(`[subagent] chain session files: ${stepFiles.map((file) => file.path).join(", ")} (agent=${agentName})`);
|
|
630
631
|
return stepFiles.map((file) => file.path);
|
|
631
632
|
}
|
|
632
633
|
}
|
|
633
634
|
catch (err) {
|
|
635
|
+
if (throwOnOperationalError) {
|
|
636
|
+
if (isMissingFilesystemError(err))
|
|
637
|
+
return [];
|
|
638
|
+
throw err;
|
|
639
|
+
}
|
|
634
640
|
if (!isExpectedFilesystemError(err))
|
|
635
641
|
throw err;
|
|
636
642
|
log.warn(`[subagent] failed to discover session file (agent=${agentName}): ${err instanceof Error ? err.message : String(err)}`);
|
|
@@ -1337,6 +1343,18 @@ function isRecord(value) {
|
|
|
1337
1343
|
function isExpectedFilesystemError(err) {
|
|
1338
1344
|
return typeof err?.code === "string";
|
|
1339
1345
|
}
|
|
1346
|
+
/** Only absence is optional during primary-root restart recovery. */
|
|
1347
|
+
function isMissingFilesystemError(err) {
|
|
1348
|
+
return err?.code === "ENOENT";
|
|
1349
|
+
}
|
|
1350
|
+
function shouldSkipRehydrationFilesystemError(err, isPrimaryRoot, context) {
|
|
1351
|
+
if (isMissingFilesystemError(err))
|
|
1352
|
+
return true;
|
|
1353
|
+
if (isPrimaryRoot || !isExpectedFilesystemError(err))
|
|
1354
|
+
return false;
|
|
1355
|
+
log.warn(`[subagent] skipped compatibility-root recovery (${context}): ${err instanceof Error ? err.message : String(err)}`);
|
|
1356
|
+
return true;
|
|
1357
|
+
}
|
|
1340
1358
|
function parseJsonlLine(line) {
|
|
1341
1359
|
try {
|
|
1342
1360
|
const parsed = JSON.parse(line);
|
|
@@ -1372,7 +1390,7 @@ function readFirstNonEmptyLine(filePath) {
|
|
|
1372
1390
|
return buffered.trim() ? buffered : undefined;
|
|
1373
1391
|
}
|
|
1374
1392
|
catch (err) {
|
|
1375
|
-
if (
|
|
1393
|
+
if (isMissingFilesystemError(err))
|
|
1376
1394
|
return undefined;
|
|
1377
1395
|
throw err;
|
|
1378
1396
|
}
|
|
@@ -1396,7 +1414,7 @@ function readFileSlice(filePath, start, length) {
|
|
|
1396
1414
|
return buffer.toString("utf8", 0, bytesRead);
|
|
1397
1415
|
}
|
|
1398
1416
|
catch (err) {
|
|
1399
|
-
if (
|
|
1417
|
+
if (isMissingFilesystemError(err))
|
|
1400
1418
|
return undefined;
|
|
1401
1419
|
throw err;
|
|
1402
1420
|
}
|
|
@@ -1417,7 +1435,7 @@ function readFileStart(filePath, maxBytes) {
|
|
|
1417
1435
|
size = Math.min(statSync(filePath).size, maxBytes);
|
|
1418
1436
|
}
|
|
1419
1437
|
catch (err) {
|
|
1420
|
-
if (
|
|
1438
|
+
if (isMissingFilesystemError(err))
|
|
1421
1439
|
return undefined;
|
|
1422
1440
|
throw err;
|
|
1423
1441
|
}
|
|
@@ -1432,7 +1450,7 @@ function readFileTail(filePath, maxBytes) {
|
|
|
1432
1450
|
length = size - start;
|
|
1433
1451
|
}
|
|
1434
1452
|
catch (err) {
|
|
1435
|
-
if (
|
|
1453
|
+
if (isMissingFilesystemError(err))
|
|
1436
1454
|
return undefined;
|
|
1437
1455
|
throw err;
|
|
1438
1456
|
}
|
|
@@ -1448,6 +1466,19 @@ function comparablePath(pathValue) {
|
|
|
1448
1466
|
const resolved = resolve(pathValue);
|
|
1449
1467
|
return process.platform === "win32" ? resolved.toLowerCase() : resolved;
|
|
1450
1468
|
}
|
|
1469
|
+
/** Canonical identity for an existing path, with a lexical fallback for races/missing paths. */
|
|
1470
|
+
function canonicalExistingPath(pathValue) {
|
|
1471
|
+
let canonical;
|
|
1472
|
+
try {
|
|
1473
|
+
canonical = realpathSync.native(pathValue);
|
|
1474
|
+
}
|
|
1475
|
+
catch (err) {
|
|
1476
|
+
if (!isMissingFilesystemError(err))
|
|
1477
|
+
throw err;
|
|
1478
|
+
canonical = resolve(pathValue);
|
|
1479
|
+
}
|
|
1480
|
+
return process.platform === "win32" ? canonical.toLowerCase() : canonical;
|
|
1481
|
+
}
|
|
1451
1482
|
function parentSessionMatches(recordedParentSession, parentSessionFile) {
|
|
1452
1483
|
if (recordedParentSession === parentSessionFile)
|
|
1453
1484
|
return true;
|
|
@@ -1524,82 +1555,125 @@ function parseStartedAt(header, sessionFile) {
|
|
|
1524
1555
|
return statSync(sessionFile).mtime.getTime();
|
|
1525
1556
|
}
|
|
1526
1557
|
catch (err) {
|
|
1527
|
-
if (
|
|
1558
|
+
if (isMissingFilesystemError(err))
|
|
1528
1559
|
return Date.now();
|
|
1529
1560
|
throw err;
|
|
1530
1561
|
}
|
|
1531
1562
|
}
|
|
1532
1563
|
function hasRegisteredSession(sessionDir, sessionFile) {
|
|
1533
|
-
const comparableSessionDir =
|
|
1534
|
-
const comparableSessionFile =
|
|
1564
|
+
const comparableSessionDir = canonicalExistingPath(sessionDir);
|
|
1565
|
+
const comparableSessionFile = canonicalExistingPath(sessionFile);
|
|
1535
1566
|
for (const agent of backgroundAgentRegistry.values()) {
|
|
1536
|
-
if (agent.sessionDir &&
|
|
1567
|
+
if (agent.sessionDir && canonicalExistingPath(agent.sessionDir) === comparableSessionDir)
|
|
1537
1568
|
return true;
|
|
1538
|
-
if (agent.sessionFile &&
|
|
1569
|
+
if (agent.sessionFile && canonicalExistingPath(agent.sessionFile) === comparableSessionFile)
|
|
1539
1570
|
return true;
|
|
1540
1571
|
}
|
|
1541
1572
|
return false;
|
|
1542
1573
|
}
|
|
1543
1574
|
/**
|
|
1544
|
-
*
|
|
1545
|
-
*
|
|
1546
|
-
*
|
|
1547
|
-
*
|
|
1575
|
+
* Recover completed background subagents after a dashboard/RPC process resumes
|
|
1576
|
+
* an existing parent session. Live background-agent state is an in-memory
|
|
1577
|
+
* registry, while child sessions are durable JSONL files under the subagent
|
|
1578
|
+
* sessions directory.
|
|
1548
1579
|
*
|
|
1549
|
-
*
|
|
1550
|
-
*
|
|
1580
|
+
* The first root is authoritative: absence races and malformed JSON are skipped,
|
|
1581
|
+
* while operational filesystem failures throw. Later roots are compatibility
|
|
1582
|
+
* stores, so their operational filesystem failures are warned and skipped.
|
|
1583
|
+
* Returns the number of newly registered agents.
|
|
1551
1584
|
*/
|
|
1552
|
-
export function rehydrateBackgroundAgentsFromDisk(parentSessionFile,
|
|
1585
|
+
export function rehydrateBackgroundAgentsFromDisk(parentSessionFile, subagentSessionRoots = getSubagentSessionsDir()) {
|
|
1553
1586
|
if (!parentSessionFile)
|
|
1554
1587
|
return 0;
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
catch (err) {
|
|
1560
|
-
if (isExpectedFilesystemError(err))
|
|
1561
|
-
return 0;
|
|
1562
|
-
throw err;
|
|
1563
|
-
}
|
|
1588
|
+
const roots = typeof subagentSessionRoots === "string" ? [subagentSessionRoots] : subagentSessionRoots;
|
|
1589
|
+
const scannedRoots = new Set();
|
|
1590
|
+
const seenSessionDirs = new Set();
|
|
1591
|
+
const seenSessionFiles = new Set();
|
|
1564
1592
|
let registered = 0;
|
|
1565
|
-
for (const
|
|
1566
|
-
|
|
1567
|
-
|
|
1568
|
-
|
|
1569
|
-
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
let header;
|
|
1574
|
-
for (const candidateFile of sessionFiles) {
|
|
1575
|
-
const candidateHeader = parseSessionHeader(candidateFile);
|
|
1576
|
-
if (candidateHeader?.type !== "session" || typeof candidateHeader.parentSession !== "string")
|
|
1577
|
-
continue;
|
|
1578
|
-
if (!parentSessionMatches(candidateHeader.parentSession, parentSessionFile))
|
|
1593
|
+
for (const [rootIndex, subagentSessionsBase] of roots.entries()) {
|
|
1594
|
+
const isPrimaryRoot = rootIndex === 0;
|
|
1595
|
+
let canonicalRoot;
|
|
1596
|
+
try {
|
|
1597
|
+
canonicalRoot = canonicalExistingPath(subagentSessionsBase);
|
|
1598
|
+
}
|
|
1599
|
+
catch (err) {
|
|
1600
|
+
if (shouldSkipRehydrationFilesystemError(err, isPrimaryRoot, `root ${subagentSessionsBase}`))
|
|
1579
1601
|
continue;
|
|
1580
|
-
|
|
1581
|
-
header = candidateHeader;
|
|
1582
|
-
break;
|
|
1602
|
+
throw err;
|
|
1583
1603
|
}
|
|
1584
|
-
if (
|
|
1585
|
-
continue;
|
|
1586
|
-
const agentId = `${REHYDRATED_AGENT_ID_PREFIX}${entry.name}`;
|
|
1587
|
-
if (backgroundAgentRegistry.has(agentId) || hasRegisteredSession(sessionDir, sessionFile))
|
|
1604
|
+
if (scannedRoots.has(canonicalRoot))
|
|
1588
1605
|
continue;
|
|
1589
|
-
|
|
1590
|
-
|
|
1591
|
-
|
|
1592
|
-
|
|
1593
|
-
|
|
1594
|
-
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
|
|
1601
|
-
|
|
1602
|
-
|
|
1606
|
+
scannedRoots.add(canonicalRoot);
|
|
1607
|
+
let entries;
|
|
1608
|
+
try {
|
|
1609
|
+
entries = readdirSync(subagentSessionsBase, { withFileTypes: true });
|
|
1610
|
+
}
|
|
1611
|
+
catch (err) {
|
|
1612
|
+
if (shouldSkipRehydrationFilesystemError(err, isPrimaryRoot, `root ${subagentSessionsBase}`))
|
|
1613
|
+
continue;
|
|
1614
|
+
throw err;
|
|
1615
|
+
}
|
|
1616
|
+
for (const entry of entries) {
|
|
1617
|
+
const sessionDir = join(subagentSessionsBase, entry.name);
|
|
1618
|
+
try {
|
|
1619
|
+
let isDirectory = entry.isDirectory();
|
|
1620
|
+
if (!isDirectory && entry.isSymbolicLink()) {
|
|
1621
|
+
isDirectory = statSync(sessionDir).isDirectory();
|
|
1622
|
+
}
|
|
1623
|
+
if (!isDirectory)
|
|
1624
|
+
continue;
|
|
1625
|
+
const canonicalSessionDir = canonicalExistingPath(sessionDir);
|
|
1626
|
+
if (seenSessionDirs.has(canonicalSessionDir))
|
|
1627
|
+
continue;
|
|
1628
|
+
seenSessionDirs.add(canonicalSessionDir);
|
|
1629
|
+
const sessionFiles = discoverSessionFiles(sessionDir, entry.name, { throwOnOperationalError: true });
|
|
1630
|
+
if (sessionFiles.length === 0)
|
|
1631
|
+
continue;
|
|
1632
|
+
let sessionFile;
|
|
1633
|
+
let header;
|
|
1634
|
+
for (const candidateFile of sessionFiles) {
|
|
1635
|
+
const candidateHeader = parseSessionHeader(candidateFile);
|
|
1636
|
+
if (candidateHeader?.type !== "session" || typeof candidateHeader.parentSession !== "string")
|
|
1637
|
+
continue;
|
|
1638
|
+
if (!parentSessionMatches(candidateHeader.parentSession, parentSessionFile))
|
|
1639
|
+
continue;
|
|
1640
|
+
const canonicalSessionFile = canonicalExistingPath(candidateFile);
|
|
1641
|
+
if (seenSessionFiles.has(canonicalSessionFile))
|
|
1642
|
+
break;
|
|
1643
|
+
seenSessionFiles.add(canonicalSessionFile);
|
|
1644
|
+
sessionFile = candidateFile;
|
|
1645
|
+
header = candidateHeader;
|
|
1646
|
+
break;
|
|
1647
|
+
}
|
|
1648
|
+
if (!sessionFile || !header || hasRegisteredSession(sessionDir, sessionFile))
|
|
1649
|
+
continue;
|
|
1650
|
+
const baseAgentId = `${REHYDRATED_AGENT_ID_PREFIX}${entry.name}`;
|
|
1651
|
+
let agentId = baseAgentId;
|
|
1652
|
+
let suffix = 2;
|
|
1653
|
+
while (backgroundAgentRegistry.has(agentId)) {
|
|
1654
|
+
agentId = `${baseAgentId}-${suffix++}`;
|
|
1655
|
+
}
|
|
1656
|
+
const statusFile = sessionFiles[sessionFiles.length - 1] ?? sessionFile;
|
|
1657
|
+
const agentType = typeof header.agentType === "string" && header.agentType.trim() ? header.agentType : "agent";
|
|
1658
|
+
const taskSummary = findFirstUserMessageSummary(sessionFile) ?? `${agentType} (${entry.name})`;
|
|
1659
|
+
backgroundAgentRegistry.set(agentId, {
|
|
1660
|
+
agentId,
|
|
1661
|
+
agentType,
|
|
1662
|
+
taskSummary,
|
|
1663
|
+
startedAt: parseStartedAt(header, sessionFile),
|
|
1664
|
+
status: inferCompletedSessionStatus(statusFile),
|
|
1665
|
+
sessionDir,
|
|
1666
|
+
sessionFile,
|
|
1667
|
+
cwd: typeof header.cwd === "string" ? header.cwd : undefined,
|
|
1668
|
+
});
|
|
1669
|
+
registered++;
|
|
1670
|
+
}
|
|
1671
|
+
catch (err) {
|
|
1672
|
+
if (shouldSkipRehydrationFilesystemError(err, isPrimaryRoot, `entry ${sessionDir}`))
|
|
1673
|
+
continue;
|
|
1674
|
+
throw err;
|
|
1675
|
+
}
|
|
1676
|
+
}
|
|
1603
1677
|
}
|
|
1604
1678
|
return registered;
|
|
1605
1679
|
}
|
|
@@ -1803,6 +1877,7 @@ export function formatSingleResult(result) {
|
|
|
1803
1877
|
return text;
|
|
1804
1878
|
}
|
|
1805
1879
|
export function createSubagentToolDefinition(cwd, options) {
|
|
1880
|
+
const subagentSessionsBase = options?.subagentSessionsDir ?? getSubagentSessionsDir();
|
|
1806
1881
|
const onBackgroundStart = options?.onBackgroundStart;
|
|
1807
1882
|
const onBackgroundComplete = options?.onBackgroundComplete;
|
|
1808
1883
|
const onBackgroundEvent = options?.onBackgroundEvent;
|
|
@@ -2016,7 +2091,6 @@ export function createSubagentToolDefinition(cwd, options) {
|
|
|
2016
2091
|
return agentId;
|
|
2017
2092
|
};
|
|
2018
2093
|
// Helper to launch a single background task
|
|
2019
|
-
const subagentSessionsBase = getSubagentSessionsDir();
|
|
2020
2094
|
const launchBackgroundTask = (agentName, task, taskLabel, taskCwd, modelOverride, thinkingOverride) => {
|
|
2021
2095
|
const resolvedCwd = taskCwd ?? cwd;
|
|
2022
2096
|
// Each background agent gets its own session subdirectory
|