sidekick-shared 0.29.0 → 0.29.1
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/CHANGELOG.md +22 -0
- package/README.md +56 -25
- package/dist/aggregation/EventAggregator.d.ts +19 -0
- package/dist/aggregation/EventAggregator.js +174 -35
- package/dist/aggregation/snapshot.d.ts +37 -8
- package/dist/aggregation/snapshot.js +31 -9
- package/dist/aggregation/types.d.ts +13 -0
- package/dist/browser.d.ts +5 -1
- package/dist/browser.js +9 -3
- package/dist/context/sessionContext.js +4 -0
- package/dist/esm/aggregation/EventAggregator.js +174 -35
- package/dist/esm/aggregation/snapshot.js +31 -9
- package/dist/esm/browser.js +1 -0
- package/dist/esm/context/sessionContext.js +4 -0
- package/dist/esm/formatters/toolSummary.js +4 -1
- package/dist/esm/index.js +3 -1
- package/dist/esm/modelCatalog.js +5 -4
- package/dist/esm/modelContext.js +4 -3
- package/dist/esm/modelInfo.js +4 -3
- package/dist/esm/node.js +1 -1
- package/dist/esm/observedContextWindows.js +2 -1
- package/dist/esm/ownKey.js +26 -0
- package/dist/esm/parsers/codexParser.js +180 -4
- package/dist/esm/parsers/openCodeParser.js +2 -1
- package/dist/esm/parsers/subagentScanner.js +33 -12
- package/dist/esm/parsers/subagentTraceParser.js +97 -37
- package/dist/esm/pricingCatalog.js +3 -2
- package/dist/esm/providers/claudeCode.js +10 -2
- package/dist/esm/providers/codex.js +82 -38
- package/dist/esm/schemas/sessionEvent.js +35 -14
- package/dist/esm/subagentSpawn.js +163 -0
- package/dist/esm/transcript.js +4 -0
- package/dist/esm/turns/assistantTurn.js +3 -2
- package/dist/esm/usage/claudeUsageDedupe.js +68 -0
- package/dist/esm/watchers/eventBridge.js +15 -0
- package/dist/esm/watchers/factory.js +5 -3
- package/dist/esm/watchers/jsonlTail.js +73 -8
- package/dist/esm/watchers/jsonlWatcher.js +51 -4
- package/dist/esm/watchers/providerReaderWatcher.js +13 -0
- package/dist/esm/zaiQuota.js +2 -1
- package/dist/formatters/toolSummary.js +4 -1
- package/dist/index.d.ts +8 -3
- package/dist/index.js +18 -9
- package/dist/modelCatalog.js +5 -4
- package/dist/modelContext.js +4 -3
- package/dist/modelInfo.js +4 -3
- package/dist/node.d.ts +1 -1
- package/dist/node.js +3 -1
- package/dist/observedContextWindows.js +2 -1
- package/dist/ownKey.d.ts +16 -0
- package/dist/ownKey.js +30 -0
- package/dist/parsers/codexParser.d.ts +63 -0
- package/dist/parsers/codexParser.js +181 -4
- package/dist/parsers/openCodeParser.js +2 -1
- package/dist/parsers/subagentScanner.d.ts +19 -6
- package/dist/parsers/subagentScanner.js +33 -12
- package/dist/parsers/subagentTraceParser.d.ts +25 -5
- package/dist/parsers/subagentTraceParser.js +97 -37
- package/dist/pricingCatalog.js +3 -2
- package/dist/providers/claudeCode.js +9 -1
- package/dist/providers/codex.js +82 -38
- package/dist/providers/types.d.ts +14 -0
- package/dist/schemas/index.d.ts +1 -0
- package/dist/schemas/sessionEvent.d.ts +27 -10
- package/dist/schemas/sessionEvent.js +35 -14
- package/dist/subagentSpawn.d.ts +80 -0
- package/dist/subagentSpawn.js +174 -0
- package/dist/transcript.js +4 -0
- package/dist/turns/assistantTurn.d.ts +1 -0
- package/dist/turns/assistantTurn.js +3 -2
- package/dist/usage/claudeUsageDedupe.d.ts +31 -0
- package/dist/usage/claudeUsageDedupe.js +68 -0
- package/dist/watchers/eventBridge.js +15 -0
- package/dist/watchers/factory.d.ts +6 -0
- package/dist/watchers/factory.js +5 -3
- package/dist/watchers/jsonlTail.d.ts +27 -4
- package/dist/watchers/jsonlTail.js +75 -8
- package/dist/watchers/jsonlWatcher.d.ts +18 -1
- package/dist/watchers/jsonlWatcher.js +50 -3
- package/dist/watchers/providerReaderWatcher.d.ts +7 -0
- package/dist/watchers/providerReaderWatcher.js +13 -0
- package/dist/watchers/types.d.ts +12 -0
- package/dist/zaiQuota.js +2 -1
- package/package.json +1 -1
|
@@ -22,6 +22,7 @@ const HeatmapTracker_1 = require("./HeatmapTracker");
|
|
|
22
22
|
const PatternExtractor_1 = require("./PatternExtractor");
|
|
23
23
|
const errorTaxonomy_1 = require("../extractors/errorTaxonomy");
|
|
24
24
|
const tokenEstimation_1 = require("../tokenEstimation");
|
|
25
|
+
const subagentSpawn_1 = require("../subagentSpawn");
|
|
25
26
|
const usageNormalization_1 = require("../usageNormalization");
|
|
26
27
|
// ── Defaults ──
|
|
27
28
|
const DEFAULT_TIMELINE_CAP = 200;
|
|
@@ -34,6 +35,22 @@ const COMPACTION_DROP_THRESHOLD = 0.8; // >20% drop
|
|
|
34
35
|
exports.SNAPSHOT_SCHEMA_VERSION = 6;
|
|
35
36
|
// ── Goal gate detection regex ──
|
|
36
37
|
const GOAL_GATE_REGEX = /\b(CRITICAL|MUST|blocker|required|must.?complete|goal.?gate|essential|do.?not.?skip|blocking)\b/i;
|
|
38
|
+
// ── Task notifications delivered as attachments ──
|
|
39
|
+
/**
|
|
40
|
+
* The notification a `system` FollowEvent carries when it stands for a
|
|
41
|
+
* mid-turn task-notification attachment (its `raw` is the attachment line or
|
|
42
|
+
* the SessionEvent `extractSessionEvents` made from it).
|
|
43
|
+
*/
|
|
44
|
+
function taskNotificationFromAttachmentFollowEvent(event) {
|
|
45
|
+
const raw = event.raw;
|
|
46
|
+
if (!raw || typeof raw !== 'object')
|
|
47
|
+
return null;
|
|
48
|
+
const prompt = (0, subagentSpawn_1.taskNotificationPromptFromAttachment)(raw);
|
|
49
|
+
if (prompt !== null)
|
|
50
|
+
return (0, subagentSpawn_1.parseTaskNotification)(prompt);
|
|
51
|
+
const asEvent = raw;
|
|
52
|
+
return (0, subagentSpawn_1.isTaskNotificationSystemEvent)(asEvent) ? (0, subagentSpawn_1.taskNotificationFromEvent)(asEvent) : null;
|
|
53
|
+
}
|
|
37
54
|
// ── Todo dependency parsing ──
|
|
38
55
|
/**
|
|
39
56
|
* Parses dependency references from a todo item's content text.
|
|
@@ -172,6 +189,17 @@ class EventAggregator {
|
|
|
172
189
|
// processEvent — main entry for SessionEvent
|
|
173
190
|
// ═══════════════════════════════════════════════════════════════════════
|
|
174
191
|
processEvent(event) {
|
|
192
|
+
// Opt-in mid-turn task notifications (`extractSessionEvents` with
|
|
193
|
+
// `includeTaskNotifications`) only finish background subagents and mark
|
|
194
|
+
// the timeline: they are not messages, prompts, context, or activity.
|
|
195
|
+
if ((0, subagentSpawn_1.isTaskNotificationSystemEvent)(event)) {
|
|
196
|
+
const notification = (0, subagentSpawn_1.taskNotificationFromEvent)(event);
|
|
197
|
+
if (notification) {
|
|
198
|
+
this.applyTaskNotification(notification, event.timestamp);
|
|
199
|
+
this.addTaskNotificationTimeline(event.timestamp, notification);
|
|
200
|
+
}
|
|
201
|
+
return;
|
|
202
|
+
}
|
|
175
203
|
// 1. Increment counters, capture timestamps
|
|
176
204
|
this.eventCount++;
|
|
177
205
|
if (!this.sessionStartTime) {
|
|
@@ -237,6 +265,15 @@ class EventAggregator {
|
|
|
237
265
|
// processFollowEvent — adapter for CLI FollowEvent format
|
|
238
266
|
// ═══════════════════════════════════════════════════════════════════════
|
|
239
267
|
processFollowEvent(event) {
|
|
268
|
+
// A mid-turn task-notification attachment, like its SessionEvent form above.
|
|
269
|
+
if (event.type === 'system') {
|
|
270
|
+
const notification = taskNotificationFromAttachmentFollowEvent(event);
|
|
271
|
+
if (notification) {
|
|
272
|
+
this.applyTaskNotification(notification, event.timestamp);
|
|
273
|
+
this.addTaskNotificationTimeline(event.timestamp, notification);
|
|
274
|
+
return;
|
|
275
|
+
}
|
|
276
|
+
}
|
|
240
277
|
// 1. Increment counters, capture timestamps
|
|
241
278
|
this.eventCount++;
|
|
242
279
|
if (!this.sessionStartTime) {
|
|
@@ -630,6 +667,14 @@ class EventAggregator {
|
|
|
630
667
|
this.pendingToolCalls.clear();
|
|
631
668
|
this.pendingTaskCreates.clear();
|
|
632
669
|
this.pendingSubagents.clear();
|
|
670
|
+
// A spawn still waiting for its tool_result is resolved by that result,
|
|
671
|
+
// which can land after the snapshot boundary. Background agents need no
|
|
672
|
+
// entry: their notifications are matched against every subagent.
|
|
673
|
+
this.subagents.forEach((agent, idx) => {
|
|
674
|
+
if (agent.status === 'running' && !agent.background && agent.id) {
|
|
675
|
+
this.pendingSubagents.set(agent.id, idx);
|
|
676
|
+
}
|
|
677
|
+
});
|
|
633
678
|
this.pendingUserRequest = null;
|
|
634
679
|
this.planExtractor.reset();
|
|
635
680
|
return true;
|
|
@@ -1108,7 +1153,7 @@ class EventAggregator {
|
|
|
1108
1153
|
else if (name === 'UpdatePlan') {
|
|
1109
1154
|
this.handleUpdatePlan(input, new Date(event.timestamp));
|
|
1110
1155
|
}
|
|
1111
|
-
else if ((
|
|
1156
|
+
else if ((0, subagentSpawn_1.isSubagentSpawnTool)(name) && toolUseId) {
|
|
1112
1157
|
this.handleAgentSpawn(toolUseId, input, new Date(event.timestamp));
|
|
1113
1158
|
}
|
|
1114
1159
|
}
|
|
@@ -1118,7 +1163,7 @@ class EventAggregator {
|
|
|
1118
1163
|
continue;
|
|
1119
1164
|
const isError = block.is_error ?? false;
|
|
1120
1165
|
this.resolveTaskCreate(toolUseId, block.content ?? block.output, event.timestamp, isError);
|
|
1121
|
-
this.resolveAgentResult(toolUseId, isError, event.timestamp);
|
|
1166
|
+
this.resolveAgentResult(toolUseId, isError, event.timestamp, block.content ?? block.output);
|
|
1122
1167
|
}
|
|
1123
1168
|
}
|
|
1124
1169
|
}
|
|
@@ -1152,7 +1197,7 @@ class EventAggregator {
|
|
|
1152
1197
|
else if (event.toolName === 'UpdatePlan') {
|
|
1153
1198
|
this.handleUpdatePlan(input, new Date(event.timestamp));
|
|
1154
1199
|
}
|
|
1155
|
-
else if ((
|
|
1200
|
+
else if ((0, subagentSpawn_1.isSubagentSpawnTool)(event.toolName) && toolUseId) {
|
|
1156
1201
|
this.handleAgentSpawn(toolUseId, input, new Date(event.timestamp));
|
|
1157
1202
|
}
|
|
1158
1203
|
}
|
|
@@ -1164,7 +1209,7 @@ class EventAggregator {
|
|
|
1164
1209
|
return;
|
|
1165
1210
|
const isError = raw.is_error ?? false;
|
|
1166
1211
|
this.resolveTaskCreate(toolUseId, raw.content, event.timestamp, isError);
|
|
1167
|
-
this.resolveAgentResult(toolUseId, isError, event.timestamp);
|
|
1212
|
+
this.resolveAgentResult(toolUseId, isError, event.timestamp, raw.content);
|
|
1168
1213
|
}
|
|
1169
1214
|
}
|
|
1170
1215
|
applyTaskUpdate(input) {
|
|
@@ -1469,11 +1514,14 @@ class EventAggregator {
|
|
|
1469
1514
|
};
|
|
1470
1515
|
this.tasks.set(agentTaskId, task);
|
|
1471
1516
|
}
|
|
1472
|
-
resolveAgentResult(toolUseId, isError, timestamp) {
|
|
1517
|
+
resolveAgentResult(toolUseId, isError, timestamp, content) {
|
|
1473
1518
|
const agentTaskId = `agent-${toolUseId}`;
|
|
1474
1519
|
const agentTask = this.tasks.get(agentTaskId);
|
|
1475
1520
|
if (!agentTask)
|
|
1476
1521
|
return;
|
|
1522
|
+
// A background launch returns at once; its task notification finishes it.
|
|
1523
|
+
if (!isError && (0, subagentSpawn_1.parseAsyncAgentLaunch)(content))
|
|
1524
|
+
return;
|
|
1477
1525
|
agentTask.status = isError ? 'deleted' : 'completed';
|
|
1478
1526
|
agentTask.updatedAt = new Date(timestamp);
|
|
1479
1527
|
}
|
|
@@ -1493,31 +1541,25 @@ class EventAggregator {
|
|
|
1493
1541
|
// Private: Subagent Tracking from SessionEvent
|
|
1494
1542
|
// ═══════════════════════════════════════════════════════════════════════
|
|
1495
1543
|
extractSubagentFromEvent(event) {
|
|
1544
|
+
const notification = (0, subagentSpawn_1.taskNotificationFromEvent)(event);
|
|
1545
|
+
if (notification)
|
|
1546
|
+
this.applyTaskNotification(notification, event.timestamp);
|
|
1496
1547
|
const content = event.message?.content;
|
|
1497
1548
|
if (!Array.isArray(content))
|
|
1498
1549
|
return;
|
|
1499
1550
|
for (const block of content) {
|
|
1500
|
-
if (block.type === 'tool_use' && block.name
|
|
1551
|
+
if (block.type === 'tool_use' && (0, subagentSpawn_1.isSubagentSpawnTool)(block.name)) {
|
|
1501
1552
|
const input = block.input;
|
|
1502
1553
|
const toolUseId = block.id;
|
|
1503
1554
|
if (!input || !toolUseId)
|
|
1504
1555
|
continue;
|
|
1505
|
-
|
|
1506
|
-
id: toolUseId,
|
|
1507
|
-
description: input.description || 'Unknown task',
|
|
1508
|
-
subagentType: input.subagent_type || input.subagentType || 'general',
|
|
1509
|
-
spawnTime: event.timestamp,
|
|
1510
|
-
status: 'running',
|
|
1511
|
-
};
|
|
1512
|
-
const idx = this.subagents.length;
|
|
1513
|
-
this.subagents.push(info);
|
|
1514
|
-
this.pendingSubagents.set(toolUseId, idx);
|
|
1556
|
+
this.trackSubagentSpawn(toolUseId, input, event.timestamp);
|
|
1515
1557
|
}
|
|
1516
1558
|
else if (block.type === 'tool_result') {
|
|
1517
1559
|
const toolUseId = block.tool_use_id;
|
|
1518
1560
|
if (!toolUseId)
|
|
1519
1561
|
continue;
|
|
1520
|
-
this.
|
|
1562
|
+
this.resolveSubagentResult(toolUseId, block.content ?? block.output, block.is_error === true, event.timestamp);
|
|
1521
1563
|
}
|
|
1522
1564
|
}
|
|
1523
1565
|
}
|
|
@@ -1526,23 +1568,10 @@ class EventAggregator {
|
|
|
1526
1568
|
// ═══════════════════════════════════════════════════════════════════════
|
|
1527
1569
|
extractSubagentFromFollowEvent(event) {
|
|
1528
1570
|
const raw = event.raw;
|
|
1529
|
-
if (event.type === 'tool_use' && event.toolName
|
|
1571
|
+
if (event.type === 'tool_use' && (0, subagentSpawn_1.isSubagentSpawnTool)(event.toolName)) {
|
|
1530
1572
|
if (!raw?.input)
|
|
1531
1573
|
return;
|
|
1532
|
-
|
|
1533
|
-
const toolUseId = raw.id || '';
|
|
1534
|
-
const info = {
|
|
1535
|
-
id: toolUseId,
|
|
1536
|
-
description: input.description || 'Unknown task',
|
|
1537
|
-
subagentType: input.subagent_type || input.subagentType || 'general',
|
|
1538
|
-
spawnTime: event.timestamp,
|
|
1539
|
-
status: 'running',
|
|
1540
|
-
};
|
|
1541
|
-
const idx = this.subagents.length;
|
|
1542
|
-
this.subagents.push(info);
|
|
1543
|
-
if (toolUseId) {
|
|
1544
|
-
this.pendingSubagents.set(toolUseId, idx);
|
|
1545
|
-
}
|
|
1574
|
+
this.trackSubagentSpawn(raw.id || '', raw.input, event.timestamp);
|
|
1546
1575
|
}
|
|
1547
1576
|
else if (event.type === 'tool_result') {
|
|
1548
1577
|
if (!raw)
|
|
@@ -1550,23 +1579,133 @@ class EventAggregator {
|
|
|
1550
1579
|
const toolUseId = raw.tool_use_id;
|
|
1551
1580
|
if (!toolUseId)
|
|
1552
1581
|
return;
|
|
1553
|
-
this.
|
|
1582
|
+
this.resolveSubagentResult(toolUseId, raw.content, raw.is_error === true, event.timestamp);
|
|
1583
|
+
}
|
|
1584
|
+
else if (event.type === 'user' && raw?.type === 'user') {
|
|
1585
|
+
// Claude Code delivers most task notifications as their own user line.
|
|
1586
|
+
const notification = (0, subagentSpawn_1.taskNotificationFromEvent)(raw);
|
|
1587
|
+
if (notification)
|
|
1588
|
+
this.applyTaskNotification(notification, event.timestamp);
|
|
1589
|
+
}
|
|
1590
|
+
}
|
|
1591
|
+
trackSubagentSpawn(toolUseId, input, timestamp) {
|
|
1592
|
+
const info = {
|
|
1593
|
+
id: toolUseId,
|
|
1594
|
+
description: input.description || 'Unknown task',
|
|
1595
|
+
subagentType: input.subagent_type || input.subagentType || 'general',
|
|
1596
|
+
spawnTime: timestamp,
|
|
1597
|
+
status: 'running',
|
|
1598
|
+
};
|
|
1599
|
+
const idx = this.subagents.length;
|
|
1600
|
+
this.subagents.push(info);
|
|
1601
|
+
if (toolUseId) {
|
|
1602
|
+
this.pendingSubagents.set(toolUseId, idx);
|
|
1554
1603
|
}
|
|
1555
1604
|
}
|
|
1556
|
-
|
|
1605
|
+
/**
|
|
1606
|
+
* The spawning tool call's result. A foreground agent ends here; a
|
|
1607
|
+
* background launch only reports the agent id, and the agent keeps running
|
|
1608
|
+
* until its task notification arrives.
|
|
1609
|
+
*/
|
|
1610
|
+
resolveSubagentResult(toolUseId, content, isError, timestamp) {
|
|
1557
1611
|
const idx = this.pendingSubagents.get(toolUseId);
|
|
1558
1612
|
if (idx === undefined)
|
|
1559
1613
|
return;
|
|
1560
|
-
|
|
1614
|
+
const launch = isError ? null : (0, subagentSpawn_1.parseAsyncAgentLaunch)(content);
|
|
1615
|
+
if (launch) {
|
|
1616
|
+
this.markBackgroundLaunch(idx, launch);
|
|
1617
|
+
return;
|
|
1618
|
+
}
|
|
1619
|
+
this.completeSubagent(toolUseId, timestamp, isError ? 'failed' : 'completed');
|
|
1620
|
+
}
|
|
1621
|
+
markBackgroundLaunch(idx, launch) {
|
|
1561
1622
|
const agent = this.subagents[idx];
|
|
1623
|
+
this.pendingSubagents.delete(agent.id);
|
|
1624
|
+
agent.background = true;
|
|
1625
|
+
if (launch.agentId)
|
|
1626
|
+
agent.agentId = launch.agentId;
|
|
1627
|
+
}
|
|
1628
|
+
completeSubagent(toolUseId, timestamp, outcome = 'completed') {
|
|
1629
|
+
const idx = this.pendingSubagents.get(toolUseId);
|
|
1630
|
+
if (idx === undefined)
|
|
1631
|
+
return;
|
|
1632
|
+
this.finishSubagent(this.subagents[idx], timestamp, outcome);
|
|
1633
|
+
}
|
|
1634
|
+
finishSubagent(agent, timestamp, outcome) {
|
|
1635
|
+
this.pendingSubagents.delete(agent.id);
|
|
1562
1636
|
agent.status = 'completed';
|
|
1563
1637
|
agent.completionTime = timestamp;
|
|
1638
|
+
agent.outcome = outcome;
|
|
1564
1639
|
const start = new Date(agent.spawnTime).getTime();
|
|
1565
1640
|
const end = new Date(timestamp).getTime();
|
|
1566
1641
|
if (!isNaN(start) && !isNaN(end) && end >= start) {
|
|
1567
1642
|
agent.durationMs = end - start;
|
|
1568
1643
|
}
|
|
1569
1644
|
}
|
|
1645
|
+
/**
|
|
1646
|
+
* Applies a background task's notification to the subagent it reports on,
|
|
1647
|
+
* matched by the spawning tool_use id (or by agent id when the notification
|
|
1648
|
+
* has none). The latest notification wins: an interim one ("waiting on its
|
|
1649
|
+
* own background work") keeps or puts the agent back to running, a final one
|
|
1650
|
+
* completes it. Notifications for background shell tasks match nothing.
|
|
1651
|
+
*/
|
|
1652
|
+
applyTaskNotification(notification, timestamp) {
|
|
1653
|
+
const agent = this.findNotifiedSubagent(notification);
|
|
1654
|
+
const toolUseId = agent?.id || notification.toolUseId;
|
|
1655
|
+
const outcome = (0, subagentSpawn_1.taskNotificationOutcome)(notification.status);
|
|
1656
|
+
if (agent) {
|
|
1657
|
+
agent.background = true;
|
|
1658
|
+
if (!agent.agentId)
|
|
1659
|
+
agent.agentId = notification.taskId;
|
|
1660
|
+
if (notification.interim) {
|
|
1661
|
+
this.pendingSubagents.delete(agent.id);
|
|
1662
|
+
agent.status = 'running';
|
|
1663
|
+
delete agent.completionTime;
|
|
1664
|
+
delete agent.durationMs;
|
|
1665
|
+
delete agent.outcome;
|
|
1666
|
+
}
|
|
1667
|
+
else {
|
|
1668
|
+
this.finishSubagent(agent, timestamp, outcome);
|
|
1669
|
+
}
|
|
1670
|
+
}
|
|
1671
|
+
const agentTask = toolUseId ? this.tasks.get(`agent-${toolUseId}`) : undefined;
|
|
1672
|
+
if (agentTask?.isSubagent) {
|
|
1673
|
+
agentTask.status = notification.interim
|
|
1674
|
+
? 'in_progress'
|
|
1675
|
+
: outcome === 'failed'
|
|
1676
|
+
? 'deleted'
|
|
1677
|
+
: 'completed';
|
|
1678
|
+
agentTask.updatedAt = new Date(timestamp);
|
|
1679
|
+
}
|
|
1680
|
+
}
|
|
1681
|
+
findNotifiedSubagent(notification) {
|
|
1682
|
+
const { toolUseId, taskId } = notification;
|
|
1683
|
+
for (let i = this.subagents.length - 1; i >= 0; i--) {
|
|
1684
|
+
if (toolUseId && this.subagents[i].id === toolUseId)
|
|
1685
|
+
return this.subagents[i];
|
|
1686
|
+
}
|
|
1687
|
+
for (let i = this.subagents.length - 1; i >= 0; i--) {
|
|
1688
|
+
if (this.subagents[i].agentId === taskId)
|
|
1689
|
+
return this.subagents[i];
|
|
1690
|
+
}
|
|
1691
|
+
return undefined;
|
|
1692
|
+
}
|
|
1693
|
+
addTaskNotificationTimeline(timestamp, notification) {
|
|
1694
|
+
let description = notification.summary ?? `Background task ${notification.status ?? 'finished'}`;
|
|
1695
|
+
if (description.length > 200)
|
|
1696
|
+
description = description.substring(0, 197) + '...';
|
|
1697
|
+
this.timeline.push({
|
|
1698
|
+
type: 'tool_result',
|
|
1699
|
+
timestamp,
|
|
1700
|
+
description,
|
|
1701
|
+
noiseLevel: 'system',
|
|
1702
|
+
messageClassification: 'system',
|
|
1703
|
+
...(notification.toolUseId ? { metadata: { toolUseId: notification.toolUseId } } : {}),
|
|
1704
|
+
});
|
|
1705
|
+
if (this.timeline.length > this.timelineCap) {
|
|
1706
|
+
this.timeline.shift();
|
|
1707
|
+
}
|
|
1708
|
+
}
|
|
1570
1709
|
// ═══════════════════════════════════════════════════════════════════════
|
|
1571
1710
|
// Private: Plan Extraction from SessionEvent
|
|
1572
1711
|
// ═══════════════════════════════════════════════════════════════════════
|
|
@@ -2,11 +2,15 @@
|
|
|
2
2
|
* Session snapshot sidecar — persists aggregator state + reader position
|
|
3
3
|
* so that re-attaching to a session skips full replay.
|
|
4
4
|
*
|
|
5
|
-
* Snapshots are stored in
|
|
6
|
-
* They are invalidated when the source file
|
|
5
|
+
* Snapshots are stored in `<config dir>/snapshots/{sessionId}.json` (see
|
|
6
|
+
* `getConfigDir()`). They are invalidated when the source file shrank below
|
|
7
|
+
* the snapshot position or, for file-backed sessions that recorded a
|
|
8
|
+
* {@link SessionSnapshot.sourceCheckpoint}, when the file is no longer the
|
|
9
|
+
* same append-only file.
|
|
7
10
|
*
|
|
8
11
|
* @module aggregation/snapshot
|
|
9
12
|
*/
|
|
13
|
+
import { type JsonlTailCheckpoint } from '../watchers/jsonlTail';
|
|
10
14
|
import { type SerializedAggregatorState } from './EventAggregator';
|
|
11
15
|
/** Newest snapshots kept on disk; older ones are pruned opportunistically. */
|
|
12
16
|
export declare const MAX_SNAPSHOT_FILES = 200;
|
|
@@ -22,6 +26,23 @@ export interface SessionSnapshot {
|
|
|
22
26
|
readerPosition: number;
|
|
23
27
|
/** Source file size at snapshot time (for staleness check; 0 for DB-backed). */
|
|
24
28
|
sourceSize: number;
|
|
29
|
+
/**
|
|
30
|
+
* Identity of the source file at `readerPosition`, from
|
|
31
|
+
* `captureJsonlCheckpoint(sourcePath, readerPosition)`: its device and
|
|
32
|
+
* inode plus a digest of its first bytes. Present for file-backed sessions
|
|
33
|
+
* written by 0.29.1 and later; absent for DB-backed sessions and older
|
|
34
|
+
* snapshots. {@link isSnapshotValid} checks it when given the source path.
|
|
35
|
+
*/
|
|
36
|
+
sourceCheckpoint?: JsonlTailCheckpoint;
|
|
37
|
+
/**
|
|
38
|
+
* The reader's parse state at `readerPosition`, from
|
|
39
|
+
* `SessionReader.getResumeState()` or `SessionWatcher.getResumeState()`
|
|
40
|
+
* (for Claude Code, which split-line responses were already counted).
|
|
41
|
+
* After seeking to `readerPosition`, pass it to `restoreResumeState()` and
|
|
42
|
+
* replay from the start when that returns false. Absent when the reader
|
|
43
|
+
* keeps none, and in snapshots written before 0.29.1.
|
|
44
|
+
*/
|
|
45
|
+
readerState?: unknown;
|
|
25
46
|
/** ISO timestamp when snapshot was written. */
|
|
26
47
|
createdAt: string;
|
|
27
48
|
/** Serialized EventAggregator state. */
|
|
@@ -55,8 +76,8 @@ export declare function pruneSnapshots(keep?: number): number;
|
|
|
55
76
|
* - Schema version doesn't match
|
|
56
77
|
* - JSON parse fails
|
|
57
78
|
*
|
|
58
|
-
* The caller is responsible for staleness checks
|
|
59
|
-
*
|
|
79
|
+
* The caller is responsible for staleness checks against the actual file:
|
|
80
|
+
* `isSnapshotValid(snapshot, currentSize, sourcePath)`.
|
|
60
81
|
*/
|
|
61
82
|
export declare function loadSnapshot(sessionId: string): SessionSnapshot | null;
|
|
62
83
|
/**
|
|
@@ -66,10 +87,18 @@ export declare function deleteSnapshot(sessionId: string): void;
|
|
|
66
87
|
/**
|
|
67
88
|
* Validates whether a snapshot is still usable for a given source file.
|
|
68
89
|
*
|
|
69
|
-
* For JSONL providers: checks that the file hasn't been truncated
|
|
70
|
-
* (current size >= snapshot position) and that the size matches or has grown.
|
|
71
|
-
*
|
|
72
90
|
* For DB-backed providers: sourceSize is 0, so we always consider valid
|
|
73
91
|
* (the DB reader's timestamp-based cursor handles staleness naturally).
|
|
92
|
+
*
|
|
93
|
+
* For JSONL providers: the file must not have shrunk below the snapshot
|
|
94
|
+
* position. With `sourcePath` the check is also content-aware: the snapshot
|
|
95
|
+
* must carry a {@link SessionSnapshot.sourceCheckpoint} for exactly
|
|
96
|
+
* `readerPosition`, and that checkpoint must still match the file at
|
|
97
|
+
* `sourcePath` (same device and inode, same first bytes, position just after
|
|
98
|
+
* a newline), so a file replaced by another one or rewritten to the same or
|
|
99
|
+
* a larger size is not resumed mid-content. A snapshot without a checkpoint
|
|
100
|
+
* (written before 0.29.1) is invalid when `sourcePath` is given, which costs
|
|
101
|
+
* one full replay. Without `sourcePath` only the size check applies, as it
|
|
102
|
+
* did before.
|
|
74
103
|
*/
|
|
75
|
-
export declare function isSnapshotValid(snapshot: SessionSnapshot, currentSourceSize: number): boolean;
|
|
104
|
+
export declare function isSnapshotValid(snapshot: SessionSnapshot, currentSourceSize: number, sourcePath?: string): boolean;
|
|
@@ -3,8 +3,11 @@
|
|
|
3
3
|
* Session snapshot sidecar — persists aggregator state + reader position
|
|
4
4
|
* so that re-attaching to a session skips full replay.
|
|
5
5
|
*
|
|
6
|
-
* Snapshots are stored in
|
|
7
|
-
* They are invalidated when the source file
|
|
6
|
+
* Snapshots are stored in `<config dir>/snapshots/{sessionId}.json` (see
|
|
7
|
+
* `getConfigDir()`). They are invalidated when the source file shrank below
|
|
8
|
+
* the snapshot position or, for file-backed sessions that recorded a
|
|
9
|
+
* {@link SessionSnapshot.sourceCheckpoint}, when the file is no longer the
|
|
10
|
+
* same append-only file.
|
|
8
11
|
*
|
|
9
12
|
* @module aggregation/snapshot
|
|
10
13
|
*/
|
|
@@ -52,6 +55,7 @@ exports.isSnapshotValid = isSnapshotValid;
|
|
|
52
55
|
const fs = __importStar(require("fs"));
|
|
53
56
|
const path = __importStar(require("path"));
|
|
54
57
|
const paths_1 = require("../paths");
|
|
58
|
+
const jsonlTail_1 = require("../watchers/jsonlTail");
|
|
55
59
|
const atomic_1 = require("../writers/atomic");
|
|
56
60
|
const EventAggregator_1 = require("./EventAggregator");
|
|
57
61
|
/** Current schema version — bump when format changes. */
|
|
@@ -143,8 +147,8 @@ function pruneSnapshots(keep = exports.MAX_SNAPSHOT_FILES) {
|
|
|
143
147
|
* - Schema version doesn't match
|
|
144
148
|
* - JSON parse fails
|
|
145
149
|
*
|
|
146
|
-
* The caller is responsible for staleness checks
|
|
147
|
-
*
|
|
150
|
+
* The caller is responsible for staleness checks against the actual file:
|
|
151
|
+
* `isSnapshotValid(snapshot, currentSize, sourcePath)`.
|
|
148
152
|
*/
|
|
149
153
|
function loadSnapshot(sessionId) {
|
|
150
154
|
try {
|
|
@@ -184,13 +188,21 @@ function deleteSnapshot(sessionId) {
|
|
|
184
188
|
/**
|
|
185
189
|
* Validates whether a snapshot is still usable for a given source file.
|
|
186
190
|
*
|
|
187
|
-
* For JSONL providers: checks that the file hasn't been truncated
|
|
188
|
-
* (current size >= snapshot position) and that the size matches or has grown.
|
|
189
|
-
*
|
|
190
191
|
* For DB-backed providers: sourceSize is 0, so we always consider valid
|
|
191
192
|
* (the DB reader's timestamp-based cursor handles staleness naturally).
|
|
193
|
+
*
|
|
194
|
+
* For JSONL providers: the file must not have shrunk below the snapshot
|
|
195
|
+
* position. With `sourcePath` the check is also content-aware: the snapshot
|
|
196
|
+
* must carry a {@link SessionSnapshot.sourceCheckpoint} for exactly
|
|
197
|
+
* `readerPosition`, and that checkpoint must still match the file at
|
|
198
|
+
* `sourcePath` (same device and inode, same first bytes, position just after
|
|
199
|
+
* a newline), so a file replaced by another one or rewritten to the same or
|
|
200
|
+
* a larger size is not resumed mid-content. A snapshot without a checkpoint
|
|
201
|
+
* (written before 0.29.1) is invalid when `sourcePath` is given, which costs
|
|
202
|
+
* one full replay. Without `sourcePath` only the size check applies, as it
|
|
203
|
+
* did before.
|
|
192
204
|
*/
|
|
193
|
-
function isSnapshotValid(snapshot, currentSourceSize) {
|
|
205
|
+
function isSnapshotValid(snapshot, currentSourceSize, sourcePath) {
|
|
194
206
|
// DB-backed providers store sourceSize=0 — always valid (cursor is a timestamp)
|
|
195
207
|
if (snapshot.sourceSize === 0) {
|
|
196
208
|
return true;
|
|
@@ -199,5 +211,15 @@ function isSnapshotValid(snapshot, currentSourceSize) {
|
|
|
199
211
|
if (currentSourceSize < snapshot.readerPosition) {
|
|
200
212
|
return false;
|
|
201
213
|
}
|
|
202
|
-
|
|
214
|
+
if (typeof sourcePath !== 'string') {
|
|
215
|
+
return true;
|
|
216
|
+
}
|
|
217
|
+
// Snapshot content comes from disk: guard the shape before trusting it.
|
|
218
|
+
const checkpoint = snapshot.sourceCheckpoint;
|
|
219
|
+
if (!checkpoint ||
|
|
220
|
+
typeof checkpoint !== 'object' ||
|
|
221
|
+
checkpoint.offset !== snapshot.readerPosition) {
|
|
222
|
+
return false;
|
|
223
|
+
}
|
|
224
|
+
return (0, jsonlTail_1.verifyJsonlCheckpoint)(sourcePath, checkpoint);
|
|
203
225
|
}
|
|
@@ -117,15 +117,28 @@ export interface BurnRateInfo {
|
|
|
117
117
|
/** Number of samples in the window. */
|
|
118
118
|
sampleCount: number;
|
|
119
119
|
}
|
|
120
|
+
/** How a subagent ended: a failed spawn, or a background agent's notification status. */
|
|
121
|
+
export type SubagentOutcome = 'completed' | 'failed' | 'killed' | 'stopped';
|
|
120
122
|
/** Subagent lifecycle info (for tracking spawn/completion from tool events). */
|
|
121
123
|
export interface SubagentLifecycle {
|
|
124
|
+
/** The spawning tool_use id (`Agent` / `Task`). */
|
|
122
125
|
id: string;
|
|
123
126
|
description: string;
|
|
124
127
|
subagentType: string;
|
|
125
128
|
spawnTime: string;
|
|
126
129
|
completionTime?: string;
|
|
130
|
+
/**
|
|
131
|
+
* A background agent stays `running` after its spawn's immediate result
|
|
132
|
+
* until its task notification arrives.
|
|
133
|
+
*/
|
|
127
134
|
status: 'running' | 'completed';
|
|
128
135
|
durationMs?: number;
|
|
136
|
+
/** Claude Code's agent id (the `agent-<id>.jsonl` transcript name), once known. */
|
|
137
|
+
agentId?: string;
|
|
138
|
+
/** The agent was launched in the background (its spawn returned at once). */
|
|
139
|
+
background?: boolean;
|
|
140
|
+
/** How the agent ended, once `status` is `completed`. */
|
|
141
|
+
outcome?: SubagentOutcome;
|
|
129
142
|
}
|
|
130
143
|
/** Frequency entry for tool/word frequency tracking. */
|
|
131
144
|
export interface FrequencyMetric {
|
package/dist/browser.d.ts
CHANGED
|
@@ -14,6 +14,7 @@ export type { UsageProvider, UsageSemantics, UsageNormalizationProvenance, Provi
|
|
|
14
14
|
export { formatTokenBreakdown, summarizeTokens, sumTokenTotals, TOKEN_CONTEXT_LABEL, TOKEN_MAIN_THREAD_LABEL, TOKEN_SESSION_TOTAL_LABEL, TOKEN_SUBAGENTS_LABEL, TOKEN_TOTAL_LABEL, } from './tokenSummary';
|
|
15
15
|
export type { TokenSummary, TokenTotalsLike } from './tokenSummary';
|
|
16
16
|
export { ClaudeUsageDeduper, SYNTHETIC_MODEL } from './usage/claudeUsageDedupe';
|
|
17
|
+
export type { ClaudeUsageDedupeBuckets, ClaudeUsageDedupeState } from './usage/claudeUsageDedupe';
|
|
17
18
|
export { ASCII_CHARS_PER_TOKEN, estimateTextTokens, estimateSerializedTokens, } from './tokenEstimation';
|
|
18
19
|
export type { ExactTokenCounterContext, ExactTokenCounter, TokenEstimationMethod, TokenEstimationConfidence, TokenEstimationOptions, TokenEstimate, } from './tokenEstimation';
|
|
19
20
|
export { projectSessionTranscript } from './transcript';
|
|
@@ -28,6 +29,9 @@ export type { AccountProviderId, ModelProviderId, QuotaProviderId, RuntimeQuotaP
|
|
|
28
29
|
/** Same type as `ProviderId` from the package root and `sidekick-shared/node`. */
|
|
29
30
|
SessionProviderId as ProviderId, } from './providerIds';
|
|
30
31
|
export type { BuildSessionContextSnapshotOptions, SessionContextCapabilities, SessionContextLayerBreakdown, SessionContextPressure, SessionContextProjector, SessionContextSnapshot, SessionContextSource, SessionContextSourceType, } from './context/sessionContext';
|
|
32
|
+
export { SUBAGENT_SPAWN_TOOL_NAMES, isSubagentSpawnTool, isTaskNotificationSystemEvent, parseTaskNotification, taskNotificationFromEvent, } from './subagentSpawn';
|
|
33
|
+
export type { TaskNotification } from './subagentSpawn';
|
|
34
|
+
export type { SubagentOutcome } from './aggregation/types';
|
|
31
35
|
export { assistantTurnEventsFromSessionEvents, extractTurnSubagents, isAssistantTurnSubagentTool, reasoningSummary, segmentAssistantTurn, } from './turns/assistantTurn';
|
|
32
36
|
export type { AssistantTurnEvent, AssistantTurnEventType, AssistantTurnProcess, AssistantTurnProcessStep, AssistantTurnProjection, AssistantTurnSubagent, AssistantTurnSubagentStatus, AssistantTurnTimelineItem, AssistantTurnToolRef, ExtractTurnSubagentsOptions, ReasoningSummary, SegmentAssistantTurnOptions, } from './turns/assistantTurn';
|
|
33
37
|
export { parseModelId, getModelPricing, resolveModelPricing, getModelInfo, calculateCost, calculateCostWithPricing, calculateCostWithProvenance, mergeCostSources, shortModelName, getModelDisplayInfo, compareModelIds, sortModelIds, formatCost, canonicalModelId, isMovingModelAlias, registerModelPricing, clearRegisteredModelPricing, getPricingCatalogInfo, costSourceFromPricingProvenance, mergeCostComponents, } from './modelInfo';
|
|
@@ -51,7 +55,7 @@ export type { SessionEvent, ClaudeSessionEvent, MessageUsage, SessionMessage, Se
|
|
|
51
55
|
export type { CodexRolloutLine, CodexSessionMeta, CodexResponseItem, CodexMessageItem, CodexContentPart, CodexReasoningItem, CodexFunctionCallItem, CodexFunctionCallOutputItem, CodexLocalShellCallItem, CodexWebSearchCallItem, CodexCustomToolCallItem, CodexCustomToolCallOutputItem, CodexCompacted, CodexTurnContext, CodexEventMsg, CodexEvent, CodexTurnStartedEvent, CodexTurnCompleteEvent, CodexTaskStartedEvent, CodexTaskCompleteEvent, CodexTurnAbortedEvent, CodexTokenCountEvent, CodexTokenUsage, CodexRateLimits, CodexAgentMessageEvent, CodexAgentReasoningEvent, CodexUserMessageEvent, CodexExecCommandBeginEvent, CodexExecCommandEndEvent, CodexMcpToolCallBeginEvent, CodexMcpToolCallEndEvent, CodexErrorEvent, CodexContextCompactedEvent, CodexPatchAppliedEvent, CodexBackgroundEvent, CodexGenericEvent, CodexDbThread, CodexReasoningSummary, } from './types/codex';
|
|
52
56
|
export { isAggregateCodexLimit } from './types/codex';
|
|
53
57
|
export { CodexRolloutParser, DEFAULT_MAX_TRACKED_TOOL_CALLS, extractPatchFilePaths, normalizeCodexToolName, normalizeCodexToolInput, resolveCodexCallUsage, } from './parsers/codexParser';
|
|
54
|
-
export type { CodexPendingStats, CodexRolloutParserOptions } from './parsers/codexParser';
|
|
58
|
+
export type { CodexPendingStats, CodexRolloutParserOptions, CodexRolloutResumeState, } from './parsers/codexParser';
|
|
55
59
|
export { codexRolloutOrigin, codexSpawnParentFromSource } from './parsers/codexRolloutOrigin';
|
|
56
60
|
export type { CodexRolloutOrigin } from './parsers/codexRolloutOrigin';
|
|
57
61
|
export { HUMAN_CLAUDE_ENTRYPOINTS, HUMAN_CODEX_SOURCES, humanPromptText, isHumanPrompt, } from './humanPrompt';
|
package/dist/browser.js
CHANGED
|
@@ -9,9 +9,9 @@
|
|
|
9
9
|
* For pricing hydration (LiteLLM catalog refresh), use `sidekick-shared/node`.
|
|
10
10
|
*/
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
-
exports.
|
|
13
|
-
exports.
|
|
14
|
-
exports.quotaWindowShortLabel = exports.quotaWindowLabel = exports.quotaWindowHasData = exports.quotaWindowApplies = exports.formatExtraUsage = exports.extraQuotaRows = exports.claudePlanLabel = exports.TOOL_CATEGORIES = exports.classifyTool = exports.renderHandoffUrlTemplate = exports.isHumanPrompt = exports.humanPromptText = exports.HUMAN_CODEX_SOURCES = void 0;
|
|
12
|
+
exports.calculateCostWithPricing = exports.calculateCost = exports.getModelInfo = exports.resolveModelPricing = exports.getModelPricing = exports.parseModelId = exports.segmentAssistantTurn = exports.reasoningSummary = exports.isAssistantTurnSubagentTool = exports.extractTurnSubagents = exports.assistantTurnEventsFromSessionEvents = exports.taskNotificationFromEvent = exports.parseTaskNotification = exports.isTaskNotificationSystemEvent = exports.isSubagentSpawnTool = exports.SUBAGENT_SPAWN_TOOL_NAMES = exports.SESSION_PROVIDER_IDS = exports.RUNTIME_QUOTA_PROVIDER_IDS = exports.QUOTA_PROVIDER_IDS = exports.MODEL_PROVIDER_IDS = exports.ACCOUNT_PROVIDER_IDS = exports.createSessionContextProjector = exports.calculateSessionContextPressure = exports.buildSessionContextSnapshot = exports.parseMcpToolName = exports.parseLocalDateKey = exports.formatTokenCount = exports.formatLocalDateKey = exports.formatDurationMs = exports.addLocalDays = exports.projectSessionTranscript = exports.estimateSerializedTokens = exports.estimateTextTokens = exports.ASCII_CHARS_PER_TOKEN = exports.SYNTHETIC_MODEL = exports.ClaudeUsageDeduper = exports.TOKEN_TOTAL_LABEL = exports.TOKEN_SUBAGENTS_LABEL = exports.TOKEN_SESSION_TOTAL_LABEL = exports.TOKEN_MAIN_THREAD_LABEL = exports.TOKEN_CONTEXT_LABEL = exports.sumTokenTotals = exports.summarizeTokens = exports.formatTokenBreakdown = exports.calculateNormalizedUsageCost = exports.extractNormalizedUsage = exports.normalizeProviderUsage = exports.DEFAULT_CONTEXT_WINDOW = exports.resolveModelContextWindow = exports.getModelContextWindowSize = void 0;
|
|
13
|
+
exports.normalizeCodexToolName = exports.extractPatchFilePaths = exports.DEFAULT_MAX_TRACKED_TOOL_CALLS = exports.CodexRolloutParser = exports.isAggregateCodexLimit = exports.parseCodexLoginStatus = exports.parseClaudeAuthStatus = exports.decodeCodexErrorInfo = exports.CODEX_ERROR_INFO_KINDS = exports.PROVIDER_RECOVERY_ACTIONS = exports.PROVIDER_FAILURE_EVIDENCE_SOURCES = exports.PROVIDER_FAILURE_CODES = exports.PROVIDER_CREDENTIAL_KINDS = exports.PROVIDER_AUTHENTICATION_STATES = exports.PROVIDER_AUTHENTICATION_SOURCES = exports.diagnoseProviderFailure = exports.mergeFailingToolWindows = exports.failingToolTrend = exports.FAILING_TOOL_TREND_ARROWS = exports.sessionSummaryFromStats = exports.removeSessionSummary = exports.markFileImported = exports.isFileImported = exports.applySessionSummary = exports.weekKey = exports.usageBucketKey = exports.summarizeUsageRows = exports.bucketUsage = exports.findActiveBillingBlock = exports.computeBillingBlocks = exports.BILLING_BLOCK_DURATION_MS = exports.RESOLVED_MODEL_CATALOG_SCHEMA_VERSION = exports.resolveModelAlias = exports.registerModelAlias = exports.importResolvedModelCatalog = exports.exportResolvedModelCatalog = exports.mergeCostComponents = exports.costSourceFromPricingProvenance = exports.getPricingCatalogInfo = exports.clearRegisteredModelPricing = exports.registerModelPricing = exports.isMovingModelAlias = exports.canonicalModelId = exports.formatCost = exports.sortModelIds = exports.compareModelIds = exports.getModelDisplayInfo = exports.shortModelName = exports.mergeCostSources = exports.calculateCostWithProvenance = void 0;
|
|
14
|
+
exports.quotaWindowShortLabel = exports.quotaWindowLabel = exports.quotaWindowHasData = exports.quotaWindowApplies = exports.formatExtraUsage = exports.extraQuotaRows = exports.claudePlanLabel = exports.TOOL_CATEGORIES = exports.classifyTool = exports.renderHandoffUrlTemplate = exports.isHumanPrompt = exports.humanPromptText = exports.HUMAN_CODEX_SOURCES = exports.HUMAN_CLAUDE_ENTRYPOINTS = exports.codexSpawnParentFromSource = exports.codexRolloutOrigin = exports.resolveCodexCallUsage = exports.normalizeCodexToolInput = void 0;
|
|
15
15
|
var modelContext_1 = require("./modelContext");
|
|
16
16
|
Object.defineProperty(exports, "getModelContextWindowSize", { enumerable: true, get: function () { return modelContext_1.getModelContextWindowSize; } });
|
|
17
17
|
Object.defineProperty(exports, "resolveModelContextWindow", { enumerable: true, get: function () { return modelContext_1.resolveModelContextWindow; } });
|
|
@@ -56,6 +56,12 @@ Object.defineProperty(exports, "MODEL_PROVIDER_IDS", { enumerable: true, get: fu
|
|
|
56
56
|
Object.defineProperty(exports, "QUOTA_PROVIDER_IDS", { enumerable: true, get: function () { return providerIds_1.QUOTA_PROVIDER_IDS; } });
|
|
57
57
|
Object.defineProperty(exports, "RUNTIME_QUOTA_PROVIDER_IDS", { enumerable: true, get: function () { return providerIds_1.RUNTIME_QUOTA_PROVIDER_IDS; } });
|
|
58
58
|
Object.defineProperty(exports, "SESSION_PROVIDER_IDS", { enumerable: true, get: function () { return providerIds_1.SESSION_PROVIDER_IDS; } });
|
|
59
|
+
var subagentSpawn_1 = require("./subagentSpawn");
|
|
60
|
+
Object.defineProperty(exports, "SUBAGENT_SPAWN_TOOL_NAMES", { enumerable: true, get: function () { return subagentSpawn_1.SUBAGENT_SPAWN_TOOL_NAMES; } });
|
|
61
|
+
Object.defineProperty(exports, "isSubagentSpawnTool", { enumerable: true, get: function () { return subagentSpawn_1.isSubagentSpawnTool; } });
|
|
62
|
+
Object.defineProperty(exports, "isTaskNotificationSystemEvent", { enumerable: true, get: function () { return subagentSpawn_1.isTaskNotificationSystemEvent; } });
|
|
63
|
+
Object.defineProperty(exports, "parseTaskNotification", { enumerable: true, get: function () { return subagentSpawn_1.parseTaskNotification; } });
|
|
64
|
+
Object.defineProperty(exports, "taskNotificationFromEvent", { enumerable: true, get: function () { return subagentSpawn_1.taskNotificationFromEvent; } });
|
|
59
65
|
var assistantTurn_1 = require("./turns/assistantTurn");
|
|
60
66
|
Object.defineProperty(exports, "assistantTurnEventsFromSessionEvents", { enumerable: true, get: function () { return assistantTurn_1.assistantTurnEventsFromSessionEvents; } });
|
|
61
67
|
Object.defineProperty(exports, "extractTurnSubagents", { enumerable: true, get: function () { return assistantTurn_1.extractTurnSubagents; } });
|
|
@@ -14,6 +14,7 @@ const EventAggregator_1 = require("../aggregation/EventAggregator");
|
|
|
14
14
|
const modelContext_1 = require("../modelContext");
|
|
15
15
|
const mcpToolName_1 = require("../parsers/mcpToolName");
|
|
16
16
|
const tokenEstimation_1 = require("../tokenEstimation");
|
|
17
|
+
const subagentSpawn_1 = require("../subagentSpawn");
|
|
17
18
|
const DEFAULT_CONTEXT_SOURCE_LIMIT = 200;
|
|
18
19
|
const DEFAULT_SNIPPET_MAX_CHARS = 240;
|
|
19
20
|
const DEFAULT_BODY_MAX_CHARS = 5000;
|
|
@@ -211,6 +212,9 @@ function extractSourcesFromEvent(event, state) {
|
|
|
211
212
|
}
|
|
212
213
|
}
|
|
213
214
|
function extractSystemSource(event, state) {
|
|
215
|
+
// Background-task notices only update subagent lifecycles (like the aggregator).
|
|
216
|
+
if ((0, subagentSpawn_1.isTaskNotificationSystemEvent)(event))
|
|
217
|
+
return;
|
|
214
218
|
const message = event.message;
|
|
215
219
|
const text = extractText(message?.content);
|
|
216
220
|
const label = message?.sourceLabel ?? message?.role ?? 'system';
|