@sema-agent/client-core 0.97.1 → 0.98.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 (281) hide show
  1. package/CHANGELOG.md +408 -0
  2. package/README.md +74 -37
  3. package/dist/adapt/arms.d.ts +1 -0
  4. package/dist/adapt/arms.js +128 -34
  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/textStream.d.ts +1 -0
  10. package/dist/adapt/textStream.js +24 -7
  11. package/dist/adapt/toolCards.d.ts +27 -5
  12. package/dist/adapt/toolCards.js +39 -6
  13. package/dist/adapt/wireShapes.js +6 -2
  14. package/dist/adapt.d.ts +2 -0
  15. package/dist/adapt.js +8 -3
  16. package/dist/adapter/activeRunSelfHeal.d.ts +5 -0
  17. package/dist/adapter/activeRunSelfHeal.js +51 -28
  18. package/dist/adapter/downstream/eventToSdkMessage.d.ts +2 -5
  19. package/dist/adapter/downstream/eventToSdkMessage.js +27 -34
  20. package/dist/adapter/downstream/terminalToSdkResult.js +11 -4
  21. package/dist/adapter/downstream/turnUsageToModelUsage.d.ts +5 -2
  22. package/dist/adapter/downstream/turnUsageToModelUsage.js +2 -0
  23. package/dist/adapter/runStream.js +29 -13
  24. package/dist/adapter/types.d.ts +4 -4
  25. package/dist/agentSession/backgroundView.js +2 -1
  26. package/dist/agentSession/engineAgentRegistryRead.d.ts +2 -2
  27. package/dist/agentSession/engineAgentRegistryRead.js +12 -13
  28. package/dist/agentsWireCaps.d.ts +8 -8
  29. package/dist/agentsWireCaps.js +168 -175
  30. package/dist/approvalDecidedByCapability.d.ts +0 -4
  31. package/dist/approvalDecidedByCapability.js +0 -6
  32. package/dist/approvalsStreamLiveCapability.d.ts +0 -4
  33. package/dist/approvalsStreamLiveCapability.js +0 -6
  34. package/dist/assistantInbox.d.ts +34 -0
  35. package/dist/assistantInbox.js +118 -0
  36. package/dist/centerWiringCapability.js +9 -1
  37. package/dist/clientSlice.d.ts +0 -9
  38. package/dist/clientSlice.js +0 -3
  39. package/dist/cloudConfigWireCaps.d.ts +4 -2
  40. package/dist/cloudConfigWireCaps.js +81 -61
  41. package/dist/compensations.js +1 -1
  42. package/dist/connectorStatus.d.ts +21 -0
  43. package/dist/connectorStatus.js +112 -0
  44. package/dist/controlRouter.d.ts +14 -1
  45. package/dist/controlRouter.js +68 -17
  46. package/dist/coreValuePorts.d.ts +3 -3
  47. package/dist/decideReceipt.d.ts +2 -2
  48. package/dist/decideReceipt.js +5 -2
  49. package/dist/declared/supportFloorDeclared.js +3 -3
  50. package/dist/deviceExecutorManagementCapability.d.ts +0 -4
  51. package/dist/deviceExecutorManagementCapability.js +0 -6
  52. package/dist/deviceRebind.d.ts +49 -1
  53. package/dist/deviceRebind.js +221 -3
  54. package/dist/displayUntrusted.d.ts +1 -0
  55. package/dist/displayUntrusted.js +250 -76
  56. package/dist/engineAgentAbsence.d.ts +1 -1
  57. package/dist/engineAgentPanelStore.d.ts +5 -4
  58. package/dist/engineAgentPanelStore.js +3 -12
  59. package/dist/engineCapReader.d.ts +0 -4
  60. package/dist/engineCapReader.js +1 -5
  61. package/dist/engineCapsCache.d.ts +4 -0
  62. package/dist/engineCapsCache.js +17 -12
  63. package/dist/engineClosedSets.d.ts +1 -0
  64. package/dist/engineClosedSets.js +4 -1
  65. package/dist/engineErrorCodes.d.ts +9 -2
  66. package/dist/engineErrorCodes.js +9 -1
  67. package/dist/engineIdentity.d.ts +1 -0
  68. package/dist/engineIdentity.js +8 -0
  69. package/dist/engineRowRef.d.ts +28 -0
  70. package/dist/engineRowRef.js +111 -0
  71. package/dist/engineSessionMessages.d.ts +67 -0
  72. package/dist/engineSessionMessages.js +364 -0
  73. package/dist/engineToolDirectory.d.ts +0 -9
  74. package/dist/engineToolDirectory.js +1 -94
  75. package/dist/engineUrl.d.ts +18 -0
  76. package/dist/engineUrl.js +52 -0
  77. package/dist/env/uiLanguage.d.ts +9 -0
  78. package/dist/env/uiLanguage.js +35 -0
  79. package/dist/eventLeg.d.ts +92 -0
  80. package/dist/eventLeg.js +285 -0
  81. package/dist/executionLaneCapability.d.ts +0 -4
  82. package/dist/executionLaneCapability.js +3 -16
  83. package/dist/fileHistoryCaptureCapability.d.ts +0 -4
  84. package/dist/fileHistoryCaptureCapability.js +5 -7
  85. package/dist/fleet/fleetLedger.d.ts +0 -3
  86. package/dist/fleet/fleetLedger.js +21 -36
  87. package/dist/fleet/fleetProjection.d.ts +2 -2
  88. package/dist/fleet/fleetProjection.js +10 -8
  89. package/dist/frameBinding.d.ts +5 -0
  90. package/dist/frameBinding.js +23 -0
  91. package/dist/gateFailureCodes.d.ts +2 -0
  92. package/dist/gateFailureCodes.js +15 -0
  93. package/dist/gateOutcome.d.ts +3 -1
  94. package/dist/gateOutcome.js +25 -6
  95. package/dist/gateVocabulary.d.ts +5 -0
  96. package/dist/gateVocabulary.js +64 -2
  97. package/dist/generated/engineAskFaceTables.js +2 -2
  98. package/dist/generated/engineFactTables.d.ts +6 -3
  99. package/dist/generated/engineFactTables.js +22 -4
  100. package/dist/generated/engineNoticeTables.js +9 -0
  101. package/dist/generated/toolNameTables.d.ts +1 -0
  102. package/dist/generated/toolNameTables.js +1 -0
  103. package/dist/hitl/allowRuleShadow.d.ts +6 -1
  104. package/dist/hitl/allowRuleShadow.js +21 -17
  105. package/dist/hitl/approvalCardReading.d.ts +15 -0
  106. package/dist/hitl/approvalCardReading.js +154 -0
  107. package/dist/hitl/approvalCardReasons.d.ts +13 -0
  108. package/dist/hitl/approvalCardReasons.js +120 -0
  109. package/dist/hitl/approvalHolds.d.ts +47 -15
  110. package/dist/hitl/approvalHolds.js +134 -28
  111. package/dist/hitl/approvalResolution.d.ts +51 -26
  112. package/dist/hitl/approvalResolution.js +86 -122
  113. package/dist/hitl/approvalsFeed.js +6 -18
  114. package/dist/hitl/askClassPair.d.ts +2 -0
  115. package/dist/hitl/askClassPair.js +1 -0
  116. package/dist/hitl/askGateWire.d.ts +20 -2
  117. package/dist/hitl/askGateWire.js +49 -1
  118. package/dist/hitl/askParkRowRouting.d.ts +5 -0
  119. package/dist/hitl/askParkRowRouting.js +32 -1
  120. package/dist/hitl/askSettlementLine.d.ts +18 -0
  121. package/dist/hitl/askSettlementLine.js +79 -0
  122. package/dist/hitl/automaticAnswerVerdict.d.ts +1 -1
  123. package/dist/hitl/automaticAnswerVerdict.js +21 -5
  124. package/dist/hitl/crashConverged.d.ts +11 -20
  125. package/dist/hitl/crashConverged.js +56 -0
  126. package/dist/hitl/crashConvergedNotice.d.ts +3 -1
  127. package/dist/hitl/crashConvergedNotice.js +48 -11
  128. package/dist/hitl/decisionConflict.js +3 -10
  129. package/dist/hitl/decisionRefusal.d.ts +40 -1
  130. package/dist/hitl/decisionRefusal.js +199 -42
  131. package/dist/hitl/frameRouter.d.ts +5 -2
  132. package/dist/hitl/frameRouter.js +20 -16
  133. package/dist/hitl/gateLedger.d.ts +2 -0
  134. package/dist/hitl/gateLedger.js +50 -13
  135. package/dist/hitl/hitlBridge.d.ts +1 -2
  136. package/dist/hitl/hitlBridge.js +10 -7
  137. package/dist/hitl/livePendingAsk.d.ts +3 -3
  138. package/dist/hitl/livePendingAsk.js +7 -18
  139. package/dist/hitl/parkResolver.d.ts +2 -24
  140. package/dist/hitl/parkResolver.js +61 -97
  141. package/dist/hitl/persistedRulesWire.d.ts +24 -0
  142. package/dist/hitl/persistedRulesWire.js +122 -2
  143. package/dist/hitl/planReviewWire.d.ts +26 -13
  144. package/dist/hitl/planReviewWire.js +112 -78
  145. package/dist/hitl/refusedToolNameProse.d.ts +0 -1
  146. package/dist/hitl/refusedToolNameProse.js +0 -3
  147. package/dist/hitl/replayedApproval.d.ts +4 -3
  148. package/dist/hitl/replayedApproval.js +7 -4
  149. package/dist/hitl/sessionPolicyDeliverable.js +2 -4
  150. package/dist/hitl/sessionPolicyWire.d.ts +32 -20
  151. package/dist/hitl/sessionPolicyWire.js +162 -52
  152. package/dist/hitl/standingRows.d.ts +20 -2
  153. package/dist/hitl/standingRows.js +69 -8
  154. package/dist/hitl/toolApprovalWire.d.ts +87 -152
  155. package/dist/hitl/toolApprovalWire.js +591 -380
  156. package/dist/hookMatcherVerdict.d.ts +6 -1
  157. package/dist/hookMatcherVerdict.js +14 -7
  158. package/dist/hooksWireCaps.d.ts +2 -2
  159. package/dist/hooksWireCaps.js +59 -55
  160. package/dist/i18n/messages.en.d.ts +121 -0
  161. package/dist/i18n/messages.en.js +119 -0
  162. package/dist/i18n/messages.zh.d.ts +3 -0
  163. package/dist/i18n/messages.zh.js +120 -0
  164. package/dist/i18n/translate.d.ts +25 -0
  165. package/dist/i18n/translate.js +127 -0
  166. package/dist/index.d.ts +53 -20
  167. package/dist/index.js +38 -11
  168. package/dist/inheritEnvCapability.d.ts +31 -0
  169. package/dist/inheritEnvCapability.js +104 -0
  170. package/dist/liveModelCatalog.d.ts +1 -2
  171. package/dist/liveModelCatalog.js +2 -6
  172. package/dist/liveQuestionStore.d.ts +2 -21
  173. package/dist/mcpLiveness.d.ts +2 -1
  174. package/dist/mcpProbeWire.d.ts +6 -1
  175. package/dist/mcpProbeWire.js +1 -1
  176. package/dist/mcpWireCaps.d.ts +13 -2
  177. package/dist/mcpWireCaps.js +48 -0
  178. package/dist/memoryEntriesWire.d.ts +4 -9
  179. package/dist/model/modelSupplyRules.d.ts +0 -2
  180. package/dist/model/modelSupplyRules.js +3 -12
  181. package/dist/model/modelsPolicy.d.ts +0 -5
  182. package/dist/model/modelsPolicy.js +6 -36
  183. package/dist/model/subagentModelWord.d.ts +31 -0
  184. package/dist/model/subagentModelWord.js +261 -0
  185. package/dist/notifications.d.ts +6 -0
  186. package/dist/notifications.js +71 -23
  187. package/dist/outputStyleSeatCapability.d.ts +0 -3
  188. package/dist/outputStyleSeatCapability.js +0 -3
  189. package/dist/ownKey.d.ts +15 -0
  190. package/dist/ownKey.js +60 -3
  191. package/dist/panelReduce.d.ts +15 -9
  192. package/dist/panelReduce.js +680 -549
  193. package/dist/panelStateHolder.d.ts +3 -7
  194. package/dist/panelStateHolder.js +14 -130
  195. package/dist/peerLaneCapability.d.ts +0 -4
  196. package/dist/peerLaneCapability.js +0 -6
  197. package/dist/permissionRulesWriteCapability.d.ts +0 -4
  198. package/dist/permissionRulesWriteCapability.js +0 -6
  199. package/dist/permissionWireCaps.d.ts +2 -2
  200. package/dist/permissionWireCaps.js +2 -0
  201. package/dist/permissionsAllowGrantCapability.d.ts +0 -4
  202. package/dist/permissionsAllowGrantCapability.js +0 -6
  203. package/dist/permissionsDeclaration.d.ts +0 -11
  204. package/dist/permissionsDeclaration.js +60 -53
  205. package/dist/pluginHooksWire.d.ts +1 -1
  206. package/dist/pluginHooksWire.js +3 -6
  207. package/dist/preemptWire.d.ts +44 -0
  208. package/dist/preemptWire.js +83 -0
  209. package/dist/printToolResultFrame.js +15 -4
  210. package/dist/replayBody.d.ts +3 -0
  211. package/dist/replayBody.js +14 -0
  212. package/dist/request/taskRequest.d.ts +0 -1
  213. package/dist/request/taskRequest.js +0 -3
  214. package/dist/resumeRefusalCopy.d.ts +2 -1
  215. package/dist/resumeRefusalCopy.js +38 -2
  216. package/dist/retryStatus.d.ts +8 -0
  217. package/dist/retryStatus.js +106 -1
  218. package/dist/rewindArchiveCapability.d.ts +0 -4
  219. package/dist/rewindArchiveCapability.js +2 -10
  220. package/dist/rewindArchiveReading.d.ts +0 -1
  221. package/dist/rewindArchiveReading.js +0 -3
  222. package/dist/runCancelContext.d.ts +2 -1
  223. package/dist/runCancelContext.js +4 -2
  224. package/dist/runReattachPolicy.d.ts +31 -0
  225. package/dist/runReattachPolicy.js +46 -0
  226. package/dist/runTerminal.d.ts +3 -6
  227. package/dist/runTerminal.js +8 -9
  228. package/dist/sandboxWire.d.ts +3 -1
  229. package/dist/sandboxWire.js +76 -27
  230. package/dist/scenarioWire.js +1 -1
  231. package/dist/seam.d.ts +24 -2
  232. package/dist/seam.js +15 -3
  233. package/dist/seatContract.d.ts +53 -10
  234. package/dist/seatContract.js +132 -81
  235. package/dist/sessionPolicyCapability.d.ts +0 -4
  236. package/dist/sessionPolicyCapability.js +0 -6
  237. package/dist/sessionSyncFileHistoryCapability.d.ts +0 -3
  238. package/dist/sessionSyncFileHistoryCapability.js +0 -3
  239. package/dist/skillToolListsCapability.d.ts +0 -3
  240. package/dist/skillToolListsCapability.js +0 -3
  241. package/dist/sqlEngineCapability.d.ts +0 -4
  242. package/dist/sqlEngineCapability.js +0 -6
  243. package/dist/steerPriorityCapability.d.ts +0 -3
  244. package/dist/steerPriorityCapability.js +0 -3
  245. package/dist/streamDrainingLegs.d.ts +4 -0
  246. package/dist/streamDrainingLegs.js +6 -1
  247. package/dist/subagent/engineCompactWire.d.ts +0 -1
  248. package/dist/subagent/engineCompactWire.js +7 -5
  249. package/dist/subagent/engineTaskHandleWire.js +4 -7
  250. package/dist/subagentContentStore.js +1 -11
  251. package/dist/submitReopen.d.ts +24 -0
  252. package/dist/submitReopen.js +75 -0
  253. package/dist/terminalStatuses.d.ts +3 -0
  254. package/dist/terminalStatuses.js +10 -2
  255. package/dist/toolResult.d.ts +10 -1
  256. package/dist/toolResult.js +34 -6
  257. package/dist/toolRoster.d.ts +0 -2
  258. package/dist/toolRoster.js +0 -2
  259. package/dist/turnFailurePresentation.d.ts +28 -0
  260. package/dist/turnFailurePresentation.js +205 -0
  261. package/dist/userInvokedSkillsCapability.d.ts +0 -3
  262. package/dist/userInvokedSkillsCapability.js +0 -3
  263. package/dist/webSearchBackendCapability.d.ts +0 -4
  264. package/dist/webSearchBackendCapability.js +0 -6
  265. package/dist/wireErrorTriage.js +5 -24
  266. package/dist/wireFailureShape.d.ts +62 -5
  267. package/dist/wireFailureShape.js +105 -5
  268. package/dist/wireRefusalCopy.d.ts +12 -2
  269. package/dist/wireRefusalCopy.js +50 -52
  270. package/dist/workflowsJournalCapability.d.ts +0 -4
  271. package/dist/workflowsJournalCapability.js +0 -6
  272. package/dist/writeProtectionCapability.d.ts +0 -4
  273. package/dist/writeProtectionCapability.js +0 -6
  274. package/docs/INTEGRATION-CLIENTS.md +1253 -46
  275. package/package.json +5 -4
  276. package/dist/attachmentSeatCapability.d.ts +0 -12
  277. package/dist/attachmentSeatCapability.js +0 -23
  278. package/dist/hitl/approvalOutcomeNote.d.ts +0 -10
  279. package/dist/hitl/approvalOutcomeNote.js +0 -29
  280. package/dist/sessionReadRedactionCapability.d.ts +0 -13
  281. package/dist/sessionReadRedactionCapability.js +0 -35
@@ -1,4 +1,4 @@
1
- import { chrome, mainLane, transcript, messageIdentityOf } from './ids.js';
1
+ import { chrome, mainLane, segmentRowId, transcript, messageIdentityOf } from './ids.js';
2
2
  import { estimateCjkTokens, FLUSH_INTERVAL_MS } from './wireShapes.js';
3
3
  import { resolveTextSegmentAuthority } from './textSegmentAuthority.js';
4
4
  export const SEMA_SEGMENT_ID_KEY = '_sema_segment_id';
@@ -44,14 +44,15 @@ export function createTextStream(ctx, idOf) {
44
44
  : FLUSH_INTERVAL_MS;
45
45
  let segmentAnchor = null;
46
46
  let thinkingAnchor = null;
47
+ let segmentLast = null;
48
+ let thinkingLast = null;
47
49
  let committedThinking = [];
48
50
  let thinkingSettled = false;
49
51
  let segmentWindowAnchor = null;
50
- let segmentWindowSerial = 0;
51
52
  let segmentIdCache = null;
52
53
  const segmentIdNow = () => {
53
54
  if (segmentIdCache === null)
54
- segmentIdCache = idOf(segmentWindowAnchor ?? {}, `segment${segmentWindowSerial}`);
55
+ segmentIdCache = idOf(segmentWindowAnchor ?? {}, 'segment');
55
56
  return segmentIdCache;
56
57
  };
57
58
  function* takeThinking() {
@@ -61,7 +62,7 @@ export function createTextStream(ctx, idOf) {
61
62
  const msg = {
62
63
  type: 'assistant',
63
64
  message: { role: 'assistant', content: [{ type: 'thinking', thinking }], ...messageIdentityOf(anchor, ctx) },
64
- uuid: idOf(anchor, 'thinking'),
65
+ uuid: segmentRowId(idOf, anchor, thinkingLast, 'thinking'),
65
66
  session_id: ctx.sessionId,
66
67
  parent_tool_use_id: null,
67
68
  };
@@ -70,6 +71,7 @@ export function createTextStream(ctx, idOf) {
70
71
  thinkingSettled = false;
71
72
  thinking = '';
72
73
  thinkingAnchor = null;
74
+ thinkingLast = null;
73
75
  thinkingBlockOpen = false;
74
76
  yield chrome({ kind: 'thinking_activity', laneProof: mainLane(), active: false });
75
77
  yield transcript(msg, ctx.now());
@@ -82,7 +84,7 @@ export function createTextStream(ctx, idOf) {
82
84
  const msg = {
83
85
  type: 'assistant',
84
86
  message: { role: 'assistant', content: [{ type: 'text', text: body }], ...messageIdentityOf(anchor, ctx) },
85
- uuid: idOf(anchor, 'text'),
87
+ uuid: segmentRowId(idOf, anchor, segmentLast, 'text'),
86
88
  session_id: ctx.sessionId,
87
89
  parent_tool_use_id: null,
88
90
  };
@@ -94,6 +96,7 @@ export function createTextStream(ctx, idOf) {
94
96
  segmentSealed = '';
95
97
  answerSegment = '';
96
98
  segmentAnchor = null;
99
+ segmentLast = null;
97
100
  emittedAssistantText = true;
98
101
  textBlockOpen = false;
99
102
  yield transcript(msg, ctx.now());
@@ -158,6 +161,7 @@ export function createTextStream(ctx, idOf) {
158
161
  }
159
162
  if (answerSegment.length === 0 && segmentSealed.length === 0)
160
163
  segmentAnchor = frame;
164
+ segmentLast = frame;
161
165
  if (segmentWindowAnchor === null)
162
166
  segmentWindowAnchor = frame;
163
167
  answer += delta;
@@ -176,6 +180,7 @@ export function createTextStream(ctx, idOf) {
176
180
  thinkingSettled = false;
177
181
  }
178
182
  }
183
+ thinkingLast = frame;
179
184
  if (thinking.length === 0) {
180
185
  thinkingAnchor = frame;
181
186
  yield chrome({ kind: 'thinking_activity', laneProof: mainLane(), active: true });
@@ -283,6 +288,8 @@ export function createTextStream(ctx, idOf) {
283
288
  }
284
289
  else {
285
290
  segmentSealed += verdict.tail;
291
+ if (diverged && anchor !== undefined)
292
+ segmentLast = anchor;
286
293
  }
287
294
  answerSegment = '';
288
295
  if (answer.endsWith(liveSegment)) {
@@ -290,6 +297,8 @@ export function createTextStream(ctx, idOf) {
290
297
  }
291
298
  if (segmentAnchor === null && anchor !== undefined)
292
299
  segmentAnchor = anchor;
300
+ if (segmentLast === null && anchor !== undefined)
301
+ segmentLast = anchor;
293
302
  segmentCommitted = '';
294
303
  previousSegmentCommitted = '';
295
304
  idleFlushUsedInSegment = false;
@@ -314,7 +323,7 @@ export function createTextStream(ctx, idOf) {
314
323
  if (typeof committed === 'string')
315
324
  committedText += committed;
316
325
  },
317
- replaceThinkingSegment: (content) => {
326
+ replaceThinkingSegment: (content, anchor) => {
318
327
  const rows = committedThinking;
319
328
  committedThinking = [];
320
329
  const prefix = rows.map((r) => r.text).join('');
@@ -330,6 +339,8 @@ export function createTextStream(ctx, idOf) {
330
339
  thinkingPending = content.startsWith(emitted) ? content.slice(emitted.length) : '';
331
340
  thinking = content;
332
341
  thinkingSettled = content.length > 0;
342
+ if (diverged && anchor !== undefined)
343
+ thinkingLast = anchor;
333
344
  return { diverged, committedPrefixLen: 0, committedPrefixDiverged: false, committedUuids: [] };
334
345
  }
335
346
  const committedPrefixDiverged = !content.startsWith(prefix);
@@ -340,19 +351,25 @@ export function createTextStream(ctx, idOf) {
340
351
  thinkingPending = tail.startsWith(emitted) ? tail.slice(emitted.length) : '';
341
352
  thinking = tail;
342
353
  thinkingSettled = tail.length > 0;
354
+ if (diverged && anchor !== undefined)
355
+ thinkingLast = anchor;
343
356
  }
344
357
  return { diverged, committedPrefixLen: prefix.length, committedPrefixDiverged: false, ...(last !== undefined ? { committedUuid: last } : {}), committedUuids: uuids };
345
358
  }
346
359
  thinking = '';
347
360
  thinkingPending = '';
348
361
  thinkingAnchor = null;
362
+ thinkingLast = null;
349
363
  thinkingSettled = false;
350
364
  return { diverged: true, committedPrefixLen: prefix.length, committedPrefixDiverged: true, ...(last !== undefined ? { committedUuid: last } : {}), committedUuids: uuids };
351
365
  },
352
366
  segmentId: segmentIdNow,
367
+ anchorWindow: (frame) => {
368
+ if (segmentWindowAnchor === null)
369
+ segmentWindowAnchor = frame;
370
+ },
353
371
  rotateSegmentIdentity: (anchor) => {
354
372
  committedTextRows = [];
355
- segmentWindowSerial += 1;
356
373
  segmentWindowAnchor = anchor;
357
374
  segmentIdCache = null;
358
375
  },
@@ -1,25 +1,44 @@
1
1
  import type { AdapterContext, AdapterOutput } from '../seam.js';
2
- import { structuredToToolUseResult, type ToolResultBody } from '../toolResult.js';
2
+ import { structuredToToolUseResult, type ToolKillCause, type ToolResultBody } from '../toolResult.js';
3
3
  import { type Frame, type IdOf } from './ids.js';
4
+ import type { EngineRowRef } from '../engineRowRef.js';
5
+ import { type GateOutcomeView } from '../gateOutcome.js';
4
6
  type RichToolUseResult = NonNullable<ReturnType<typeof structuredToToolUseResult>>;
5
7
  export interface ToolResultOutcome {
6
8
  readonly body: ToolResultBody;
7
9
  readonly rich: RichToolUseResult | null;
8
10
  }
9
11
  export type ToolResultOwner = 'leader' | 'subagent';
10
- export declare function toolResultOutcomeOf(toolName: string, end: ToolEndPayload | undefined, rawInput: PendingToolUse['rawInput'], owner: ToolResultOwner, ledgerTier?: (isError: boolean) => RichToolUseResult | null): ToolResultOutcome;
12
+ export declare function toolResultOutcomeOf(toolName: string, end: ToolEndPayload | undefined, rawInput: PendingToolUse['rawInput'], owner: ToolResultOwner, ledgerTier?: (isError: boolean) => RichToolUseResult | null, killCauseOf?: () => ToolKillCause | undefined): ToolResultOutcome;
11
13
  export interface ToolResultEnvelopeKeys {
12
14
  readonly tool_use_result?: ToolResultBody['toolUseResult'];
13
15
  readonly _sema_degraded?: ToolResultBody['degraded'];
14
16
  }
15
17
  export declare function toolResultEnvelopeParts(o: ToolResultOutcome): ToolResultEnvelopeKeys;
16
- interface PendingToolUse {
18
+ export interface PendingToolUse {
17
19
  id: string;
18
20
  name: string;
19
- rawInput: unknown;
21
+ rawInput: {} | null | undefined;
20
22
  eventId?: string;
21
23
  parentToolCallId?: string;
24
+ engineRef?: EngineRowRef | undefined;
25
+ rowUuid?: string | undefined;
22
26
  }
27
+ export declare function toolResultRowIdentity(sources: readonly {
28
+ readonly eventId?: string | undefined;
29
+ readonly engineRef?: EngineRowRef | undefined;
30
+ }[], toolCallId: string, ctx: Pick<AdapterContext, 'uuid'>): {
31
+ readonly uuid: string;
32
+ readonly engineRef?: EngineRowRef;
33
+ };
34
+ export interface ToolResultRowFlagParts {
35
+ readonly _sema_not_executed?: true;
36
+ readonly _sema_collateral_abort?: true;
37
+ readonly _sema_interrupted_never_started?: true;
38
+ readonly _sema_approval_window_expired?: true;
39
+ readonly _sema_denial_limit_window_expired?: true;
40
+ }
41
+ export declare function toolResultRowFlagParts(arm: object | null | undefined): ToolResultRowFlagParts;
23
42
  interface ToolEndPayload {
24
43
  output?: unknown;
25
44
  structured?: unknown;
@@ -28,7 +47,9 @@ interface ToolEndPayload {
28
47
  eventId?: string | undefined;
29
48
  parentToolCallId?: string | undefined;
30
49
  denialKind?: string | undefined;
31
- notExecuted?: boolean | undefined;
50
+ closeArm?: object | undefined;
51
+ engineRef?: EngineRowRef | undefined;
52
+ gate?: GateOutcomeView | undefined;
32
53
  }
33
54
  export interface OpenCardView {
34
55
  has(id: string): boolean;
@@ -37,6 +58,7 @@ export interface OpenCardView {
37
58
  }
38
59
  export interface ToolCardLedger extends OpenCardView {
39
60
  open(p: PendingToolUse): void;
61
+ detach(id: string): PendingToolUse | undefined;
40
62
  close(p: PendingToolUse, end?: ToolEndPayload): Generator<AdapterOutput>;
41
63
  sweep(): Generator<AdapterOutput>;
42
64
  mintResponseId(frame: Frame): string;
@@ -5,14 +5,17 @@ import { flattenWireOutput } from './wireShapes.js';
5
5
  import { toolResultBlocksOf } from '../toolResultContent.js';
6
6
  import { bashExitOf, bashExitReadingFailed } from '../bashExitReading.js';
7
7
  import { isCcToolDenialKind } from '../gateVocabulary.js';
8
+ import { guardedRead, readFrameStringKey, readFrameTrueMark } from '../ownKey.js';
9
+ import { gateOutcomeOf, isApprovalWindowExpiredGate, isDenialLimitAutoDeniedGate } from '../gateOutcome.js';
10
+ import { TOOL_END_INTERRUPTED_NEVER_STARTED } from '../engineErrorCodes.js';
8
11
  function toolUseResultParts(v) {
9
12
  return v !== undefined ? { tool_use_result: v } : {};
10
13
  }
11
- export function toolResultOutcomeOf(toolName, end, rawInput, owner, ledgerTier) {
14
+ export function toolResultOutcomeOf(toolName, end, rawInput, owner, ledgerTier, killCauseOf) {
12
15
  const isError = end?.isError ?? false;
13
16
  const leaderLedger = owner === 'leader';
14
17
  const body = end && end.output !== undefined
15
- ? wireOutputToBody(toolName, end.output, isError, end.truncated === true, flattenWireOutput, end.structured, leaderLedger)
18
+ ? wireOutputToBody(toolName, end.output, isError, end.truncated === true, flattenWireOutput, end.structured, leaderLedger, killCauseOf)
16
19
  : degradedToolResultBody(isError);
17
20
  let rich = end?.structured !== undefined
18
21
  ? structuredToToolUseResult(end.structured, end.output !== undefined ? flattenWireOutput(end.output) : undefined, leaderLedger)
@@ -40,6 +43,27 @@ export function toolResultEnvelopeParts(o) {
40
43
  ...(o.body.degraded !== undefined ? { _sema_degraded: o.body.degraded } : {}),
41
44
  };
42
45
  }
46
+ export function toolResultRowIdentity(sources, toolCallId, ctx) {
47
+ for (const src of sources) {
48
+ if (typeof src.eventId === 'string' && src.eventId.length > 0) {
49
+ const ref = src.engineRef;
50
+ return { uuid: src.eventId, ...(ref !== undefined && ref.eventId === src.eventId ? { engineRef: ref } : {}) };
51
+ }
52
+ }
53
+ return { uuid: deriveTranscriptId({ toolCallId }, ctx) };
54
+ }
55
+ export function toolResultRowFlagParts(arm) {
56
+ if (arm === null || arm === undefined)
57
+ return {};
58
+ const gate = guardedRead(() => gateOutcomeOf(arm));
59
+ return {
60
+ ...(readFrameTrueMark(arm, 'notExecuted') ? { _sema_not_executed: true } : {}),
61
+ ...(readFrameTrueMark(arm, '_sema_collateral_abort') ? { _sema_collateral_abort: true } : {}),
62
+ ...(readFrameStringKey(arm, 'errorCode') === TOOL_END_INTERRUPTED_NEVER_STARTED ? { _sema_interrupted_never_started: true } : {}),
63
+ ...(isApprovalWindowExpiredGate(gate) ? { _sema_approval_window_expired: true } : {}),
64
+ ...(isDenialLimitAutoDeniedGate(gate) ? { _sema_denial_limit_window_expired: true } : {}),
65
+ };
66
+ }
43
67
  export function createToolCardLedger(ctx, idOf) {
44
68
  const pending = new Map();
45
69
  let assistantResponseId = null;
@@ -63,9 +87,9 @@ export function createToolCardLedger(ctx, idOf) {
63
87
  return null;
64
88
  lastLiveTodos = todo.newTodos;
65
89
  return { toolUseResult: todo.toolUseResult, isError: todo.isError };
66
- });
90
+ }, () => ctx.toolKillCause?.({ toolCallId: p.id, toolName: p.name }));
67
91
  const { body } = outcome;
68
- const eventId = end?.eventId ?? p.eventId;
92
+ const ident = toolResultRowIdentity([{ eventId: end?.eventId, engineRef: end?.engineRef }, { eventId: p.eventId, engineRef: p.engineRef }], p.id, ctx);
69
93
  yield transcript({
70
94
  type: 'user',
71
95
  message: {
@@ -79,12 +103,13 @@ export function createToolCardLedger(ctx, idOf) {
79
103
  },
80
104
  ],
81
105
  },
82
- uuid: eventId ?? deriveTranscriptId({ toolCallId: p.id }, ctx),
106
+ uuid: idOf.adopt(ident.uuid, ident.engineRef),
83
107
  session_id: ctx.sessionId,
84
108
  ...(parentToolCallId !== undefined ? { parent_tool_use_id: parentToolCallId } : {}),
85
109
  ...toolResultEnvelopeParts(outcome),
86
110
  ...(isCcToolDenialKind(end?.denialKind) ? { _sema_denial_kind: end.denialKind } : {}),
87
- ...(end?.notExecuted === true ? { _sema_not_executed: true } : {}),
111
+ ...(end?.gate !== undefined ? { _sema_gate: end.gate } : {}),
112
+ ...toolResultRowFlagParts(end?.closeArm),
88
113
  }, ctx.now());
89
114
  }
90
115
  function* closeCard(p, end) {
@@ -99,6 +124,14 @@ export function createToolCardLedger(ctx, idOf) {
99
124
  open: (p) => {
100
125
  pending.set(p.id, p);
101
126
  },
127
+ detach: (id) => {
128
+ const p = pending.get(id);
129
+ if (p === undefined)
130
+ return undefined;
131
+ pending.delete(id);
132
+ assistantResponseId = null;
133
+ return p;
134
+ },
102
135
  close: closeCard,
103
136
  *sweep() {
104
137
  for (const [, p] of pending) {
@@ -1,8 +1,13 @@
1
1
  import { frozenSet } from '../frozenSet.js';
2
+ import { CORE_BUILTIN_SUBAGENT_TYPES } from '../generated/engineFactTables.js';
2
3
  import { stripToolUseSideChannels } from '../adapter/types.js';
3
4
  import { toolEndOutputText } from '../toolResultContent.js';
4
5
  export const FLUSH_INTERVAL_MS = 100;
5
6
  export const IDLE_FLUSH_MS = 1500;
7
+ const SHELL_ROLE_SUBAGENT_TYPE = 'worker';
8
+ function isHonouredSubagentType(word) {
9
+ return word === SHELL_ROLE_SUBAGENT_TYPE || CORE_BUILTIN_SUBAGENT_TYPES.includes(word);
10
+ }
6
11
  export const SUBAGENT_TOOL_NAMES = frozenSet(['Task', 'Agent', 'Fork']);
7
12
  export const WORKFLOW_TOOL_NAMES = frozenSet(['Workflow', 'RunWorkflow', 'run_workflow']);
8
13
  export const TASK_TOOL_NAMES = new Set(['TodoWrite', 'TaskCreate', 'TaskUpdate']);
@@ -61,8 +66,7 @@ export function sanitizeToolUseBlock(block) {
61
66
  }
62
67
  if (SUBAGENT_TOOL_NAMES.has(out.name) && out.input && typeof out.input === 'object') {
63
68
  const inp = out.input;
64
- if (typeof inp.subagent_type === 'string' &&
65
- !['fork', 'general-purpose', 'worker'].includes(inp.subagent_type)) {
69
+ if (typeof inp.subagent_type === 'string' && !isHonouredSubagentType(inp.subagent_type)) {
66
70
  delete inp.subagent_type;
67
71
  }
68
72
  }
package/dist/adapt.d.ts CHANGED
@@ -1,10 +1,12 @@
1
1
  import type { AdapterContext, AdapterOutput, WireToCcAdapter } from './seam.js';
2
2
  export { CANCEL_MESSAGE, estimateCjkTokens, flattenWireOutput, FLUSH_INTERVAL_MS, IDLE_FLUSH_MS, REJECT_MESSAGE, sanitizeToolUseBlock, SUBAGENT_TOOL_NAMES, WORKFLOW_TOOL_NAMES, } from './adapt/wireShapes.js';
3
+ import { type ParkedToolRowSnapshot } from './adapt/instanceLedger.js';
3
4
  export interface AdapterLedgerState {
4
5
  version: 1;
5
6
  renderedNotifications: string[];
6
7
  notifiedRuns: string[];
7
8
  cardEnqueuedRuns: string[];
9
+ parkedToolRows?: ParkedToolRowSnapshot[];
8
10
  }
9
11
  export declare const ADAPTER_COVERAGE: {
10
12
  readonly frames: readonly ["assistant", "user", "stream_event", "turn_usage", "result", "system", "task_notification", "workflow_complete", "diagnostics", "steering_injected", "workspace_changed", "human_input", "message_committed", "engine_notice", "text_end", "prompt_suggestions", "retry_status", "task_progress", "tool_end_result(label 补位 + 关卡 settle + response-id 复位 + 开卡台账出栈 + 经 cards.close 铸 tool_result)"];
package/dist/adapt.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import { isEngineWorkflowNotified, isWorkflowCompletionCardEnqueued, listNotifiedRuns, listWorkflowCompletionCardsEnqueued, markEngineWorkflowNotified, noteWorkflowCompletionCardEnqueued, parseTranscriptNotificationSeeds, } from './notifications.js';
2
2
  export { CANCEL_MESSAGE, estimateCjkTokens, flattenWireOutput, FLUSH_INTERVAL_MS, IDLE_FLUSH_MS, REJECT_MESSAGE, sanitizeToolUseBlock, SUBAGENT_TOOL_NAMES, WORKFLOW_TOOL_NAMES, } from './adapt/wireShapes.js';
3
3
  import { IDLE_FLUSH_MS } from './adapt/wireShapes.js';
4
- import { chrome, mainLane, makeIdOf } from './adapt/ids.js';
4
+ import { carryRowSidecars, chrome, mainLane, makeIdOf } from './adapt/ids.js';
5
5
  import { createTextStream } from './adapt/textStream.js';
6
6
  import { createToolCardLedger } from './adapt/toolCards.js';
7
7
  import { createPanelTaskLedger } from './adapt/panelTasks.js';
@@ -122,6 +122,7 @@ class WireToCcAdapterImpl {
122
122
  renderedNotifications: this.ledger.listRenderedNotifications(),
123
123
  notifiedRuns: listNotifiedRuns(),
124
124
  cardEnqueuedRuns: listWorkflowCompletionCardsEnqueued(),
125
+ ...((rows) => (rows.length > 0 ? { parkedToolRows: rows } : {}))(this.ledger.listParkedToolRows()),
125
126
  };
126
127
  }
127
128
  importLedger(state) {
@@ -142,6 +143,7 @@ class WireToCcAdapterImpl {
142
143
  n += this.ledger.takeRenderedNotifications(rendered);
143
144
  takeModule(s.notifiedRuns, isEngineWorkflowNotified, markEngineWorkflowNotified);
144
145
  takeModule(s.cardEnqueuedRuns, isWorkflowCompletionCardEnqueued, noteWorkflowCompletionCardEnqueued);
146
+ n += this.ledger.takeParkedToolRows(s.parkedToolRows);
145
147
  return n;
146
148
  }
147
149
  importLedgerFromTranscript(messages) {
@@ -159,19 +161,22 @@ class WireToCcAdapterImpl {
159
161
  async *adapt(frames, ctx) {
160
162
  const slot = {};
161
163
  for await (const out of this.adaptUnstamped(frames, ctx, slot)) {
162
- yield slot.text === undefined ? out : slot.text.stampSegmentIdentity(out);
164
+ const segmented = slot.text === undefined ? out : slot.text.stampSegmentIdentity(out);
165
+ yield slot.idOf === undefined ? segmented : carryRowSidecars(segmented, slot.idOf);
163
166
  }
164
167
  }
165
168
  async *adaptUnstamped(frames, ctx, slot) {
166
169
  const inst = this.ledger;
167
170
  const turnStartAt = ctx.now();
168
171
  const idOf = makeIdOf(ctx);
172
+ slot.idOf = idOf;
169
173
  const text = createTextStream(ctx, idOf);
170
174
  slot.text = text;
171
175
  const cards = createToolCardLedger(ctx, idOf);
172
176
  const panel = createPanelTaskLedger(ctx, cards, inst);
173
177
  const flags = createTurnFlags(ctx, turnStartAt);
174
- const deps = { ctx, idOf, text, cards, panel, flags, inst };
178
+ const pass = inst.beginPass();
179
+ const deps = { ctx, idOf, text, cards, panel, flags, inst, pass };
175
180
  yield chrome({ kind: 'retry_status', laneProof: mainLane(), status: null });
176
181
  yield chrome({ kind: 'prompt_suggestions', laneProof: mainLane(), suggestions: null });
177
182
  yield chrome({ kind: 'thinking_activity', laneProof: mainLane(), active: false });
@@ -99,6 +99,7 @@ export type SelfHealOutcome = {
99
99
  taskId: string;
100
100
  status: string;
101
101
  alreadyOffered?: true;
102
+ pendingGateKind?: string | null;
102
103
  } | {
103
104
  kind: 'running-not-found';
104
105
  taskId: string;
@@ -159,6 +160,10 @@ export type SelfHealOutcome = {
159
160
  } | {
160
161
  kind: 'ask-run-not-found';
161
162
  taskId: string;
163
+ } | {
164
+ kind: 'ask-run-settled';
165
+ taskId: string;
166
+ status: string;
162
167
  } | {
163
168
  kind: 'stale-park-cancelled';
164
169
  taskId: string;
@@ -1,10 +1,11 @@
1
1
  import { abortableSleep } from '../abortableSleep.js';
2
2
  import { corruptStoredRowContent, corruptStoredRowWhere, effectiveWireErrorCode } from '../wireErrorTriage.js';
3
+ import { readThrownStatusSlot } from '../wireFailureShape.js';
3
4
  import { steerBodyOf, UNOBSERVED_STEER_PRIORITY } from '../controlRouter.js';
4
5
  import { atMostOnceFailureClass } from '../atMostOnce.js';
5
6
  import { readSteerReceipt } from '../steerReceipt.js';
6
7
  import { resumeAttachReplayDisclosure, runningAttachOffered } from '../hitl/resumeRunningCard.js';
7
- import { isSdkRunTerminal, SDK_PARKED_RUN_STATUSES } from '../terminalStatuses.js';
8
+ import { isSdkRunParked, isSdkRunTerminal, SDK_RUN_LIVE_STATUSES } from '../terminalStatuses.js';
8
9
  import { SDK_APPROVAL_DECIDE_GATE_KINDS, SDK_PLAN_REVIEW_GATE_KINDS } from '../generated/sdkFactTables.js';
9
10
  export const PLAN_REVIEW_GATE_KIND = 'plan_review';
10
11
  const APPROVAL_LEG_GATE_KINDS = SDK_APPROVAL_DECIDE_GATE_KINDS;
@@ -40,7 +41,7 @@ export function askParkForeignGateKind(row) {
40
41
  export const PLAN_REVIEW_STATES = Object.freeze(['needs_review']);
41
42
  export const ASK_PARK_STATES = Object.freeze(['suspended']);
42
43
  export const RUNNING_STATES = Object.freeze(['running']);
43
- export const CLAIM_HELD_STATES = Object.freeze(['running', ...SDK_PARKED_RUN_STATUSES]);
44
+ export const CLAIM_HELD_STATES = SDK_RUN_LIVE_STATUSES;
44
45
  export function selfHealSubmissionDisposition(outcome) {
45
46
  switch (outcome.kind) {
46
47
  case 'decision-pending':
@@ -76,16 +77,6 @@ function sessionOpts(deps) {
76
77
  const sessionId = deps?.sessionId;
77
78
  return typeof sessionId === 'string' && sessionId.length > 0 ? { session: sessionId } : {};
78
79
  }
79
- function errorSlot(e, key) {
80
- if (e === null || e === undefined)
81
- return undefined;
82
- try {
83
- return e[key];
84
- }
85
- catch {
86
- return undefined;
87
- }
88
- }
89
80
  function describeFailure(e) {
90
81
  const where = corruptStoredRowWhere(e);
91
82
  const rowNote = where === undefined ? '' : ` — ${corruptStoredRowContent(where)}`;
@@ -452,6 +443,7 @@ export async function attemptActiveRunSelfHeal(signal, runs, deps) {
452
443
  if (gateLeg === 'approval')
453
444
  return askParkArm(taskId, signal, runs, deps);
454
445
  let status = signal.activeTaskStatus;
446
+ const statusFresh = status === null;
455
447
  if (status === null) {
456
448
  if (typeof runs?.get !== 'function') {
457
449
  return { kind: 'state-unknown', taskId, detail: 'this client exposes no durable run verbs' };
@@ -468,8 +460,11 @@ export async function attemptActiveRunSelfHeal(signal, runs, deps) {
468
460
  if (status === null) {
469
461
  return { kind: 'state-unknown', taskId, detail: 'the engine reported no status for that run' };
470
462
  }
463
+ if (isSdkRunTerminal(status))
464
+ return { kind: 'running-settled', taskId, status };
465
+ const triageGate = signal.pendingGate && !statusFresh ? { pendingGateKind: signal.pendingGate.kind ?? null } : {};
471
466
  if (gateKind !== null)
472
- return { kind: 'not-parked', taskId, status };
467
+ return { kind: 'not-parked', taskId, status, ...triageGate };
473
468
  if (PLAN_REVIEW_STATES.includes(status))
474
469
  return planReviewArm(taskId, signal, deps);
475
470
  if (ASK_PARK_STATES.includes(status))
@@ -477,7 +472,7 @@ export async function attemptActiveRunSelfHeal(signal, runs, deps) {
477
472
  if (RUNNING_STATES.includes(status)) {
478
473
  return runningChoiceArm(taskId, status, signal, signal.activeTaskStatus !== null, runs, deps);
479
474
  }
480
- return { kind: 'not-parked', taskId, status };
475
+ return { kind: 'not-parked', taskId, status, ...triageGate };
481
476
  }
482
477
  async function planVerdict(taskId, deps) {
483
478
  try {
@@ -576,7 +571,7 @@ async function probeRunStatusOnce(taskId, durable, durableGet, deps) {
576
571
  answered = true;
577
572
  }
578
573
  catch (e) {
579
- if (errorSlot(e, 'status') === 404)
574
+ if (typeof e === 'object' && e !== null && readThrownStatusSlot(e) === 404)
580
575
  ghost = true;
581
576
  else
582
577
  errorCode = failureWireCode(e);
@@ -619,6 +614,8 @@ async function staleParkArm(taskId, busy, runs, deps) {
619
614
  return runningChoiceArm(taskId, fresh, busy, false, runs, deps);
620
615
  if (PLAN_REVIEW_STATES.includes(fresh))
621
616
  return planReviewArm(taskId, busy, deps);
617
+ if (isSdkRunTerminal(fresh))
618
+ return { kind: 'ask-run-settled', taskId, status: fresh };
622
619
  if (!ASK_PARK_STATES.includes(fresh))
623
620
  return reopenFailed;
624
621
  const offer = deps?.offerStaleParkChoice;
@@ -656,6 +653,10 @@ async function staleParkArm(taskId, busy, runs, deps) {
656
653
  if (afterCard.status === null)
657
654
  return withFailureCode(reopenFailedAfterCard, afterCard.errorCode);
658
655
  if (!ASK_PARK_STATES.includes(afterCard.status)) {
656
+ if (isSdkRunTerminal(afterCard.status))
657
+ return { kind: 'ask-run-settled', taskId, status: afterCard.status };
658
+ if (RUNNING_STATES.includes(afterCard.status))
659
+ return { kind: 'not-parked', taskId, status: afterCard.status };
659
660
  return !CLAIM_HELD_STATES.includes(afterCard.status) ? reopenFailed : reopenFailedAfterCard;
660
661
  }
661
662
  const recheck = await readOwnedPendingCount(recheckOwnedPending, deps);
@@ -737,14 +738,10 @@ async function runningChoiceArm(taskId, status, busy, statusFromWire, runs, deps
737
738
  return { kind: 'running-not-found', taskId };
738
739
  if (probeCallerAborted())
739
740
  return notParked;
740
- if (fresh !== null && !RUNNING_STATES.includes(fresh)) {
741
- if (PLAN_REVIEW_STATES.includes(fresh))
742
- return planReviewArm(taskId, busy, deps);
743
- if (ASK_PARK_STATES.includes(fresh))
744
- return askParkArm(taskId, busy, runs, deps);
745
- if (isSdkRunTerminal(fresh))
746
- return { kind: 'running-settled', taskId, status: fresh };
747
- return { kind: 'not-parked', taskId, status: fresh };
741
+ if (fresh !== null) {
742
+ const routed = await routeFreshNonRunning(fresh, taskId, busy, runs, deps);
743
+ if (routed !== undefined)
744
+ return routed;
748
745
  }
749
746
  }
750
747
  const declineKey = runningChoiceDeclineKey(deps?.sessionId, taskId);
@@ -795,6 +792,16 @@ async function runningChoiceArm(taskId, status, busy, statusFromWire, runs, deps
795
792
  }
796
793
  }
797
794
  if (choice === 'cancel' && canCancel && runs?.cancel !== undefined && runs.get !== undefined) {
795
+ if (probeCallerAborted())
796
+ return notParked;
797
+ const preFire = await probeRunStatusOnce(taskId, runs, runs.get, deps);
798
+ if (preFire.ghost)
799
+ return { kind: 'running-not-found', taskId };
800
+ if (probeCallerAborted() || preFire.status === null)
801
+ return notParked;
802
+ const rerouted = await routeFreshNonRunning(preFire.status, taskId, busy, runs, deps);
803
+ if (rerouted !== undefined)
804
+ return rerouted;
798
805
  const verdict = await cancelAndConfirmRelease(taskId, runs, runs.get, deps);
799
806
  if (verdict.outcome === 'released') {
800
807
  return { kind: 'running-cancelled', taskId, ...(verdict.engineStatedRelease ? { releaseConfirmedByEngine: true } : {}) };
@@ -814,6 +821,17 @@ async function runningChoiceArm(taskId, status, busy, statusFromWire, runs, deps
814
821
  return { kind: 'running-attach', taskId };
815
822
  return notParked;
816
823
  }
824
+ async function routeFreshNonRunning(fresh, taskId, busy, runs, deps) {
825
+ if (RUNNING_STATES.includes(fresh))
826
+ return undefined;
827
+ if (PLAN_REVIEW_STATES.includes(fresh))
828
+ return planReviewArm(taskId, busy, deps);
829
+ if (ASK_PARK_STATES.includes(fresh))
830
+ return askParkArm(taskId, busy, runs, deps);
831
+ if (isSdkRunTerminal(fresh))
832
+ return { kind: 'running-settled', taskId, status: fresh };
833
+ return { kind: 'not-parked', taskId, status: fresh };
834
+ }
817
835
  export const INTERACTIVE_WAY_OUT = 'run /clear to keep working in a fresh session';
818
836
  const DEFAULT_WAY_OUT = INTERACTIVE_WAY_OUT;
819
837
  const DEFAULT_FRESH_SESSION = 'start a new session (drop --resume/--continue)';
@@ -853,11 +871,11 @@ export function activeRunSelfHealRow(outcome, signal, copy, origin, follow) {
853
871
  (outcome.kind !== 'plan-review-reopen-failed' || outcome.dismissedByUser !== true)
854
872
  ? keepSessionWayOutOf(copy)
855
873
  : null;
856
- const base = activeRunSelfHealBaseRow(outcome, signal, copy?.wayOut ?? DEFAULT_WAY_OUT, following, keep, engineDecide);
874
+ const base = activeRunSelfHealBaseRow(outcome, copy?.wayOut ?? DEFAULT_WAY_OUT, following, keep, engineDecide);
857
875
  const viaEngine = engineDecide ? decidePathClause(signal) : '';
858
876
  switch (outcome.kind) {
859
877
  case 'not-parked':
860
- return base + lastActivityClause(signal) + viaEngine + governanceOriginClause(signal);
878
+ return base + lastActivityClause(signal) + (outcome.pendingGateKind !== undefined ? viaEngine + governanceOriginClause(signal) : '');
861
879
  case 'state-unknown':
862
880
  return base + viaEngine + governanceOriginClause(signal);
863
881
  default:
@@ -961,7 +979,7 @@ function keepSessionWayOutOf(copy) {
961
979
  return null;
962
980
  }
963
981
  }
964
- function activeRunSelfHealBaseRow(outcome, signal, wayOut, following = false, keepSessionWayOut = null, engineDecide = true) {
982
+ function activeRunSelfHealBaseRow(outcome, wayOut, following = false, keepSessionWayOut = null, engineDecide = true) {
965
983
  switch (outcome.kind) {
966
984
  case 'decision-pending':
967
985
  return (`This session is held by an earlier turn${outcome.taskId ? ` (run ${outcome.taskId})` : ''} that ` +
@@ -1129,6 +1147,10 @@ function activeRunSelfHealBaseRow(outcome, signal, wayOut, following = false, ke
1129
1147
  `not-found — a lookup that cannot separate a run that is really gone from one this session is simply ` +
1130
1148
  `not allowed to read. Either way sema has nothing it can act on here, so it did NOT cancel anything. ` +
1131
1149
  `Your message was NOT sent; send it again (if the session really is free it will just run), or ${wayOut}.`);
1150
+ case 'ask-run-settled':
1151
+ return (`The previous turn was recorded as parked on a decision (run ${outcome.taskId}), but that run has already finished ` +
1152
+ `(status ${outcome.status}) — there is nothing left to answer and nothing to cancel, so sema did NOT cancel anything. ` +
1153
+ `Your message was NOT sent; send it again (once that run has let go of the session it will just run), or ${wayOut}.`);
1132
1154
  case 'stale-park-cancelled':
1133
1155
  if (outcome.releaseConfirmedByEngine === true) {
1134
1156
  return (`Run ${outcome.taskId} was parked on an approval that no longer exists on the engine, so there was ` +
@@ -1196,9 +1218,10 @@ function activeRunSelfHealBaseRow(outcome, signal, wayOut, following = false, ke
1196
1218
  `Your message was NOT sent; wait for that run, cancel it on the engine ` +
1197
1219
  `(POST /v1/runs/${outcome.taskId}/cancel), or ${wayOut}.`);
1198
1220
  }
1199
- if (signal?.pendingGate) {
1221
+ const parkedOn = outcome.pendingGateKind !== undefined ? gateKindPhrase(outcome.pendingGateKind) : isSdkRunParked(outcome.status) ? gateKindPhrase(null) : undefined;
1222
+ if (parkedOn !== undefined) {
1200
1223
  return (`This session is held by an earlier run (run ${outcome.taskId}, status ${outcome.status}) that is ` +
1201
- `waiting on ${gateKindPhrase(signal.pendingGate.kind)} — it will not finish on its own. sema did ` +
1224
+ `waiting on ${parkedOn} — it will not finish on its own. sema did ` +
1202
1225
  `NOT cancel it, because cancelling would decide that item for you. Your message was NOT sent; ` +
1203
1226
  `${wayOut} if you no longer want it.`);
1204
1227
  }
@@ -2,6 +2,7 @@ import type { AgentEvent, CheckpointGate, TaskResult } from '@sema-agent/sdk';
2
2
  import { type WiringManifestView } from './wiringManifestView.js';
3
3
  import { type SDKMessage, type EmitContext, type ModelUsage } from '../types.js';
4
4
  import { type McpLivenessView } from '../../mcpLiveness.js';
5
+ import { type ContextUsageSectionRow } from '../../ownKey.js';
5
6
  export declare const INTERNAL_SDK_ARM_TYPES: ReadonlySet<string>;
6
7
  export type EventProjectionNoneReason = 'usage_only' | 'terminal_delegated' | 'hitl_out_of_slice' | 'not_in_slice' | 'empty_payload';
7
8
  export type EventProjectionDropReason = 'malformed' | 'unknown_arm' | 'unsupported_arm';
@@ -66,11 +67,7 @@ export interface WiringManifestLspSeamView {
66
67
  mounted: boolean;
67
68
  lane?: string;
68
69
  }
69
- export interface ContextUsageSectionView {
70
- id: string;
71
- tokens: number;
72
- kind?: string;
73
- }
70
+ export type ContextUsageSectionView = ContextUsageSectionRow;
74
71
  export interface PromptManifestSectionView {
75
72
  id: string;
76
73
  chars: number;