@sema-agent/client-core 0.77.1 → 0.77.2

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 (382) hide show
  1. package/CHANGELOG.md +13 -1
  2. package/README.md +5 -4
  3. package/dist/abortableSleep.d.ts +0 -28
  4. package/dist/abortableSleep.js +0 -28
  5. package/dist/adapt/arms.d.ts +0 -46
  6. package/dist/adapt/arms.js +9 -544
  7. package/dist/adapt/ids.d.ts +0 -58
  8. package/dist/adapt/ids.js +0 -63
  9. package/dist/adapt/instanceLedger.d.ts +0 -25
  10. package/dist/adapt/instanceLedger.js +0 -20
  11. package/dist/adapt/panelTasks.d.ts +0 -69
  12. package/dist/adapt/panelTasks.js +0 -95
  13. package/dist/adapt/textSegmentAuthority.d.ts +1 -137
  14. package/dist/adapt/textSegmentAuthority.js +0 -54
  15. package/dist/adapt/textStream.d.ts +0 -252
  16. package/dist/adapt/textStream.js +2 -281
  17. package/dist/adapt/toolCards.d.ts +0 -46
  18. package/dist/adapt/toolCards.js +0 -23
  19. package/dist/adapt/turnFlags.d.ts +0 -54
  20. package/dist/adapt/turnFlags.js +1 -17
  21. package/dist/adapt/wireShapes.d.ts +0 -92
  22. package/dist/adapt/wireShapes.js +0 -83
  23. package/dist/adapt.d.ts +0 -55
  24. package/dist/adapt.js +1 -120
  25. package/dist/adapter/activeRunSelfHeal.d.ts +22 -515
  26. package/dist/adapter/activeRunSelfHeal.js +10 -625
  27. package/dist/adapter/downstream/eventToSdkMessage.d.ts +2 -305
  28. package/dist/adapter/downstream/eventToSdkMessage.js +2 -867
  29. package/dist/adapter/downstream/terminalToSdkResult.d.ts +2 -314
  30. package/dist/adapter/downstream/terminalToSdkResult.js +13 -560
  31. package/dist/adapter/downstream/turnUsageToModelUsage.d.ts +0 -95
  32. package/dist/adapter/downstream/turnUsageToModelUsage.js +2 -31
  33. package/dist/adapter/runStream.d.ts +0 -206
  34. package/dist/adapter/runStream.js +6 -596
  35. package/dist/adapter/types.d.ts +0 -111
  36. package/dist/adapter/types.js +0 -29
  37. package/dist/agentSession/backgroundView.d.ts +0 -106
  38. package/dist/agentSession/backgroundView.js +3 -49
  39. package/dist/agentSession/contract.d.ts +0 -98
  40. package/dist/agentSession/contract.js +0 -12
  41. package/dist/agentsWireCaps.d.ts +0 -72
  42. package/dist/agentsWireCaps.js +4 -72
  43. package/dist/approvalsStreamLiveCapability.d.ts +0 -25
  44. package/dist/approvalsStreamLiveCapability.js +0 -31
  45. package/dist/argvFlagValue.d.ts +0 -33
  46. package/dist/argvFlagValue.js +3 -35
  47. package/dist/attachmentsWireCaps.d.ts +0 -127
  48. package/dist/attachmentsWireCaps.js +0 -144
  49. package/dist/autoModeUnavailable.d.ts +0 -120
  50. package/dist/autoModeUnavailable.js +0 -144
  51. package/dist/classifierStatus.d.ts +0 -72
  52. package/dist/classifierStatus.js +0 -167
  53. package/dist/classifierVerdictWire.d.ts +0 -54
  54. package/dist/classifierVerdictWire.js +0 -133
  55. package/dist/clientContextWireCaps.d.ts +0 -37
  56. package/dist/clientContextWireCaps.js +0 -36
  57. package/dist/clientSlice.d.ts +0 -63
  58. package/dist/clientSlice.js +0 -45
  59. package/dist/cloudConfigWireCaps.d.ts +0 -86
  60. package/dist/cloudConfigWireCaps.js +2 -65
  61. package/dist/compensations.d.ts +0 -52
  62. package/dist/compensations.js +2 -63
  63. package/dist/controlRouter.d.ts +2 -208
  64. package/dist/controlRouter.js +1 -129
  65. package/dist/coreValuePorts.d.ts +0 -84
  66. package/dist/coreValuePorts.js +0 -29
  67. package/dist/decideReceipt.d.ts +0 -110
  68. package/dist/decideReceipt.js +0 -84
  69. package/dist/detachWire.d.ts +0 -130
  70. package/dist/detachWire.js +1 -130
  71. package/dist/deviceExecutorManagementCapability.d.ts +2 -35
  72. package/dist/deviceExecutorManagementCapability.js +1 -37
  73. package/dist/diagnostics.d.ts +0 -8
  74. package/dist/diagnostics.js +0 -8
  75. package/dist/diff/patch.d.ts +0 -17
  76. package/dist/diff/patch.js +0 -19
  77. package/dist/effectiveFacts.d.ts +0 -40
  78. package/dist/effectiveFacts.js +0 -22
  79. package/dist/effortWire.d.ts +0 -11
  80. package/dist/effortWire.js +0 -12
  81. package/dist/engineAgentPanelStore.d.ts +0 -169
  82. package/dist/engineAgentPanelStore.js +13 -293
  83. package/dist/engineCapReader.d.ts +0 -62
  84. package/dist/engineCapReader.js +1 -43
  85. package/dist/engineCapsCache.d.ts +0 -177
  86. package/dist/engineCapsCache.js +0 -199
  87. package/dist/engineCapsGenerationGuard.d.ts +0 -2
  88. package/dist/engineCapsGenerationGuard.js +0 -11
  89. package/dist/engineErrorCodes.d.ts +1 -316
  90. package/dist/engineErrorCodes.js +0 -427
  91. package/dist/engineHttpTools.d.ts +0 -29
  92. package/dist/engineHttpTools.js +0 -29
  93. package/dist/engineIdentity.d.ts +0 -83
  94. package/dist/engineIdentity.js +0 -88
  95. package/dist/engineInlineTaskStats.d.ts +0 -57
  96. package/dist/engineInlineTaskStats.js +1 -42
  97. package/dist/engineNoticeCodes.d.ts +0 -190
  98. package/dist/engineNoticeCodes.js +0 -182
  99. package/dist/engineSessionParam.d.ts +0 -30
  100. package/dist/engineSessionParam.js +0 -52
  101. package/dist/engineToolLabelStore.d.ts +0 -29
  102. package/dist/engineToolLabelStore.js +0 -31
  103. package/dist/engineWireSdk.d.ts +0 -90
  104. package/dist/engineWireSdk.js +0 -74
  105. package/dist/engineWireTarget.d.ts +0 -14
  106. package/dist/engineWireTarget.js +0 -39
  107. package/dist/env/localeGeo.d.ts +0 -12
  108. package/dist/env/localeGeo.js +2 -77
  109. package/dist/env/localeTag.d.ts +0 -34
  110. package/dist/env/localeTag.js +0 -32
  111. package/dist/env/uiLanguage.d.ts +0 -13
  112. package/dist/env/uiLanguage.js +0 -25
  113. package/dist/envFlag.d.ts +0 -37
  114. package/dist/envFlag.js +0 -40
  115. package/dist/executionLaneCapability.d.ts +0 -48
  116. package/dist/executionLaneCapability.js +0 -54
  117. package/dist/finalVerifyWire.d.ts +0 -67
  118. package/dist/finalVerifyWire.js +3 -43
  119. package/dist/fleet/fleetLedger.d.ts +0 -308
  120. package/dist/fleet/fleetLedger.js +10 -429
  121. package/dist/fleet/fleetProjection.d.ts +0 -240
  122. package/dist/fleet/fleetProjection.js +0 -189
  123. package/dist/fleet/fleetRowAgentType.d.ts +0 -6
  124. package/dist/fleet/fleetRowAgentType.js +1 -32
  125. package/dist/fleet/workflowSizeWarning.d.ts +0 -47
  126. package/dist/fleet/workflowSizeWarning.js +1 -46
  127. package/dist/fleetAgentPanelProjection.d.ts +0 -48
  128. package/dist/fleetAgentPanelProjection.js +8 -173
  129. package/dist/fleetTaskDesc.d.ts +0 -39
  130. package/dist/fleetTaskDesc.js +0 -69
  131. package/dist/forkWireCaps.d.ts +0 -23
  132. package/dist/forkWireCaps.js +1 -24
  133. package/dist/gateOutcome.d.ts +0 -140
  134. package/dist/gateOutcome.js +0 -85
  135. package/dist/gateVocabulary.d.ts +0 -114
  136. package/dist/gateVocabulary.js +1 -161
  137. package/dist/goalStopHook.d.ts +0 -127
  138. package/dist/goalStopHook.js +0 -178
  139. package/dist/headlessPermissionModeWire.d.ts +0 -76
  140. package/dist/headlessPermissionModeWire.js +1 -155
  141. package/dist/headlessReconnectWire.d.ts +0 -84
  142. package/dist/headlessReconnectWire.js +13 -67
  143. package/dist/hitl/approvalDecisionNoteAudit.d.ts +0 -49
  144. package/dist/hitl/approvalDecisionNoteAudit.js +0 -56
  145. package/dist/hitl/approvalOutcomeNote.d.ts +0 -2
  146. package/dist/hitl/approvalOutcomeNote.js +0 -20
  147. package/dist/hitl/approvalResolution.d.ts +0 -113
  148. package/dist/hitl/approvalResolution.js +0 -66
  149. package/dist/hitl/approvalsFeed.d.ts +0 -183
  150. package/dist/hitl/approvalsFeed.js +12 -243
  151. package/dist/hitl/armedGateRegistry.d.ts +0 -55
  152. package/dist/hitl/armedGateRegistry.js +0 -146
  153. package/dist/hitl/askGateWire.d.ts +0 -86
  154. package/dist/hitl/askGateWire.js +1 -95
  155. package/dist/hitl/askParkRowRouting.d.ts +0 -123
  156. package/dist/hitl/askParkRowRouting.js +1 -89
  157. package/dist/hitl/crashConverged.d.ts +0 -148
  158. package/dist/hitl/crashConverged.js +0 -214
  159. package/dist/hitl/editedRuleTextPrecheck.d.ts +0 -109
  160. package/dist/hitl/editedRuleTextPrecheck.js +0 -71
  161. package/dist/hitl/frameRouter.d.ts +0 -134
  162. package/dist/hitl/frameRouter.js +6 -378
  163. package/dist/hitl/gateIdentity.d.ts +0 -39
  164. package/dist/hitl/gateIdentity.js +0 -41
  165. package/dist/hitl/gateLedger.d.ts +0 -267
  166. package/dist/hitl/gateLedger.js +0 -121
  167. package/dist/hitl/hitlBridge.d.ts +7 -431
  168. package/dist/hitl/hitlBridge.js +7 -476
  169. package/dist/hitl/hitlHostSurface.d.ts +0 -150
  170. package/dist/hitl/hitlHostSurface.js +0 -169
  171. package/dist/hitl/livePendingAsk.d.ts +0 -91
  172. package/dist/hitl/livePendingAsk.js +0 -74
  173. package/dist/hitl/localAllowRule.d.ts +0 -62
  174. package/dist/hitl/localAllowRule.js +1 -33
  175. package/dist/hitl/parkOwnership.d.ts +0 -56
  176. package/dist/hitl/parkOwnership.js +0 -22
  177. package/dist/hitl/parkResolver.d.ts +3 -88
  178. package/dist/hitl/parkResolver.js +8 -349
  179. package/dist/hitl/parkRowBirthWait.d.ts +2 -26
  180. package/dist/hitl/parkRowBirthWait.js +3 -93
  181. package/dist/hitl/persistedRulesWire.d.ts +13 -358
  182. package/dist/hitl/persistedRulesWire.js +0 -310
  183. package/dist/hitl/planReviewWire.d.ts +4 -176
  184. package/dist/hitl/planReviewWire.js +9 -312
  185. package/dist/hitl/resumeRunningCard.d.ts +0 -105
  186. package/dist/hitl/resumeRunningCard.js +0 -105
  187. package/dist/hitl/sessionPolicyWire.d.ts +11 -191
  188. package/dist/hitl/sessionPolicyWire.js +0 -149
  189. package/dist/hitl/suspendedReopen.d.ts +3 -24
  190. package/dist/hitl/suspendedReopen.js +0 -14
  191. package/dist/hitl/toolApprovalWire.d.ts +5 -1308
  192. package/dist/hitl/toolApprovalWire.js +5 -945
  193. package/dist/hooksWireCaps.d.ts +0 -38
  194. package/dist/hooksWireCaps.js +0 -190
  195. package/dist/host.d.ts +0 -105
  196. package/dist/host.js +0 -33
  197. package/dist/hostEnv.d.ts +0 -14
  198. package/dist/hostEnv.js +0 -13
  199. package/dist/imagesWireCaps.d.ts +0 -21
  200. package/dist/imagesWireCaps.js +0 -22
  201. package/dist/index.d.ts +0 -134
  202. package/dist/index.js +0 -476
  203. package/dist/interactiveHalt.d.ts +5 -153
  204. package/dist/interactiveHalt.js +0 -111
  205. package/dist/interactiveToolsWire.d.ts +0 -62
  206. package/dist/interactiveToolsWire.js +1 -67
  207. package/dist/leaderConflict.d.ts +0 -59
  208. package/dist/leaderConflict.js +0 -48
  209. package/dist/limitsWire.d.ts +0 -125
  210. package/dist/limitsWire.js +2 -120
  211. package/dist/liveInitToolFace.d.ts +0 -77
  212. package/dist/liveInitToolFace.js +1 -109
  213. package/dist/liveModelCatalog.d.ts +0 -52
  214. package/dist/liveModelCatalog.js +0 -48
  215. package/dist/liveQuestionStore.d.ts +0 -87
  216. package/dist/liveQuestionStore.js +1 -56
  217. package/dist/mcpLiveness.d.ts +0 -151
  218. package/dist/mcpLiveness.js +0 -122
  219. package/dist/mcpPanel.d.ts +0 -104
  220. package/dist/mcpPanel.js +0 -49
  221. package/dist/mcpReconnect.d.ts +0 -58
  222. package/dist/mcpReconnect.js +0 -69
  223. package/dist/mcpWireCaps.d.ts +0 -55
  224. package/dist/mcpWireCaps.js +1 -13
  225. package/dist/memoryComplianceCapability.d.ts +3 -57
  226. package/dist/memoryComplianceCapability.js +0 -57
  227. package/dist/memoryEntriesWire.d.ts +6 -198
  228. package/dist/memoryEntriesWire.js +0 -144
  229. package/dist/memoryOriginCapability.d.ts +3 -53
  230. package/dist/memoryOriginCapability.js +0 -50
  231. package/dist/memorySpecWire.d.ts +0 -116
  232. package/dist/memorySpecWire.js +0 -150
  233. package/dist/model/catalog.d.ts +0 -111
  234. package/dist/model/catalog.js +0 -87
  235. package/dist/model/catalogLoader.d.ts +0 -114
  236. package/dist/model/catalogLoader.js +2 -139
  237. package/dist/model/modelSupplyRules.d.ts +1 -55
  238. package/dist/model/modelSupplyRules.js +0 -62
  239. package/dist/model/providerAuth.d.ts +0 -103
  240. package/dist/model/providerAuth.js +2 -38
  241. package/dist/model/providerCatalog.d.ts +0 -45
  242. package/dist/model/providerCatalog.js +0 -37
  243. package/dist/model/providerPresets.d.ts +0 -33
  244. package/dist/model/providerPresets.js +2 -91
  245. package/dist/model/tierVocabulary.d.ts +0 -31
  246. package/dist/model/tierVocabulary.js +0 -27
  247. package/dist/modelBudgetRule.d.ts +0 -39
  248. package/dist/modelBudgetRule.js +0 -39
  249. package/dist/modelCapabilityProbe.d.ts +0 -175
  250. package/dist/modelCapabilityProbe.js +0 -147
  251. package/dist/modelWireCaps.d.ts +0 -13
  252. package/dist/modelWireCaps.js +0 -13
  253. package/dist/notifications.d.ts +0 -233
  254. package/dist/notifications.js +14 -492
  255. package/dist/oneShotWireCaps.d.ts +0 -34
  256. package/dist/oneShotWireCaps.js +0 -35
  257. package/dist/ownKey.d.ts +0 -33
  258. package/dist/ownKey.js +0 -33
  259. package/dist/panelRunningHistory.d.ts +0 -28
  260. package/dist/panelRunningHistory.js +0 -43
  261. package/dist/peerFrames.d.ts +0 -71
  262. package/dist/peerFrames.js +0 -168
  263. package/dist/peerLaneCapability.d.ts +0 -44
  264. package/dist/peerLaneCapability.js +0 -52
  265. package/dist/permissionRuleIssue.d.ts +0 -30
  266. package/dist/permissionRuleIssue.js +0 -78
  267. package/dist/permissionRulesWriteCapability.d.ts +0 -46
  268. package/dist/permissionRulesWriteCapability.js +0 -54
  269. package/dist/permissionWireCaps.d.ts +0 -37
  270. package/dist/permissionWireCaps.js +0 -37
  271. package/dist/postureKnob.d.ts +0 -71
  272. package/dist/postureKnob.js +0 -86
  273. package/dist/principalWire.d.ts +0 -17
  274. package/dist/principalWire.js +0 -17
  275. package/dist/printToolResultFrame.d.ts +0 -100
  276. package/dist/printToolResultFrame.js +0 -33
  277. package/dist/promptProfileWireCaps.d.ts +0 -13
  278. package/dist/promptProfileWireCaps.js +0 -13
  279. package/dist/readFacePosture.d.ts +0 -43
  280. package/dist/readFacePosture.js +0 -46
  281. package/dist/request/printNotification.d.ts +0 -20
  282. package/dist/request/printNotification.js +0 -55
  283. package/dist/request/taskRequest.d.ts +0 -249
  284. package/dist/request/taskRequest.js +6 -498
  285. package/dist/resumeRefusalCopy.d.ts +0 -136
  286. package/dist/resumeRefusalCopy.js +1 -117
  287. package/dist/retainBackgroundWireCaps.d.ts +0 -48
  288. package/dist/retainBackgroundWireCaps.js +0 -48
  289. package/dist/retryStatus.d.ts +2 -221
  290. package/dist/retryStatus.js +0 -107
  291. package/dist/rewindWireCaps.d.ts +0 -27
  292. package/dist/rewindWireCaps.js +0 -24
  293. package/dist/runCancelContext.d.ts +1 -20
  294. package/dist/runCancelContext.js +0 -34
  295. package/dist/runTerminal.d.ts +0 -273
  296. package/dist/runTerminal.js +0 -177
  297. package/dist/sandboxWire.d.ts +0 -38
  298. package/dist/sandboxWire.js +0 -82
  299. package/dist/scenarioWire.d.ts +0 -60
  300. package/dist/scenarioWire.js +0 -68
  301. package/dist/scratchpadWireCaps.d.ts +0 -11
  302. package/dist/scratchpadWireCaps.js +0 -32
  303. package/dist/sdkWireTransit.d.ts +0 -38
  304. package/dist/sdkWireTransit.js +0 -30
  305. package/dist/seam.d.ts +18 -853
  306. package/dist/seam.js +0 -52
  307. package/dist/seatContract.d.ts +0 -555
  308. package/dist/seatContract.js +5 -304
  309. package/dist/selfOrchestrationDenial.d.ts +0 -189
  310. package/dist/selfOrchestrationDenial.js +0 -162
  311. package/dist/selfOrchestrationWireCaps.d.ts +0 -38
  312. package/dist/selfOrchestrationWireCaps.js +0 -38
  313. package/dist/sessionMap.d.ts +0 -60
  314. package/dist/sessionMap.js +0 -37
  315. package/dist/sessionMemoryStatus.d.ts +11 -114
  316. package/dist/sessionMemoryStatus.js +0 -112
  317. package/dist/sessionModelLatch.d.ts +0 -29
  318. package/dist/sessionModelLatch.js +0 -40
  319. package/dist/sessionPolicyCapability.d.ts +3 -53
  320. package/dist/sessionPolicyCapability.js +0 -52
  321. package/dist/sessionSlot.d.ts +0 -26
  322. package/dist/sessionSlot.js +0 -17
  323. package/dist/skillsWireCaps.d.ts +0 -87
  324. package/dist/skillsWireCaps.js +0 -38
  325. package/dist/sqlEngineCapability.d.ts +0 -118
  326. package/dist/sqlEngineCapability.js +0 -134
  327. package/dist/sseIdleTriage.d.ts +0 -79
  328. package/dist/sseIdleTriage.js +1 -80
  329. package/dist/steering.d.ts +0 -54
  330. package/dist/steering.js +0 -63
  331. package/dist/subagent/engineCompactWire.d.ts +0 -34
  332. package/dist/subagent/engineCompactWire.js +4 -134
  333. package/dist/subagent/engineDelegatedPrompt.d.ts +0 -31
  334. package/dist/subagent/engineDelegatedPrompt.js +1 -103
  335. package/dist/subagent/engineRowStopGate.d.ts +0 -20
  336. package/dist/subagent/engineRowStopGate.js +0 -49
  337. package/dist/subagent/engineSubagentOutput.d.ts +0 -7
  338. package/dist/subagent/engineSubagentOutput.js +1 -51
  339. package/dist/subagent/engineSubagentResume.d.ts +2 -279
  340. package/dist/subagent/engineSubagentResume.js +2 -129
  341. package/dist/subagent/engineSubagentSteer.d.ts +0 -26
  342. package/dist/subagent/engineSubagentSteer.js +0 -63
  343. package/dist/subagent/engineSubagentTail.d.ts +0 -38
  344. package/dist/subagent/engineSubagentTail.js +2 -110
  345. package/dist/subagent/engineTaskHandleWire.d.ts +6 -67
  346. package/dist/subagent/engineTaskHandleWire.js +0 -126
  347. package/dist/subagent/subagentOwnerAbsence.d.ts +0 -2
  348. package/dist/subagent/subagentOwnerAbsence.js +0 -25
  349. package/dist/subagentContentStore.d.ts +3 -260
  350. package/dist/subagentContentStore.js +7 -540
  351. package/dist/systemReminderTag.d.ts +0 -49
  352. package/dist/systemReminderTag.js +0 -61
  353. package/dist/toolResult.d.ts +1 -211
  354. package/dist/toolResult.js +1 -358
  355. package/dist/toolRoster.d.ts +0 -140
  356. package/dist/toolRoster.js +0 -66
  357. package/dist/typePins.d.ts +0 -46
  358. package/dist/types/engineState.d.ts +0 -71
  359. package/dist/types/engineState.js +0 -16
  360. package/dist/ultracodeWireCaps.d.ts +0 -75
  361. package/dist/ultracodeWireCaps.js +0 -92
  362. package/dist/unrefTimer.d.ts +0 -27
  363. package/dist/webSearchBackendCapability.d.ts +0 -72
  364. package/dist/webSearchBackendCapability.js +0 -79
  365. package/dist/webSearchWireCaps.d.ts +0 -37
  366. package/dist/webSearchWireCaps.js +0 -34
  367. package/dist/websearch/searchProviderPresets.d.ts +0 -81
  368. package/dist/websearch/searchProviderPresets.js +0 -27
  369. package/dist/wireErrorTriage.d.ts +4 -160
  370. package/dist/wireErrorTriage.js +0 -171
  371. package/dist/wireRefusalCopy.d.ts +0 -28
  372. package/dist/wireRefusalCopy.js +0 -28
  373. package/dist/workflow.d.ts +0 -40
  374. package/dist/workflow.js +0 -52
  375. package/dist/workflowClient.d.ts +0 -122
  376. package/dist/workflowClient.js +8 -360
  377. package/dist/workflowMonitor.d.ts +2 -72
  378. package/dist/workflowMonitor.js +0 -26
  379. package/dist/writeProtectionCapability.d.ts +0 -112
  380. package/dist/writeProtectionCapability.js +0 -109
  381. package/docs/INTEGRATION-CLIENTS.md +30 -1
  382. package/package.json +1 -1
@@ -6,29 +6,10 @@ import { engineWireTargetFor } from '../engineWireTarget.js';
6
6
  import { activeEngineRunId, engineSessionParamFor } from '../engineSessionParam.js';
7
7
  import { DEFAULT_SESSION_KEY } from '../sessionSlot.js';
8
8
  import { getBgParentRunOwner, parentToolCallIdOf, } from '../subagentContentStore.js';
9
- /** 能力位键(server `routes/capabilities.ts` 的 `subagentResume`;SDK `Capabilities.subagentResume`)。 */
10
9
  export const SUBAGENT_RESUME_CAP = 'subagentResume';
11
- /**
12
- * 复活口在不在。未判/缺键 = false = 详情面不渲「继续」腿。
13
- *
14
- * 🔴 design/285 批 3(D7b):`baseUrl` 缺席时的派生从零参 `engineWireTarget()`(写死默认槽)换成
15
- * `engineWireTargetFor(sessionKey)`。**本腿没有行上下文**(它答的是「这台引擎有没有这个口」,
16
- * 不是「这一行该打到哪」)⇒ 槽键只能由调用方给,缺省 `DEFAULT_SESSION_KEY` = 与 0.44.0 逐字同。
17
- * 显式 `baseUrl` 恒赢(既有注入缝不动;空串仍原样保留 —— `??` 只对 `undefined` 让位,与默认参形同)。
18
- */
19
10
  export function subagentResumeAvailable(baseUrl, sessionKey = DEFAULT_SESSION_KEY) {
20
11
  return engineCapTrue(baseUrl ?? engineWireTargetFor(sessionKey)?.baseUrl, SUBAGENT_RESUME_CAP);
21
12
  }
22
- /**
23
- * 「继续」腿的 resume 取址(1.0.74 终扫 P2-11)。
24
- *
25
- * 🔴 resume API 的 `target` 契约只认两种取址:委派工具调用的 **parentToolCallId**(一等精确取址,
26
- * 同型并发子代唯一能分开的键)与**子代显示名**(同名多员 ⇒ server 409 `steering.ambiguous_target`)。
27
- * 行 taskId 不是契约取址形 —— 传它只会得到一条不带替代路径的歧义/未知错。
28
- * alias 台账(`registerSubagentAlias`,task_progress 双携建;taskToParent 无删除无淘汰,子代 settle
29
- * 后仍可取)⇒ 精确取址优先;显示名仅回落(它可能是 'Task' 字面占位,同名多员的 409 由每格出路
30
- * 文案接);两支皆缺 ⇒ undefined,调用方按诚实缺席**不渲入口**。
31
- */
32
13
  export function resolveSubagentContinueTarget(rowId, displayName) {
33
14
  const precise = parentToolCallIdOf(rowId);
34
15
  if (precise !== undefined && precise !== '')
@@ -36,7 +17,6 @@ export function resolveSubagentContinueTarget(rowId, displayName) {
36
17
  const name = typeof displayName === 'string' ? displayName.trim() : '';
37
18
  return name !== '' ? name : undefined;
38
19
  }
39
- /** 留存失效族(三码同处置:留存曾经在、现在没了;文案一致,留痕分得开)。 */
40
20
  const RETENTION_LAPSED_CODES = new Set([
41
21
  'resume.evicted',
42
22
  'resume.cap',
@@ -50,22 +30,10 @@ function shapeOf(e) {
50
30
  message: typeof o.message === 'string' && o.message !== '' ? o.message : String(e),
51
31
  };
52
32
  }
53
- /**
54
- * resume 失败 → 处置分类。机器轴 = `errorCode`(开集);`status` 只用于**码缺席**时的两格粗分
55
- * (404 无存在性谕示 / 400 入参),绝不用数字去猜某个具体 409 成因(那些 409 只有 `errorCode`
56
- * 分得开,按数字分支等于把好几种处置压成一种)。
57
- */
58
33
  export function classifySubagentResumeFailure(e) {
59
34
  const { status, errorCode, message } = shapeOf(e);
60
- // L-102(0.57.0):时间性拒绝二码 —— **先判具名闭集**(与 SDK `classifyApiError` 同序:具名码排在
61
- // `resume.` 前缀兜底之前)。此前这两码双双落进末尾的开集兜底 `error`,于是 server 明明给了
62
- // 「等多久」,到端只剩一句泛泛失败(与 #318 件④ 收 `row_recycling`/`row_gone` 那次同形)。
63
- // 读口在 `wireErrorTriage`,不在这里就地重判:同一把窄读器还要服务不走本腿的宿主(decide/park
64
- // 腿也吃这两码),两处各写一遍就是两个会各自漂的判官。
65
35
  const retryLater = resumeRetryLaterFromError(e);
66
36
  if (retryLater !== null) {
67
- // 🔴 **按证据分两格,不按码分**:`waitable` 是读口那一位(全包单一判断点)——`terminal` 臂的
68
- // 预检拒没有可等证据,归 `refused-preflight`(不可判),绝不渲成「稍后重试」。
69
37
  return {
70
38
  reason: retryLater.waitable ? 'retry-later' : 'refused-preflight',
71
39
  detail: message,
@@ -84,9 +52,6 @@ export function classifySubagentResumeFailure(e) {
84
52
  return { reason: 'not-resumable', detail: message };
85
53
  if (errorCode === 'steering.ambiguous_target')
86
54
  return { reason: 'ambiguous-target', detail: message };
87
- // #318 件④([4743] SendMessage 复活语义)—— 复活裁决腿的两码。此前它们双双落进末尾的开集兜底
88
- // `error`,于是 core 明明给了**两个不同的下一步**(等一会儿再发 / 重开一个新 agent),到客户端
89
- // 只剩一句泛泛失败。判定归包、文案归端:这里只分格,不写出路文案。
90
55
  if (errorCode === 'resume.row_recycling')
91
56
  return { reason: 'row-contended', detail: message };
92
57
  if (errorCode === 'resume.row_gone')
@@ -99,77 +64,19 @@ export function classifySubagentResumeFailure(e) {
99
64
  return { reason: 'not-found', detail: message };
100
65
  return { reason: 'error', detail: message };
101
66
  }
102
- /**
103
- * 「这一行子代该打到哪条 run」——**纯函数,单点判据**(对抗复审 H1 的修 + 它的可证伪点)。
104
- *
105
- * 🔴 **按行取,不取「此刻在飞的那条」**:`activeEngineRunId()` 是 turn-scoped(壳 `seamQuery` 在
106
- * turn 收尾 `setActiveEngineTaskId(null)`),而「继续」这个动作按定义只在子代**已 settle** 之后
107
- * 才出现 —— 那时它恒空;更坏的一支是另一条 turn 正飞时它有值但**是别的 run**,请求会打到不
108
- * 相干的 run 上(404,或叫醒那条 run 里的同名子代)。判据必须锚在决定量(这一行的宿主 run)
109
- * 上,不是锚在「有没有 run 在飞」这个前置条件上([anchor-on-the-deciding-quantity])。
110
- *
111
- * 三态:
112
- * · 台账有这一行 ⇒ 用台账值(**哪怕此刻另有 run 在飞**);
113
- * · 台账没有、且调用方**指名了某一行** ⇒ `undefined`(诚实不知道 ⇒ no-run 出路),绝不回落成在飞的那条;
114
- * · 调用方**没指名行**(无行上下文的通用调用)⇒ 才回落到在飞的那条。
115
- *
116
- * @param activeRunId 注入缝(缺省 = `activeEngineRunId()`)—— 判据要能在没有 SessionPort 的纯层里验。
117
- */
118
67
  export function resolveOwnerRunId(childTaskId, activeRunId) {
119
68
  const owner = getBgParentRunOwner(childTaskId);
120
69
  if (owner !== undefined)
121
70
  return owner.runId;
122
71
  if (childTaskId !== undefined && childTaskId !== '')
123
72
  return undefined;
124
- // 🔴 **惰性求值**(design/285 批 3,异源对抗复审 [medium] 采纳):此前 `activeRunId` 是**默认参**,
125
- // 于是**每一次**调用都先读一遍**默认槽**的 `SessionPort` —— 哪怕台账里明明有这一行、第三态根本
126
- // 走不到。批 3 之后 keyed 宿主是成文支持的路径,那次白读会给 keyed-only 宿主(默认槽本就没装)
127
- // 刷 `hostPortMisses()`,而接入档要求宿主的自检**恒空**:一个恒响的假警报会把真漏装淹掉。
128
- // 注入语义一字未变(传值即用;传 `undefined` 与不传都落到这条真读)。
129
73
  return activeRunId ?? activeEngineRunId();
130
74
  }
131
- /**
132
- * 「这一行子代属于哪个会话槽」—— design/285 批 3(D6+D7b)读侧的**一次读**。
133
- *
134
- * 五个读点(tail / output / taskHandle 两口 / delegatedPrompt)此前各自读一次台账,而 wire target
135
- * 一律走零参 `engineWireTarget()`(= 默认槽)。keyed 多会话宿主上那意味着「会话对了、打的服务器与
136
- * 凭证可能还是别人的」(D7b)。本函数把「取哪一行的记录 + 它属于哪个槽」收成一处;
137
- * `key` 缺席回落默认槽 ⇒ `engineWireTargetFor(DEFAULT_SESSION_KEY)` ≡ `engineWireTarget()`,
138
- * 单会话宿主逐字同。
139
- *
140
- * 🔴 **会话策略刻意留在各腿**(不在这里合并):steer/tail/output 是二态(行的会话优先,缺则退现势),
141
- * resume 是三态(指名了行却没有会话 ⇒ 干脆不带,AT-MOST-ONCE 不许猜)。收成一份就必然要加一个
142
- * 「模式」参数,那等于把两条**有意不同**的口径伪装成同一个函数的两种配置。
143
- */
144
75
  export function resolveOwnerContext(childTaskId) {
145
76
  const record = getBgParentRunOwner(childTaskId);
146
77
  return { record, runId: record?.runId, key: record?.sessionKey ?? DEFAULT_SESSION_KEY };
147
78
  }
148
- /**
149
- * 产品 facade + 运行定位。**逐字复用 `steerEngineSubagent` 的三步**(engineWireTarget → 无则 no-wire;
150
- * 取运行 → 无则 no-run;makeEngineWireClient)—— 两条腿共用同一套装配,免得 steer 能到达而 resume
151
- * 到不了(或反过来),那种不对称在用户面上表现为「同一个 agent 有时能说话有时不能」。
152
- *
153
- * 🔴 `session` 的三态(#242 批 2 定口径,对抗复审 medium 收紧):
154
- * · 台账有这一行**且**捕到了它的会话 ⇒ 用**行登记的**会话(resume 是 per-id 读面,配错的
155
- * `{runId, session}` 组合在 session-bound run 上 fail-closed 404);
156
- * · 台账**有这一行但没捕到会话**(fleet 行帧腿/通知腿今天不传 session)⇒ **不带 `?session=`**,
157
- * 🔴 **绝不拿「此刻的会话」去猜** —— resume 是有副作用的动作(AT-MOST-ONCE,叫醒 = 真跑一轮),
158
- * 猜错会话可能落到**另一个会话的同名子代**上,那是不可回收的伤害;不带参数的失败只是 server
159
- * fail-closed 的干净 404,已有 `not-found` 出路文案接。与本模块「错值比缺席更坏」同一条口径。
160
- * · 调用方**完全没指名行**(无行上下文的通用调用)⇒ 才退当前会话(既有口径不变)。
161
- * ⚠️ 供给面欠账(**已由 design/285 批 2 补上**):fleet/通知两腿此前手里没有流会话;ingress 落地后
162
- * 它们按 `{runId, sessionId, sessionKey}` 三值原子写,第二态自然变成第一态,判据一字未改 ——
163
- * 这正是本注 0.30.x 时预告过的那一步。
164
- *
165
- * 🔴 design/285 批 3(D7b):wire target 从零参 `engineWireTarget()`(默认槽)换成
166
- * `engineWireTargetFor(owner.sessionKey ?? DEFAULT_SESSION_KEY)`。会话对了而 baseUrl/token/
167
- * principal 还是别人的,等于把 resume 这条 AT-MOST-ONCE 的动作发到另一台引擎上。
168
- * 第三态(没指名行)的现势会话回落**同样按 key**(`engineSessionParamFor(key)`)—— 没指名行时
169
- * key 恒是默认槽,与 0.44.0 逐字同。
170
- */
171
79
  export function resolveSubagentResumeContext(childTaskId) {
172
- // 记录先取(纯台账读):`key` 决定 wire target 取哪个槽,所以它必须排在 cfg 之前。
173
80
  const { record: owner, key } = resolveOwnerContext(childTaskId);
174
81
  const cfg = engineWireTargetFor(key);
175
82
  if (!cfg)
@@ -183,30 +90,17 @@ export function resolveSubagentResumeContext(childTaskId) {
183
90
  return { facade: null, runId: undefined, session: {} };
184
91
  const named = childTaskId !== undefined && childTaskId !== '';
185
92
  const sessionFromRow = owner?.sessionId;
186
- // 第三态(没指名行)的现势会话回落**也按 key** —— 没指名行时 key 恒是默认槽,与 0.44.0 逐字同。
187
93
  const fallback = named ? undefined : engineSessionParamFor(key);
188
94
  const session = sessionFromRow !== undefined
189
95
  ? { session: sessionFromRow }
190
96
  : fallback !== undefined
191
- ? { session: fallback } // 没指名行 ⇒ 退当前会话(既有第三态口径不变)
192
- : {}; // 指名了行却没有它的会话 ⇒ 诚实缺席,绝不用当前会话冒充
193
- // 取址三态的唯一判据(含「没指名行才回落在飞 run」那一态);刻意排在 wire 两道闸**之后**,
194
- // 与 0.44.0 求值序逐字同 —— 无 wire 时一次 SessionPort 都不读。
97
+ ? { session: fallback }
98
+ : {};
195
99
  return { facade: client.runs, runId: resolveOwnerRunId(childTaskId), session };
196
100
  }
197
- /** UNTRUSTED 串的呈前消毒。 */
198
101
  function clean(v, max = 200) {
199
- // eslint-disable-next-line no-control-regex
200
102
  return String(v ?? '').replace(/[\x00-\x1f\x7f]/g, '.').slice(0, max);
201
103
  }
202
- /**
203
- * 叫醒一个已 settle 的保留子代。
204
- *
205
- * @param target parentToolCallId 或 agentName(与 `steerEngineSubagent` 同一取址口径;
206
- * 同名多个活体 ⇒ server 409 `steering.ambiguous_target`)。
207
- * 🔴 AT-MOST-ONCE:server 明写不重试。本层因此**不重试任何一格** —— 「叫醒」是有副作用的动作,
208
- * 重投一次可能真的多跑一轮。
209
- */
210
104
  export async function resumeSettledSubagent(facade, runId, target, content, opts) {
211
105
  if (facade === null)
212
106
  return { ok: false, reason: 'no-wire', detail: 'no engine wire' };
@@ -231,27 +125,7 @@ export async function resumeSettledSubagent(facade, runId, target, content, opts
231
125
  return { ok: false, ...f };
232
126
  }
233
127
  }
234
- // ── caps × verb 组合告警([4000] Q5 裁定的另一半)────────────────────────────────────────────
235
- // Q5 裁定:`ClientSliceLike.wakeSubagent` 在 `CLIENT_VERBS` 表里**维持 `required:false`**
236
- // (fail-soft —— 不实现只是少一个入口,不丢已发生的行为);但「引擎这边留存在付费、客户端这边
237
- // 一个兑现口都没有」这个**组合**必须响亮说出来,否则它就是一笔谁也看不见的常驻成本。
238
- //
239
- // 🔴 键名订正(勘设计稿措辞):caps 上**没有** `retainSubagentSessions` 这个位 ——
240
- // `retainSubagentSessions` 是**run 请求位**(`request/taskRequest.ts:118/320`,壳默认 true),
241
- // 引擎宣示兑现口的 caps 位是 **`subagentResume`**(SDK `Capabilities.subagentResume`,
242
- // `types.d.ts:1879` 逐字「还需 run 侧 retainSubagentSessions」)。所以本告警的判据是
243
- // **两半都在场**:caps 宣示 `subagentResume` ∧ 本端的 run 请求真在打 retain ⇒ 成本真在付。
244
128
  const warnedRetainWithoutWake = new Set();
245
- /**
246
- * 「引擎有复活口 + 本端在付留存成本 + 本端没有 wake 实现」⇒ 响亮一条(每 baseUrl 至多一次)。
247
- *
248
- * 返回 {@link RetainWithoutWakeVerdict}:`undefined` = 组合不成立(没这笔账);有记录 = 组合成立,
249
- * 其中 `emitted` 说明**本次**响没响。**返回值即判据** —— 只落日志的告警在测试里等于不存在,
250
- * 而只回一个字符串又分不出「本次响了」与「早响过了」(按返回值呈现的调用方会重复提示)。
251
- *
252
- * @param slice 本端的 `ClientSliceLike` 实现(或它的任意子集);`wakeSubagent` 不是函数即算未实现。
253
- * @param retainRequested 本端 run 请求里的 `retainSubagentSessions`(缺省 true = 包内 taskRequest 的缺省)。
254
- */
255
129
  export function auditRetainWithoutWake(input) {
256
130
  const baseUrl = input.baseUrl ?? engineWireTargetFor(input.sessionKey ?? DEFAULT_SESSION_KEY)?.baseUrl;
257
131
  if (!engineCapTrue(baseUrl, SUBAGENT_RESUME_CAP))
@@ -271,7 +145,6 @@ export function auditRetainWithoutWake(input) {
271
145
  hostLog('warn', message);
272
146
  return { message, emitted: true };
273
147
  }
274
- /** 测试钩:清 once 去重台账。 */
275
148
  export function __resetRetainWithoutWakeWarningForTests() {
276
149
  warnedRetainWithoutWake.clear();
277
150
  }
@@ -6,30 +6,4 @@ export type SubagentSteerOutcome = {
6
6
  reason: 'no-wire' | 'no-run' | 'not-running' | 'error';
7
7
  detail?: string;
8
8
  };
9
- /**
10
- * Steer a running engine subagent (target = its parentToolCallId, or agentName).
11
- *
12
- * 🔴 #280 件A(取址第四腿并入 [4000] Q3=B 口径):`childTaskId` 在场时**台账优先、缺席即诚实缺席**,
13
- * 与 tail / taskOutput·taskStop / subagentOutput 三腿同姿势,也与孪生的 resume 腿共用**同一个**
14
- * 取址判据(`resolveOwnerRunId`,不是第二份手抄)。此前本腿直取 `activeEngineRunId()` —— 正是
15
- * `engineSubagentResume` 头注点名的那处不对称(「同一个 agent 有时能说话有时不能」):
16
- * · 进程级活跃 run 被并发 main/fork 流互相覆写、又在每个 query 的 finally 清空 ⇒ 后台子代在
17
- * 宿主 turn 收尾之后仍在跑时,这里恒空(no-run,消息发不出去);另一条 turn 正飞时它有值
18
- * 但**是别的 run**(打到不相干的 run 上 —— 错值比缺席更坏,与 Q3 同一条理由)。
19
- * 三态(`resolveOwnerRunId` 的单一判据):台账有这一行 ⇒ 用行值(哪怕此刻另有 run 在飞);
20
- * 指名了行而台账缺席 ⇒ `no-run` + `noteBgOwnerAbsence` 留痕(绝不回落在飞 run);
21
- * **没指名行**(既有两参调用)⇒ 才回落在飞 run —— 老调用方逐字零行为变化,本参数是 additive。
22
- *
23
- * 🔴 会话参数**二态**(对抗复审 medium 采纳:「取了台账的 run 却配现势 session」是确定性 404):
24
- * · 行登记时**捕到了会话** ⇒ 用**行的会话**(与行的 runId 同源同拍,是唯一自洽的组合);
25
- * · 行**没有**随行会话(`recordBgParentRun` 只写 run —— 今天 bg 行多数是这一格)⇒ 退**现势会话**。
26
- * 刻意**不**跟 resume 腿的「没捕到就干脆不带」:本腿与 tail/subagentOutput 同族,遵 [1498]③
27
- * 无条件带 session 的双版本兼容纪律;runId 既已由台账钉死,配错的 `{runId, session}` 组合在
28
- * session-bound run 上是 server 干净的 fail-closed 404(落既有 `not-running` 出路),**不会**把消息
29
- * 投到别的会话 —— 而「没捕到就不带」会让今天最常见的那一格整批 404。resume 那边更严是因为它是
30
- * AT-MOST-ONCE 的叫醒(真跑一轮,不可回收),两者的代价不对称。
31
- * 诚实边界:行无会话且端已切到别的会话时,对旧行 steer 会得到 `not-running`(而非静默投错人)。
32
- *
33
- * @param childTaskId 这一行子代的 taskId(fleet 行 id 尾段;端有行上下文时**应当**传)。
34
- */
35
9
  export declare function steerEngineSubagent(target: string, text: string, childTaskId?: string): Promise<SubagentSteerOutcome>;
@@ -1,76 +1,17 @@
1
- /**
2
- * ⇄ B6 批搬迁(2026-07-27,设计稿 §3 B6):cli `src/sema/engineSubagentSteer.ts` 整搬。
3
- *
4
- * 🔴 搬迁三处差分(端资产上移到 port,行为一字节不变):`wireConfig()`(六份手抄之一,而且
5
- * **这一份的 token 读法与另外五份不同步** —— 收编前它是 `token: process.env.SEMA_LIVE_TOKEN`
6
- * 直挂而非 `...(cfg.token ? … )` spread,漂移已实际发生)→ `engineWireTarget()`;
7
- * `getActiveEngineTaskId()` → `activeEngineRunId()`;`logForDebugging` → `hostLog`。
8
- *
9
- * ── 以下为原文件的领域说明(逐字保留)────────────────────────────────────────────────────────
10
- *
11
- * engineSubagentSteer — C2 (service 1.89): direct steer to a RUNNING engine subagent.
12
- *
13
- * Wire: `POST /v1/runs/:runId/subagents/:target/steer` (SubagentSteerRegistry, three-legged onSubagentSpawn;
14
- * target = parentToolCallId or agentName — the client always has the parentToolCallId from the diverted C1
15
- * content events / progress binding). SDK 宪法迁移批:SDK 0.0.52 有 runs.steerSubagent verb(同 wire 同
16
- * encodeURIComponent 同 body {content}),raw fetch 退役 —— 改走 engineWireSdk 工厂 client;auth
17
- * (Bearer SEMA_LIVE_TOKEN)+ x-agent-principal(owner-gated route — must match the run's stamped
18
- * principal)姿势 = Transport buildHeaders,与原手抄同三头。
19
- *
20
- * Semantics (CC AGe parity): the message drains at the subagent's next tool round; the service echoes CC's
21
- * verbatim receipt "Message queued for delivery…". 409 = subagent not running (settled/unknown) — surfaced
22
- * honestly so the caller can fall back (steer the lead) or tell the user the agent already ended.
23
- * 迁移差分记账:原 raw POST 无超时 → SDK 缺省 60s 上界(steer 是入队即回的 verb,纯上界改善);
24
- * 'not-running' 的 detail 从「响应体原文」→「APIError.message(server body.error 原文)」——该 detail
25
- * 只进 debug 日志(REPL 对 not-running 显示固定文案),error 形语义不劣化。
26
- */
27
1
  import { hostLog } from '../host.js';
28
2
  import { makeEngineWireClient } from '../engineWireSdk.js';
29
3
  import { engineWireTargetFor } from '../engineWireTarget.js';
30
4
  import { engineSessionParamFor } from '../engineSessionParam.js';
31
5
  import { resolveOwnerContext, resolveOwnerRunId } from './engineSubagentResume.js';
32
6
  import { noteBgOwnerAbsence } from './subagentOwnerAbsence.js';
33
- /**
34
- * Steer a running engine subagent (target = its parentToolCallId, or agentName).
35
- *
36
- * 🔴 #280 件A(取址第四腿并入 [4000] Q3=B 口径):`childTaskId` 在场时**台账优先、缺席即诚实缺席**,
37
- * 与 tail / taskOutput·taskStop / subagentOutput 三腿同姿势,也与孪生的 resume 腿共用**同一个**
38
- * 取址判据(`resolveOwnerRunId`,不是第二份手抄)。此前本腿直取 `activeEngineRunId()` —— 正是
39
- * `engineSubagentResume` 头注点名的那处不对称(「同一个 agent 有时能说话有时不能」):
40
- * · 进程级活跃 run 被并发 main/fork 流互相覆写、又在每个 query 的 finally 清空 ⇒ 后台子代在
41
- * 宿主 turn 收尾之后仍在跑时,这里恒空(no-run,消息发不出去);另一条 turn 正飞时它有值
42
- * 但**是别的 run**(打到不相干的 run 上 —— 错值比缺席更坏,与 Q3 同一条理由)。
43
- * 三态(`resolveOwnerRunId` 的单一判据):台账有这一行 ⇒ 用行值(哪怕此刻另有 run 在飞);
44
- * 指名了行而台账缺席 ⇒ `no-run` + `noteBgOwnerAbsence` 留痕(绝不回落在飞 run);
45
- * **没指名行**(既有两参调用)⇒ 才回落在飞 run —— 老调用方逐字零行为变化,本参数是 additive。
46
- *
47
- * 🔴 会话参数**二态**(对抗复审 medium 采纳:「取了台账的 run 却配现势 session」是确定性 404):
48
- * · 行登记时**捕到了会话** ⇒ 用**行的会话**(与行的 runId 同源同拍,是唯一自洽的组合);
49
- * · 行**没有**随行会话(`recordBgParentRun` 只写 run —— 今天 bg 行多数是这一格)⇒ 退**现势会话**。
50
- * 刻意**不**跟 resume 腿的「没捕到就干脆不带」:本腿与 tail/subagentOutput 同族,遵 [1498]③
51
- * 无条件带 session 的双版本兼容纪律;runId 既已由台账钉死,配错的 `{runId, session}` 组合在
52
- * session-bound run 上是 server 干净的 fail-closed 404(落既有 `not-running` 出路),**不会**把消息
53
- * 投到别的会话 —— 而「没捕到就不带」会让今天最常见的那一格整批 404。resume 那边更严是因为它是
54
- * AT-MOST-ONCE 的叫醒(真跑一轮,不可回收),两者的代价不对称。
55
- * 诚实边界:行无会话且端已切到别的会话时,对旧行 steer 会得到 `not-running`(而非静默投错人)。
56
- *
57
- * @param childTaskId 这一行子代的 taskId(fleet 行 id 尾段;端有行上下文时**应当**传)。
58
- */
59
7
  export async function steerEngineSubagent(target, text, childTaskId) {
60
- // 空串/非串按「没指名行」处理(与 resolveOwnerRunId 的 named 判据同口径);窄成 string|undefined
61
- // 而不是 boolean —— 布尔位不给 TS 窄化,留痕那一行会被迫 cast。
62
8
  const named = typeof childTaskId === 'string' && childTaskId !== '' ? childTaskId : undefined;
63
- // 🔴 design/285 批 3(D7b):台账记录**先取**(纯读)—— wire target 按**这一行的会话槽**取,
64
- // 零参 `engineWireTarget()` 写死默认槽(会话对了而 baseUrl/token/principal 是别人的)。
65
- // 这也顺带把本腿原有的「同一张表读两次」收成一次读(取址判据仍在 resolveOwnerRunId 一处)。
66
9
  const { record: owner, key } = resolveOwnerContext(named);
67
10
  const cfg = engineWireTargetFor(key);
68
11
  if (!cfg)
69
12
  return { ok: false, reason: 'no-wire' };
70
13
  const runId = resolveOwnerRunId(named);
71
14
  if (!runId) {
72
- // 指名了行才算「台账缺席」——不指名的通用调用只是没有在飞 run,不是宿主映射缺席(两者出路
73
- // 同为 no-run,但只有前者是 Q3 要响亮的那一类)。
74
15
  if (named !== undefined)
75
16
  noteBgOwnerAbsence('subagent-steer', named);
76
17
  return { ok: false, reason: 'no-run' };
@@ -82,9 +23,6 @@ export async function steerEngineSubagent(target, text, childTaskId) {
82
23
  });
83
24
  if (!client)
84
25
  return { ok: false, reason: 'no-wire' };
85
- // 会话二态(见头注):行登记的会话优先,缺则退现势会话。记录来自上面那一次读(`resolveOwnerContext`),
86
- // 不再第二次查表;取址判据本身仍只有 `resolveOwnerRunId` 那一处,不另铸。
87
- // 🔴 design/285 批 3:现势会话回落也按 `key` 取(没指名行时 key 恒是默认槽 ⇒ 与 0.44.0 逐字同)。
88
26
  const rowSession = owner?.sessionId;
89
27
  const fallbackSession = rowSession === undefined ? engineSessionParamFor(key) : undefined;
90
28
  const session = rowSession !== undefined
@@ -93,7 +31,6 @@ export async function steerEngineSubagent(target, text, childTaskId) {
93
31
  ? { session: fallbackSession }
94
32
  : {};
95
33
  try {
96
- // service 1.89 receipt shape: { note: "Message queued for delivery to <name> …", delivery, … }
97
34
  const body = await client.runs.steerSubagent(runId, target, { content: text }, session);
98
35
  let receipt = 'Message queued for delivery at the next tool round.';
99
36
  const copy = body?.note ?? body?.message;
@@ -1,58 +1,20 @@
1
- /** 测试钩:清 caps 缓存。 */
2
1
  export declare function __resetSubagentStreamCapCacheForTests(): void;
3
- /**
4
- * 一次子代工具活动(详情页 `Progress` 段的数据面,CC 2.1.220 `Zja` 的 recentActivities)。
5
- *
6
- * 🔴 `toolName` 必须是**真工具名**、`args` 必须是**真参数** —— 端的 `renderToolActivity` 拿
7
- * `toolName` 去工具注册表查、再用工具自己的 `userFacingName(input)` 渲染。把 `currentAction`
8
- * 那类自由文本塞进 `toolName` 只会走 `!tool` 回落分支把原文吐出来,是「看起来能显示」的假绑定。
9
- * 自由文本只能进 `activityDescription` 展示位。
10
- */
11
2
  export interface SubagentActivity {
12
3
  taskId: string;
13
4
  toolName: string;
14
- /** `tool_start.args` 原样(非对象由端归一;端会拿它过工具 schema 的 safeParse)。 */
15
5
  args: unknown;
16
- /** UNTRUSTED 展示文本(server 已 redact+bound);绝不冒充结构化 args。 */
17
6
  activityDescription?: string;
18
7
  }
19
- /** 端装的活动落点(执行半场)。不装 ⇒ Progress 段无数据(不是错误态,只是该面不启用)。 */
20
8
  export type SubagentActivitySink = (a: SubagentActivity) => void;
21
- /** 装/卸 Progress 段落点。传 null 卸。返回还原函数。 */
22
9
  export declare function installSubagentActivitySink(sink: SubagentActivitySink | null): () => void;
23
- /**
24
- * 一帧 tail `event: meta` 的发布载荷(#280 件2,0.30.4)。`meta` 是连接语义帧(server 建连即发:
25
- * `{version, runId, target, status, seq?, contentFrames?, …}`),**不进内容面** —— 但其中的
26
- * **供给形判别位 `contentFrames`**(server e439a6c,闭集 {on | progress_only | unknown})是端
27
- * 区分「内容帧**永远不会来**(forward 缺席宿主,结构性无内容)vs **还没来**」的唯一诚实依据;
28
- * 0.30.3 及之前它被消费循环的 forward-only 过滤整类 skip,端结构性到不了。
29
- * 🔴 `meta` 为**开集原文**(SDK subagentStream 产物 `Record<string, unknown>` 原样):判别位的
30
- * 窄读(闭集判词/缺席处置)归消费端,包只搬运 —— additive 上游往 meta 里加键零施工。
31
- * ⚠️ 供给形登记随句柄终态在 server 侧撤销(SubagentTailBus.forgetHandleContentMode)⇒ 判别位
32
- * 要在子代存活窗内消费,终态后重开的 tail 读到 `unknown` 不是回归。
33
- */
34
10
  export interface SubagentTailMeta {
35
11
  taskId: string;
36
- /** meta 帧原文(开集;`contentFrames` 等判别位的窄读归消费端)。 */
37
12
  meta: Record<string, unknown>;
38
13
  }
39
- /** 端装的 meta 帧落点(#280 件2)。不装 ⇒ 判别位不达端(不是错误态,该面不启用;0.30.3 现状字节不变)。 */
40
14
  export type SubagentTailMetaSink = (m: SubagentTailMeta) => void;
41
- /** 装/卸 tail meta 帧落点。传 null 卸。返回还原函数。 */
42
15
  export declare function installSubagentTailMetaSink(sink: SubagentTailMetaSink | null): () => void;
43
- /**
44
- * tail 是否正对该行开着 —— **两源互斥判别口**(行帧 `currentTool` 臂在 tail 活跃时让位:
45
- * tail 的 tool_start 带真 args,渲染更细;两源同录 = 每步双行)。
46
- */
47
16
  export declare function isEngineSubagentTailActive(taskId: string): boolean;
48
- /**
49
- * 打开一个后台子代的 live tail(幂等:已开着的同 id 直接返回)。内容帧进 subagentContentStore,
50
- * 渲染由既有 C1 notify 链接管。绝不 throw;开不了(无 wire/caps 缺/寻址失败)= 静默维持现状。
51
- */
52
17
  export declare function tailEngineSubagent(taskId: string): void;
53
- /** 关闭一个子代的 tail(幂等;查看态退出/终态/行消失时调)。 */
54
18
  export declare function stopEngineSubagentTail(taskId: string): void;
55
- /** 在飞判别([1543]① 重开路用):true = 该子代已有 tail 挂着。 */
56
19
  export declare function hasActiveSubagentTail(taskId: string): boolean;
57
- /** 测试钩:在飞 tail 数。 */
58
20
  export declare function __activeTailCountForTests(): number;
@@ -1,52 +1,3 @@
1
- /**
2
- * ⇄ B6 批搬迁(2026-07-27,设计稿 §3 B6):cli `src/sema/engineSubagentTail.ts` 的**流消费半场**。
3
- *
4
- * ── 拆缝(T35/T36/T44 同一条原则:判定半场进包、执行半场留宿主)────────────────────────────────
5
- * **进包**:caps 探测 · tail 台账(每 taskId 至多一条)· SSE 消费循环 · 帧 → subagentContentStore
6
- * 的四条投影 · settle 收口 · 诊断锚 · 两源互斥判别口 `isEngineSubagentTailActive`
7
- * (`coerceOutput` 原也在这里,2026-08-12 搬去 `subagentContentStore.ts` 与 C1 腿共用一份)。
8
- * **留宿主**:`recordSubagentActivity` / `recordFleetCurrentTool` 里对
9
- * `AppState.tasks[taskId].progress.recentActivities` 的读改写 —— 那是**端的任务状态形状**
10
- * (`LocalAgentTaskState` / `ToolActivity`),web/桌面各有各的形。
11
- * 本包改为在 `tool_start` 上调 `SubagentActivitySink`(下面的可装口),壳侧 shim 装一个
12
- * 把原 `recordSubagentActivity` 逐字搬过去的 sink ⇒ 行为一字节不变。
13
- *
14
- * 🔴 单实例纪律:`activeTails` 是 module 级 Map。写者 = 本文件;读者 = **两源互斥判别**
15
- * (行帧 `currentTool` 臂在 tail 活跃时必须让位)与查看态 watcher 的「重开」判别。
16
- * 两份实例 ⇒ 让位判别恒读 false ⇒ tail 与行帧两源同时录 Progress 段 = 每步双行
17
- * ([new-data-source-systemic-checks]「两臂共写台账要整臂让位」)。
18
- *
19
- * 🔴 搬迁差分:`wireConfig()`(六份手抄的第六份,至此**全部收编**)→ `engineWireTarget()`;
20
- * `getActiveEngineTaskId()` → `activeEngineRunId()`;`logForDebugging` → `hostLog`。
21
- *
22
- * ── 以下为原文件的领域说明(逐字保留)────────────────────────────────────────────────────────
23
- *
24
- * engineSubagentTail — 后台子代 live tail(A2,server 1.251 subagentStream 提货;1.253 起
25
- * probe→subscribe 竞态已修([1524] HIGH-2 → [1526] 即修),接线以 1.253+ 为期望域)。
26
- *
27
- * Wire: `GET /v1/runs/:runId/subagents/:handle/stream`(SSE)——SDK runs.subagentStream 消费:
28
- * · `event: meta` {version:1, runId, target, status, seq?, …}:status 非 running/pending 时
29
- * server 立即收流(终态无 tail,回放面=subagentOutput);
30
- * · `event: forward` = projectTailFrame 投影帧:text_delta/reasoning_delta {delta,…}、
31
- * tool_start {toolCallId,toolName,args,label?}、tool_end {toolCallId,toolName,isError,output?}、
32
- * task_progress {…}(rollup,面板已有 task_progress 腿,这里不重复消费)、
33
- * task_settled {taskId,status,seq?,summary?} = 收口帧(server 随即 end);
34
- * · `event: heartbeat` {} 每 15s(连接活性由 server 保障,端侧无需 idle timer)。
35
- *
36
- * 消费面:帧 → subagentContentStore.publishSubagentContentEvent(C1 同一 store)——既有
37
- * notify→重组链零改动接管渲染;running 查看态的「live transcript pending engine wire」占位行在
38
- * 首个内容项落地时自然消失。
39
- *
40
- * 防双注入:task_settled → settleSubagentContent(flush 流式尾巴)后关流;终报正文不从
41
- * tail 合成——终态渲染仍走既有 subagentOutput 读面 / bg 事实臂,臂序(content prefix → report)
42
- * 保证两面不重复。
43
- *
44
- * 生命周期:查看态进入开,退出/终态/行消失关;每 taskId 至多一条(幂等);caps 探测
45
- * capabilities.subagentStream(true 固化/false TTL/失败不缓存,engineSubagentOutput 同纪律);
46
- * 寻址 runId=getBgParentRun **唯一源**(#242 批 3 起台账缺席即诚实缺席不回落,warn 留痕)、
47
- * 无条件带 `?session=`(同 [1498]③ 纪律)。
48
- * 一切失败 fail-soft:tail 断=回到占位行现状,绝不 throw。
49
- */
50
1
  import { hostLog } from '../host.js';
51
2
  import { makeEngineWireClient } from '../engineWireSdk.js';
52
3
  import { engineWireTargetFor } from '../engineWireTarget.js';
@@ -54,7 +5,6 @@ import { engineSessionParamFor } from '../engineSessionParam.js';
54
5
  import { resolveOwnerContext } from './engineSubagentResume.js';
55
6
  import { coerceOutput, parentToolCallIdOf, publishSubagentContentEvent, settleSubagentContent, } from '../subagentContentStore.js';
56
7
  import { noteBgOwnerAbsence } from './subagentOwnerAbsence.js';
57
- // ── caps 探测(true 固化 / false TTL / 失败不缓存)────────────────────────────────────────────
58
8
  const capByBase = new Map();
59
9
  const CAP_FALSE_RETRY_TTL_MS = 5 * 60_000;
60
10
  async function subagentStreamCapable(client, baseUrl, signal) {
@@ -62,24 +12,20 @@ async function subagentStreamCapable(client, baseUrl, signal) {
62
12
  if (hit && (hit.ok || Date.now() - hit.at < CAP_FALSE_RETRY_TTL_MS))
63
13
  return hit.ok;
64
14
  try {
65
- // SDK 0.0.77 起 capabilities() 有真型(Capabilities 开集)——宽形 cast 已撤;键仍防御读。
66
15
  const caps = await client.capabilities({ ...(signal ? { signal } : {}) });
67
16
  const ok = caps.subagentStream === true;
68
17
  capByBase.set(baseUrl, { ok, at: Date.now() });
69
18
  return ok;
70
19
  }
71
20
  catch {
72
- return false; // 探测失败不缓存(引擎瞬断):本次不开,下次再判
21
+ return false;
73
22
  }
74
23
  }
75
- /** 测试钩:清 caps 缓存。 */
76
24
  export function __resetSubagentStreamCapCacheForTests() {
77
25
  capByBase.clear();
78
26
  }
79
- // ── tail 台账(每 taskId 至多一条)──────────────────────────────────────────────────────────────
80
27
  const activeTails = new Map();
81
28
  let activitySink = null;
82
- /** 装/卸 Progress 段落点。传 null 卸。返回还原函数。 */
83
29
  export function installSubagentActivitySink(sink) {
84
30
  const prev = activitySink;
85
31
  activitySink = sink;
@@ -88,7 +34,6 @@ export function installSubagentActivitySink(sink) {
88
34
  };
89
35
  }
90
36
  let tailMetaSink = null;
91
- /** 装/卸 tail meta 帧落点。传 null 卸。返回还原函数。 */
92
37
  export function installSubagentTailMetaSink(sink) {
93
38
  const prev = tailMetaSink;
94
39
  tailMetaSink = sink;
@@ -96,38 +41,16 @@ export function installSubagentTailMetaSink(sink) {
96
41
  tailMetaSink = prev;
97
42
  };
98
43
  }
99
- /* `coerceOutput`(tool_end.output 的字符串化口)**已搬到 `subagentContentStore.ts`**
100
- * (#158 移交① / [3674](d) 姊妹病,2026-08-12):喂那个 store 的是两条腿(本 tail 腿 + seam
101
- * 适配器的 C1 分流臂),字符串化口必须只有一份,故跟着它服务的那个位走。公面导出名不变
102
- * (index.ts 对两个模块都是 `export *`,所以这里**不再 re-export** —— 同名双星导出会撞)。 */
103
- /**
104
- * tail 是否正对该行开着 —— **两源互斥判别口**(行帧 `currentTool` 臂在 tail 活跃时让位:
105
- * tail 的 tool_start 带真 args,渲染更细;两源同录 = 每步双行)。
106
- */
107
44
  export function isEngineSubagentTailActive(taskId) {
108
45
  return activeTails.has(taskId);
109
46
  }
110
- /**
111
- * 打开一个后台子代的 live tail(幂等:已开着的同 id 直接返回)。内容帧进 subagentContentStore,
112
- * 渲染由既有 C1 notify 链接管。绝不 throw;开不了(无 wire/caps 缺/寻址失败)= 静默维持现状。
113
- */
114
47
  export function tailEngineSubagent(taskId) {
115
48
  if (activeTails.has(taskId))
116
49
  return;
117
- // 🔴 design/285 批 3(D7b):台账记录**先取**(纯读),因为 wire target 要按**这一行的会话槽**取 ——
118
- // 零参 `engineWireTarget()` 写死默认槽,keyed 宿主上会拿 A 槽的 baseUrl/token/principal 去
119
- // 读 B 槽的子代。`sessionKey` 缺席 ⇒ 回落默认槽 ⇒ 与 0.44.0 逐字同。
120
- // ⚠️ 两道闸的**次序一字未动**(无 wire 仍先于「台账缺席」返回,缺席留痕不会在离线宿主上刷屏)。
121
50
  const { record: owner, runId, key } = resolveOwnerContext(taskId);
122
51
  const cfg = engineWireTargetFor(key);
123
52
  if (!cfg)
124
53
  return;
125
- // 🔴 #242 批 3([4000] Q3=B 裁定执行,行为翻面):台账缺席即**诚实缺席,绝不回落**
126
- // `activeEngineRunId()` —— 与 resume 腿 `resolveOwnerRunId` 同口径(错值比缺席更坏:回落值
127
- // 被并发 main/fork 流覆写,可能连到不相干的 run)。缺席不静默:留痕见 noteBgOwnerAbsence。
128
- // 供给面:本表由 fleet 行帧 parentId / bg 通知 parentTaskId / task_progress tick 三腿喂
129
- // (fleetLedger.ts:394/:496 + recordSubagentOwnerFromProgress),正常 bg 子代出生帧即有值;
130
- // 缺席 = 真不知道宿主(壳重启且行帧未重播等),此时连「当前活跃 run」纯属赌。
131
54
  if (!runId) {
132
55
  noteBgOwnerAbsence('subagent-tail', taskId);
133
56
  return;
@@ -141,8 +64,6 @@ export function tailEngineSubagent(taskId) {
141
64
  return;
142
65
  const ac = new AbortController();
143
66
  activeTails.set(taskId, ac);
144
- // [1568] 诊断锚(SEMA_DEBUG 才落盘,量有界:每条 tail 一行首帧 + 一行收尾统计)——查看态
145
- // 「慢/稀疏」类报障必须能把【数据面到端】与【端渲染】分层归因,首帧时延是那条分界线。
146
67
  const openedAt = Date.now();
147
68
  let frames = 0;
148
69
  let connectLogged = false;
@@ -151,15 +72,7 @@ export function tailEngineSubagent(taskId) {
151
72
  try {
152
73
  if (!(await subagentStreamCapable(client, cfg.baseUrl, ac.signal)))
153
74
  return;
154
- // 🔴 design/285 批 3(D6,会话二态;与 steer 腿 `:88-91` 同一口径):
155
- // · 行登记时**捕到了会话** ⇒ 用**行的**会话(与行的 runId 同源同拍,唯一自洽的组合);
156
- // · 行没有随行会话 ⇒ 退**本槽的现势会话**(遵 [1498]③ 无条件带 session 的双版本兼容纪律;
157
- // runId 已由台账钉死,配错的组合在 session-bound run 上是 server 干净的 404,落既有静默出路)。
158
- // 🔴 **BEHAVIOR CHANGE(默认槽也变)**:tick 腿今天就在默认槽写 `sessionId`,所以「会话轮换后
159
- // 对旧行开 tail」此前用**现势**会话打一条 session-bound 的旧 run = 确定性 404;现在用行登记的
160
- // 那一个,与 steer/resume 已成立的口径统一。现势会话回落也按 `key` 取,不再写死默认槽。
161
75
  const session = owner?.sessionId ?? engineSessionParamFor(key);
162
- // SDK 0.0.77 起 runs.subagentStream 有真型([1547]① 候发版即消费兑现)——宽形 cast 已撤。
163
76
  const stream = client.runs.subagentStream(runId, taskId, {
164
77
  signal: ac.signal,
165
78
  ...(session ? { session } : {}),
@@ -171,20 +84,10 @@ export function tailEngineSubagent(taskId) {
171
84
  break;
172
85
  if (!connectLogged) {
173
86
  connectLogged = true;
174
- // 连接分界线:meta 帧即到 = SSE 建连成功(与「子代此刻恰好在跑长工具、没内容可发」区分开)
175
87
  hostLog('debug', `[subagent-tail] ${taskId} stream connected +${Date.now() - openedAt}ms`);
176
88
  }
177
- // #280 件2(0.30.4):帧分类闸 —— `meta` 经发布口出去(`contentFrames` 判别位在其中,
178
- // 见 SubagentTailMeta 顶注),`forward` 进内容面,其余(heartbeat / 未来新连接语义帧)
179
- // 维持 skip。🔴 开闸范围**只放 meta**(最小化):放宽 default 臂 = 把未知帧灌进发布口,
180
- // 消费端会把连接杂音当判别位读。
181
89
  switch (ev.event) {
182
90
  case 'meta':
183
- // 连接语义帧,不进内容面;不装 sink = 现状。🔴 消费端 sink 失败**绝不撕裂 tail**
184
- //(本文件头注铁律「一切失败 fail-soft…绝不 throw」;runStream onDroppedFrame
185
- // 「sink 抛错绝不打断流且痕迹落回」同族)——两臂都要:同步 throw 由 try/catch 兜,
186
- // **异步拒绝**(类型虽 void,宿主传 async 函数合法)也要有界观察 —— 不观察 =
187
- // unhandledRejection = Node 缺省整进程崩,TUI 宿主最坏形。痕迹留 hostLog,内容帧照常消费。
188
91
  try {
189
92
  const out = tailMetaSink?.({ taskId, meta: ev.data });
190
93
  if (out !== null && typeof out === 'object' && typeof out.then === 'function') {
@@ -201,7 +104,7 @@ export function tailEngineSubagent(taskId) {
201
104
  case 'forward':
202
105
  break;
203
106
  default:
204
- continue; // heartbeat 等连接语义帧,不进内容面
107
+ continue;
205
108
  }
206
109
  const d = ev.data;
207
110
  const t = d.type;
@@ -230,8 +133,6 @@ export function tailEngineSubagent(taskId) {
230
133
  ...(typeof d.toolName === 'string' ? { toolName: d.toolName } : {}),
231
134
  args: d.args,
232
135
  });
233
- // 详情页 `Progress` 段的数据面(执行半场在端,见 SubagentActivitySink)。
234
- // 只有真拿到工具名才记 —— 无名帧不编。
235
136
  if (typeof d.toolName === 'string' && d.toolName.length > 0) {
236
137
  activitySink?.({ taskId, toolName: d.toolName, args: d.args });
237
138
  }
@@ -249,16 +150,10 @@ export function tailEngineSubagent(taskId) {
249
150
  });
250
151
  }
251
152
  else if (t === 'task_settled') {
252
- // 收口:flush 流式尾巴;终报/结局事实由既有 hydrate/bg 事实臂渲染,不从 tail 合成。
253
- // [1543]①:seq 骑帧(core 1.373 UnifiedTaskOutput.seq;1.377 起 live 臂同键全域投影,
254
- // [1548]——settle 世代口径 spawn=1/复活承袭 claim 周期号)——≥2 = 复活周期(S3c revive)
255
- // 的 settle。tail 台账按周期关流;重开由查看态 watcher 兜(viewing 行回 running 且无
256
- // 在飞 tail 即重开,revive/断线同一恢复路)。
257
153
  settleSubagentContent(taskId);
258
154
  hostLog('debug', `[subagent-tail] ${taskId} settled (${String(d.status)}${typeof d.seq === 'number' ? ` seq=${d.seq}` : ''}${typeof d.summary === 'string' ? ` summary=${d.summary.slice(0, 80)}` : ''}) — close`);
259
155
  break;
260
156
  }
261
- // task_progress:面板 rollup 已有独立腿,这里不重复消费
262
157
  }
263
158
  }
264
159
  catch (e) {
@@ -273,7 +168,6 @@ export function tailEngineSubagent(taskId) {
273
168
  }
274
169
  })();
275
170
  }
276
- /** 关闭一个子代的 tail(幂等;查看态退出/终态/行消失时调)。 */
277
171
  export function stopEngineSubagentTail(taskId) {
278
172
  const ac = activeTails.get(taskId);
279
173
  if (!ac)
@@ -281,11 +175,9 @@ export function stopEngineSubagentTail(taskId) {
281
175
  activeTails.delete(taskId);
282
176
  ac.abort();
283
177
  }
284
- /** 在飞判别([1543]① 重开路用):true = 该子代已有 tail 挂着。 */
285
178
  export function hasActiveSubagentTail(taskId) {
286
179
  return activeTails.has(taskId);
287
180
  }
288
- /** 测试钩:在飞 tail 数。 */
289
181
  export function __activeTailCountForTests() {
290
182
  return activeTails.size;
291
183
  }