@sema-agent/client-core 0.94.0 → 0.95.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/CHANGELOG.md +341 -0
- package/README.md +70 -47
- package/dist/adapt/arms.js +5 -6
- package/dist/adapt/panelTasks.js +4 -10
- package/dist/adapt/toolCards.js +2 -2
- package/dist/adapt/wireShapes.js +3 -8
- package/dist/adapter/activeRunSelfHeal.d.ts +8 -3
- package/dist/adapter/activeRunSelfHeal.js +20 -12
- package/dist/adapter/downstream/eventToSdkMessage.js +24 -17
- package/dist/adapter/downstream/terminalToSdkResult.js +11 -3
- package/dist/adapter/runStream.js +2 -1
- package/dist/adapter/types.d.ts +7 -0
- package/dist/adapter/types.js +15 -0
- package/dist/agentSession/backgroundView.js +5 -1
- package/dist/agentSession/engineAgentRegistryRead.js +2 -1
- package/dist/agentSession/engineSessionBackgroundStop.js +3 -2
- package/dist/agentsWireCaps.d.ts +2 -0
- package/dist/approvalDecidedByCapability.d.ts +0 -1
- package/dist/approvalDecidedByCapability.js +2 -7
- package/dist/approvalsStreamLiveCapability.d.ts +0 -1
- package/dist/approvalsStreamLiveCapability.js +2 -6
- package/dist/atMostOnce.d.ts +8 -0
- package/dist/atMostOnce.js +36 -0
- package/dist/attachmentSeatCapability.d.ts +0 -1
- package/dist/attachmentSeatCapability.js +0 -3
- package/dist/attachmentsWireCaps.js +11 -6
- package/dist/bashExitReading.d.ts +10 -0
- package/dist/bashExitReading.js +12 -0
- package/dist/callerCwdCapability.d.ts +0 -1
- package/dist/callerCwdCapability.js +2 -7
- package/dist/centerWiringCapability.d.ts +1 -3
- package/dist/centerWiringCapability.js +18 -21
- package/dist/classifierStatus.js +4 -4
- package/dist/cloudConfigWireCaps.js +43 -21
- package/dist/compensations.js +1 -1
- package/dist/cycleOrder.d.ts +15 -0
- package/dist/cycleOrder.js +45 -0
- package/dist/decideFailureNote.js +4 -1
- package/dist/decideReceipt.d.ts +2 -1
- package/dist/decideReceipt.js +41 -13
- package/dist/declared/supportFloorDeclared.d.ts +1 -0
- package/dist/declared/supportFloorDeclared.js +5 -0
- package/dist/deviceExecutorManagementCapability.d.ts +0 -1
- package/dist/deviceExecutorManagementCapability.js +7 -16
- package/dist/deviceRebind.d.ts +88 -0
- package/dist/deviceRebind.js +242 -0
- package/dist/displayUntrusted.d.ts +1 -0
- package/dist/displayUntrusted.js +313 -11
- package/dist/engineAgentAbsence.d.ts +2 -2
- package/dist/engineAgentPanelStore.d.ts +8 -18
- package/dist/engineAgentPanelStore.js +19 -537
- package/dist/engineCapReader.d.ts +6 -6
- package/dist/engineCapReader.js +30 -43
- package/dist/engineCapsCache.d.ts +7 -2
- package/dist/engineCapsCache.js +64 -26
- package/dist/engineCredentialRequirement.d.ts +9 -0
- package/dist/engineCredentialRequirement.js +23 -0
- package/dist/engineEnvSourcing.d.ts +53 -0
- package/dist/engineEnvSourcing.js +81 -0
- package/dist/engineErrorCodes.d.ts +14 -3
- package/dist/engineErrorCodes.js +31 -10
- package/dist/engineIdentity.js +2 -0
- package/dist/engineWireSdk.js +2 -2
- package/dist/executionLaneCapability.d.ts +2 -3
- package/dist/executionLaneCapability.js +18 -23
- package/dist/fileHistoryCaptureCapability.d.ts +0 -1
- package/dist/fileHistoryCaptureCapability.js +2 -6
- package/dist/fileHistoryLegNotice.d.ts +3 -2
- package/dist/fileHistoryLegNotice.js +51 -2
- package/dist/fleet/fleetLedger.d.ts +2 -0
- package/dist/fleet/fleetLedger.js +69 -52
- package/dist/fleet/fleetProjection.d.ts +0 -3
- package/dist/fleet/fleetProjection.js +9 -16
- package/dist/fleetAgentPanelProjection.d.ts +4 -17
- package/dist/fleetAgentPanelProjection.js +7 -197
- package/dist/fleetAgentRowLike.d.ts +16 -0
- package/dist/fleetAgentRowLike.js +1 -0
- package/dist/gateOutcome.js +30 -18
- package/dist/generated/sdkFactTables.d.ts +2 -0
- package/dist/generated/sdkFactTables.js +17 -0
- package/dist/generated/settingsSchemaFns.d.ts +10 -0
- package/dist/generated/settingsSchemaFns.js +22 -0
- package/dist/headlessPermissionModeWire.d.ts +1 -1
- package/dist/headlessPermissionModeWire.js +1 -1
- package/dist/headlessReconnectWire.js +49 -20
- package/dist/hitl/allowRuleShadow.d.ts +1 -1
- package/dist/hitl/allowRuleShadow.js +49 -8
- package/dist/hitl/approvalCompleteParked.d.ts +1 -0
- package/dist/hitl/approvalCompleteParked.js +14 -0
- package/dist/hitl/approvalEndingCause.d.ts +5 -0
- package/dist/hitl/approvalEndingCause.js +61 -0
- package/dist/hitl/approvalHolds.d.ts +12 -2
- package/dist/hitl/approvalHolds.js +53 -2
- package/dist/hitl/approvalsFeed.js +23 -11
- package/dist/hitl/askGateWire.d.ts +2 -1
- package/dist/hitl/askGateWire.js +26 -1
- package/dist/hitl/automaticAnswerVerdict.js +2 -2
- package/dist/hitl/crashConverged.js +2 -0
- package/dist/hitl/decisionConflict.d.ts +3 -0
- package/dist/hitl/decisionConflict.js +43 -0
- package/dist/hitl/decisionRefusal.d.ts +4 -0
- package/dist/hitl/decisionRefusal.js +26 -1
- package/dist/hitl/frameRouter.js +26 -43
- package/dist/hitl/gateLedger.d.ts +5 -0
- package/dist/hitl/gateLedger.js +21 -0
- package/dist/hitl/hitlBridge.d.ts +12 -1
- package/dist/hitl/hitlBridge.js +68 -53
- package/dist/hitl/hitlHostSurface.js +3 -11
- package/dist/hitl/livePendingAsk.d.ts +16 -6
- package/dist/hitl/livePendingAsk.js +36 -4
- package/dist/hitl/parkExpiryJudgements.d.ts +19 -0
- package/dist/hitl/parkExpiryJudgements.js +46 -0
- package/dist/hitl/parkResolver.d.ts +3 -7
- package/dist/hitl/parkResolver.js +50 -26
- package/dist/hitl/persistedRulesWire.js +5 -1
- package/dist/hitl/planReviewWire.d.ts +2 -2
- package/dist/hitl/planReviewWire.js +56 -30
- package/dist/hitl/replayedApproval.d.ts +8 -0
- package/dist/hitl/replayedApproval.js +125 -10
- package/dist/hitl/resumeRunningCard.d.ts +2 -0
- package/dist/hitl/resumeRunningCard.js +15 -4
- package/dist/hitl/toolApprovalWire.d.ts +24 -4
- package/dist/hitl/toolApprovalWire.js +115 -38
- package/dist/hooksWireCaps.js +38 -6
- package/dist/host.d.ts +5 -0
- package/dist/host.js +3 -1
- package/dist/hostCallbackGuard.d.ts +1 -0
- package/dist/hostCallbackGuard.js +25 -0
- package/dist/index.d.ts +30 -11
- package/dist/index.js +20 -8
- package/dist/interactiveInterrupt.d.ts +8 -0
- package/dist/interactiveInterrupt.js +54 -0
- package/dist/limitsWire.d.ts +5 -0
- package/dist/limitsWire.js +49 -3
- package/dist/liveModelCatalog.d.ts +95 -0
- package/dist/liveModelCatalog.js +297 -32
- package/dist/mcpEngineLeg.d.ts +25 -0
- package/dist/mcpEngineLeg.js +71 -15
- package/dist/mcpPanel.js +2 -1
- package/dist/mcpProbeCapability.d.ts +0 -1
- package/dist/mcpProbeCapability.js +2 -6
- package/dist/mcpReconnect.d.ts +1 -3
- package/dist/mcpReconnect.js +10 -5
- package/dist/memoryComplianceCapability.d.ts +0 -1
- package/dist/memoryComplianceCapability.js +2 -6
- package/dist/memoryOriginCapability.d.ts +0 -1
- package/dist/memoryOriginCapability.js +2 -6
- package/dist/memoryVerbsWire.d.ts +1 -1
- package/dist/memoryVerbsWire.js +4 -0
- package/dist/model/liveCatalogShape.d.ts +14 -0
- package/dist/model/liveCatalogShape.js +71 -0
- package/dist/model/modelSupplyRules.d.ts +1 -0
- package/dist/model/modelSupplyRules.js +30 -9
- package/dist/model/modelsPolicy.d.ts +21 -0
- package/dist/model/modelsPolicy.js +90 -0
- package/dist/modelIdentityResolvability.d.ts +1 -1
- package/dist/modelIdentityResolvability.js +5 -12
- package/dist/modelSwitchFallback.d.ts +69 -0
- package/dist/modelSwitchFallback.js +206 -0
- package/dist/notifications.js +12 -11
- package/dist/outputStyleSeatCapability.d.ts +0 -1
- package/dist/outputStyleSeatCapability.js +2 -7
- package/dist/ownKey.d.ts +6 -0
- package/dist/ownKey.js +48 -0
- package/dist/panelReduce.d.ts +114 -0
- package/dist/panelReduce.js +1135 -0
- package/dist/panelStateHolder.d.ts +17 -0
- package/dist/panelStateHolder.js +201 -0
- package/dist/peerLaneCapability.d.ts +0 -1
- package/dist/peerLaneCapability.js +2 -6
- package/dist/permissionModesCapability.d.ts +0 -1
- package/dist/permissionModesCapability.js +5 -10
- package/dist/permissionRulesWriteCapability.d.ts +0 -1
- package/dist/permissionRulesWriteCapability.js +2 -6
- package/dist/permissionsAllowGrantCapability.d.ts +0 -1
- package/dist/permissionsAllowGrantCapability.js +3 -9
- package/dist/permissionsDeclaration.d.ts +6 -0
- package/dist/permissionsDeclaration.js +45 -0
- package/dist/printToolResultFrame.js +2 -10
- package/dist/promptDelivery.js +0 -8
- package/dist/resumeRefusalCopy.d.ts +18 -1
- package/dist/resumeRefusalCopy.js +126 -15
- package/dist/rewindArchiveCapability.d.ts +2 -1
- package/dist/rewindArchiveCapability.js +15 -7
- package/dist/rewindEngineAction.d.ts +21 -0
- package/dist/rewindEngineAction.js +36 -0
- package/dist/rewindWireCaps.d.ts +2 -1
- package/dist/rewindWireCaps.js +1 -0
- package/dist/runTerminal.d.ts +0 -11
- package/dist/runTerminal.js +4 -27
- package/dist/sdkRegistryTransit.d.ts +2 -1
- package/dist/sdkRegistryTransit.js +1 -0
- package/dist/sealedKeyCapability.d.ts +0 -1
- package/dist/sealedKeyCapability.js +3 -9
- package/dist/seatContract.d.ts +54 -25
- package/dist/seatContract.js +394 -171
- package/dist/sessionIdSegment.d.ts +1 -0
- package/dist/sessionIdSegment.js +11 -0
- package/dist/sessionMemoryErase.d.ts +1 -1
- package/dist/sessionMemoryErase.js +6 -1
- package/dist/sessionMemoryStatus.js +3 -2
- package/dist/sessionPolicyCapability.d.ts +0 -1
- package/dist/sessionPolicyCapability.js +2 -6
- package/dist/sessionReadRedactionCapability.d.ts +0 -1
- package/dist/sessionReadRedactionCapability.js +2 -7
- package/dist/sessionSyncFileHistoryCapability.d.ts +0 -1
- package/dist/sessionSyncFileHistoryCapability.js +2 -6
- package/dist/skillToolListsCapability.d.ts +0 -1
- package/dist/skillToolListsCapability.js +2 -6
- package/dist/skillsWireCaps.d.ts +4 -0
- package/dist/skillsWireCaps.js +66 -1
- package/dist/sqlEngineCapability.d.ts +0 -1
- package/dist/sqlEngineCapability.js +9 -14
- package/dist/steerPriorityCapability.d.ts +0 -1
- package/dist/steerPriorityCapability.js +3 -9
- package/dist/storePostureCapability.d.ts +1 -1
- package/dist/storePostureCapability.js +16 -16
- package/dist/streamDrainingLegs.d.ts +6 -0
- package/dist/streamDrainingLegs.js +23 -0
- package/dist/subagent/engineCompactWire.js +13 -38
- package/dist/subagent/engineDelegatedPrompt.js +10 -6
- package/dist/subagent/engineSubagentOutput.d.ts +0 -1
- package/dist/subagent/engineSubagentOutput.js +5 -20
- package/dist/subagent/engineSubagentTail.d.ts +0 -1
- package/dist/subagent/engineSubagentTail.js +7 -32
- package/dist/subagentContentStore.js +3 -3
- package/dist/supportFloor.js +2 -5
- package/dist/terminalStatuses.d.ts +30 -0
- package/dist/terminalStatuses.js +67 -0
- package/dist/toolResult.d.ts +5 -0
- package/dist/toolResult.js +88 -36
- package/dist/types/engineState.d.ts +2 -1
- package/dist/usageAnalytics.d.ts +146 -0
- package/dist/usageAnalytics.js +311 -0
- package/dist/userInvokedSkillsCapability.d.ts +0 -1
- package/dist/userInvokedSkillsCapability.js +2 -6
- package/dist/webSearchBackendCapability.d.ts +0 -1
- package/dist/webSearchBackendCapability.js +3 -7
- package/dist/webSearchWireCaps.js +3 -11
- package/dist/wireFailureShape.d.ts +4 -0
- package/dist/wireFailureShape.js +42 -2
- package/dist/wireRefusalCopy.js +2 -18
- package/dist/workflowClient.js +7 -11
- package/dist/workflowsJournalCapability.d.ts +0 -1
- package/dist/workflowsJournalCapability.js +2 -6
- package/dist/writeProtectionCapability.d.ts +0 -1
- package/dist/writeProtectionCapability.js +5 -10
- package/docs/INTEGRATION-CLIENTS.md +1033 -26
- package/package.json +5 -5
- package/dist/engineCapsGenerationGuard.d.ts +0 -4
- package/dist/engineCapsGenerationGuard.js +0 -19
- package/dist/panelRunningHistory.d.ts +0 -22
- package/dist/panelRunningHistory.js +0 -82
- package/dist/registryConflict.d.ts +0 -3
- package/dist/registryConflict.js +0 -44
|
@@ -0,0 +1,1135 @@
|
|
|
1
|
+
import { rowIdTail } from './workflow.js';
|
|
2
|
+
import { isSdkFleetTaskTerminal, isSdkFleetTaskTerminalNotSuccess } from './terminalStatuses.js';
|
|
3
|
+
import { carryCycle, cycleEmpty, cycleKeysChanged, cycleOf, cycleOrder, mergeCycle, } from './cycleOrder.js';
|
|
4
|
+
export function isStaleEngineAgentPanelEnd(end, current) {
|
|
5
|
+
return cycleOrder(end, current) === 'before';
|
|
6
|
+
}
|
|
7
|
+
export function isNewEngineAgentPanelCycle(prev, next) {
|
|
8
|
+
const o = cycleOrder(prev, next);
|
|
9
|
+
return o === 'before' || o === 'after';
|
|
10
|
+
}
|
|
11
|
+
const TOMB = 0;
|
|
12
|
+
class PMap {
|
|
13
|
+
base;
|
|
14
|
+
over;
|
|
15
|
+
size;
|
|
16
|
+
constructor(base, over, size) {
|
|
17
|
+
this.base = base;
|
|
18
|
+
this.over = over;
|
|
19
|
+
this.size = size;
|
|
20
|
+
}
|
|
21
|
+
static empty() {
|
|
22
|
+
return new PMap(new Map(), new Map(), 0);
|
|
23
|
+
}
|
|
24
|
+
get(k) {
|
|
25
|
+
const o = this.over.get(k);
|
|
26
|
+
if (o !== undefined)
|
|
27
|
+
return o === TOMB ? undefined : o.v;
|
|
28
|
+
return this.base.get(k);
|
|
29
|
+
}
|
|
30
|
+
has(k) {
|
|
31
|
+
return this.get(k) !== undefined;
|
|
32
|
+
}
|
|
33
|
+
*entries() {
|
|
34
|
+
for (const [k, v] of this.base) {
|
|
35
|
+
const o = this.over.get(k);
|
|
36
|
+
if (o === undefined)
|
|
37
|
+
yield [k, v];
|
|
38
|
+
else if (o !== TOMB && o.moved !== true)
|
|
39
|
+
yield [k, o.v];
|
|
40
|
+
}
|
|
41
|
+
for (const [k, o] of this.over) {
|
|
42
|
+
if (o === TOMB)
|
|
43
|
+
continue;
|
|
44
|
+
if (this.base.has(k) && o.moved !== true)
|
|
45
|
+
continue;
|
|
46
|
+
yield [k, o.v];
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
draft() {
|
|
50
|
+
return new PDraft(this);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
class PDraft {
|
|
54
|
+
base;
|
|
55
|
+
over = null;
|
|
56
|
+
src;
|
|
57
|
+
size;
|
|
58
|
+
constructor(src) {
|
|
59
|
+
this.src = src;
|
|
60
|
+
this.base = src.base;
|
|
61
|
+
this.size = src.size;
|
|
62
|
+
}
|
|
63
|
+
w() {
|
|
64
|
+
if (this.over === null)
|
|
65
|
+
this.over = new Map(this.src.over);
|
|
66
|
+
return this.over;
|
|
67
|
+
}
|
|
68
|
+
ov() {
|
|
69
|
+
return this.over ?? this.src.over;
|
|
70
|
+
}
|
|
71
|
+
get(k) {
|
|
72
|
+
const o = this.ov().get(k);
|
|
73
|
+
if (o !== undefined)
|
|
74
|
+
return o === TOMB ? undefined : o.v;
|
|
75
|
+
return this.base.get(k);
|
|
76
|
+
}
|
|
77
|
+
has(k) {
|
|
78
|
+
return this.get(k) !== undefined;
|
|
79
|
+
}
|
|
80
|
+
set(k, v) {
|
|
81
|
+
const over = this.w();
|
|
82
|
+
const o = over.get(k);
|
|
83
|
+
if (o !== undefined && o !== TOMB) {
|
|
84
|
+
over.set(k, o.moved === true ? { v, moved: true } : { v });
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
if (o === TOMB) {
|
|
88
|
+
over.delete(k);
|
|
89
|
+
over.set(k, { v, moved: true });
|
|
90
|
+
this.size++;
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
if (!this.base.has(k))
|
|
94
|
+
this.size++;
|
|
95
|
+
over.set(k, { v });
|
|
96
|
+
}
|
|
97
|
+
delete(k) {
|
|
98
|
+
if (!this.has(k))
|
|
99
|
+
return;
|
|
100
|
+
const over = this.w();
|
|
101
|
+
if (this.base.has(k))
|
|
102
|
+
over.set(k, TOMB);
|
|
103
|
+
else
|
|
104
|
+
over.delete(k);
|
|
105
|
+
this.size--;
|
|
106
|
+
}
|
|
107
|
+
touch(k) {
|
|
108
|
+
const v = this.get(k);
|
|
109
|
+
if (v === undefined)
|
|
110
|
+
return;
|
|
111
|
+
const over = this.w();
|
|
112
|
+
over.delete(k);
|
|
113
|
+
over.set(k, this.base.has(k) ? { v, moved: true } : { v });
|
|
114
|
+
}
|
|
115
|
+
*entries() {
|
|
116
|
+
yield* new PMap(this.base, this.ov(), this.size).entries();
|
|
117
|
+
}
|
|
118
|
+
first(pred) {
|
|
119
|
+
for (const [k, v] of this.entries())
|
|
120
|
+
if (pred(k, v))
|
|
121
|
+
return k;
|
|
122
|
+
return undefined;
|
|
123
|
+
}
|
|
124
|
+
freeze() {
|
|
125
|
+
if (this.over === null)
|
|
126
|
+
return this.src;
|
|
127
|
+
if (this.over.size > Math.max(32, this.base.size >> 4)) {
|
|
128
|
+
return new PMap(new Map(new PMap(this.base, this.over, this.size).entries()), new Map(), this.size);
|
|
129
|
+
}
|
|
130
|
+
return new PMap(this.base, this.over, this.size);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
export const ABSENT_SETTLE_MS = 30_000;
|
|
134
|
+
const SETTLED_RETENTION_MS = ABSENT_SETTLE_MS * 4;
|
|
135
|
+
export const MAX_HELD_WIRE_TICK_BEATS = 16;
|
|
136
|
+
const MAX_HELD_WIRE_TICKS = 64;
|
|
137
|
+
const MAX_ALIAS_PER_KIND = 2048;
|
|
138
|
+
const MAX_WIRE_KEYS = 8192;
|
|
139
|
+
const MAX_OWNED_TAILS = 8192;
|
|
140
|
+
const MAX_RUNNING = 4096;
|
|
141
|
+
const MAX_ENDED = 4096;
|
|
142
|
+
const MAX_HELD_ROWS = 4096;
|
|
143
|
+
const MAX_ROWS = 8192;
|
|
144
|
+
export const PANEL_DELTA_OPS = Object.freeze(['upsert', 'usage_delta', 'terminal', 'remove']);
|
|
145
|
+
export const PANEL_REDUCE_STATE_KEYS = Object.freeze(['__panelReduceState', 'records', 'alias', 'pending', 'sessions', 'overflowed', 'counts']);
|
|
146
|
+
export function createPanelReduceState() {
|
|
147
|
+
const s = {
|
|
148
|
+
__panelReduceState: true,
|
|
149
|
+
records: PMap.empty(),
|
|
150
|
+
alias: PMap.empty(),
|
|
151
|
+
pending: PMap.empty(),
|
|
152
|
+
sessions: PMap.empty(),
|
|
153
|
+
overflowed: false,
|
|
154
|
+
counts: { alias: { t: 0, p: 0, w: 0 }, wire: 0, owned: 0, running: 0, ended: 0, held: 0, rows: 0 },
|
|
155
|
+
};
|
|
156
|
+
return Object.freeze(s);
|
|
157
|
+
}
|
|
158
|
+
function impl(s) {
|
|
159
|
+
return s;
|
|
160
|
+
}
|
|
161
|
+
class Step {
|
|
162
|
+
records;
|
|
163
|
+
alias;
|
|
164
|
+
pending;
|
|
165
|
+
sessionsDraft;
|
|
166
|
+
overflowed;
|
|
167
|
+
counts;
|
|
168
|
+
deltas = [];
|
|
169
|
+
facts = [];
|
|
170
|
+
constructor(s) {
|
|
171
|
+
this.records = s.records.draft();
|
|
172
|
+
this.alias = s.alias.draft();
|
|
173
|
+
this.pending = s.pending.draft();
|
|
174
|
+
this.sessionsDraft = s.sessions.draft();
|
|
175
|
+
this.overflowed = s.overflowed;
|
|
176
|
+
this.counts = { alias: { ...s.counts.alias }, wire: s.counts.wire, owned: s.counts.owned, running: s.counts.running, ended: s.counts.ended, held: s.counts.held, rows: s.counts.rows };
|
|
177
|
+
}
|
|
178
|
+
freeze() {
|
|
179
|
+
return Object.freeze({
|
|
180
|
+
__panelReduceState: true,
|
|
181
|
+
records: this.records.freeze(),
|
|
182
|
+
alias: this.alias.freeze(),
|
|
183
|
+
pending: this.pending.freeze(),
|
|
184
|
+
sessions: this.sessionsDraft.freeze(),
|
|
185
|
+
overflowed: this.overflowed,
|
|
186
|
+
counts: Object.freeze({ ...this.counts, alias: Object.freeze({ ...this.counts.alias }) }),
|
|
187
|
+
});
|
|
188
|
+
}
|
|
189
|
+
rec(key) {
|
|
190
|
+
return this.records.get(key);
|
|
191
|
+
}
|
|
192
|
+
put(key, patch) {
|
|
193
|
+
const old = this.records.get(key) ?? {};
|
|
194
|
+
const next = { ...old };
|
|
195
|
+
for (const [f, v] of Object.entries(patch)) {
|
|
196
|
+
if (v === undefined)
|
|
197
|
+
delete next[f];
|
|
198
|
+
else
|
|
199
|
+
next[f] = v;
|
|
200
|
+
}
|
|
201
|
+
const n = next;
|
|
202
|
+
this.counts.wire += (n.wire !== undefined ? 1 : 0) - (old.wire !== undefined ? 1 : 0);
|
|
203
|
+
this.counts.owned += (n.ownedBy !== undefined ? 1 : 0) - (old.ownedBy !== undefined ? 1 : 0);
|
|
204
|
+
this.counts.running += (n.running !== undefined ? 1 : 0) - (old.running !== undefined ? 1 : 0);
|
|
205
|
+
this.counts.ended += (n.ended !== undefined ? 1 : 0) - (old.ended !== undefined ? 1 : 0);
|
|
206
|
+
this.counts.held += (n.held !== undefined ? 1 : 0) - (old.held !== undefined ? 1 : 0);
|
|
207
|
+
this.counts.rows += (n.row !== undefined ? 1 : 0) - (old.row !== undefined ? 1 : 0);
|
|
208
|
+
if (Object.keys(next).length === 0)
|
|
209
|
+
this.records.delete(key);
|
|
210
|
+
else
|
|
211
|
+
this.records.set(key, n);
|
|
212
|
+
const from = old.ownedBy?.wireId;
|
|
213
|
+
const to = n.ownedBy?.wireId;
|
|
214
|
+
if (from !== to) {
|
|
215
|
+
if (from !== undefined)
|
|
216
|
+
this.linkOwned(from, key, false);
|
|
217
|
+
if (to !== undefined)
|
|
218
|
+
this.linkOwned(to, key, true);
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
linkOwned(owner, tail, add) {
|
|
222
|
+
const r = this.records.get(owner) ?? {};
|
|
223
|
+
const cur = r.owns ?? [];
|
|
224
|
+
if (cur.includes(tail) === add)
|
|
225
|
+
return;
|
|
226
|
+
const owns = add ? [...cur, tail] : cur.filter((t) => t !== tail);
|
|
227
|
+
const next = { ...r };
|
|
228
|
+
if (owns.length > 0)
|
|
229
|
+
next.owns = owns;
|
|
230
|
+
else
|
|
231
|
+
delete next.owns;
|
|
232
|
+
if (Object.keys(next).length === 0)
|
|
233
|
+
this.records.delete(owner);
|
|
234
|
+
else
|
|
235
|
+
this.records.set(owner, next);
|
|
236
|
+
}
|
|
237
|
+
ownedTails(owner) {
|
|
238
|
+
return this.records.get(owner)?.owns ?? [];
|
|
239
|
+
}
|
|
240
|
+
aliasGet(kind, key, touch) {
|
|
241
|
+
const k = `${kind}:${key}`;
|
|
242
|
+
const e = this.alias.get(k);
|
|
243
|
+
if (e !== undefined && touch)
|
|
244
|
+
this.alias.touch(k);
|
|
245
|
+
return e;
|
|
246
|
+
}
|
|
247
|
+
aliasHas(kind, key) {
|
|
248
|
+
return this.alias.has(`${kind}:${key}`);
|
|
249
|
+
}
|
|
250
|
+
aliasSet(kind, key, entry) {
|
|
251
|
+
const k = `${kind}:${key}`;
|
|
252
|
+
const had = this.alias.has(k);
|
|
253
|
+
if (had)
|
|
254
|
+
this.alias.delete(k);
|
|
255
|
+
else
|
|
256
|
+
this.counts.alias[kind]++;
|
|
257
|
+
this.alias.set(k, entry);
|
|
258
|
+
if (this.counts.alias[kind] > MAX_ALIAS_PER_KIND) {
|
|
259
|
+
const prefix = `${kind}:`;
|
|
260
|
+
const oldest = this.alias.first((key2) => key2.startsWith(prefix));
|
|
261
|
+
if (oldest !== undefined) {
|
|
262
|
+
this.alias.delete(oldest);
|
|
263
|
+
this.counts.alias[kind]--;
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
session(sessionKey) {
|
|
268
|
+
return (this.sessionsDraft.get(sessionKey) ?? PMap.empty()).draft();
|
|
269
|
+
}
|
|
270
|
+
putSession(sessionKey, d) {
|
|
271
|
+
if (d.size === 0)
|
|
272
|
+
this.sessionsDraft.delete(sessionKey);
|
|
273
|
+
else
|
|
274
|
+
this.sessionsDraft.set(sessionKey, d.freeze());
|
|
275
|
+
}
|
|
276
|
+
dropSessions(sessionKey) {
|
|
277
|
+
if (sessionKey !== undefined) {
|
|
278
|
+
this.sessionsDraft.delete(sessionKey);
|
|
279
|
+
return;
|
|
280
|
+
}
|
|
281
|
+
for (const [k] of [...this.sessionsDraft.entries()])
|
|
282
|
+
this.sessionsDraft.delete(k);
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
function boundFields(d) {
|
|
286
|
+
if (d.counts.wire > MAX_WIRE_KEYS) {
|
|
287
|
+
const k = d.records.first((_, r) => r.wire?.retired === true) ?? d.records.first((_, r) => r.wire !== undefined);
|
|
288
|
+
if (k !== undefined)
|
|
289
|
+
d.put(k, { wire: undefined });
|
|
290
|
+
}
|
|
291
|
+
if (d.counts.owned > MAX_OWNED_TAILS) {
|
|
292
|
+
const k = d.records.first((_, r) => r.ownedBy?.retired === true) ?? d.records.first((_, r) => r.ownedBy !== undefined);
|
|
293
|
+
if (k !== undefined)
|
|
294
|
+
d.put(k, { ownedBy: undefined });
|
|
295
|
+
}
|
|
296
|
+
if (d.counts.running > MAX_RUNNING) {
|
|
297
|
+
d.overflowed = true;
|
|
298
|
+
const k = d.records.first((_, r) => r.running === true);
|
|
299
|
+
if (k !== undefined)
|
|
300
|
+
d.put(k, { running: undefined });
|
|
301
|
+
}
|
|
302
|
+
if (d.counts.ended > MAX_ENDED) {
|
|
303
|
+
const k = d.records.first((_, r) => r.ended !== undefined);
|
|
304
|
+
if (k !== undefined)
|
|
305
|
+
d.put(k, { ended: undefined });
|
|
306
|
+
}
|
|
307
|
+
if (d.counts.held > MAX_HELD_ROWS) {
|
|
308
|
+
const k = d.records.first((_, r) => r.held !== undefined);
|
|
309
|
+
if (k !== undefined)
|
|
310
|
+
d.put(k, { held: undefined });
|
|
311
|
+
}
|
|
312
|
+
if (d.counts.rows > MAX_ROWS) {
|
|
313
|
+
const k = d.records.first((_, r) => r.row?.phase === 'ended') ?? d.records.first((_, r) => r.row !== undefined);
|
|
314
|
+
if (k !== undefined) {
|
|
315
|
+
const announced = d.rec(k)?.row?.announced === true;
|
|
316
|
+
d.put(k, { row: undefined });
|
|
317
|
+
if (announced)
|
|
318
|
+
d.deltas.push({ op: 'remove', canonicalId: k });
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
export function panelEndFact(taskId, isError, extra) {
|
|
323
|
+
return {
|
|
324
|
+
kind: 'end',
|
|
325
|
+
taskId,
|
|
326
|
+
isError,
|
|
327
|
+
...(extra?.cycleSeq !== undefined ? { cycleSeq: extra.cycleSeq } : {}),
|
|
328
|
+
...(extra?.startedAt !== undefined ? { startedAt: extra.startedAt } : {}),
|
|
329
|
+
...(extra?.report !== undefined ? { report: extra.report } : {}),
|
|
330
|
+
};
|
|
331
|
+
}
|
|
332
|
+
function terminalDelta(key, isError, report, cause) {
|
|
333
|
+
return { op: 'terminal', canonicalId: key, isError, ...(report !== undefined ? { report } : {}), cause };
|
|
334
|
+
}
|
|
335
|
+
function mintTerminal(d, key, isError, report, cause) {
|
|
336
|
+
d.deltas.push(terminalDelta(key, isError, report, cause));
|
|
337
|
+
}
|
|
338
|
+
function tickFields(ev) {
|
|
339
|
+
return {
|
|
340
|
+
...(ev.name !== undefined ? { name: ev.name } : {}),
|
|
341
|
+
...(ev.description !== undefined ? { description: ev.description } : {}),
|
|
342
|
+
...(ev.prompt !== undefined ? { prompt: ev.prompt } : {}),
|
|
343
|
+
...(ev.currentAction !== undefined ? { currentAction: ev.currentAction } : {}),
|
|
344
|
+
...(ev.spawnName !== undefined ? { spawnName: ev.spawnName } : {}),
|
|
345
|
+
...(ev.parentToolCallId !== undefined ? { parentToolCallId: ev.parentToolCallId } : {}),
|
|
346
|
+
...(ev.wireTaskId !== undefined ? { wireTaskId: ev.wireTaskId } : {}),
|
|
347
|
+
...(ev.taskIdOrigin !== undefined ? { taskIdOrigin: ev.taskIdOrigin } : {}),
|
|
348
|
+
};
|
|
349
|
+
}
|
|
350
|
+
function fleetFields(ev) {
|
|
351
|
+
return {
|
|
352
|
+
...(ev.name !== undefined ? { name: ev.name } : {}),
|
|
353
|
+
...(ev.description !== undefined ? { description: ev.description } : {}),
|
|
354
|
+
...(ev.currentTool !== undefined ? { currentTool: ev.currentTool } : {}),
|
|
355
|
+
...(ev.transcriptId !== undefined ? { transcriptId: ev.transcriptId } : {}),
|
|
356
|
+
...(ev.parentToolCallId !== undefined ? { parentToolCallId: ev.parentToolCallId } : {}),
|
|
357
|
+
...(ev.startedAt !== undefined ? { startedAt: ev.startedAt } : {}),
|
|
358
|
+
...(ev.cycleSeq !== undefined ? { cycleSeq: ev.cycleSeq } : {}),
|
|
359
|
+
...(ev.wireTaskId !== undefined ? { wireTaskId: ev.wireTaskId } : {}),
|
|
360
|
+
...(ev.taskIdOrigin !== undefined ? { taskIdOrigin: ev.taskIdOrigin } : {}),
|
|
361
|
+
};
|
|
362
|
+
}
|
|
363
|
+
function changedFields(row, next, onlyMissing) {
|
|
364
|
+
const out = {};
|
|
365
|
+
for (const [k, v] of Object.entries(next)) {
|
|
366
|
+
const cur = row[k];
|
|
367
|
+
if (onlyMissing.includes(k) && cur !== undefined)
|
|
368
|
+
continue;
|
|
369
|
+
if (JSON.stringify(cur) !== JSON.stringify(v))
|
|
370
|
+
out[k] = v;
|
|
371
|
+
}
|
|
372
|
+
return out;
|
|
373
|
+
}
|
|
374
|
+
const TICK_LATE_BIND = Object.freeze(['prompt', 'description', 'name']);
|
|
375
|
+
function usageDelta(key, row, tokens, toolUses) {
|
|
376
|
+
const t = tokens !== undefined && tokens !== row?.totalTokens ? tokens : undefined;
|
|
377
|
+
const u = toolUses !== undefined && toolUses !== row?.toolUses ? toolUses : undefined;
|
|
378
|
+
if (t === undefined && u === undefined)
|
|
379
|
+
return undefined;
|
|
380
|
+
return { op: 'usage_delta', canonicalId: key, ...(t !== undefined ? { totalTokens: t } : {}), ...(u !== undefined ? { toolUses: u } : {}) };
|
|
381
|
+
}
|
|
382
|
+
function announce(d, key, row) {
|
|
383
|
+
d.deltas.push({ op: 'upsert', canonicalId: key, created: true, fields: { ...row.fields } });
|
|
384
|
+
const u = usageDelta(key, undefined, row.totalTokens, row.toolUses);
|
|
385
|
+
if (u !== undefined)
|
|
386
|
+
d.deltas.push(u);
|
|
387
|
+
if (row.phase === 'ended')
|
|
388
|
+
mintTerminal(d, key, row.isError === true, row.report, 'end');
|
|
389
|
+
return { ...row, announced: true };
|
|
390
|
+
}
|
|
391
|
+
function foldTick(d, ev) {
|
|
392
|
+
const key = ev.taskId;
|
|
393
|
+
const row = d.rec(key)?.row;
|
|
394
|
+
if (row === undefined || !row.announced) {
|
|
395
|
+
const fresh = row !== undefined
|
|
396
|
+
? { ...row, lane: 'tick', fields: { ...row.fields, ...tickFields(ev) }, totalTokens: ev.totalTokens, toolUses: ev.toolUses }
|
|
397
|
+
: { phase: 'running', lane: 'tick', announced: false, fields: tickFields(ev), totalTokens: ev.totalTokens, toolUses: ev.toolUses };
|
|
398
|
+
d.put(key, { row: announce(d, key, fresh) });
|
|
399
|
+
return;
|
|
400
|
+
}
|
|
401
|
+
if (row.phase !== 'running')
|
|
402
|
+
return;
|
|
403
|
+
const next = tickFields(ev);
|
|
404
|
+
const changed = changedFields(row.fields, next, TICK_LATE_BIND);
|
|
405
|
+
if (row.fields.absence)
|
|
406
|
+
changed.absence = null;
|
|
407
|
+
if (Object.keys(changed).length > 0)
|
|
408
|
+
d.deltas.push({ op: 'upsert', canonicalId: key, fields: changed });
|
|
409
|
+
const u = usageDelta(key, row, ev.totalTokens, ev.toolUses);
|
|
410
|
+
if (u !== undefined)
|
|
411
|
+
d.deltas.push(u);
|
|
412
|
+
const fields = { ...row.fields, ...changed };
|
|
413
|
+
if (changed.absence === null)
|
|
414
|
+
delete fields.absence;
|
|
415
|
+
d.put(key, { row: { ...row, lane: 'tick', fields, totalTokens: ev.totalTokens, toolUses: ev.toolUses } });
|
|
416
|
+
}
|
|
417
|
+
function foldFleetRow(d, ev, prior) {
|
|
418
|
+
const key = ev.taskId;
|
|
419
|
+
const row = d.rec(key)?.row;
|
|
420
|
+
const order = cycleOrder(prior, ev);
|
|
421
|
+
if (order === 'after')
|
|
422
|
+
return;
|
|
423
|
+
const endGen = row?.phase === 'ended' ? row.endCycle : undefined;
|
|
424
|
+
const newCycle = order === 'before' || (endGen !== undefined && cycleOrder(endGen, ev) === 'before');
|
|
425
|
+
if (row === undefined) {
|
|
426
|
+
const fresh = { phase: 'running', lane: 'fleet', announced: false, fields: fleetFields(ev), ...(ev.totalTokens !== undefined ? { totalTokens: ev.totalTokens } : {}), ...(ev.toolUses !== undefined ? { toolUses: ev.toolUses } : {}) };
|
|
427
|
+
d.put(key, { row: announce(d, key, fresh) });
|
|
428
|
+
return;
|
|
429
|
+
}
|
|
430
|
+
if (!row.announced) {
|
|
431
|
+
const merged = newCycle
|
|
432
|
+
? { phase: 'running', lane: 'fleet', announced: false, fields: fleetFields(ev), ...(ev.totalTokens !== undefined ? { totalTokens: ev.totalTokens } : {}), ...(ev.toolUses !== undefined ? { toolUses: ev.toolUses } : {}) }
|
|
433
|
+
: { ...row, fields: { ...row.fields, ...fleetFields(ev) }, ...(ev.totalTokens !== undefined ? { totalTokens: ev.totalTokens } : {}), ...(ev.toolUses !== undefined ? { toolUses: ev.toolUses } : {}) };
|
|
434
|
+
d.put(key, { row: announce(d, key, merged) });
|
|
435
|
+
return;
|
|
436
|
+
}
|
|
437
|
+
if (newCycle) {
|
|
438
|
+
const fields = fleetFields(ev);
|
|
439
|
+
d.deltas.push({ op: 'upsert', canonicalId: key, revived: true, fields: { ...fields, ...(row.fields.absence ? { absence: null } : {}) } });
|
|
440
|
+
const u = usageDelta(key, undefined, ev.totalTokens, ev.toolUses);
|
|
441
|
+
if (u !== undefined)
|
|
442
|
+
d.deltas.push(u);
|
|
443
|
+
const kept = { ...row.fields, ...fields };
|
|
444
|
+
delete kept.absence;
|
|
445
|
+
d.put(key, { row: { phase: 'running', lane: 'fleet', announced: true, fields: kept, ...(ev.totalTokens !== undefined ? { totalTokens: ev.totalTokens } : {}), ...(ev.toolUses !== undefined ? { toolUses: ev.toolUses } : {}) } });
|
|
446
|
+
return;
|
|
447
|
+
}
|
|
448
|
+
if (row.phase !== 'running')
|
|
449
|
+
return;
|
|
450
|
+
if (row.lane === 'tick') {
|
|
451
|
+
if (row.fields.absence) {
|
|
452
|
+
d.deltas.push({ op: 'upsert', canonicalId: key, fields: { absence: null } });
|
|
453
|
+
const fields = { ...row.fields };
|
|
454
|
+
delete fields.absence;
|
|
455
|
+
d.put(key, { row: { ...row, fields } });
|
|
456
|
+
}
|
|
457
|
+
return;
|
|
458
|
+
}
|
|
459
|
+
const changed = changedFields(row.fields, fleetFields(ev), []);
|
|
460
|
+
if (row.fields.absence)
|
|
461
|
+
changed.absence = null;
|
|
462
|
+
if (Object.keys(changed).length > 0)
|
|
463
|
+
d.deltas.push({ op: 'upsert', canonicalId: key, fields: changed });
|
|
464
|
+
const u = usageDelta(key, row, ev.totalTokens, ev.toolUses);
|
|
465
|
+
if (u !== undefined)
|
|
466
|
+
d.deltas.push(u);
|
|
467
|
+
const fields = { ...row.fields, ...changed };
|
|
468
|
+
if (changed.absence === null)
|
|
469
|
+
delete fields.absence;
|
|
470
|
+
d.put(key, { row: { ...row, fields, ...(ev.totalTokens !== undefined ? { totalTokens: ev.totalTokens } : {}), ...(ev.toolUses !== undefined ? { toolUses: ev.toolUses } : {}) } });
|
|
471
|
+
}
|
|
472
|
+
function foldEnd(d, ev) {
|
|
473
|
+
const key = ev.taskId;
|
|
474
|
+
const rec = d.rec(key);
|
|
475
|
+
if (endOlderThanKnown(d, ev, key, rec?.cycle))
|
|
476
|
+
return;
|
|
477
|
+
const row = rec?.row;
|
|
478
|
+
if (row === undefined) {
|
|
479
|
+
d.put(key, { row: { phase: 'ended', lane: 'fleet', announced: false, isError: ev.isError, cause: 'end', ...(cycleEmpty(ev) ? {} : { endCycle: cycleOf(ev) }), ...(ev.report !== undefined ? { report: ev.report } : {}), fields: {} } });
|
|
480
|
+
return;
|
|
481
|
+
}
|
|
482
|
+
if (row.phase !== 'running')
|
|
483
|
+
return;
|
|
484
|
+
const fields = { ...row.fields };
|
|
485
|
+
delete fields.absence;
|
|
486
|
+
d.put(key, { row: { ...row, phase: 'ended', lane: 'fleet', isError: ev.isError, cause: 'end', ...(cycleEmpty(ev) ? {} : { endCycle: cycleOf(ev) }), ...(ev.report !== undefined ? { report: ev.report } : {}), fields } });
|
|
487
|
+
if (row.announced)
|
|
488
|
+
mintTerminal(d, key, ev.isError, ev.report, 'end');
|
|
489
|
+
}
|
|
490
|
+
function foldSweep(d) {
|
|
491
|
+
const hits = [];
|
|
492
|
+
for (const [key, r] of d.records.entries()) {
|
|
493
|
+
const row = r.row;
|
|
494
|
+
if (row === undefined || !row.announced || row.phase !== 'running')
|
|
495
|
+
continue;
|
|
496
|
+
if (row.fields.absence)
|
|
497
|
+
continue;
|
|
498
|
+
if (row.lane === 'fleet' || r.resident === true)
|
|
499
|
+
continue;
|
|
500
|
+
hits.push(key);
|
|
501
|
+
}
|
|
502
|
+
for (const key of hits) {
|
|
503
|
+
const row = d.rec(key)?.row;
|
|
504
|
+
if (row === undefined)
|
|
505
|
+
continue;
|
|
506
|
+
d.put(key, { row: { ...row, phase: 'ended', isError: false, cause: 'sweep' } });
|
|
507
|
+
mintTerminal(d, key, false, undefined, 'sweep');
|
|
508
|
+
}
|
|
509
|
+
}
|
|
510
|
+
function foldAbsence(d, a) {
|
|
511
|
+
const row = d.rec(a.taskId)?.row;
|
|
512
|
+
if (row === undefined || !row.announced || row.phase !== 'running')
|
|
513
|
+
return;
|
|
514
|
+
const absence = { lastSeenAtMs: a.lastSeenAtMs, absentForMs: a.absentForMs };
|
|
515
|
+
d.deltas.push({ op: 'upsert', canonicalId: a.taskId, fields: { absence } });
|
|
516
|
+
d.put(a.taskId, { row: { ...row, fields: { ...row.fields, absence } } });
|
|
517
|
+
}
|
|
518
|
+
function emit(d, ev, prior) {
|
|
519
|
+
d.facts.push({ ch: 'event', ev });
|
|
520
|
+
switch (ev.kind) {
|
|
521
|
+
case 'tick':
|
|
522
|
+
foldTick(d, ev);
|
|
523
|
+
break;
|
|
524
|
+
case 'fleet-row':
|
|
525
|
+
foldFleetRow(d, ev, prior);
|
|
526
|
+
break;
|
|
527
|
+
case 'end':
|
|
528
|
+
foldEnd(d, ev);
|
|
529
|
+
break;
|
|
530
|
+
default:
|
|
531
|
+
foldSweep(d);
|
|
532
|
+
}
|
|
533
|
+
boundFields(d);
|
|
534
|
+
}
|
|
535
|
+
function identityOf(a) {
|
|
536
|
+
return { taskId: a.to, origin: 'fleet-row', ...cycleOf(a.cycle) };
|
|
537
|
+
}
|
|
538
|
+
function resolve(d, wireTaskId, parentToolCallId, touch) {
|
|
539
|
+
const byT = d.aliasGet('t', wireTaskId, touch);
|
|
540
|
+
if (byT !== undefined)
|
|
541
|
+
return identityOf(byT);
|
|
542
|
+
const byP = parentToolCallId !== undefined ? d.aliasGet('p', parentToolCallId, touch) : undefined;
|
|
543
|
+
if (byP !== undefined)
|
|
544
|
+
return identityOf(byP);
|
|
545
|
+
return { taskId: wireTaskId, origin: 'wire' };
|
|
546
|
+
}
|
|
547
|
+
function rememberResolvedWire(d, wireTaskId, id) {
|
|
548
|
+
if (d.aliasHas('t', wireTaskId))
|
|
549
|
+
return;
|
|
550
|
+
const c = cycleOf(id);
|
|
551
|
+
d.aliasSet('t', wireTaskId, { to: id.taskId, ...(cycleEmpty(c) ? {} : { cycle: c }) });
|
|
552
|
+
}
|
|
553
|
+
function notePublishedWire(d, ev) {
|
|
554
|
+
d.put(ev.taskId, { wire: { retired: d.rec(ev.taskId)?.wire?.retired ?? false } });
|
|
555
|
+
if (ev.parentToolCallId !== undefined && ev.parentToolCallId.length > 0)
|
|
556
|
+
d.aliasSet('w', ev.parentToolCallId, { to: ev.taskId });
|
|
557
|
+
}
|
|
558
|
+
function retireWire(d, wireId) {
|
|
559
|
+
const w = d.rec(wireId)?.wire;
|
|
560
|
+
if (w !== undefined)
|
|
561
|
+
d.put(wireId, { wire: { retired: true } });
|
|
562
|
+
const owned = d.ownedTails(wireId).filter((k) => d.rec(k)?.ownedBy?.retired === false);
|
|
563
|
+
for (const k of owned) {
|
|
564
|
+
const o = d.rec(k)?.ownedBy;
|
|
565
|
+
if (o !== undefined)
|
|
566
|
+
d.put(k, { ownedBy: { ...o, retired: true } });
|
|
567
|
+
}
|
|
568
|
+
}
|
|
569
|
+
function isPublishedWire(d, id) {
|
|
570
|
+
return d.rec(id)?.wire !== undefined;
|
|
571
|
+
}
|
|
572
|
+
function publishedWireFor(d, ev) {
|
|
573
|
+
if (ev.transcriptId !== undefined && isPublishedWire(d, ev.transcriptId))
|
|
574
|
+
return ev.transcriptId;
|
|
575
|
+
if (ev.parentToolCallId !== undefined) {
|
|
576
|
+
const u = d.aliasGet('w', ev.parentToolCallId, false)?.to;
|
|
577
|
+
if (u !== undefined && d.rec(u)?.wire?.retired === false)
|
|
578
|
+
return u;
|
|
579
|
+
}
|
|
580
|
+
return undefined;
|
|
581
|
+
}
|
|
582
|
+
function wireOwnerOf(d, fleetId, current, transcriptId) {
|
|
583
|
+
const o = d.rec(fleetId)?.ownedBy;
|
|
584
|
+
if (o === undefined)
|
|
585
|
+
return undefined;
|
|
586
|
+
const newTranscript = transcriptId !== undefined && transcriptId !== (o.transcriptId ?? o.wireId);
|
|
587
|
+
if (newTranscript || (current !== undefined && isStaleEngineAgentPanelEnd(d.rec(o.wireId)?.cycle, current))) {
|
|
588
|
+
d.put(fleetId, { ownedBy: undefined });
|
|
589
|
+
retireWire(d, o.wireId);
|
|
590
|
+
return undefined;
|
|
591
|
+
}
|
|
592
|
+
return o.wireId;
|
|
593
|
+
}
|
|
594
|
+
function ageHeld(d, except) {
|
|
595
|
+
for (const [wireId, held] of [...d.pending.entries()]) {
|
|
596
|
+
if (wireId === except)
|
|
597
|
+
continue;
|
|
598
|
+
const beats = held.beats + 1;
|
|
599
|
+
if (beats >= MAX_HELD_WIRE_TICK_BEATS) {
|
|
600
|
+
d.pending.delete(wireId);
|
|
601
|
+
emit(d, asIsTick(d, held.ev));
|
|
602
|
+
}
|
|
603
|
+
else {
|
|
604
|
+
d.pending.set(wireId, { ev: held.ev, beats });
|
|
605
|
+
}
|
|
606
|
+
}
|
|
607
|
+
}
|
|
608
|
+
function migrateResidency(d, wireTaskId, fleetId) {
|
|
609
|
+
if (wireTaskId !== fleetId && d.rec(wireTaskId)?.resident === true) {
|
|
610
|
+
d.put(wireTaskId, { resident: undefined });
|
|
611
|
+
d.put(fleetId, { resident: true });
|
|
612
|
+
}
|
|
613
|
+
}
|
|
614
|
+
function stripCardBound(ev) {
|
|
615
|
+
const { cardBound: _cardBound, ...rest } = ev;
|
|
616
|
+
void _cardBound;
|
|
617
|
+
return rest;
|
|
618
|
+
}
|
|
619
|
+
function normalizedTick(d, ev, fleetId) {
|
|
620
|
+
migrateResidency(d, ev.taskId, fleetId);
|
|
621
|
+
return { ...stripCardBound(ev), taskId: fleetId, wireTaskId: ev.taskId, taskIdOrigin: 'fleet-row' };
|
|
622
|
+
}
|
|
623
|
+
function asIsTick(d, ev) {
|
|
624
|
+
notePublishedWire(d, ev);
|
|
625
|
+
return { ...stripCardBound(ev), taskIdOrigin: 'wire' };
|
|
626
|
+
}
|
|
627
|
+
function staleWireTick(d, id) {
|
|
628
|
+
return isStaleEngineAgentPanelEnd(id, d.rec(id.taskId)?.cycle);
|
|
629
|
+
}
|
|
630
|
+
function flushHeld(d, wireTaskId) {
|
|
631
|
+
const held = d.pending.get(wireTaskId);
|
|
632
|
+
if (held === undefined)
|
|
633
|
+
return;
|
|
634
|
+
d.pending.delete(wireTaskId);
|
|
635
|
+
if (isPublishedWire(d, held.ev.taskId)) {
|
|
636
|
+
emit(d, asIsTick(d, held.ev));
|
|
637
|
+
return;
|
|
638
|
+
}
|
|
639
|
+
const id = resolve(d, held.ev.taskId, held.ev.parentToolCallId, true);
|
|
640
|
+
if (id.origin === 'fleet-row') {
|
|
641
|
+
if (staleWireTick(d, id))
|
|
642
|
+
return;
|
|
643
|
+
rememberResolvedWire(d, held.ev.taskId, id);
|
|
644
|
+
emit(d, normalizedTick(d, held.ev, id.taskId));
|
|
645
|
+
return;
|
|
646
|
+
}
|
|
647
|
+
emit(d, asIsTick(d, held.ev));
|
|
648
|
+
}
|
|
649
|
+
function notePanelRowRunning(d, taskId) {
|
|
650
|
+
if (d.rec(taskId)?.running === true)
|
|
651
|
+
return;
|
|
652
|
+
d.put(taskId, { running: true });
|
|
653
|
+
}
|
|
654
|
+
function panelRowUnknownToConsumer(d, taskId) {
|
|
655
|
+
const r = d.rec(taskId);
|
|
656
|
+
return !d.overflowed && r?.running !== true && r?.ended === undefined;
|
|
657
|
+
}
|
|
658
|
+
function notePanelRowEnded(d, taskId, cycle, older) {
|
|
659
|
+
const existing = d.rec(taskId)?.ended;
|
|
660
|
+
if (existing !== undefined && older)
|
|
661
|
+
return;
|
|
662
|
+
d.put(taskId, { ended: mergeCycle(cycleOf(cycle), existing) });
|
|
663
|
+
}
|
|
664
|
+
function settleRowHistory(d, taskId, cycle) {
|
|
665
|
+
d.put(taskId, { running: undefined });
|
|
666
|
+
notePanelRowEnded(d, taskId, cycle, isStaleEngineAgentPanelEnd(cycle, d.rec(taskId)?.ended));
|
|
667
|
+
}
|
|
668
|
+
function endOlderThanKnown(d, end, taskId, rowCycle) {
|
|
669
|
+
return isStaleEngineAgentPanelEnd(end, rowCycle) || isStaleEngineAgentPanelEnd(end, d.rec(taskId)?.ended);
|
|
670
|
+
}
|
|
671
|
+
function heldRowConsumerKey(d, tail, held) {
|
|
672
|
+
const owner = d.rec(tail)?.ownedBy;
|
|
673
|
+
if (owner !== undefined)
|
|
674
|
+
return owner.wireId;
|
|
675
|
+
return publishedWireFor(d, held) ?? tail;
|
|
676
|
+
}
|
|
677
|
+
function heldVerdict(d, taskId, endCycle) {
|
|
678
|
+
const held = d.rec(taskId)?.held;
|
|
679
|
+
if (held === undefined)
|
|
680
|
+
return 'none';
|
|
681
|
+
const o = cycleOrder(endCycle, held);
|
|
682
|
+
if (o === 'before')
|
|
683
|
+
return 'keep';
|
|
684
|
+
if (o === 'after')
|
|
685
|
+
return 'drop';
|
|
686
|
+
return 'release';
|
|
687
|
+
}
|
|
688
|
+
function heldRowReleasesOntoSameKey(d, tail, end) {
|
|
689
|
+
const held = d.rec(tail)?.held;
|
|
690
|
+
if (held === undefined)
|
|
691
|
+
return false;
|
|
692
|
+
const rowKey = heldRowConsumerKey(d, tail, held);
|
|
693
|
+
if (rowKey === end.taskId)
|
|
694
|
+
return true;
|
|
695
|
+
return rowKey === tail && held.transcriptId === end.taskId && !isPublishedWire(d, end.taskId);
|
|
696
|
+
}
|
|
697
|
+
function releaseHeld(d, taskId, endCycle) {
|
|
698
|
+
const verdict = heldVerdict(d, taskId, endCycle);
|
|
699
|
+
if (verdict === 'drop') {
|
|
700
|
+
d.put(taskId, { held: undefined });
|
|
701
|
+
return;
|
|
702
|
+
}
|
|
703
|
+
if (verdict !== 'release')
|
|
704
|
+
return;
|
|
705
|
+
const held = d.rec(taskId)?.held;
|
|
706
|
+
if (held === undefined)
|
|
707
|
+
return;
|
|
708
|
+
d.put(taskId, { held: undefined });
|
|
709
|
+
publish(d, held);
|
|
710
|
+
}
|
|
711
|
+
function publish(d, ev) {
|
|
712
|
+
if (ev.kind === 'end' || ev.kind === 'sweep')
|
|
713
|
+
ageHeld(d, ev.kind === 'sweep' ? undefined : ev.taskId);
|
|
714
|
+
switch (ev.kind) {
|
|
715
|
+
case 'fleet-row':
|
|
716
|
+
return publishFleetRow(d, ev);
|
|
717
|
+
case 'tick':
|
|
718
|
+
return publishTick(d, ev);
|
|
719
|
+
case 'end':
|
|
720
|
+
return publishEnd(d, ev);
|
|
721
|
+
default:
|
|
722
|
+
emit(d, ev);
|
|
723
|
+
}
|
|
724
|
+
}
|
|
725
|
+
function publishFleetRow(d, ev) {
|
|
726
|
+
const rowCycle = cycleOf(ev);
|
|
727
|
+
const published = wireOwnerOf(d, ev.taskId, rowCycle, ev.transcriptId) ?? publishedWireFor(d, ev);
|
|
728
|
+
if (published !== undefined && published !== ev.taskId) {
|
|
729
|
+
const prev = d.rec(ev.taskId)?.ownedBy;
|
|
730
|
+
const transcriptId = ev.transcriptId ?? prev?.transcriptId;
|
|
731
|
+
d.put(ev.taskId, { ownedBy: { wireId: published, retired: prev?.wireId === published ? prev.retired : false, ...(transcriptId !== undefined ? { transcriptId } : {}) } });
|
|
732
|
+
const tailAnchor = d.rec(ev.taskId)?.anchor;
|
|
733
|
+
if (tailAnchor !== undefined && tailAnchor === (transcriptId ?? published)) {
|
|
734
|
+
d.put(published, { anchor: tailAnchor });
|
|
735
|
+
d.put(ev.taskId, { anchor: undefined });
|
|
736
|
+
}
|
|
737
|
+
const prior = d.rec(published)?.cycle;
|
|
738
|
+
if (cycleOrder(rowCycle, prior) !== 'before')
|
|
739
|
+
d.put(published, { cycle: cycleEmpty(rowCycle) ? undefined : rowCycle });
|
|
740
|
+
emit(d, { ...ev, taskId: published, wireTaskId: ev.taskId, taskIdOrigin: 'wire' }, prior);
|
|
741
|
+
ageHeld(d, undefined);
|
|
742
|
+
return;
|
|
743
|
+
}
|
|
744
|
+
const prior = d.rec(ev.taskId)?.cycle;
|
|
745
|
+
if (!cycleEmpty(rowCycle) && cycleOrder(rowCycle, prior) !== 'before')
|
|
746
|
+
d.put(ev.taskId, { cycle: rowCycle });
|
|
747
|
+
const alias = { to: ev.taskId, ...(cycleEmpty(rowCycle) ? {} : { cycle: rowCycle }) };
|
|
748
|
+
if (ev.transcriptId !== undefined && ev.transcriptId.length > 0)
|
|
749
|
+
d.aliasSet('t', ev.transcriptId, alias);
|
|
750
|
+
if (ev.parentToolCallId !== undefined && ev.parentToolCallId.length > 0)
|
|
751
|
+
d.aliasSet('p', ev.parentToolCallId, alias);
|
|
752
|
+
emit(d, ev, prior);
|
|
753
|
+
for (const [wireId, held] of [...d.pending.entries()]) {
|
|
754
|
+
if (wireId === ev.transcriptId || (held.ev.parentToolCallId !== undefined && held.ev.parentToolCallId === ev.parentToolCallId))
|
|
755
|
+
flushHeld(d, wireId);
|
|
756
|
+
}
|
|
757
|
+
ageHeld(d, undefined);
|
|
758
|
+
}
|
|
759
|
+
function publishTick(d, ev) {
|
|
760
|
+
if (isPublishedWire(d, ev.taskId)) {
|
|
761
|
+
d.pending.delete(ev.taskId);
|
|
762
|
+
emit(d, asIsTick(d, ev));
|
|
763
|
+
return;
|
|
764
|
+
}
|
|
765
|
+
const id = resolve(d, ev.taskId, ev.parentToolCallId, true);
|
|
766
|
+
if (id.origin === 'fleet-row') {
|
|
767
|
+
d.pending.delete(ev.taskId);
|
|
768
|
+
if (staleWireTick(d, id))
|
|
769
|
+
return;
|
|
770
|
+
rememberResolvedWire(d, ev.taskId, id);
|
|
771
|
+
emit(d, normalizedTick(d, ev, id.taskId));
|
|
772
|
+
return;
|
|
773
|
+
}
|
|
774
|
+
if (ev.cardBound === true) {
|
|
775
|
+
emit(d, asIsTick(d, ev));
|
|
776
|
+
return;
|
|
777
|
+
}
|
|
778
|
+
if (d.pending.has(ev.taskId)) {
|
|
779
|
+
d.pending.delete(ev.taskId);
|
|
780
|
+
emit(d, asIsTick(d, ev));
|
|
781
|
+
return;
|
|
782
|
+
}
|
|
783
|
+
if (d.pending.size >= MAX_HELD_WIRE_TICKS) {
|
|
784
|
+
const oldest = d.pending.first(() => true);
|
|
785
|
+
if (oldest !== undefined)
|
|
786
|
+
flushHeld(d, oldest);
|
|
787
|
+
}
|
|
788
|
+
d.pending.set(ev.taskId, { ev, beats: 0 });
|
|
789
|
+
}
|
|
790
|
+
function publishEnd(d, ev) {
|
|
791
|
+
releaseHeld(d, ev.taskId, ev);
|
|
792
|
+
{
|
|
793
|
+
const pre = resolve(d, ev.taskId, undefined, true);
|
|
794
|
+
if (pre.origin === 'fleet-row' && pre.taskId !== ev.taskId) {
|
|
795
|
+
releaseHeld(d, pre.taskId, mergeCycle(cycleOf(ev), cycleOf(pre)));
|
|
796
|
+
}
|
|
797
|
+
const owners = d.ownedTails(ev.taskId).filter((fleetId) => d.rec(fleetId)?.ownedBy?.retired === false);
|
|
798
|
+
for (const fleetId of owners)
|
|
799
|
+
releaseHeld(d, fleetId, ev);
|
|
800
|
+
const heldMatches = [];
|
|
801
|
+
if (d.counts.held > 0)
|
|
802
|
+
for (const [tail, r] of d.records.entries()) {
|
|
803
|
+
const held = r.held;
|
|
804
|
+
if (held === undefined || tail === ev.taskId)
|
|
805
|
+
continue;
|
|
806
|
+
const byTranscript = typeof held.transcriptId === 'string' && held.transcriptId.length > 0 && held.transcriptId === ev.taskId;
|
|
807
|
+
const byParent = typeof held.parentToolCallId === 'string' && held.parentToolCallId.length > 0 &&
|
|
808
|
+
d.aliasGet('w', held.parentToolCallId, false)?.to === ev.taskId &&
|
|
809
|
+
d.rec(ev.taskId)?.wire?.retired === false;
|
|
810
|
+
if (byTranscript || byParent)
|
|
811
|
+
heldMatches.push(tail);
|
|
812
|
+
}
|
|
813
|
+
const releasable = [];
|
|
814
|
+
for (const tail of heldMatches) {
|
|
815
|
+
const verdict = heldVerdict(d, tail, ev);
|
|
816
|
+
if (verdict === 'drop')
|
|
817
|
+
d.put(tail, { held: undefined });
|
|
818
|
+
else if (verdict === 'release' && heldRowReleasesOntoSameKey(d, tail, ev))
|
|
819
|
+
releasable.push(tail);
|
|
820
|
+
}
|
|
821
|
+
if (releasable.length === 1)
|
|
822
|
+
releaseHeld(d, releasable[0], ev);
|
|
823
|
+
}
|
|
824
|
+
const wireOwner = wireOwnerOf(d, ev.taskId, ev);
|
|
825
|
+
if (wireOwner !== undefined) {
|
|
826
|
+
const staleA = endOlderThanKnown(d, ev, ev.taskId, d.rec(wireOwner)?.cycle) || isStaleEngineAgentPanelEnd(ev, d.rec(wireOwner)?.ended);
|
|
827
|
+
emit(d, { ...ev, taskId: wireOwner, wireTaskId: ev.taskId, taskIdOrigin: 'wire' });
|
|
828
|
+
if (!staleA) {
|
|
829
|
+
retireWire(d, wireOwner);
|
|
830
|
+
settleRowHistory(d, ev.taskId, ev);
|
|
831
|
+
settleRowHistory(d, wireOwner, ev);
|
|
832
|
+
}
|
|
833
|
+
return;
|
|
834
|
+
}
|
|
835
|
+
if (isPublishedWire(d, ev.taskId)) {
|
|
836
|
+
flushHeld(d, ev.taskId);
|
|
837
|
+
const ownedFleetIds = d.ownedTails(ev.taskId).filter((fleetId) => !endOlderThanKnown(d, ev, fleetId, d.rec(ev.taskId)?.cycle));
|
|
838
|
+
const alias = d.aliasGet('t', ev.taskId, false);
|
|
839
|
+
if (alias !== undefined && !endOlderThanKnown(d, ev, alias.to, alias.cycle) && !ownedFleetIds.includes(alias.to))
|
|
840
|
+
ownedFleetIds.push(alias.to);
|
|
841
|
+
emit(d, ev);
|
|
842
|
+
retireWire(d, ev.taskId);
|
|
843
|
+
if (!isStaleEngineAgentPanelEnd(ev, d.rec(ev.taskId)?.ended))
|
|
844
|
+
settleRowHistory(d, ev.taskId, ev);
|
|
845
|
+
for (const fleetId of ownedFleetIds)
|
|
846
|
+
settleRowHistory(d, fleetId, ev);
|
|
847
|
+
return;
|
|
848
|
+
}
|
|
849
|
+
const id = resolve(d, ev.taskId, undefined, true);
|
|
850
|
+
if (id.origin === 'fleet-row' && id.taskId !== ev.taskId) {
|
|
851
|
+
flushHeld(d, ev.taskId);
|
|
852
|
+
migrateResidency(d, ev.taskId, id.taskId);
|
|
853
|
+
const effectiveEnd = mergeCycle(cycleOf(ev), cycleOf(id));
|
|
854
|
+
const staleC = endOlderThanKnown(d, effectiveEnd, id.taskId, d.rec(id.taskId)?.cycle);
|
|
855
|
+
emit(d, { ...ev, taskId: id.taskId, wireTaskId: ev.taskId, taskIdOrigin: 'fleet-row', ...effectiveEnd });
|
|
856
|
+
if (!staleC)
|
|
857
|
+
settleRowHistory(d, id.taskId, effectiveEnd);
|
|
858
|
+
return;
|
|
859
|
+
}
|
|
860
|
+
flushHeld(d, ev.taskId);
|
|
861
|
+
const staleD = endOlderThanKnown(d, ev, ev.taskId, d.rec(ev.taskId)?.cycle);
|
|
862
|
+
emit(d, ev);
|
|
863
|
+
retireWire(d, ev.taskId);
|
|
864
|
+
if (!staleD)
|
|
865
|
+
settleRowHistory(d, ev.taskId, ev);
|
|
866
|
+
}
|
|
867
|
+
function publishAbsence(d, a) {
|
|
868
|
+
const owner = wireOwnerOf(d, a.taskId);
|
|
869
|
+
const ev = owner !== undefined ? { ...a, taskId: owner, wireTaskId: a.taskId } : a;
|
|
870
|
+
d.facts.push({ ch: 'absence', absence: ev });
|
|
871
|
+
foldAbsence(d, ev);
|
|
872
|
+
}
|
|
873
|
+
function clearResidentByWire(d, wireTaskId, cycle) {
|
|
874
|
+
d.put(wireTaskId, { resident: undefined });
|
|
875
|
+
const owner = d.rec(wireTaskId)?.ownedBy;
|
|
876
|
+
if (owner !== undefined && !(cycle !== undefined && isStaleEngineAgentPanelEnd(cycle, d.rec(owner.wireId)?.cycle)))
|
|
877
|
+
d.put(owner.wireId, { resident: undefined });
|
|
878
|
+
const id = resolve(d, wireTaskId, undefined, true);
|
|
879
|
+
if (id.taskId === wireTaskId)
|
|
880
|
+
return;
|
|
881
|
+
if (isStaleEngineAgentPanelEnd(id, d.rec(id.taskId)?.cycle))
|
|
882
|
+
return;
|
|
883
|
+
d.put(id.taskId, { resident: undefined });
|
|
884
|
+
}
|
|
885
|
+
function currentToolKeyOf(ct) {
|
|
886
|
+
if (!ct || typeof ct.toolName !== 'string' || ct.toolName.length === 0)
|
|
887
|
+
return undefined;
|
|
888
|
+
return `${ct.toolName}\u0000${ct.target ?? ''}`;
|
|
889
|
+
}
|
|
890
|
+
function project(d, sessionKey, rows, nowMs) {
|
|
891
|
+
const seen = d.session(sessionKey);
|
|
892
|
+
const present = new Set();
|
|
893
|
+
for (const row of rows) {
|
|
894
|
+
if (!row?.id)
|
|
895
|
+
continue;
|
|
896
|
+
const taskId = rowIdTail(row.id);
|
|
897
|
+
if (!taskId)
|
|
898
|
+
continue;
|
|
899
|
+
present.add(taskId);
|
|
900
|
+
const status = row.status ?? 'running';
|
|
901
|
+
const tokens = typeof row.tokens === 'number' && Number.isInteger(row.tokens) && row.tokens >= 0 ? row.tokens : undefined;
|
|
902
|
+
const toolUses = typeof row.toolUses === 'number' ? row.toolUses : undefined;
|
|
903
|
+
const transcriptId = row.transcriptId || undefined;
|
|
904
|
+
const parentToolCallId = typeof row.parentToolCallId === 'string' && row.parentToolCallId.length > 0 ? row.parentToolCallId : undefined;
|
|
905
|
+
const frameCycle = cycleOf(row);
|
|
906
|
+
const currentTool = currentToolKeyOf(row.currentTool) !== undefined ? row.currentTool : undefined;
|
|
907
|
+
const currentToolKey = currentToolKeyOf(row.currentTool);
|
|
908
|
+
const prev = seen.get(taskId);
|
|
909
|
+
const prevCycle = prev !== undefined ? (d.rec(taskId)?.cycle ?? {}) : undefined;
|
|
910
|
+
const order = prev !== undefined ? cycleOrder(frameCycle, prevCycle) : 'unknown';
|
|
911
|
+
if (order === 'before')
|
|
912
|
+
continue;
|
|
913
|
+
const rowNewer = order === 'after';
|
|
914
|
+
const sameCycle = prev !== undefined && !prev.settled && (order === 'same' || order === 'unknown');
|
|
915
|
+
const knownTokens = tokens !== undefined ? tokens : sameCycle ? prev?.tokens : undefined;
|
|
916
|
+
const known = carryCycle(frameCycle, prevCycle, prev !== undefined && !rowNewer);
|
|
917
|
+
const knownFields = {
|
|
918
|
+
...(known.startedAt !== undefined ? { startedAt: known.startedAt } : {}),
|
|
919
|
+
...(known.cycleSeq !== undefined ? { cycleSeq: known.cycleSeq } : {}),
|
|
920
|
+
};
|
|
921
|
+
const base = {
|
|
922
|
+
kind: 'fleet-row',
|
|
923
|
+
taskId,
|
|
924
|
+
...(row.name ? { name: row.name } : {}),
|
|
925
|
+
...(row.description ? { description: row.description } : {}),
|
|
926
|
+
...(knownTokens !== undefined ? { totalTokens: knownTokens } : {}),
|
|
927
|
+
...(toolUses !== undefined ? { toolUses } : {}),
|
|
928
|
+
...(transcriptId !== undefined ? { transcriptId } : {}),
|
|
929
|
+
...(parentToolCallId !== undefined ? { parentToolCallId } : {}),
|
|
930
|
+
...knownFields,
|
|
931
|
+
};
|
|
932
|
+
if (isSdkFleetTaskTerminal(status)) {
|
|
933
|
+
const wireEnded = transcriptId !== undefined ? d.rec(transcriptId)?.ended : undefined;
|
|
934
|
+
const endedViaWire = wireEnded !== undefined && cycleOrder(wireEnded, frameCycle) !== 'before';
|
|
935
|
+
const newbornTerminal = prev === undefined && panelRowUnknownToConsumer(d, taskId) && !endedViaWire;
|
|
936
|
+
const settledThisCycle = prev?.settled === true && !rowNewer;
|
|
937
|
+
const endedRec = prev === undefined ? d.rec(taskId)?.ended : undefined;
|
|
938
|
+
if (endedRec !== undefined && cycleOrder(frameCycle, endedRec) === 'before')
|
|
939
|
+
continue;
|
|
940
|
+
const endedSameCycle = endedRec !== undefined && cycleOrder(endedRec, frameCycle) !== 'before';
|
|
941
|
+
if (newbornTerminal) {
|
|
942
|
+
d.put(taskId, { held: base });
|
|
943
|
+
}
|
|
944
|
+
else if (!settledThisCycle) {
|
|
945
|
+
if (rowNewer ||
|
|
946
|
+
cycleKeysChanged(prevCycle, frameCycle) ||
|
|
947
|
+
(tokens !== undefined && prev?.tokens !== tokens) ||
|
|
948
|
+
(toolUses !== undefined && prev?.toolUses !== toolUses) ||
|
|
949
|
+
(transcriptId !== undefined && prev?.transcriptId !== transcriptId) ||
|
|
950
|
+
(parentToolCallId !== undefined && prev?.parentToolCallId !== parentToolCallId)) {
|
|
951
|
+
publish(d, base);
|
|
952
|
+
}
|
|
953
|
+
if (!endedSameCycle)
|
|
954
|
+
publish(d, panelEndFact(taskId, isSdkFleetTaskTerminalNotSuccess(status), known));
|
|
955
|
+
}
|
|
956
|
+
d.put(taskId, { cycle: cycleEmpty(known) ? undefined : known });
|
|
957
|
+
seen.set(taskId, {
|
|
958
|
+
status,
|
|
959
|
+
tokens: knownTokens,
|
|
960
|
+
toolUses: toolUses !== undefined ? toolUses : prev?.toolUses,
|
|
961
|
+
transcriptId: transcriptId !== undefined ? transcriptId : prev?.transcriptId,
|
|
962
|
+
parentToolCallId: parentToolCallId !== undefined ? parentToolCallId : prev?.parentToolCallId,
|
|
963
|
+
currentToolKey: currentToolKey !== undefined ? currentToolKey : prev?.currentToolKey,
|
|
964
|
+
lastSeenAt: nowMs,
|
|
965
|
+
settled: true,
|
|
966
|
+
settledAtMs: prev?.settled ? prev.settledAtMs : nowMs,
|
|
967
|
+
absentReportedAtMs: undefined,
|
|
968
|
+
});
|
|
969
|
+
continue;
|
|
970
|
+
}
|
|
971
|
+
if (prev !== undefined && prev.settled && order === 'same' && d.rec(taskId)?.held !== undefined)
|
|
972
|
+
continue;
|
|
973
|
+
if (!prev ||
|
|
974
|
+
prev.settled ||
|
|
975
|
+
prev.absentReportedAtMs !== undefined ||
|
|
976
|
+
prev.status !== status ||
|
|
977
|
+
prev.tokens !== knownTokens ||
|
|
978
|
+
(toolUses !== undefined && prev.toolUses !== toolUses) ||
|
|
979
|
+
(transcriptId !== undefined && prev.transcriptId !== transcriptId) ||
|
|
980
|
+
(parentToolCallId !== undefined && prev.parentToolCallId !== parentToolCallId) ||
|
|
981
|
+
cycleKeysChanged(prevCycle, frameCycle) ||
|
|
982
|
+
(currentToolKey !== undefined && prev.currentToolKey !== currentToolKey)) {
|
|
983
|
+
notePanelRowRunning(d, taskId);
|
|
984
|
+
d.put(taskId, { held: undefined });
|
|
985
|
+
publish(d, { ...base, ...(currentTool !== undefined ? { currentTool } : {}) });
|
|
986
|
+
}
|
|
987
|
+
d.put(taskId, { cycle: cycleEmpty(known) ? undefined : known });
|
|
988
|
+
seen.set(taskId, {
|
|
989
|
+
status,
|
|
990
|
+
tokens: knownTokens,
|
|
991
|
+
toolUses: toolUses !== undefined ? toolUses : prev?.toolUses,
|
|
992
|
+
transcriptId: transcriptId !== undefined ? transcriptId : prev?.transcriptId,
|
|
993
|
+
parentToolCallId: parentToolCallId !== undefined ? parentToolCallId : prev?.parentToolCallId,
|
|
994
|
+
currentToolKey: currentToolKey !== undefined ? currentToolKey : prev?.currentToolKey,
|
|
995
|
+
lastSeenAt: nowMs,
|
|
996
|
+
settled: false,
|
|
997
|
+
settledAtMs: undefined,
|
|
998
|
+
absentReportedAtMs: undefined,
|
|
999
|
+
});
|
|
1000
|
+
}
|
|
1001
|
+
for (const [taskId, s] of [...seen.entries()]) {
|
|
1002
|
+
if (present.has(taskId) || s.settled || s.absentReportedAtMs !== undefined)
|
|
1003
|
+
continue;
|
|
1004
|
+
const absentForMs = nowMs - s.lastSeenAt;
|
|
1005
|
+
if (absentForMs <= ABSENT_SETTLE_MS)
|
|
1006
|
+
continue;
|
|
1007
|
+
publishAbsence(d, { taskId, lastSeenAtMs: s.lastSeenAt, absentForMs });
|
|
1008
|
+
seen.set(taskId, { ...s, absentReportedAtMs: nowMs });
|
|
1009
|
+
}
|
|
1010
|
+
for (const [taskId, s] of [...seen.entries()]) {
|
|
1011
|
+
if (present.has(taskId))
|
|
1012
|
+
continue;
|
|
1013
|
+
if (s.settled) {
|
|
1014
|
+
const settledAt = s.settledAtMs ?? s.lastSeenAt;
|
|
1015
|
+
if (nowMs - settledAt > SETTLED_RETENTION_MS)
|
|
1016
|
+
seen.delete(taskId);
|
|
1017
|
+
}
|
|
1018
|
+
else if (s.absentReportedAtMs !== undefined && nowMs - s.absentReportedAtMs > SETTLED_RETENTION_MS) {
|
|
1019
|
+
seen.delete(taskId);
|
|
1020
|
+
}
|
|
1021
|
+
}
|
|
1022
|
+
d.putSession(sessionKey, seen);
|
|
1023
|
+
}
|
|
1024
|
+
export function stepPanelFrame(state, frame) {
|
|
1025
|
+
const d = new Step(impl(state));
|
|
1026
|
+
switch (frame.kind) {
|
|
1027
|
+
case 'tick':
|
|
1028
|
+
case 'fleet-row':
|
|
1029
|
+
case 'end':
|
|
1030
|
+
case 'sweep':
|
|
1031
|
+
publish(d, frame);
|
|
1032
|
+
break;
|
|
1033
|
+
case 'fleet-rows':
|
|
1034
|
+
project(d, frame.sessionKey, frame.rows, frame.nowMs);
|
|
1035
|
+
break;
|
|
1036
|
+
case 'fleet-rows-reset':
|
|
1037
|
+
d.dropSessions(frame.sessionKey);
|
|
1038
|
+
if (frame.sessionKey === undefined) {
|
|
1039
|
+
for (const [k, r] of [...d.records.entries()]) {
|
|
1040
|
+
if (r.running !== undefined || r.ended !== undefined || r.held !== undefined)
|
|
1041
|
+
d.put(k, { running: undefined, ended: undefined, held: undefined });
|
|
1042
|
+
}
|
|
1043
|
+
d.overflowed = false;
|
|
1044
|
+
}
|
|
1045
|
+
break;
|
|
1046
|
+
case 'absence':
|
|
1047
|
+
publishAbsence(d, frame.absence);
|
|
1048
|
+
break;
|
|
1049
|
+
case 'resident':
|
|
1050
|
+
d.put(frame.taskId, { resident: frame.resident ? true : undefined });
|
|
1051
|
+
break;
|
|
1052
|
+
case 'resident-clear-wire':
|
|
1053
|
+
clearResidentByWire(d, frame.taskId, frame.cycle);
|
|
1054
|
+
break;
|
|
1055
|
+
case 'anchor':
|
|
1056
|
+
if (frame.taskId && frame.transcriptId)
|
|
1057
|
+
d.put(anchorKeyOf(d, frame.taskId), { anchor: frame.transcriptId });
|
|
1058
|
+
break;
|
|
1059
|
+
}
|
|
1060
|
+
boundFields(d);
|
|
1061
|
+
return { state: d.freeze(), deltas: d.deltas, facts: d.facts };
|
|
1062
|
+
}
|
|
1063
|
+
export function reducePanelFrame(state, frame) {
|
|
1064
|
+
const r = stepPanelFrame(state, frame);
|
|
1065
|
+
return { state: r.state, deltas: r.deltas };
|
|
1066
|
+
}
|
|
1067
|
+
export function panelRowSnapshot(state) {
|
|
1068
|
+
const out = [];
|
|
1069
|
+
for (const [key, r] of impl(state).records.entries()) {
|
|
1070
|
+
const row = r.row;
|
|
1071
|
+
if (row === undefined || !row.announced)
|
|
1072
|
+
continue;
|
|
1073
|
+
out.push({ op: 'upsert', canonicalId: key, created: true, fields: { ...row.fields } });
|
|
1074
|
+
const u = usageDelta(key, undefined, row.totalTokens, row.toolUses);
|
|
1075
|
+
if (u !== undefined)
|
|
1076
|
+
out.push(u);
|
|
1077
|
+
if (row.phase === 'ended')
|
|
1078
|
+
out.push(terminalDelta(key, row.isError === true, row.report, row.cause ?? 'end'));
|
|
1079
|
+
}
|
|
1080
|
+
return out;
|
|
1081
|
+
}
|
|
1082
|
+
export function panelResolveTaskId(state, wireTaskId, parentToolCallId) {
|
|
1083
|
+
const s = impl(state);
|
|
1084
|
+
const byT = s.alias.get(`t:${wireTaskId}`);
|
|
1085
|
+
if (byT !== undefined)
|
|
1086
|
+
return identityOf(byT);
|
|
1087
|
+
const byP = parentToolCallId !== undefined ? s.alias.get(`p:${parentToolCallId}`) : undefined;
|
|
1088
|
+
if (byP !== undefined)
|
|
1089
|
+
return identityOf(byP);
|
|
1090
|
+
return { taskId: wireTaskId, origin: 'wire' };
|
|
1091
|
+
}
|
|
1092
|
+
export function panelIsResident(state, taskId) {
|
|
1093
|
+
return impl(state).records.get(taskId)?.resident === true;
|
|
1094
|
+
}
|
|
1095
|
+
function anchorKeyOf(d, taskId) {
|
|
1096
|
+
const o = d.rec(taskId)?.ownedBy;
|
|
1097
|
+
return o !== undefined && !o.retired ? o.wireId : taskId;
|
|
1098
|
+
}
|
|
1099
|
+
export function panelAnchorOf(state, taskId) {
|
|
1100
|
+
const recs = impl(state).records;
|
|
1101
|
+
const own = recs.get(taskId);
|
|
1102
|
+
if (own?.anchor !== undefined)
|
|
1103
|
+
return own.anchor;
|
|
1104
|
+
return own?.ownedBy !== undefined ? recs.get(own.ownedBy.wireId)?.anchor : undefined;
|
|
1105
|
+
}
|
|
1106
|
+
export function panelPresenceSize(state, sessionKey) {
|
|
1107
|
+
return impl(state).sessions.get(sessionKey)?.size ?? 0;
|
|
1108
|
+
}
|
|
1109
|
+
export function panelClearIdentity(state) {
|
|
1110
|
+
const d = new Step(impl(state));
|
|
1111
|
+
for (const [k] of [...d.alias.entries()])
|
|
1112
|
+
d.alias.delete(k);
|
|
1113
|
+
d.counts.alias = { t: 0, p: 0, w: 0 };
|
|
1114
|
+
for (const [k] of [...d.pending.entries()])
|
|
1115
|
+
d.pending.delete(k);
|
|
1116
|
+
for (const [k, r] of [...d.records.entries()]) {
|
|
1117
|
+
if (r.cycle !== undefined || r.wire !== undefined || r.ownedBy !== undefined)
|
|
1118
|
+
d.put(k, { cycle: undefined, wire: undefined, ownedBy: undefined });
|
|
1119
|
+
}
|
|
1120
|
+
return d.freeze();
|
|
1121
|
+
}
|
|
1122
|
+
export function panelClearAnchors(state) {
|
|
1123
|
+
const d = new Step(impl(state));
|
|
1124
|
+
for (const [k, r] of [...d.records.entries()])
|
|
1125
|
+
if (r.anchor !== undefined)
|
|
1126
|
+
d.put(k, { anchor: undefined });
|
|
1127
|
+
return d.freeze();
|
|
1128
|
+
}
|
|
1129
|
+
export function panelClearRows(state) {
|
|
1130
|
+
const d = new Step(impl(state));
|
|
1131
|
+
for (const [k, r] of [...d.records.entries()])
|
|
1132
|
+
if (r.row !== undefined)
|
|
1133
|
+
d.put(k, { row: undefined });
|
|
1134
|
+
return d.freeze();
|
|
1135
|
+
}
|