@sema-agent/client-core 0.97.1 → 0.99.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.
Files changed (353) hide show
  1. package/CHANGELOG.md +607 -0
  2. package/README.md +96 -46
  3. package/dist/adapt/arms.d.ts +1 -0
  4. package/dist/adapt/arms.js +188 -53
  5. package/dist/adapt/ids.d.ts +12 -1
  6. package/dist/adapt/ids.js +59 -8
  7. package/dist/adapt/instanceLedger.d.ts +50 -0
  8. package/dist/adapt/instanceLedger.js +147 -0
  9. package/dist/adapt/panelTasks.d.ts +1 -1
  10. package/dist/adapt/panelTasks.js +2 -2
  11. package/dist/adapt/textStream.d.ts +1 -0
  12. package/dist/adapt/textStream.js +24 -7
  13. package/dist/adapt/toolCards.d.ts +27 -5
  14. package/dist/adapt/toolCards.js +39 -6
  15. package/dist/adapt/wireShapes.js +6 -2
  16. package/dist/adapt.d.ts +2 -0
  17. package/dist/adapt.js +8 -3
  18. package/dist/adapter/activeRunSelfHeal.d.ts +9 -3
  19. package/dist/adapter/activeRunSelfHeal.js +205 -313
  20. package/dist/adapter/downstream/eventToSdkMessage.d.ts +2 -5
  21. package/dist/adapter/downstream/eventToSdkMessage.js +77 -36
  22. package/dist/adapter/downstream/terminalToSdkResult.js +11 -4
  23. package/dist/adapter/downstream/turnUsageToModelUsage.d.ts +5 -2
  24. package/dist/adapter/downstream/turnUsageToModelUsage.js +2 -0
  25. package/dist/adapter/runStream.js +79 -48
  26. package/dist/adapter/types.d.ts +4 -4
  27. package/dist/adapter/types.js +2 -1
  28. package/dist/agentSession/backgroundView.js +2 -1
  29. package/dist/agentSession/engineAgentRegistryRead.d.ts +2 -2
  30. package/dist/agentSession/engineAgentRegistryRead.js +12 -13
  31. package/dist/agentSession/engineSessionBackgroundStop.js +16 -8
  32. package/dist/agentsWireCaps.d.ts +8 -11
  33. package/dist/agentsWireCaps.js +196 -194
  34. package/dist/approvalDecidedByCapability.d.ts +0 -4
  35. package/dist/approvalDecidedByCapability.js +0 -6
  36. package/dist/approvalsStreamLiveCapability.d.ts +0 -4
  37. package/dist/approvalsStreamLiveCapability.js +0 -6
  38. package/dist/assistantInbox.d.ts +34 -0
  39. package/dist/assistantInbox.js +118 -0
  40. package/dist/centerWiringCapability.js +9 -1
  41. package/dist/clientSlice.d.ts +0 -9
  42. package/dist/clientSlice.js +0 -3
  43. package/dist/cloudConfigWireCaps.d.ts +5 -3
  44. package/dist/cloudConfigWireCaps.js +106 -64
  45. package/dist/compensations.js +1 -1
  46. package/dist/connectorStatus.d.ts +21 -0
  47. package/dist/connectorStatus.js +112 -0
  48. package/dist/controlRouter.d.ts +18 -3
  49. package/dist/controlRouter.js +106 -67
  50. package/dist/coreValuePorts.d.ts +29 -4
  51. package/dist/coreValuePorts.js +10 -0
  52. package/dist/corruptSessionCopy.d.ts +2 -1
  53. package/dist/corruptSessionCopy.js +3 -3
  54. package/dist/decideReceipt.d.ts +2 -2
  55. package/dist/decideReceipt.js +5 -2
  56. package/dist/declared/supportFloorDeclared.js +3 -3
  57. package/dist/detachWire.js +3 -2
  58. package/dist/deviceExecutorManagementCapability.d.ts +0 -4
  59. package/dist/deviceExecutorManagementCapability.js +0 -6
  60. package/dist/deviceRebind.d.ts +49 -1
  61. package/dist/deviceRebind.js +221 -3
  62. package/dist/devicesFace.d.ts +34 -0
  63. package/dist/devicesFace.js +90 -0
  64. package/dist/displayUntrusted.d.ts +2 -0
  65. package/dist/displayUntrusted.js +253 -76
  66. package/dist/engineAgentAbsence.d.ts +1 -1
  67. package/dist/engineAgentPanelStore.d.ts +12 -4
  68. package/dist/engineAgentPanelStore.js +16 -11
  69. package/dist/engineCapReader.d.ts +2 -5
  70. package/dist/engineCapReader.js +8 -10
  71. package/dist/engineCapsCache.d.ts +12 -0
  72. package/dist/engineCapsCache.js +76 -18
  73. package/dist/engineCapsChange.d.ts +2 -0
  74. package/dist/engineCapsChange.js +9 -0
  75. package/dist/engineClosedSets.d.ts +1 -0
  76. package/dist/engineClosedSets.js +4 -1
  77. package/dist/engineErrorCodes.d.ts +11 -3
  78. package/dist/engineErrorCodes.js +11 -8
  79. package/dist/engineIdentity.d.ts +1 -0
  80. package/dist/engineIdentity.js +8 -0
  81. package/dist/engineRowRef.d.ts +28 -0
  82. package/dist/engineRowRef.js +114 -0
  83. package/dist/engineSessionMessages.d.ts +68 -0
  84. package/dist/engineSessionMessages.js +370 -0
  85. package/dist/engineTargetSeat.d.ts +27 -0
  86. package/dist/engineTargetSeat.js +199 -0
  87. package/dist/engineToolDirectory.d.ts +0 -9
  88. package/dist/engineToolDirectory.js +1 -94
  89. package/dist/engineUrl.d.ts +18 -0
  90. package/dist/engineUrl.js +52 -0
  91. package/dist/engineWireFor.js +3 -8
  92. package/dist/env/uiLanguage.d.ts +11 -1
  93. package/dist/env/uiLanguage.js +38 -2
  94. package/dist/eventLeg.d.ts +100 -0
  95. package/dist/eventLeg.js +305 -0
  96. package/dist/executionLaneCapability.d.ts +0 -4
  97. package/dist/executionLaneCapability.js +3 -16
  98. package/dist/fileHistoryCaptureCapability.d.ts +2 -5
  99. package/dist/fileHistoryCaptureCapability.js +13 -21
  100. package/dist/fileHistoryLegNotice.d.ts +2 -1
  101. package/dist/fileHistoryLegNotice.js +3 -3
  102. package/dist/fleet/fleetLedger.d.ts +0 -3
  103. package/dist/fleet/fleetLedger.js +21 -36
  104. package/dist/fleet/fleetProjection.d.ts +2 -2
  105. package/dist/fleet/fleetProjection.js +10 -8
  106. package/dist/frameBinding.d.ts +8 -0
  107. package/dist/frameBinding.js +35 -0
  108. package/dist/gateFailureCodes.d.ts +2 -0
  109. package/dist/gateFailureCodes.js +15 -0
  110. package/dist/gateOutcome.d.ts +3 -1
  111. package/dist/gateOutcome.js +41 -8
  112. package/dist/gateVocabulary.d.ts +10 -4
  113. package/dist/gateVocabulary.js +107 -47
  114. package/dist/generated/engineAskFaceTables.js +2 -2
  115. package/dist/generated/engineFactTables.d.ts +22 -3
  116. package/dist/generated/engineFactTables.js +51 -4
  117. package/dist/generated/engineNoticeTables.js +18 -3
  118. package/dist/generated/settingsSchemaFns.d.ts +6 -0
  119. package/dist/generated/settingsSchemaFns.js +57 -0
  120. package/dist/generated/settingsSchemaHooksClassifier.d.ts +2 -0
  121. package/dist/generated/settingsSchemaHooksClassifier.js +254 -0
  122. package/dist/generated/settingsSchemaTables.d.ts +1 -0
  123. package/dist/generated/settingsSchemaTables.js +4 -0
  124. package/dist/generated/settingsSchemaTypes.d.ts +105 -0
  125. package/dist/generated/settingsSchemaTypes.js +1 -0
  126. package/dist/generated/toolNameTables.d.ts +1 -0
  127. package/dist/generated/toolNameTables.js +1 -0
  128. package/dist/hitl/allowRuleShadow.d.ts +8 -2
  129. package/dist/hitl/allowRuleShadow.js +36 -29
  130. package/dist/hitl/approvalCardReading.d.ts +15 -0
  131. package/dist/hitl/approvalCardReading.js +154 -0
  132. package/dist/hitl/approvalCardReasons.d.ts +14 -0
  133. package/dist/hitl/approvalCardReasons.js +119 -0
  134. package/dist/hitl/approvalHolds.d.ts +50 -15
  135. package/dist/hitl/approvalHolds.js +177 -27
  136. package/dist/hitl/approvalResolution.d.ts +51 -26
  137. package/dist/hitl/approvalResolution.js +86 -122
  138. package/dist/hitl/approvalsFeed.js +6 -18
  139. package/dist/hitl/askClassPair.d.ts +2 -0
  140. package/dist/hitl/askClassPair.js +17 -0
  141. package/dist/hitl/askGateWire.d.ts +20 -2
  142. package/dist/hitl/askGateWire.js +50 -1
  143. package/dist/hitl/askParkRowRouting.d.ts +5 -0
  144. package/dist/hitl/askParkRowRouting.js +32 -1
  145. package/dist/hitl/askSettlementLine.d.ts +28 -0
  146. package/dist/hitl/askSettlementLine.js +99 -0
  147. package/dist/hitl/automaticAnswerVerdict.d.ts +3 -2
  148. package/dist/hitl/automaticAnswerVerdict.js +29 -13
  149. package/dist/hitl/crashConverged.d.ts +11 -20
  150. package/dist/hitl/crashConverged.js +56 -0
  151. package/dist/hitl/crashConvergedNotice.d.ts +6 -3
  152. package/dist/hitl/crashConvergedNotice.js +48 -24
  153. package/dist/hitl/decisionConflict.js +3 -10
  154. package/dist/hitl/decisionRefusal.d.ts +40 -1
  155. package/dist/hitl/decisionRefusal.js +199 -42
  156. package/dist/hitl/frameRouter.d.ts +5 -2
  157. package/dist/hitl/frameRouter.js +27 -24
  158. package/dist/hitl/gateLedger.d.ts +2 -0
  159. package/dist/hitl/gateLedger.js +50 -13
  160. package/dist/hitl/hitlBridge.d.ts +2 -2
  161. package/dist/hitl/hitlBridge.js +13 -10
  162. package/dist/hitl/livePendingAsk.d.ts +3 -3
  163. package/dist/hitl/livePendingAsk.js +7 -18
  164. package/dist/hitl/parkResolver.d.ts +2 -24
  165. package/dist/hitl/parkResolver.js +61 -97
  166. package/dist/hitl/persistedRulesWire.d.ts +25 -0
  167. package/dist/hitl/persistedRulesWire.js +104 -2
  168. package/dist/hitl/planReviewWire.d.ts +31 -13
  169. package/dist/hitl/planReviewWire.js +120 -78
  170. package/dist/hitl/refusedToolNameProse.d.ts +0 -1
  171. package/dist/hitl/refusedToolNameProse.js +0 -3
  172. package/dist/hitl/replayedApproval.d.ts +4 -3
  173. package/dist/hitl/replayedApproval.js +7 -4
  174. package/dist/hitl/sessionPolicyDeliverable.d.ts +2 -0
  175. package/dist/hitl/sessionPolicyDeliverable.js +48 -7
  176. package/dist/hitl/sessionPolicyWire.d.ts +34 -21
  177. package/dist/hitl/sessionPolicyWire.js +179 -70
  178. package/dist/hitl/standingRows.d.ts +20 -2
  179. package/dist/hitl/standingRows.js +69 -8
  180. package/dist/hitl/suspendedReopen.d.ts +2 -1
  181. package/dist/hitl/suspendedReopen.js +7 -10
  182. package/dist/hitl/toolApprovalWire.d.ts +103 -156
  183. package/dist/hitl/toolApprovalWire.js +661 -411
  184. package/dist/hookMatcherVerdict.d.ts +6 -1
  185. package/dist/hookMatcherVerdict.js +14 -7
  186. package/dist/hooksWireCaps.d.ts +2 -2
  187. package/dist/hooksWireCaps.js +174 -81
  188. package/dist/host.d.ts +21 -0
  189. package/dist/hostTurnSettings.d.ts +71 -0
  190. package/dist/hostTurnSettings.js +291 -0
  191. package/dist/humanTurn.d.ts +14 -1
  192. package/dist/humanTurn.js +100 -12
  193. package/dist/humanTurnRead.d.ts +2 -0
  194. package/dist/humanTurnRead.js +22 -1
  195. package/dist/i18n/messages.en.d.ts +703 -0
  196. package/dist/i18n/messages.en.js +701 -0
  197. package/dist/i18n/messages.zh.d.ts +3 -0
  198. package/dist/i18n/messages.zh.js +837 -0
  199. package/dist/i18n/translate.d.ts +25 -0
  200. package/dist/i18n/translate.js +127 -0
  201. package/dist/index.d.ts +78 -29
  202. package/dist/index.js +54 -18
  203. package/dist/inheritEnvCapability.d.ts +32 -0
  204. package/dist/inheritEnvCapability.js +104 -0
  205. package/dist/inheritEnvWire.d.ts +3 -2
  206. package/dist/inheritEnvWire.js +12 -14
  207. package/dist/interactiveHalt.js +17 -6
  208. package/dist/liveModelCatalog.d.ts +3 -3
  209. package/dist/liveModelCatalog.js +15 -13
  210. package/dist/liveQuestionStore.d.ts +2 -21
  211. package/dist/mcpLiveness.d.ts +2 -1
  212. package/dist/mcpPanel.d.ts +10 -1
  213. package/dist/mcpPanel.js +40 -13
  214. package/dist/mcpProbeCapability.d.ts +2 -1
  215. package/dist/mcpProbeCapability.js +7 -11
  216. package/dist/mcpProbeWire.d.ts +9 -2
  217. package/dist/mcpProbeWire.js +6 -1
  218. package/dist/mcpWireCaps.d.ts +47 -2
  219. package/dist/mcpWireCaps.js +164 -16
  220. package/dist/memoryEntriesWire.d.ts +4 -9
  221. package/dist/memoryEntriesWire.js +5 -10
  222. package/dist/model/modelSupplyRules.d.ts +0 -2
  223. package/dist/model/modelSupplyRules.js +3 -12
  224. package/dist/model/modelsPolicy.d.ts +0 -5
  225. package/dist/model/modelsPolicy.js +6 -36
  226. package/dist/model/onboardJudgement.d.ts +93 -0
  227. package/dist/model/onboardJudgement.js +415 -0
  228. package/dist/model/subagentModelWord.d.ts +31 -0
  229. package/dist/model/subagentModelWord.js +261 -0
  230. package/dist/model/tierVocabulary.d.ts +2 -0
  231. package/dist/model/tierVocabulary.js +17 -5
  232. package/dist/modelCapabilityProbe.d.ts +64 -0
  233. package/dist/modelCapabilityProbe.js +600 -0
  234. package/dist/modelIdentityResolvability.d.ts +3 -0
  235. package/dist/modelIdentityResolvability.js +26 -17
  236. package/dist/notifications.d.ts +6 -0
  237. package/dist/notifications.js +71 -23
  238. package/dist/outputStyleSeatCapability.d.ts +0 -3
  239. package/dist/outputStyleSeatCapability.js +0 -3
  240. package/dist/ownKey.d.ts +22 -0
  241. package/dist/ownKey.js +94 -3
  242. package/dist/panelReduce.d.ts +21 -10
  243. package/dist/panelReduce.js +728 -550
  244. package/dist/panelStateHolder.d.ts +3 -7
  245. package/dist/panelStateHolder.js +14 -130
  246. package/dist/peerLaneCapability.d.ts +0 -4
  247. package/dist/peerLaneCapability.js +0 -6
  248. package/dist/permissionRuleIssue.js +2 -0
  249. package/dist/permissionRulesWriteCapability.d.ts +2 -5
  250. package/dist/permissionRulesWriteCapability.js +8 -12
  251. package/dist/permissionWireCaps.d.ts +2 -2
  252. package/dist/permissionWireCaps.js +2 -0
  253. package/dist/permissionsAllowGrantCapability.d.ts +0 -4
  254. package/dist/permissionsAllowGrantCapability.js +0 -6
  255. package/dist/permissionsDeclaration.d.ts +0 -11
  256. package/dist/permissionsDeclaration.js +60 -53
  257. package/dist/pluginHooksWire.d.ts +46 -3
  258. package/dist/pluginHooksWire.js +219 -16
  259. package/dist/preemptWire.d.ts +44 -0
  260. package/dist/preemptWire.js +83 -0
  261. package/dist/printModelStatus.d.ts +63 -0
  262. package/dist/printModelStatus.js +155 -0
  263. package/dist/printToolResultFrame.js +15 -4
  264. package/dist/replayBody.d.ts +3 -0
  265. package/dist/replayBody.js +14 -0
  266. package/dist/request/taskRequest.d.ts +11 -6
  267. package/dist/request/taskRequest.js +112 -19
  268. package/dist/resumeRefusalCopy.d.ts +13 -9
  269. package/dist/resumeRefusalCopy.js +81 -118
  270. package/dist/retryStatus.d.ts +45 -0
  271. package/dist/retryStatus.js +185 -1
  272. package/dist/rewindArchiveCapability.d.ts +0 -4
  273. package/dist/rewindArchiveCapability.js +2 -10
  274. package/dist/rewindArchiveReading.d.ts +0 -1
  275. package/dist/rewindArchiveReading.js +0 -3
  276. package/dist/runCancelContext.d.ts +2 -1
  277. package/dist/runCancelContext.js +4 -2
  278. package/dist/runReattachPolicy.d.ts +31 -0
  279. package/dist/runReattachPolicy.js +46 -0
  280. package/dist/runTerminal.d.ts +3 -6
  281. package/dist/runTerminal.js +8 -9
  282. package/dist/sandboxWire.d.ts +3 -1
  283. package/dist/sandboxWire.js +76 -27
  284. package/dist/scenarioRefusal.d.ts +9 -0
  285. package/dist/scenarioRefusal.js +111 -0
  286. package/dist/scenarioWire.js +1 -1
  287. package/dist/seam.d.ts +48 -2
  288. package/dist/seam.js +25 -4
  289. package/dist/seatContract.d.ts +311 -18
  290. package/dist/seatContract.js +824 -100
  291. package/dist/selfOrchestrationDenial.js +7 -19
  292. package/dist/sessionIdSegment.d.ts +6 -0
  293. package/dist/sessionIdSegment.js +24 -0
  294. package/dist/sessionMemoryStatus.js +6 -11
  295. package/dist/sessionPolicyCapability.d.ts +2 -5
  296. package/dist/sessionPolicyCapability.js +8 -12
  297. package/dist/sessionSyncFileHistoryCapability.d.ts +0 -3
  298. package/dist/sessionSyncFileHistoryCapability.js +0 -3
  299. package/dist/settingsHooksSalvage.d.ts +44 -0
  300. package/dist/settingsHooksSalvage.js +211 -0
  301. package/dist/skillToolListsCapability.d.ts +2 -4
  302. package/dist/skillToolListsCapability.js +8 -9
  303. package/dist/sqlEngineCapability.d.ts +0 -4
  304. package/dist/sqlEngineCapability.js +0 -6
  305. package/dist/sseIdleTriage.js +3 -2
  306. package/dist/steerPriorityCapability.d.ts +0 -3
  307. package/dist/steerPriorityCapability.js +0 -3
  308. package/dist/streamDrainingLegs.d.ts +4 -0
  309. package/dist/streamDrainingLegs.js +6 -1
  310. package/dist/subagent/engineCompactWire.d.ts +0 -1
  311. package/dist/subagent/engineCompactWire.js +7 -5
  312. package/dist/subagent/engineSubagentResume.js +15 -9
  313. package/dist/subagent/engineTaskHandleWire.js +4 -7
  314. package/dist/subagentContentStore.d.ts +3 -0
  315. package/dist/subagentContentStore.js +22 -10
  316. package/dist/submitReopen.d.ts +24 -0
  317. package/dist/submitReopen.js +75 -0
  318. package/dist/terminalStatuses.d.ts +3 -0
  319. package/dist/terminalStatuses.js +10 -2
  320. package/dist/toolHistoryMismatch.js +3 -2
  321. package/dist/toolResult.d.ts +10 -1
  322. package/dist/toolResult.js +34 -6
  323. package/dist/toolRoster.d.ts +3 -4
  324. package/dist/toolRoster.js +21 -22
  325. package/dist/turnFailurePresentation.d.ts +39 -0
  326. package/dist/turnFailurePresentation.js +402 -0
  327. package/dist/usageAnalytics.js +6 -11
  328. package/dist/userAttachmentEnvelope.d.ts +1 -0
  329. package/dist/userAttachmentEnvelope.js +37 -7
  330. package/dist/userAttachmentSeat.d.ts +21 -0
  331. package/dist/userAttachmentSeat.js +75 -0
  332. package/dist/userInvokedSkillsCapability.d.ts +11 -4
  333. package/dist/userInvokedSkillsCapability.js +31 -10
  334. package/dist/webSearchBackendCapability.d.ts +0 -4
  335. package/dist/webSearchBackendCapability.js +0 -6
  336. package/dist/wireErrorTriage.d.ts +7 -0
  337. package/dist/wireErrorTriage.js +26 -23
  338. package/dist/wireFailureShape.d.ts +62 -5
  339. package/dist/wireFailureShape.js +106 -5
  340. package/dist/wireRefusalCopy.d.ts +25 -3
  341. package/dist/wireRefusalCopy.js +74 -80
  342. package/dist/workflowsJournalCapability.d.ts +2 -5
  343. package/dist/workflowsJournalCapability.js +8 -12
  344. package/dist/writeProtectionCapability.d.ts +0 -4
  345. package/dist/writeProtectionCapability.js +0 -6
  346. package/docs/INTEGRATION-CLIENTS.md +1775 -56
  347. package/package.json +6 -5
  348. package/dist/attachmentSeatCapability.d.ts +0 -12
  349. package/dist/attachmentSeatCapability.js +0 -23
  350. package/dist/hitl/approvalOutcomeNote.d.ts +0 -10
  351. package/dist/hitl/approvalOutcomeNote.js +0 -29
  352. package/dist/sessionReadRedactionCapability.d.ts +0 -13
  353. package/dist/sessionReadRedactionCapability.js +0 -35
@@ -134,24 +134,21 @@ export const ABSENT_SETTLE_MS = 30_000;
134
134
  const SETTLED_RETENTION_MS = ABSENT_SETTLE_MS * 4;
135
135
  export const MAX_HELD_WIRE_TICK_BEATS = 16;
136
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;
137
+ const MAX_RECORDS = 8192;
138
+ const MAX_IDS_PER_RECORD = 16;
139
+ const MAX_CARD_HINTS = 2048;
144
140
  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']);
141
+ export const PANEL_REDUCE_STATE_KEYS = Object.freeze(['__panelReduceState', 'records', 'index', 'cards', 'pending', 'sessions', 'overflowed', 'counts']);
146
142
  export function createPanelReduceState() {
147
143
  const s = {
148
144
  __panelReduceState: true,
149
145
  records: PMap.empty(),
150
- alias: PMap.empty(),
146
+ index: PMap.empty(),
147
+ cards: PMap.empty(),
151
148
  pending: PMap.empty(),
152
149
  sessions: PMap.empty(),
153
150
  overflowed: false,
154
- counts: { alias: { t: 0, p: 0, w: 0 }, wire: 0, owned: 0, running: 0, ended: 0, held: 0, rows: 0 },
151
+ counts: { nextRecord: 0, nextAnnounce: 0, unattributedTicks: 0, endedRows: 0 },
155
152
  };
156
153
  return Object.freeze(s);
157
154
  }
@@ -160,7 +157,8 @@ function impl(s) {
160
157
  }
161
158
  class Step {
162
159
  records;
163
- alias;
160
+ index;
161
+ cards;
164
162
  pending;
165
163
  sessionsDraft;
166
164
  overflowed;
@@ -169,28 +167,35 @@ class Step {
169
167
  facts = [];
170
168
  constructor(s) {
171
169
  this.records = s.records.draft();
172
- this.alias = s.alias.draft();
170
+ this.index = s.index.draft();
171
+ this.cards = s.cards.draft();
173
172
  this.pending = s.pending.draft();
174
173
  this.sessionsDraft = s.sessions.draft();
175
174
  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 };
175
+ this.counts = { nextRecord: s.counts.nextRecord, nextAnnounce: s.counts.nextAnnounce, unattributedTicks: s.counts.unattributedTicks, endedRows: s.counts.endedRows };
177
176
  }
178
177
  freeze() {
179
178
  return Object.freeze({
180
179
  __panelReduceState: true,
181
180
  records: this.records.freeze(),
182
- alias: this.alias.freeze(),
181
+ index: this.index.freeze(),
182
+ cards: this.cards.freeze(),
183
183
  pending: this.pending.freeze(),
184
184
  sessions: this.sessionsDraft.freeze(),
185
185
  overflowed: this.overflowed,
186
- counts: Object.freeze({ ...this.counts, alias: Object.freeze({ ...this.counts.alias }) }),
186
+ counts: Object.freeze({ ...this.counts }),
187
187
  });
188
188
  }
189
- rec(key) {
190
- return this.records.get(key);
189
+ rec(rid) {
190
+ return this.records.get(rid);
191
191
  }
192
- put(key, patch) {
193
- const old = this.records.get(key) ?? {};
192
+ find(id) {
193
+ return this.index.get(id);
194
+ }
195
+ put(rid, patch) {
196
+ const old = this.records.get(rid);
197
+ if (old === undefined)
198
+ return;
194
199
  const next = { ...old };
195
200
  for (const [f, v] of Object.entries(patch)) {
196
201
  if (v === undefined)
@@ -199,70 +204,29 @@ class Step {
199
204
  next[f] = v;
200
205
  }
201
206
  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
- }
207
+ this.counts.endedRows += (rowEnded(n) ? 1 : 0) - (rowEnded(old) ? 1 : 0);
208
+ this.records.set(rid, n);
220
209
  }
221
- linkOwned(owner, tail, add) {
222
- const r = this.records.get(owner) ?? {};
223
- const cur = r.owns ?? [];
224
- if (cur.includes(tail) === add)
210
+ drop(rid) {
211
+ const old = this.records.get(rid);
212
+ if (old === undefined)
225
213
  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
- }
214
+ if (rowEnded(old))
215
+ this.counts.endedRows--;
216
+ this.records.delete(rid);
217
+ }
218
+ create(init) {
219
+ const rid = `r${this.counts.nextRecord}`;
220
+ this.counts.nextRecord++;
221
+ this.records.set(rid, {
222
+ ...(init.tail !== undefined ? { tail: init.tail } : {}),
223
+ ...(init.id !== undefined ? { ids: [{ id: init.id }] } : {}),
224
+ });
225
+ if (init.tail !== undefined)
226
+ this.index.set(init.tail, rid);
227
+ if (init.id !== undefined)
228
+ this.index.set(init.id, rid);
229
+ return rid;
266
230
  }
267
231
  session(sessionKey) {
268
232
  return (this.sessionsDraft.get(sessionKey) ?? PMap.empty()).draft();
@@ -282,41 +246,265 @@ class Step {
282
246
  this.sessionsDraft.delete(k);
283
247
  }
284
248
  }
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 });
249
+ function rowEnded(r) {
250
+ return r.row?.phase === 'ended';
251
+ }
252
+ function idsOf(r) {
253
+ const out = [];
254
+ if (r.tail !== undefined)
255
+ out.push(r.tail);
256
+ for (const b of r.ids ?? [])
257
+ if (!out.includes(b.id))
258
+ out.push(b.id);
259
+ if (r.consumerKey !== undefined && !out.includes(r.consumerKey))
260
+ out.push(r.consumerKey);
261
+ return out;
262
+ }
263
+ function keyOf(r) {
264
+ return r.consumerKey ?? r.tail ?? r.ids?.[0]?.id ?? '';
265
+ }
266
+ function bindingOf(r, id) {
267
+ return (r.ids ?? []).find((b) => b.id === id);
268
+ }
269
+ function hasCycleSeq(c) {
270
+ return c?.cycleSeq !== undefined;
271
+ }
272
+ function formerGeneration(r, id) {
273
+ const b = bindingOf(r, id);
274
+ if (b === undefined)
275
+ return false;
276
+ if (b.superseded === true)
277
+ return true;
278
+ return b.gen !== undefined && cycleOrder(b.gen, r.cycle) === 'before';
279
+ }
280
+ function frameCycleOn(r, id, own) {
281
+ return mergeCycle(cycleOf(own), r !== undefined ? bindingOf(r, id)?.gen : undefined);
282
+ }
283
+ function newerCycle(a, b) {
284
+ if (a === undefined)
285
+ return b;
286
+ if (b === undefined)
287
+ return a;
288
+ return cycleOrder(a, b) === 'before' ? b : a;
289
+ }
290
+ function recordOrdinal(rid) {
291
+ return Number(rid.slice(1));
292
+ }
293
+ function addId(d, rid, id, gen) {
294
+ const r = d.rec(rid);
295
+ if (r === undefined)
296
+ return;
297
+ const ids = [...(r.ids ?? [])];
298
+ const g = gen !== undefined && !cycleEmpty(gen) ? cycleOf(gen) : undefined;
299
+ const at = ids.findIndex((b) => b.id === id);
300
+ const cur = at >= 0 ? ids[at] : undefined;
301
+ if (cur !== undefined) {
302
+ if (g !== undefined && (cur.gen === undefined || cycleOrder(cur.gen, g) === 'before')) {
303
+ ids[at] = { ...cur, gen: g };
304
+ d.put(rid, { ids });
305
+ }
306
+ d.index.set(id, rid);
307
+ return;
290
308
  }
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 });
309
+ ids.push({ id, ...(g !== undefined ? { gen: g } : {}) });
310
+ while (ids.length > MAX_IDS_PER_RECORD) {
311
+ const k = ids.findIndex((b) => b.id !== r.currentRun && b.id !== r.consumerKey && b.id !== id);
312
+ if (k < 0)
313
+ break;
314
+ const [gone] = ids.splice(k, 1);
315
+ if (gone !== undefined && d.index.get(gone.id) === rid)
316
+ d.index.delete(gone.id);
317
+ }
318
+ d.put(rid, { ids });
319
+ d.index.set(id, rid);
320
+ }
321
+ function bind(d, first, kind, second, gen) {
322
+ const two = second !== undefined && second.length > 0 && second !== first ? second : undefined;
323
+ const a = d.find(first);
324
+ const b = two !== undefined ? d.find(two) : undefined;
325
+ if (a === undefined && b === undefined) {
326
+ const rid = d.create({ tail: first });
327
+ if (two !== undefined)
328
+ addId(d, rid, two, gen);
329
+ return rid;
330
+ }
331
+ if (a === undefined) {
332
+ const rb = b !== undefined ? d.rec(b) : undefined;
333
+ if (b === undefined || rb === undefined || (rb.tail !== undefined && rb.tail !== first))
334
+ return d.create({ tail: first });
335
+ if (rb.tail === undefined) {
336
+ d.put(b, { tail: first });
337
+ d.index.set(first, b);
338
+ }
339
+ if (two !== undefined)
340
+ addId(d, b, two, gen);
341
+ return b;
342
+ }
343
+ if (kind === 'tail' && d.rec(a)?.tail === undefined)
344
+ d.put(a, { tail: first });
345
+ if (b === undefined || b === a) {
346
+ if (two !== undefined)
347
+ addId(d, a, two, gen);
348
+ return a;
349
+ }
350
+ const ra = d.rec(a);
351
+ const rb = d.rec(b);
352
+ if (ra?.tail !== undefined && rb?.tail !== undefined && ra.tail !== rb.tail)
353
+ return a;
354
+ const s = merge(d, a, b);
355
+ if (two !== undefined)
356
+ addId(d, s, two, gen);
357
+ return s;
358
+ }
359
+ function merge(d, a, b) {
360
+ const ra = d.rec(a);
361
+ const rb = d.rec(b);
362
+ if (ra === undefined || rb === undefined)
363
+ return ra === undefined ? b : a;
364
+ const aFirst = ra.announceSeq !== undefined
365
+ ? rb.announceSeq === undefined || ra.announceSeq < rb.announceSeq
366
+ : rb.announceSeq === undefined && recordOrdinal(a) < recordOrdinal(b);
367
+ const s = aFirst ? a : b;
368
+ const l = aFirst ? b : a;
369
+ const rs = aFirst ? ra : rb;
370
+ const rl = aFirst ? rb : ra;
371
+ const ids = [...(rs.ids ?? [])];
372
+ for (const x of rl.ids ?? []) {
373
+ const at = ids.findIndex((y) => y.id === x.id);
374
+ const y = at >= 0 ? ids[at] : undefined;
375
+ if (y === undefined)
376
+ ids.push(x);
377
+ else if (x.gen !== undefined && (y.gen === undefined || cycleOrder(y.gen, x.gen) === 'before'))
378
+ ids[at] = { ...y, gen: x.gen };
379
+ }
380
+ if (rl.tail !== undefined && rs.tail !== undefined && rl.tail !== rs.tail && !ids.some((y) => y.id === rl.tail))
381
+ ids.push({ id: rl.tail });
382
+ const order = cycleOrder(genOf(rs), genOf(rl));
383
+ const loserNewer = order === 'before';
384
+ const cycle = newerCycle(newerCycle(rs.cycle, rl.cycle), loserNewer ? rl.row?.endCycle : undefined);
385
+ const loserUsage = !hasCycleSeq(cycle) || rl.cycle !== undefined;
386
+ const merged = loserNewer ? adoptRow(rs.row, rl.row) : order === 'after' ? { row: rs.row, filled: {}, usage: undefined, endedNow: false, revived: false } : mergeRows(rs.row, rl.row, cycle, loserUsage);
387
+ d.put(s, {
388
+ tail: rs.tail ?? rl.tail,
389
+ ids,
390
+ cycle,
391
+ ended: newerCycle(rs.ended, rl.ended),
392
+ currentRun: loserNewer ? (rl.currentRun ?? rs.currentRun) : (rs.currentRun ?? rl.currentRun),
393
+ running: rs.running ?? rl.running,
394
+ held: rs.held ?? rl.held,
395
+ resident: rs.resident ?? rl.resident,
396
+ anchor: rs.anchor ?? rl.anchor,
397
+ startedAt: rs.startedAt ?? rl.startedAt,
398
+ row: merged.row,
399
+ });
400
+ for (const id of idsOf(rl))
401
+ d.index.set(id, s);
402
+ d.drop(l);
403
+ const after = d.rec(s);
404
+ if (after === undefined)
405
+ return s;
406
+ const key = keyOf(after);
407
+ if (rl.row?.announced === true)
408
+ d.deltas.push({ op: 'remove', canonicalId: keyOf(rl), supersededBy: key });
409
+ if (rs.row?.announced === true && merged.row !== undefined) {
410
+ if (merged.revived) {
411
+ d.deltas.push({ op: 'upsert', canonicalId: key, revived: true, fields: { ...merged.row.fields } });
412
+ const u = fullUsage(key, merged.row);
413
+ if (u !== undefined)
414
+ d.deltas.push(u);
415
+ if (merged.row.phase === 'ended')
416
+ mintTerminal(d, key, merged.row.isError === true, merged.row.report, merged.row.cause ?? 'end');
417
+ }
418
+ else {
419
+ if (Object.keys(merged.filled).length > 0)
420
+ d.deltas.push({ op: 'upsert', canonicalId: key, fields: merged.filled });
421
+ if (merged.usage !== undefined)
422
+ d.deltas.push(usageDelta(key, merged.usage));
423
+ if (merged.endedNow)
424
+ mintTerminal(d, key, merged.row.isError === true, merged.row.report, 'end');
425
+ }
295
426
  }
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 });
427
+ fillStartedAt(d, s);
428
+ return s;
429
+ }
430
+ function genOf(r) {
431
+ return newerCycle(r.cycle, r.row?.endCycle);
432
+ }
433
+ function adoptRow(s, l) {
434
+ if (l === undefined)
435
+ return { row: s, filled: {}, usage: undefined, endedNow: false, revived: false };
436
+ if (s === undefined)
437
+ return { row: l, filled: {}, usage: undefined, endedNow: false, revived: false };
438
+ const fields = { ...s.fields, ...l.fields };
439
+ delete fields.absence;
440
+ return { row: { ...l, announced: s.announced, fields }, filled: {}, usage: undefined, endedNow: false, revived: s.announced };
441
+ }
442
+ function mergeRows(s, l, cycle, loserUsage) {
443
+ if (l === undefined)
444
+ return { row: s, filled: {}, usage: undefined, endedNow: false, revived: false };
445
+ if (s === undefined)
446
+ return { row: l, filled: {}, usage: undefined, endedNow: false, revived: false };
447
+ const filled = changedFields(s.fields, l.fields, Object.keys(l.fields));
448
+ delete filled.absence;
449
+ const carrier = loserUsage ? { totalTokens: l.totalTokens, toolUses: l.toolUses, final: l.final } : {};
450
+ const u = foldUsage({
451
+ ...s,
452
+ ...(l.gateBound === true ? { gateBound: true } : {}),
453
+ ...(s.deferredEndError === undefined && l.deferredEndError !== undefined ? { deferredEndError: l.deferredEndError } : {}),
454
+ tickSeen: s.tickSeen || l.tickSeen,
455
+ fields: { ...s.fields, ...filled },
456
+ }, carrier);
457
+ let row = u.row;
458
+ const lateEnd = l.endCycle !== undefined && cycleOrder(l.endCycle, cycle) === 'before';
459
+ const endedNow = row.phase === 'running' && l.phase === 'ended' && !lateEnd;
460
+ if (endedNow) {
461
+ const f = { ...row.fields };
462
+ delete f.absence;
463
+ row = {
464
+ ...row,
465
+ phase: 'ended',
466
+ fields: f,
467
+ ...(l.isError !== undefined ? { isError: l.isError } : {}),
468
+ ...(l.report !== undefined ? { report: l.report } : {}),
469
+ ...(l.cause !== undefined ? { cause: l.cause } : {}),
470
+ ...(l.endCycle !== undefined ? { endCycle: l.endCycle } : {}),
471
+ };
301
472
  }
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 });
473
+ return { row, filled, usage: u.change, endedNow, revived: false };
474
+ }
475
+ function noteCard(d, card) {
476
+ if (card === undefined || card.length === 0)
477
+ return;
478
+ if (d.cards.has(card)) {
479
+ d.cards.touch(card);
480
+ return;
306
481
  }
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 });
482
+ d.cards.set(card, true);
483
+ if (d.cards.size > MAX_CARD_HINTS) {
484
+ const oldest = d.cards.first(() => true);
485
+ if (oldest !== undefined)
486
+ d.cards.delete(oldest);
311
487
  }
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
- }
488
+ }
489
+ function evict(d, rid) {
490
+ const r = d.rec(rid);
491
+ if (r === undefined)
492
+ return;
493
+ if (r.running === true && !rowEnded(r))
494
+ d.overflowed = true;
495
+ for (const id of idsOf(r))
496
+ if (d.index.get(id) === rid)
497
+ d.index.delete(id);
498
+ d.drop(rid);
499
+ if (r.row?.announced === true)
500
+ d.deltas.push({ op: 'remove', canonicalId: keyOf(r) });
501
+ }
502
+ function boundRecords(d) {
503
+ while (d.records.size > MAX_RECORDS) {
504
+ const victim = (d.counts.endedRows > 0 ? d.records.first((_, r) => rowEnded(r)) : undefined) ?? d.records.first(() => true);
505
+ if (victim === undefined)
506
+ return;
507
+ evict(d, victim);
320
508
  }
321
509
  }
322
510
  export function panelEndFact(taskId, isError, extra) {
@@ -327,6 +515,7 @@ export function panelEndFact(taskId, isError, extra) {
327
515
  ...(extra?.cycleSeq !== undefined ? { cycleSeq: extra.cycleSeq } : {}),
328
516
  ...(extra?.startedAt !== undefined ? { startedAt: extra.startedAt } : {}),
329
517
  ...(extra?.report !== undefined ? { report: extra.report } : {}),
518
+ ...(typeof extra?.sessionId === 'string' && extra.sessionId.length > 0 ? { sessionId: extra.sessionId } : {}),
330
519
  };
331
520
  }
332
521
  function terminalDelta(key, isError, report, cause) {
@@ -335,6 +524,67 @@ function terminalDelta(key, isError, report, cause) {
335
524
  function mintTerminal(d, key, isError, report, cause) {
336
525
  d.deltas.push(terminalDelta(key, isError, report, cause));
337
526
  }
527
+ function withCount(row, k, v) {
528
+ return k === 'totalTokens' ? { ...row, totalTokens: v } : { ...row, toolUses: v };
529
+ }
530
+ function foldUsage(row, c) {
531
+ let next = row;
532
+ const final = { ...(row.final ?? {}) };
533
+ const vals = {};
534
+ let finalChanged = false;
535
+ for (const k of ['totalTokens', 'toolUses']) {
536
+ const v = c[k];
537
+ if (v === undefined)
538
+ continue;
539
+ const isFinal = c.final?.[k] === true;
540
+ const cur = next[k];
541
+ const curFinal = final[k] === true;
542
+ if (curFinal && !isFinal)
543
+ continue;
544
+ if (cur === undefined || v > cur) {
545
+ vals[k] = v;
546
+ next = withCount(next, k, v);
547
+ if (isFinal && !curFinal) {
548
+ final[k] = true;
549
+ finalChanged = true;
550
+ }
551
+ }
552
+ else if (v === cur && isFinal && !curFinal) {
553
+ final[k] = true;
554
+ finalChanged = true;
555
+ }
556
+ }
557
+ if (finalChanged)
558
+ next = { ...next, final };
559
+ if (vals.totalTokens === undefined && vals.toolUses === undefined && !finalChanged)
560
+ return { row: next, change: undefined };
561
+ return { row: next, change: { ...vals, ...(finalChanged ? { final } : {}) } };
562
+ }
563
+ function usageDelta(key, u) {
564
+ return {
565
+ op: 'usage_delta',
566
+ canonicalId: key,
567
+ ...(u.totalTokens !== undefined ? { totalTokens: u.totalTokens } : {}),
568
+ ...(u.toolUses !== undefined ? { toolUses: u.toolUses } : {}),
569
+ ...(u.final !== undefined ? { final: u.final } : {}),
570
+ };
571
+ }
572
+ function fullUsage(key, row) {
573
+ const fin = row.final !== undefined && (row.final.totalTokens === true || row.final.toolUses === true) ? row.final : undefined;
574
+ if (row.totalTokens === undefined && row.toolUses === undefined && fin === undefined)
575
+ return undefined;
576
+ return usageDelta(key, { ...(row.totalTokens !== undefined ? { totalTokens: row.totalTokens } : {}), ...(row.toolUses !== undefined ? { toolUses: row.toolUses } : {}), ...(fin !== undefined ? { final: fin } : {}) });
577
+ }
578
+ function fleetCarrier(ev) {
579
+ const f = ev.final;
580
+ const final = { ...(f?.totalTokens === true ? { totalTokens: true } : {}), ...(f?.toolUses === true ? { toolUses: true } : {}) };
581
+ return { totalTokens: ev.totalTokens, toolUses: ev.toolUses, final };
582
+ }
583
+ function finalityOf(tokens, toolUses) {
584
+ if (tokens === undefined && toolUses === undefined)
585
+ return undefined;
586
+ return { ...(tokens !== undefined ? { totalTokens: true } : {}), ...(toolUses !== undefined ? { toolUses: true } : {}) };
587
+ }
338
588
  function tickFields(ev) {
339
589
  return {
340
590
  ...(ev.name !== undefined ? { name: ev.name } : {}),
@@ -372,88 +622,96 @@ function changedFields(row, next, onlyMissing) {
372
622
  return out;
373
623
  }
374
624
  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);
625
+ function announce(d, rid) {
626
+ const r = d.rec(rid);
627
+ const row = r?.row;
628
+ if (r === undefined || row === undefined || row.announced)
629
+ return;
630
+ const key = keyOf(r);
631
+ const fields = row.fields.startedAt === undefined && r.startedAt !== undefined ? { ...row.fields, startedAt: r.startedAt } : row.fields;
632
+ d.put(rid, { consumerKey: key, announceSeq: d.counts.nextAnnounce, row: { ...row, fields, announced: true } });
633
+ d.counts.nextAnnounce++;
634
+ d.deltas.push({ op: 'upsert', canonicalId: key, created: true, fields: { ...fields } });
635
+ const u = fullUsage(key, row);
385
636
  if (u !== undefined)
386
637
  d.deltas.push(u);
387
638
  if (row.phase === 'ended')
388
639
  mintTerminal(d, key, row.isError === true, row.report, 'end');
389
- return { ...row, announced: true };
390
640
  }
391
- function foldTick(d, ev) {
392
- const key = ev.taskId;
393
- const row = d.rec(key)?.row;
641
+ function foldTick(d, rid, ev, cardBound) {
642
+ const r = d.rec(rid);
643
+ if (r === undefined)
644
+ return;
645
+ const row = r.row;
646
+ const gate = cardBound ? { gateBound: true } : {};
647
+ const wireId = ev.wireTaskId ?? ev.taskId;
648
+ const attributable = !hasCycleSeq(r.cycle) && (r.currentRun === undefined || r.currentRun === wireId);
649
+ if (!attributable)
650
+ d.counts.unattributedTicks++;
651
+ const carrier = attributable ? { totalTokens: ev.totalTokens, toolUses: ev.toolUses } : {};
394
652
  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) });
653
+ const base = row !== undefined
654
+ ? { ...row, ...gate, tickSeen: true, fields: { ...row.fields, ...tickFields(ev) } }
655
+ : { phase: 'running', ...gate, tickSeen: true, announced: false, fields: tickFields(ev) };
656
+ d.put(rid, { row: foldUsage(base, carrier).row });
657
+ announce(d, rid);
399
658
  return;
400
659
  }
401
- if (row.phase !== 'running')
660
+ const key = keyOf(r);
661
+ if (row.phase !== 'running') {
662
+ const u = foldUsage(row, carrier);
663
+ if (u.change !== undefined)
664
+ d.deltas.push(usageDelta(key, u.change));
665
+ d.put(rid, { row: u.row });
402
666
  return;
403
- const next = tickFields(ev);
404
- const changed = changedFields(row.fields, next, TICK_LATE_BIND);
667
+ }
668
+ const changed = changedFields(row.fields, tickFields(ev), TICK_LATE_BIND);
405
669
  if (row.fields.absence)
406
670
  changed.absence = null;
407
671
  if (Object.keys(changed).length > 0)
408
672
  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);
673
+ const u = foldUsage(row, carrier);
674
+ if (u.change !== undefined)
675
+ d.deltas.push(usageDelta(key, u.change));
412
676
  const fields = { ...row.fields, ...changed };
413
677
  if (changed.absence === null)
414
678
  delete fields.absence;
415
- d.put(key, { row: { ...row, lane: 'tick', fields, totalTokens: ev.totalTokens, toolUses: ev.toolUses } });
679
+ d.put(rid, { row: { ...u.row, ...gate, tickSeen: true, fields } });
416
680
  }
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')
681
+ function foldFleetRow(d, rid, ev, carrier, newGen) {
682
+ const r = d.rec(rid);
683
+ if (r === undefined)
422
684
  return;
423
- const endGen = row?.phase === 'ended' ? row.endCycle : undefined;
424
- const newCycle = order === 'before' || (endGen !== undefined && cycleOrder(endGen, ev) === 'before');
685
+ const row = r.row;
686
+ const fresh = () => foldUsage({ phase: 'running', tickSeen: false, announced: false, fields: fleetFields(ev) }, carrier).row;
425
687
  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) });
688
+ d.put(rid, { row: fresh() });
689
+ announce(d, rid);
428
690
  return;
429
691
  }
430
692
  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) });
693
+ d.put(rid, { row: newGen ? fresh() : foldUsage({ ...row, fields: { ...row.fields, ...fleetFields(ev) } }, carrier).row });
694
+ announce(d, rid);
435
695
  return;
436
696
  }
437
- if (newCycle) {
697
+ const key = keyOf(r);
698
+ if (newGen) {
438
699
  const fields = fleetFields(ev);
439
700
  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
701
  const kept = { ...row.fields, ...fields };
444
702
  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 } : {}) } });
703
+ const next = foldUsage({ phase: 'running', tickSeen: false, announced: true, fields: kept }, carrier).row;
704
+ const u = fullUsage(key, next);
705
+ if (u !== undefined)
706
+ d.deltas.push(u);
707
+ d.put(rid, { row: next });
446
708
  return;
447
709
  }
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
- }
710
+ if (row.phase !== 'running') {
711
+ const u = foldUsage(row, carrier);
712
+ if (u.change !== undefined)
713
+ d.deltas.push(usageDelta(key, u.change));
714
+ d.put(rid, { row: u.row });
457
715
  return;
458
716
  }
459
717
  const changed = changedFields(row.fields, fleetFields(ev), []);
@@ -461,135 +719,105 @@ function foldFleetRow(d, ev, prior) {
461
719
  changed.absence = null;
462
720
  if (Object.keys(changed).length > 0)
463
721
  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);
722
+ const u = foldUsage(row, carrier);
723
+ if (u.change !== undefined)
724
+ d.deltas.push(usageDelta(key, u.change));
467
725
  const fields = { ...row.fields, ...changed };
468
726
  if (changed.absence === null)
469
727
  delete fields.absence;
470
- d.put(key, { row: { ...row, fields, ...(ev.totalTokens !== undefined ? { totalTokens: ev.totalTokens } : {}), ...(ev.toolUses !== undefined ? { toolUses: ev.toolUses } : {}) } });
728
+ d.put(rid, { row: { ...u.row, fields } });
471
729
  }
472
- function foldEnd(d, ev) {
473
- const key = ev.taskId;
474
- const rec = d.rec(key);
475
- if (endOlderThanKnown(d, ev, key, rec?.cycle))
730
+ function foldEnd(d, rid, ev) {
731
+ const r = d.rec(rid);
732
+ if (r === undefined)
476
733
  return;
477
- const row = rec?.row;
734
+ const row = r.row;
735
+ const gen = cycleEmpty(ev) ? {} : { endCycle: cycleOf(ev) };
478
736
  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: {} } });
737
+ d.put(rid, { row: { phase: 'ended', tickSeen: false, announced: false, isError: ev.isError, cause: 'end', ...gen, ...(ev.report !== undefined ? { report: ev.report } : {}), fields: {} } });
480
738
  return;
481
739
  }
482
740
  if (row.phase !== 'running')
483
741
  return;
484
742
  const fields = { ...row.fields };
485
743
  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 } });
744
+ d.put(rid, { row: { ...row, phase: 'ended', isError: ev.isError, cause: 'end', ...gen, ...(ev.report !== undefined ? { report: ev.report } : {}), fields } });
487
745
  if (row.announced)
488
- mintTerminal(d, key, ev.isError, ev.report, 'end');
746
+ mintTerminal(d, keyOf(r), ev.isError, ev.report, 'end');
489
747
  }
490
748
  function foldSweep(d) {
491
749
  const hits = [];
492
- for (const [key, r] of d.records.entries()) {
750
+ for (const [rid, r] of d.records.entries()) {
493
751
  const row = r.row;
494
752
  if (row === undefined || !row.announced || row.phase !== 'running')
495
753
  continue;
496
754
  if (row.fields.absence)
497
755
  continue;
498
- if (row.lane === 'fleet' || r.resident === true)
756
+ if (!row.tickSeen || r.resident === true)
499
757
  continue;
500
- hits.push(key);
758
+ hits.push(rid);
501
759
  }
502
- for (const key of hits) {
503
- const row = d.rec(key)?.row;
504
- if (row === undefined)
760
+ for (const rid of hits) {
761
+ const r = d.rec(rid);
762
+ const row = r?.row;
763
+ if (r === undefined || row === undefined)
505
764
  continue;
506
- d.put(key, { row: { ...row, phase: 'ended', isError: false, cause: 'sweep' } });
507
- mintTerminal(d, key, false, undefined, 'sweep');
765
+ const isError = row.deferredEndError === true;
766
+ d.put(rid, { row: { ...row, phase: 'ended', isError, cause: 'sweep' } });
767
+ mintTerminal(d, keyOf(r), isError, undefined, 'sweep');
508
768
  }
509
769
  }
510
- function foldAbsence(d, a) {
511
- const row = d.rec(a.taskId)?.row;
512
- if (row === undefined || !row.announced || row.phase !== 'running')
770
+ function noteDeferredEnd(d, rid, isError, frameCycle, transcript) {
771
+ if (rid === undefined)
513
772
  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 } } });
773
+ const r = d.rec(rid);
774
+ const row = r?.row;
775
+ if (r === undefined || row === undefined || row.phase !== 'running')
776
+ return;
777
+ if (cycleOrder(r.cycle, frameCycle) === 'after')
778
+ return;
779
+ if (transcript !== undefined && bindingOf(r, transcript)?.superseded === true)
780
+ return;
781
+ d.put(rid, { row: { ...row, deferredEndError: isError } });
517
782
  }
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))
783
+ function foldAbsence(d, rid, a) {
784
+ const r = d.rec(rid);
785
+ const row = r?.row;
786
+ if (r === undefined || row === undefined || !row.announced || row.phase !== 'running')
549
787
  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
- }
788
+ const absence = { lastSeenAtMs: a.lastSeenAtMs, absentForMs: a.absentForMs };
789
+ d.deltas.push({ op: 'upsert', canonicalId: keyOf(r), fields: { absence } });
790
+ d.put(rid, { row: { ...row, fields: { ...row.fields, absence } } });
568
791
  }
569
- function isPublishedWire(d, id) {
570
- return d.rec(id)?.wire !== undefined;
792
+ function stripCardBound(ev) {
793
+ const { cardBound: _cardBound, ...rest } = ev;
794
+ void _cardBound;
795
+ return rest;
571
796
  }
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;
797
+ function emitTick(d, ev) {
798
+ const found = d.find(ev.taskId);
799
+ const fr = found !== undefined ? d.rec(found) : undefined;
800
+ if (fr !== undefined && formerGeneration(fr, ev.taskId))
801
+ return;
802
+ const rid = found ?? d.create({ id: ev.taskId });
803
+ d.records.touch(rid);
804
+ const r = d.rec(rid);
805
+ if (r === undefined)
806
+ return;
807
+ const key = keyOf(r);
808
+ const plain = stripCardBound(ev);
809
+ const fact = key === ev.taskId
810
+ ? { ...plain, taskIdOrigin: 'wire' }
811
+ : { ...plain, taskId: key, wireTaskId: ev.taskId, taskIdOrigin: key === r.tail ? 'fleet-row' : 'wire' };
812
+ d.facts.push({ ch: 'event', ev: fact });
813
+ foldTick(d, rid, fact, ev.cardBound === true);
581
814
  }
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;
815
+ function flushHeld(d, wireTaskId) {
816
+ const held = d.pending.get(wireTaskId);
817
+ if (held === undefined)
818
+ return;
819
+ d.pending.delete(wireTaskId);
820
+ emitTick(d, held.ev);
593
821
  }
594
822
  function ageHeld(d, except) {
595
823
  for (const [wireId, held] of [...d.pending.entries()]) {
@@ -598,116 +826,13 @@ function ageHeld(d, except) {
598
826
  const beats = held.beats + 1;
599
827
  if (beats >= MAX_HELD_WIRE_TICK_BEATS) {
600
828
  d.pending.delete(wireId);
601
- emit(d, asIsTick(d, held.ev));
829
+ emitTick(d, held.ev);
602
830
  }
603
831
  else {
604
832
  d.pending.set(wireId, { ev: held.ev, beats });
605
833
  }
606
834
  }
607
835
  }
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
836
  function publish(d, ev) {
712
837
  if (ev.kind === 'end' || ev.kind === 'sweep')
713
838
  ageHeld(d, ev.kind === 'sweep' ? undefined : ev.taskId);
@@ -719,65 +844,59 @@ function publish(d, ev) {
719
844
  case 'end':
720
845
  return publishEnd(d, ev);
721
846
  default:
722
- emit(d, ev);
847
+ d.facts.push({ ch: 'event', ev });
848
+ foldSweep(d);
723
849
  }
724
850
  }
725
851
  function publishFleetRow(d, ev) {
726
852
  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);
853
+ const transcript = typeof ev.transcriptId === 'string' && ev.transcriptId.length > 0 ? ev.transcriptId : undefined;
854
+ noteCard(d, ev.parentToolCallId);
855
+ const rid = bind(d, ev.taskId, 'tail', transcript, rowCycle);
856
+ d.records.touch(rid);
857
+ const r = d.rec(rid);
858
+ if (r === undefined)
859
+ return;
860
+ if (transcript !== undefined && bindingOf(r, transcript)?.superseded === true) {
741
861
  ageHeld(d, undefined);
742
862
  return;
743
863
  }
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);
864
+ const order = cycleOrder(r.cycle, rowCycle);
865
+ const stale = order === 'after';
866
+ let newGen = false;
867
+ if (!stale) {
868
+ const endedHere = r.ended !== undefined && (r.cycle === undefined || cycleOrder(r.ended, r.cycle) === 'same') ? r.ended : undefined;
869
+ const endGen = r.row?.phase === 'ended' ? (r.row.endCycle ?? endedHere) : undefined;
870
+ newGen = order === 'before' || (endGen !== undefined && cycleOrder(endGen, rowCycle) === 'before');
871
+ if (!newGen && transcript !== undefined && !hasCycleSeq(r.cycle) && !hasCycleSeq(rowCycle) && r.currentRun !== undefined && r.currentRun !== transcript) {
872
+ newGen = true;
873
+ const ids = (r.ids ?? []).map((b) => (b.id === r.currentRun ? { ...b, superseded: true } : b));
874
+ d.put(rid, { ids });
875
+ }
876
+ d.put(rid, {
877
+ ...(transcript !== undefined ? { currentRun: transcript } : {}),
878
+ ...(!cycleEmpty(rowCycle) ? { cycle: rowCycle } : {}),
879
+ });
756
880
  }
881
+ const key = keyOf(d.rec(rid) ?? r);
882
+ const { final: _final, ...plain } = ev;
883
+ void _final;
884
+ const fact = key === ev.taskId ? plain : { ...plain, taskId: key, wireTaskId: ev.taskId, taskIdOrigin: 'wire' };
885
+ d.facts.push({ ch: 'event', ev: fact });
886
+ if (!stale)
887
+ foldFleetRow(d, rid, fact, fleetCarrier(ev), newGen);
888
+ if (transcript !== undefined)
889
+ flushHeld(d, transcript);
890
+ flushHeld(d, ev.taskId);
757
891
  ageHeld(d, undefined);
758
892
  }
759
893
  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)) {
894
+ noteCard(d, ev.parentToolCallId);
895
+ const rid = d.find(ev.taskId);
896
+ const r = rid !== undefined ? d.rec(rid) : undefined;
897
+ if ((r !== undefined && (r.consumerKey !== undefined || r.tail !== undefined)) || ev.cardBound === true || d.pending.has(ev.taskId)) {
779
898
  d.pending.delete(ev.taskId);
780
- emit(d, asIsTick(d, ev));
899
+ emitTick(d, ev);
781
900
  return;
782
901
  }
783
902
  if (d.pending.size >= MAX_HELD_WIRE_TICKS) {
@@ -787,106 +906,139 @@ function publishTick(d, ev) {
787
906
  }
788
907
  d.pending.set(ev.taskId, { ev, beats: 0 });
789
908
  }
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
- }
909
+ function publishStart(d, ev) {
910
+ if (typeof ev.workflowRunId === 'string' && ev.workflowRunId.length > 0)
833
911
  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);
912
+ if (typeof ev.taskId !== 'string' || ev.taskId.length === 0)
847
913
  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);
914
+ const startedAt = typeof ev.startedAt === 'number' && Number.isFinite(ev.startedAt) ? ev.startedAt : undefined;
915
+ if (startedAt === undefined)
858
916
  return;
859
- }
917
+ const found = d.find(ev.taskId);
918
+ const former = found !== undefined ? d.rec(found) : undefined;
919
+ if (former !== undefined && formerGeneration(former, ev.taskId))
920
+ return;
921
+ if (found === undefined && d.records.size >= MAX_RECORDS)
922
+ return;
923
+ const rid = found ?? d.create({ id: ev.taskId });
924
+ const r = d.rec(rid);
925
+ if (r === undefined)
926
+ return;
927
+ if (r.startedAt === undefined)
928
+ d.put(rid, { startedAt });
929
+ fillStartedAt(d, rid);
930
+ }
931
+ function fillStartedAt(d, rid) {
932
+ const r = d.rec(rid);
933
+ const row = r?.row;
934
+ if (r === undefined || r.startedAt === undefined || row === undefined || !row.announced || row.phase !== 'running' || row.fields.startedAt !== undefined)
935
+ return;
936
+ d.deltas.push({ op: 'upsert', canonicalId: keyOf(r), fields: { startedAt: r.startedAt } });
937
+ d.put(rid, { row: { ...row, fields: { ...row.fields, startedAt: r.startedAt } } });
938
+ }
939
+ function releaseHeld(d, rid, endCycle) {
940
+ const held = d.rec(rid)?.held;
941
+ if (held === undefined)
942
+ return;
943
+ const o = cycleOrder(endCycle, held);
944
+ if (o === 'before')
945
+ return;
946
+ d.put(rid, { held: undefined });
947
+ if (o === 'after')
948
+ return;
949
+ publish(d, held);
950
+ }
951
+ function settle(d, rid, cycle) {
952
+ const r = d.rec(rid);
953
+ if (r === undefined)
954
+ return;
955
+ const older = r.ended !== undefined && isStaleEngineAgentPanelEnd(cycle, r.ended);
956
+ d.put(rid, { running: undefined, ended: older ? r.ended : mergeCycle(cycleOf(cycle), r.ended) });
957
+ }
958
+ function publishEnd(d, ev) {
959
+ const sessionId = typeof ev.sessionId === 'string' && ev.sessionId.length > 0 && ev.sessionId !== ev.taskId ? ev.sessionId : undefined;
960
+ if (sessionId !== undefined) {
961
+ const at = d.find(ev.taskId);
962
+ const ra = at !== undefined ? d.rec(at) : undefined;
963
+ const evCycle = frameCycleOn(ra, ev.taskId, ev);
964
+ const provablyOld = ra !== undefined && (isStaleEngineAgentPanelEnd(evCycle, ra.cycle) || isStaleEngineAgentPanelEnd(evCycle, ra.ended));
965
+ if (!provablyOld)
966
+ bind(d, ev.taskId, 'tail', sessionId, cycleOf(ev));
967
+ }
968
+ const pre = d.find(ev.taskId);
969
+ const pr = pre !== undefined ? d.rec(pre) : undefined;
970
+ if (pre !== undefined && pr !== undefined)
971
+ releaseHeld(d, pre, frameCycleOn(pr, ev.taskId, ev));
860
972
  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);
973
+ const found = d.find(ev.taskId);
974
+ const r0 = found !== undefined ? d.rec(found) : undefined;
975
+ if (r0 !== undefined && bindingOf(r0, ev.taskId)?.superseded === true)
976
+ return;
977
+ const effective = frameCycleOn(r0, ev.taskId, ev);
978
+ const rid = found ?? d.create({ id: ev.taskId });
979
+ d.records.touch(rid);
980
+ const r = d.rec(rid);
981
+ if (r === undefined)
982
+ return;
983
+ const stale = isStaleEngineAgentPanelEnd(effective, r.cycle) || isStaleEngineAgentPanelEnd(effective, r.ended);
984
+ const key = keyOf(r);
985
+ const fact = {
986
+ ...ev,
987
+ ...(key !== ev.taskId ? { taskId: key, wireTaskId: ev.taskId, taskIdOrigin: key === r.tail ? 'fleet-row' : 'wire' } : {}),
988
+ ...effective,
989
+ };
990
+ d.facts.push({ ch: 'event', ev: fact });
991
+ if (stale)
992
+ return;
993
+ foldEnd(d, rid, fact);
994
+ settle(d, rid, effective);
866
995
  }
867
996
  function publishAbsence(d, a) {
868
- const owner = wireOwnerOf(d, a.taskId);
869
- const ev = owner !== undefined ? { ...a, taskId: owner, wireTaskId: a.taskId } : a;
997
+ const rid = d.find(a.taskId);
998
+ const r = rid !== undefined ? d.rec(rid) : undefined;
999
+ const key = r !== undefined ? keyOf(r) : a.taskId;
1000
+ const ev = key !== a.taskId ? { ...a, taskId: key, wireTaskId: a.taskId } : a;
870
1001
  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)
1002
+ if (rid !== undefined)
1003
+ foldAbsence(d, rid, ev);
1004
+ }
1005
+ function setResident(d, id, resident) {
1006
+ const rid = d.find(id);
1007
+ if (resident)
1008
+ d.put(rid ?? d.create({ id }), { resident: true });
1009
+ else if (rid !== undefined)
1010
+ d.put(rid, { resident: undefined });
1011
+ }
1012
+ function clearResidentByWire(d, id, cycle) {
1013
+ const rid = d.find(id);
1014
+ const r = rid !== undefined ? d.rec(rid) : undefined;
1015
+ if (rid === undefined || r === undefined)
880
1016
  return;
881
- if (isStaleEngineAgentPanelEnd(id, d.rec(id.taskId)?.cycle))
1017
+ if (bindingOf(r, id)?.superseded === true)
882
1018
  return;
883
- d.put(id.taskId, { resident: undefined });
1019
+ if (isStaleEngineAgentPanelEnd(frameCycleOn(r, id, cycleOf(cycle)), r.cycle))
1020
+ return;
1021
+ d.put(rid, { resident: undefined });
884
1022
  }
885
1023
  function currentToolKeyOf(ct) {
886
1024
  if (!ct || typeof ct.toolName !== 'string' || ct.toolName.length === 0)
887
1025
  return undefined;
888
1026
  return `${ct.toolName}\u0000${ct.target ?? ''}`;
889
1027
  }
1028
+ function sameGeneration(r, frameCycle, transcript) {
1029
+ if (cycleOrder(r.cycle, frameCycle) === 'before')
1030
+ return false;
1031
+ if (r.row?.endCycle !== undefined && cycleOrder(r.row.endCycle, frameCycle) === 'before')
1032
+ return false;
1033
+ if (!hasCycleSeq(r.cycle) && transcript !== undefined && r.currentRun !== undefined && r.currentRun !== transcript)
1034
+ return false;
1035
+ return true;
1036
+ }
1037
+ function knownToProcess(r, frameCycle) {
1038
+ if (r === undefined)
1039
+ return false;
1040
+ return r.running === true || r.row?.announced === true || (r.ended !== undefined && cycleOrder(r.ended, frameCycle) !== 'before');
1041
+ }
890
1042
  function project(d, sessionKey, rows, nowMs) {
891
1043
  const seen = d.session(sessionKey);
892
1044
  const present = new Set();
@@ -906,7 +1058,9 @@ function project(d, sessionKey, rows, nowMs) {
906
1058
  const currentTool = currentToolKeyOf(row.currentTool) !== undefined ? row.currentTool : undefined;
907
1059
  const currentToolKey = currentToolKeyOf(row.currentTool);
908
1060
  const prev = seen.get(taskId);
909
- const prevCycle = prev !== undefined ? (d.rec(taskId)?.cycle ?? {}) : undefined;
1061
+ const tailRid = d.find(taskId);
1062
+ const tailRec = tailRid !== undefined ? d.rec(tailRid) : undefined;
1063
+ const prevCycle = prev !== undefined ? (tailRec?.cycle ?? {}) : undefined;
910
1064
  const order = prev !== undefined ? cycleOrder(frameCycle, prevCycle) : 'unknown';
911
1065
  if (order === 'before')
912
1066
  continue;
@@ -930,30 +1084,49 @@ function project(d, sessionKey, rows, nowMs) {
930
1084
  ...knownFields,
931
1085
  };
932
1086
  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;
1087
+ const viaRun = transcriptId !== undefined ? d.find(transcriptId) : undefined;
1088
+ const runAny = viaRun !== undefined ? d.rec(viaRun) : undefined;
1089
+ const runRec = runAny !== undefined && (runAny.tail === undefined || runAny.tail === taskId) ? runAny : undefined;
1090
+ const knownHere = knownToProcess(tailRec, frameCycle) || knownToProcess(runRec, frameCycle);
1091
+ const cardSeen = parentToolCallId !== undefined && d.cards.has(parentToolCallId);
1092
+ const newbornTerminal = prev === undefined && !d.overflowed && !knownHere && !cardSeen;
936
1093
  const settledThisCycle = prev?.settled === true && !rowNewer;
937
- const endedRec = prev === undefined ? d.rec(taskId)?.ended : undefined;
1094
+ const settledRec = [tailRec, runRec].find((r) => r?.row?.announced === true) ?? tailRec;
1095
+ const endedRec = prev === undefined ? settledRec?.ended : undefined;
938
1096
  if (endedRec !== undefined && cycleOrder(frameCycle, endedRec) === 'before')
939
1097
  continue;
940
1098
  const endedSameCycle = endedRec !== undefined && cycleOrder(endedRec, frameCycle) !== 'before';
1099
+ const target = tailRec ?? runRec;
1100
+ const gateOwned = target?.row?.phase === 'running' && target.row.gateBound === true && sameGeneration(target, frameCycle, transcriptId);
1101
+ const final = finalityOf(tokens, toolUses);
1102
+ const terminalRow = final !== undefined ? { ...base, final } : base;
941
1103
  if (newbornTerminal) {
942
- d.put(taskId, { held: base });
1104
+ d.put(bind(d, taskId, 'tail', transcriptId, frameCycle), { held: terminalRow });
943
1105
  }
944
- else if (!settledThisCycle) {
945
- if (rowNewer ||
1106
+ else if (settledThisCycle) {
1107
+ const more = (tokens !== undefined && prev?.tokens !== tokens) || (toolUses !== undefined && prev?.toolUses !== toolUses);
1108
+ if (more && tailRid !== undefined && tailRec?.held !== undefined)
1109
+ d.put(tailRid, { held: terminalRow });
1110
+ else if (more)
1111
+ publish(d, terminalRow);
1112
+ }
1113
+ else {
1114
+ if (tailRid === undefined ||
1115
+ final !== undefined ||
1116
+ rowNewer ||
946
1117
  cycleKeysChanged(prevCycle, frameCycle) ||
947
- (tokens !== undefined && prev?.tokens !== tokens) ||
948
- (toolUses !== undefined && prev?.toolUses !== toolUses) ||
949
1118
  (transcriptId !== undefined && prev?.transcriptId !== transcriptId) ||
950
1119
  (parentToolCallId !== undefined && prev?.parentToolCallId !== parentToolCallId)) {
951
- publish(d, base);
1120
+ publish(d, terminalRow);
952
1121
  }
953
- if (!endedSameCycle)
1122
+ if (!endedSameCycle && !gateOwned)
954
1123
  publish(d, panelEndFact(taskId, isSdkFleetTaskTerminalNotSuccess(status), known));
1124
+ else if (!endedSameCycle)
1125
+ noteDeferredEnd(d, d.find(taskId), isSdkFleetTaskTerminalNotSuccess(status), frameCycle, transcriptId);
955
1126
  }
956
- d.put(taskId, { cycle: cycleEmpty(known) ? undefined : known });
1127
+ const rid = d.find(taskId);
1128
+ if (rid !== undefined && !cycleEmpty(known))
1129
+ d.put(rid, { cycle: known });
957
1130
  seen.set(taskId, {
958
1131
  status,
959
1132
  tokens: knownTokens,
@@ -968,9 +1141,10 @@ function project(d, sessionKey, rows, nowMs) {
968
1141
  });
969
1142
  continue;
970
1143
  }
971
- if (prev !== undefined && prev.settled && order === 'same' && d.rec(taskId)?.held !== undefined)
1144
+ if (prev !== undefined && prev.settled && order === 'same' && tailRec?.held !== undefined)
972
1145
  continue;
973
1146
  if (!prev ||
1147
+ tailRid === undefined ||
974
1148
  prev.settled ||
975
1149
  prev.absentReportedAtMs !== undefined ||
976
1150
  prev.status !== status ||
@@ -980,11 +1154,14 @@ function project(d, sessionKey, rows, nowMs) {
980
1154
  (parentToolCallId !== undefined && prev.parentToolCallId !== parentToolCallId) ||
981
1155
  cycleKeysChanged(prevCycle, frameCycle) ||
982
1156
  (currentToolKey !== undefined && prev.currentToolKey !== currentToolKey)) {
983
- notePanelRowRunning(d, taskId);
984
- d.put(taskId, { held: undefined });
985
1157
  publish(d, { ...base, ...(currentTool !== undefined ? { currentTool } : {}) });
1158
+ const rid = d.find(taskId);
1159
+ if (rid !== undefined)
1160
+ d.put(rid, { running: true, held: undefined });
986
1161
  }
987
- d.put(taskId, { cycle: cycleEmpty(known) ? undefined : known });
1162
+ const rid = d.find(taskId);
1163
+ if (rid !== undefined && !cycleEmpty(known))
1164
+ d.put(rid, { cycle: known });
988
1165
  seen.set(taskId, {
989
1166
  status,
990
1167
  tokens: knownTokens,
@@ -1036,10 +1213,12 @@ export function stepPanelFrame(state, frame) {
1036
1213
  case 'fleet-rows-reset':
1037
1214
  d.dropSessions(frame.sessionKey);
1038
1215
  if (frame.sessionKey === undefined) {
1039
- for (const [k, r] of [...d.records.entries()]) {
1216
+ for (const [rid, r] of [...d.records.entries()]) {
1040
1217
  if (r.running !== undefined || r.ended !== undefined || r.held !== undefined)
1041
- d.put(k, { running: undefined, ended: undefined, held: undefined });
1218
+ d.put(rid, { running: undefined, ended: undefined, held: undefined });
1042
1219
  }
1220
+ for (const [k] of [...d.cards.entries()])
1221
+ d.cards.delete(k);
1043
1222
  d.overflowed = false;
1044
1223
  }
1045
1224
  break;
@@ -1047,17 +1226,20 @@ export function stepPanelFrame(state, frame) {
1047
1226
  publishAbsence(d, frame.absence);
1048
1227
  break;
1049
1228
  case 'resident':
1050
- d.put(frame.taskId, { resident: frame.resident ? true : undefined });
1229
+ setResident(d, frame.taskId, frame.resident);
1051
1230
  break;
1052
1231
  case 'resident-clear-wire':
1053
1232
  clearResidentByWire(d, frame.taskId, frame.cycle);
1054
1233
  break;
1234
+ case 'start':
1235
+ publishStart(d, frame);
1236
+ break;
1055
1237
  case 'anchor':
1056
1238
  if (frame.taskId && frame.transcriptId)
1057
- d.put(anchorKeyOf(d, frame.taskId), { anchor: frame.transcriptId });
1239
+ d.put(bind(d, frame.taskId, 'unknown', frame.transcriptId, undefined), { anchor: frame.transcriptId });
1058
1240
  break;
1059
1241
  }
1060
- boundFields(d);
1242
+ boundRecords(d);
1061
1243
  return { state: d.freeze(), deltas: d.deltas, facts: d.facts };
1062
1244
  }
1063
1245
  export function reducePanelFrame(state, frame) {
@@ -1066,12 +1248,18 @@ export function reducePanelFrame(state, frame) {
1066
1248
  }
1067
1249
  export function panelRowSnapshot(state) {
1068
1250
  const out = [];
1069
- for (const [key, r] of impl(state).records.entries()) {
1251
+ const shown = [];
1252
+ for (const [, r] of impl(state).records.entries())
1253
+ if (r.row?.announced === true)
1254
+ shown.push(r);
1255
+ shown.sort((a, b) => (a.announceSeq ?? 0) - (b.announceSeq ?? 0));
1256
+ for (const r of shown) {
1070
1257
  const row = r.row;
1071
- if (row === undefined || !row.announced)
1258
+ if (row === undefined)
1072
1259
  continue;
1260
+ const key = keyOf(r);
1073
1261
  out.push({ op: 'upsert', canonicalId: key, created: true, fields: { ...row.fields } });
1074
- const u = usageDelta(key, undefined, row.totalTokens, row.toolUses);
1262
+ const u = fullUsage(key, row);
1075
1263
  if (u !== undefined)
1076
1264
  out.push(u);
1077
1265
  if (row.phase === 'ended')
@@ -1079,57 +1267,47 @@ export function panelRowSnapshot(state) {
1079
1267
  }
1080
1268
  return out;
1081
1269
  }
1082
- export function panelResolveTaskId(state, wireTaskId, parentToolCallId) {
1270
+ function recordOfId(state, id) {
1083
1271
  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' };
1272
+ const rid = s.index.get(id);
1273
+ return rid !== undefined ? s.records.get(rid) : undefined;
1091
1274
  }
1092
- export function panelIsResident(state, taskId) {
1093
- return impl(state).records.get(taskId)?.resident === true;
1275
+ export function panelResolveTaskId(state, wireTaskId) {
1276
+ const r = recordOfId(state, wireTaskId);
1277
+ if (r?.tail === undefined)
1278
+ return { taskId: wireTaskId, origin: 'wire' };
1279
+ return { taskId: r.tail, origin: 'fleet-row', ...cycleOf(bindingOf(r, wireTaskId)?.gen) };
1094
1280
  }
1095
- function anchorKeyOf(d, taskId) {
1096
- const o = d.rec(taskId)?.ownedBy;
1097
- return o !== undefined && !o.retired ? o.wireId : taskId;
1281
+ export function panelIsResident(state, taskId) {
1282
+ return recordOfId(state, taskId)?.resident === true;
1098
1283
  }
1099
1284
  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;
1285
+ return recordOfId(state, taskId)?.anchor;
1105
1286
  }
1106
1287
  export function panelPresenceSize(state, sessionKey) {
1107
1288
  return impl(state).sessions.get(sessionKey)?.size ?? 0;
1108
1289
  }
1109
1290
  export function panelClearIdentity(state) {
1110
1291
  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 };
1292
+ for (const [k] of [...d.index.entries()])
1293
+ d.index.delete(k);
1114
1294
  for (const [k] of [...d.pending.entries()])
1115
1295
  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
- }
1296
+ for (const [k] of [...d.cards.entries()])
1297
+ d.cards.delete(k);
1120
1298
  return d.freeze();
1121
1299
  }
1122
1300
  export function panelClearAnchors(state) {
1123
1301
  const d = new Step(impl(state));
1124
- for (const [k, r] of [...d.records.entries()])
1302
+ for (const [rid, r] of [...d.records.entries()])
1125
1303
  if (r.anchor !== undefined)
1126
- d.put(k, { anchor: undefined });
1304
+ d.put(rid, { anchor: undefined });
1127
1305
  return d.freeze();
1128
1306
  }
1129
1307
  export function panelClearRows(state) {
1130
1308
  const d = new Step(impl(state));
1131
- for (const [k, r] of [...d.records.entries()])
1309
+ for (const [rid, r] of [...d.records.entries()])
1132
1310
  if (r.row !== undefined)
1133
- d.put(k, { row: undefined });
1311
+ d.put(rid, { row: undefined });
1134
1312
  return d.freeze();
1135
1313
  }