@sema-agent/client-core 0.100.0 → 0.102.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 (358) hide show
  1. package/CHANGELOG.md +452 -0
  2. package/README.md +172 -120
  3. package/dist/adapt/arms.js +51 -16
  4. package/dist/adapt/textStream.js +7 -4
  5. package/dist/adapt/toolCards.d.ts +2 -1
  6. package/dist/adapt/toolCards.js +28 -13
  7. package/dist/adapt.d.ts +1 -1
  8. package/dist/adapt.js +8 -2
  9. package/dist/adapter/activeRunSelfHeal.d.ts +24 -2
  10. package/dist/adapter/activeRunSelfHeal.js +108 -6
  11. package/dist/adapter/downstream/eventToSdkMessage.js +38 -79
  12. package/dist/adapter/downstream/terminalToSdkResult.d.ts +60 -1
  13. package/dist/adapter/downstream/terminalToSdkResult.js +209 -39
  14. package/dist/adapter/downstream/wiringManifestView.d.ts +1 -0
  15. package/dist/adapter/downstream/wiringManifestView.js +138 -0
  16. package/dist/adapter/runStream.d.ts +4 -4
  17. package/dist/adapter/runStream.js +158 -43
  18. package/dist/agentsWireCaps.d.ts +2 -7
  19. package/dist/agentsWireCaps.js +1 -2
  20. package/dist/approvalDecidedByCapability.js +2 -2
  21. package/dist/approvalFrameFamilies.d.ts +33 -0
  22. package/dist/approvalFrameFamilies.js +120 -0
  23. package/dist/approvalsStreamLiveCapability.js +2 -2
  24. package/dist/attachmentsWireCaps.js +41 -13
  25. package/dist/callerCwdCapability.js +2 -2
  26. package/dist/centerWiringCapability.js +2 -2
  27. package/dist/clockReading.d.ts +2 -0
  28. package/dist/clockReading.js +4 -0
  29. package/dist/cloudConfigWireCaps.d.ts +19 -5
  30. package/dist/cloudConfigWireCaps.js +193 -56
  31. package/dist/compensations.js +1 -1
  32. package/dist/coreValuePorts.d.ts +12 -2
  33. package/dist/coreValuePorts.js +9 -0
  34. package/dist/decideFailureNote.js +5 -3
  35. package/dist/decideReceipt.js +2 -2
  36. package/dist/deviceExecutorManagementCapability.js +2 -2
  37. package/dist/deviceFlowPolling.js +1 -1
  38. package/dist/disableSkillsWire.d.ts +1 -1
  39. package/dist/disableSkillsWire.js +4 -3
  40. package/dist/displayUntrusted.d.ts +9 -4
  41. package/dist/displayUntrusted.js +834 -104
  42. package/dist/engineCapReader.js +1 -1
  43. package/dist/engineConfigDrift.js +1 -1
  44. package/dist/engineErrorCodes.d.ts +14 -5
  45. package/dist/engineErrorCodes.js +27 -6
  46. package/dist/engineGenerationConvergence.d.ts +39 -0
  47. package/dist/engineGenerationConvergence.js +95 -0
  48. package/dist/engineGenerationPort.d.ts +61 -0
  49. package/dist/engineGenerationPort.js +144 -0
  50. package/dist/engineHealthFacts.d.ts +23 -0
  51. package/dist/engineHealthFacts.js +92 -0
  52. package/dist/engineIdentity.d.ts +4 -0
  53. package/dist/engineIdentity.js +11 -0
  54. package/dist/engineNoticeCodes.d.ts +2 -5
  55. package/dist/engineRowRef.js +4 -0
  56. package/dist/engineSessionMessages.js +2 -2
  57. package/dist/engineToolDirectory.js +2 -2
  58. package/dist/engineWireFor.d.ts +99 -0
  59. package/dist/engineWireFor.js +248 -6
  60. package/dist/engineWireTarget.d.ts +1 -0
  61. package/dist/engineWireTarget.js +8 -0
  62. package/dist/env/uiLanguage.js +1 -1
  63. package/dist/errorSupplementRoles.d.ts +3 -0
  64. package/dist/errorSupplementRoles.js +37 -0
  65. package/dist/executionLaneCapability.js +2 -2
  66. package/dist/fileHistoryCaptureCapability.js +3 -3
  67. package/dist/finalVerifyWire.d.ts +6 -3
  68. package/dist/finalVerifyWire.js +6 -23
  69. package/dist/flagInput.d.ts +4 -0
  70. package/dist/flagInput.js +24 -0
  71. package/dist/fleet/fleetLedger.js +5 -2
  72. package/dist/fleet/fleetProjection.d.ts +1 -0
  73. package/dist/fleet/fleetProjection.js +16 -3
  74. package/dist/gateVocabulary.js +3 -0
  75. package/dist/generated/engineFactTables.d.ts +7 -3
  76. package/dist/generated/engineFactTables.js +52 -0
  77. package/dist/generated/engineNoticeTables.js +12 -0
  78. package/dist/generated/settingsSchemaActiveTiers.d.ts +1 -0
  79. package/dist/generated/settingsSchemaActiveTiers.js +14 -0
  80. package/dist/generated/settingsSchemaCallerTextEcho.d.ts +1 -0
  81. package/dist/generated/settingsSchemaCallerTextEcho.js +8 -0
  82. package/dist/generated/settingsSchemaControlAndBidi.d.ts +1 -0
  83. package/dist/generated/settingsSchemaControlAndBidi.js +8 -0
  84. package/dist/generated/settingsSchemaDefaultModel.d.ts +11 -0
  85. package/dist/generated/settingsSchemaDefaultModel.js +25 -0
  86. package/dist/generated/settingsSchemaFns.d.ts +54 -0
  87. package/dist/generated/settingsSchemaFns.js +26 -1
  88. package/dist/generated/settingsSchemaMcpRequestEntry.d.ts +1 -1
  89. package/dist/generated/settingsSchemaMcpRequestEntry.js +1 -7
  90. package/dist/generated/settingsSchemaSafetyMergeSpec.d.ts +1 -0
  91. package/dist/generated/settingsSchemaSafetyMergeSpec.js +95 -0
  92. package/dist/generated/settingsSchemaSettingsSources.d.ts +1 -0
  93. package/dist/generated/settingsSchemaSettingsSources.js +58 -0
  94. package/dist/generated/settingsSchemaTables.d.ts +2 -0
  95. package/dist/generated/settingsSchemaTables.js +13 -0
  96. package/dist/generated/settingsSchemaUrlPattern.d.ts +1 -0
  97. package/dist/generated/settingsSchemaUrlPattern.js +183 -0
  98. package/dist/headlessPermissionModeWire.d.ts +18 -2
  99. package/dist/headlessPermissionModeWire.js +30 -19
  100. package/dist/hitl/allowRuleShadow.js +7 -5
  101. package/dist/hitl/approvalCardReading.d.ts +3 -0
  102. package/dist/hitl/approvalCardReading.js +17 -0
  103. package/dist/hitl/approvalCompleteParked.js +1 -1
  104. package/dist/hitl/approvalDelivery.d.ts +87 -0
  105. package/dist/hitl/approvalDelivery.js +193 -0
  106. package/dist/hitl/approvalResolution.d.ts +11 -0
  107. package/dist/hitl/approvalResolution.js +50 -11
  108. package/dist/hitl/askClassPair.d.ts +6 -0
  109. package/dist/hitl/askClassPair.js +30 -3
  110. package/dist/hitl/askParkAutoReopenBlock.d.ts +30 -0
  111. package/dist/hitl/askParkAutoReopenBlock.js +117 -0
  112. package/dist/hitl/askParkRowRouting.js +4 -1
  113. package/dist/hitl/attributionLadder.d.ts +42 -3
  114. package/dist/hitl/attributionLadder.js +79 -8
  115. package/dist/hitl/automaticAnswerVerdict.d.ts +6 -1
  116. package/dist/hitl/automaticAnswerVerdict.js +46 -11
  117. package/dist/hitl/crashConverged.js +2 -2
  118. package/dist/hitl/decisionConflict.d.ts +6 -2
  119. package/dist/hitl/decisionConflict.js +24 -9
  120. package/dist/hitl/decisionRefusal.d.ts +20 -10
  121. package/dist/hitl/decisionRefusal.js +99 -54
  122. package/dist/hitl/decisionSend.d.ts +3 -0
  123. package/dist/hitl/decisionSend.js +87 -103
  124. package/dist/hitl/frameRouter.d.ts +1 -0
  125. package/dist/hitl/frameRouter.js +9 -2
  126. package/dist/hitl/hitlBridge.d.ts +18 -6
  127. package/dist/hitl/hitlBridge.js +41 -37
  128. package/dist/hitl/livePendingAsk.js +4 -3
  129. package/dist/hitl/noAllowCause.js +1 -1
  130. package/dist/hitl/parkResolver.js +3 -2
  131. package/dist/hitl/persistedRulesWire.js +1 -0
  132. package/dist/hitl/planReviewWire.d.ts +4 -0
  133. package/dist/hitl/planReviewWire.js +59 -30
  134. package/dist/hitl/resumeRunningCard.d.ts +3 -2
  135. package/dist/hitl/resumeRunningCard.js +17 -11
  136. package/dist/hitl/sessionPolicyDeliverable.d.ts +5 -2
  137. package/dist/hitl/sessionPolicyDeliverable.js +62 -29
  138. package/dist/hitl/sessionPolicyWire.d.ts +13 -3
  139. package/dist/hitl/sessionPolicyWire.js +81 -16
  140. package/dist/hitl/standingRows.js +1 -1
  141. package/dist/hitl/toolApprovalWire.d.ts +9 -10
  142. package/dist/hitl/toolApprovalWire.js +72 -54
  143. package/dist/hookMatcherVerdict.d.ts +2 -0
  144. package/dist/hookMatcherVerdict.js +12 -0
  145. package/dist/hooksCompactTransition.d.ts +19 -0
  146. package/dist/hooksCompactTransition.js +41 -0
  147. package/dist/hooksWireCaps.d.ts +1 -1
  148. package/dist/hooksWireCaps.js +202 -203
  149. package/dist/host.d.ts +1 -14
  150. package/dist/host.js +0 -8
  151. package/dist/hostCallbackGuard.d.ts +1 -0
  152. package/dist/hostCallbackGuard.js +1 -1
  153. package/dist/hostSettingsSource.d.ts +172 -0
  154. package/dist/hostSettingsSource.js +675 -0
  155. package/dist/hostTurnSettings.d.ts +73 -17
  156. package/dist/hostTurnSettings.js +594 -97
  157. package/dist/httpHookPolicy.d.ts +37 -0
  158. package/dist/httpHookPolicy.js +176 -0
  159. package/dist/humanTurn.d.ts +2 -1
  160. package/dist/humanTurn.js +37 -7
  161. package/dist/humanTurnRead.js +4 -3
  162. package/dist/humanTurnSentences.d.ts +10 -0
  163. package/dist/humanTurnSentences.js +74 -0
  164. package/dist/i18n/messages.en.d.ts +222 -2
  165. package/dist/i18n/messages.en.js +225 -5
  166. package/dist/i18n/messages.zh.js +237 -5
  167. package/dist/i18n/translate.js +3 -3
  168. package/dist/index.d.ts +77 -15
  169. package/dist/index.js +50 -13
  170. package/dist/inheritEnvCapability.d.ts +3 -1
  171. package/dist/inheritEnvCapability.js +31 -17
  172. package/dist/inheritEnvWire.d.ts +2 -1
  173. package/dist/inheritEnvWire.js +11 -5
  174. package/dist/interactiveHalt.d.ts +3 -1
  175. package/dist/interactiveHalt.js +2 -0
  176. package/dist/interactiveInterrupt.d.ts +2 -0
  177. package/dist/interactiveInterrupt.js +15 -0
  178. package/dist/interactiveToolsWire.d.ts +4 -2
  179. package/dist/interactiveToolsWire.js +5 -5
  180. package/dist/jsonFaithful.d.ts +20 -0
  181. package/dist/jsonFaithful.js +152 -0
  182. package/dist/limitsWire.d.ts +7 -2
  183. package/dist/limitsWire.js +19 -13
  184. package/dist/liveInitToolFace.d.ts +6 -1
  185. package/dist/liveInitToolFace.js +5 -3
  186. package/dist/liveModelCatalog.d.ts +22 -0
  187. package/dist/liveModelCatalog.js +132 -18
  188. package/dist/mcpPanel.js +1 -1
  189. package/dist/mcpProbeCapability.js +2 -2
  190. package/dist/mcpStatusSupersetKeys.d.ts +24 -0
  191. package/dist/mcpStatusSupersetKeys.js +45 -0
  192. package/dist/mcpToolToggles.js +2 -1
  193. package/dist/mcpWireCaps.d.ts +39 -1
  194. package/dist/mcpWireCaps.js +254 -50
  195. package/dist/memoryComplianceCapability.js +2 -2
  196. package/dist/memoryOriginCapability.js +2 -2
  197. package/dist/model/catalogDefault.d.ts +24 -0
  198. package/dist/model/catalogDefault.js +4 -0
  199. package/dist/model/liveCatalogShape.js +5 -4
  200. package/dist/model/modelsPolicy.js +4 -3
  201. package/dist/model/onboardJudgement.d.ts +1 -0
  202. package/dist/model/onboardJudgement.js +1 -1
  203. package/dist/model/subagentModelWord.js +2 -2
  204. package/dist/modelCapabilityProbe.js +6 -6
  205. package/dist/modelIdentityResolvability.d.ts +10 -1
  206. package/dist/modelIdentityResolvability.js +62 -39
  207. package/dist/modsFace.d.ts +8 -0
  208. package/dist/modsFace.js +59 -0
  209. package/dist/modsKernelIdentity.d.ts +10 -0
  210. package/dist/modsKernelIdentity.js +103 -0
  211. package/dist/modsKernelTransit.d.ts +8 -0
  212. package/dist/modsKernelTransit.js +6 -0
  213. package/dist/notifications.d.ts +30 -12
  214. package/dist/notifications.js +241 -53
  215. package/dist/outputStyleSeatCapability.js +2 -2
  216. package/dist/ownKey.d.ts +12 -0
  217. package/dist/ownKey.js +179 -3
  218. package/dist/panelReduce.js +1 -1
  219. package/dist/peerFrames.d.ts +1 -1
  220. package/dist/peerFrames.js +6 -2
  221. package/dist/peerLaneCapability.js +2 -2
  222. package/dist/permissionModesCapability.js +4 -4
  223. package/dist/permissionRuleIssue.js +2 -0
  224. package/dist/permissionRulesWriteCapability.js +2 -2
  225. package/dist/permissionsAllowGrantCapability.js +2 -2
  226. package/dist/permissionsDeclaration.d.ts +43 -4
  227. package/dist/permissionsDeclaration.js +102 -35
  228. package/dist/pluginHooksWire.d.ts +20 -4
  229. package/dist/pluginHooksWire.js +92 -53
  230. package/dist/prepareRefusal.d.ts +3 -2
  231. package/dist/prepareRefusal.js +27 -9
  232. package/dist/printInitToolFace.js +2 -2
  233. package/dist/printModelStatus.js +1 -1
  234. package/dist/printToolResultFrame.js +1 -1
  235. package/dist/projectMemory.d.ts +32 -0
  236. package/dist/projectMemory.js +70 -0
  237. package/dist/promptBlockedCopy.d.ts +2 -1
  238. package/dist/promptBlockedCopy.js +2 -1
  239. package/dist/promptDelivery.d.ts +23 -3
  240. package/dist/promptDelivery.js +169 -30
  241. package/dist/providerRejection.d.ts +19 -1
  242. package/dist/providerRejection.js +75 -4
  243. package/dist/queuedDelivery.d.ts +48 -0
  244. package/dist/queuedDelivery.js +233 -0
  245. package/dist/reattachWindow.d.ts +94 -0
  246. package/dist/reattachWindow.js +127 -0
  247. package/dist/request/printNotification.d.ts +1 -1
  248. package/dist/request/printNotification.js +6 -2
  249. package/dist/request/submissionIdentity.d.ts +37 -0
  250. package/dist/request/submissionIdentity.js +65 -0
  251. package/dist/request/taskRequest.d.ts +33 -4
  252. package/dist/request/taskRequest.js +341 -156
  253. package/dist/resultFrameKeys.d.ts +1 -0
  254. package/dist/resultFrameKeys.js +4 -1
  255. package/dist/retryStatus.d.ts +8 -0
  256. package/dist/retryStatus.js +57 -9
  257. package/dist/rewindArchiveCapability.js +2 -2
  258. package/dist/rewindEngineAction.d.ts +2 -0
  259. package/dist/rewindEngineAction.js +23 -1
  260. package/dist/rowKind.d.ts +36 -0
  261. package/dist/rowKind.js +97 -0
  262. package/dist/ruleCompileVerdict.d.ts +18 -0
  263. package/dist/ruleCompileVerdict.js +67 -2
  264. package/dist/ruleReadings.d.ts +58 -0
  265. package/dist/ruleReadings.js +132 -0
  266. package/dist/ruleRefusalSentence.d.ts +4 -0
  267. package/dist/ruleRefusalSentence.js +9 -3
  268. package/dist/runCancelContext.d.ts +0 -1
  269. package/dist/runCancelContext.js +1 -2
  270. package/dist/runTerminal.d.ts +5 -0
  271. package/dist/runTerminal.js +52 -17
  272. package/dist/sandboxWire.d.ts +1 -1
  273. package/dist/sandboxWire.js +4 -6
  274. package/dist/scenarioRefusal.js +1 -1
  275. package/dist/scenarioSkills.d.ts +20 -0
  276. package/dist/scenarioSkills.js +72 -0
  277. package/dist/scenarioWire.d.ts +5 -2
  278. package/dist/scenarioWire.js +9 -9
  279. package/dist/sealedKeyCapability.js +2 -2
  280. package/dist/seam.d.ts +2 -0
  281. package/dist/seam.js +3 -3
  282. package/dist/seatContract.d.ts +68 -7
  283. package/dist/seatContract.js +84 -25
  284. package/dist/selfOrchestrationDenial.js +1 -1
  285. package/dist/sessionBackground.d.ts +165 -0
  286. package/dist/sessionBackground.js +781 -0
  287. package/dist/sessionBackgroundHandoff.d.ts +54 -0
  288. package/dist/sessionBackgroundHandoff.js +321 -0
  289. package/dist/sessionMap.js +4 -1
  290. package/dist/sessionPolicyCapability.js +2 -2
  291. package/dist/sessionRulesChildrenReadLive.d.ts +6 -0
  292. package/dist/sessionRulesChildrenReadLive.js +5 -0
  293. package/dist/sessionRulesNamespaceFormsCapability.d.ts +12 -0
  294. package/dist/sessionRulesNamespaceFormsCapability.js +29 -0
  295. package/dist/sessionSyncFileHistoryCapability.js +2 -2
  296. package/dist/settingsCredentialKeyPaths.js +55 -15
  297. package/dist/settingsHooksSalvage.d.ts +1 -0
  298. package/dist/settingsHooksSalvage.js +7 -1
  299. package/dist/settingsLayerAdmission.d.ts +4 -0
  300. package/dist/settingsLayerAdmission.js +16 -0
  301. package/dist/skillToolListsCapability.js +6 -5
  302. package/dist/skillsWireCaps.d.ts +14 -0
  303. package/dist/skillsWireCaps.js +47 -16
  304. package/dist/slashCommandGate.d.ts +24 -0
  305. package/dist/slashCommandGate.js +74 -0
  306. package/dist/slashCommandTable.d.ts +14 -0
  307. package/dist/slashCommandTable.js +99 -0
  308. package/dist/sqlEngineCapability.js +2 -2
  309. package/dist/steerPriorityCapability.js +2 -2
  310. package/dist/storePostureCapability.js +2 -2
  311. package/dist/subagent/agentStateDetail.js +1 -1
  312. package/dist/subagent/engineDelegatedPrompt.d.ts +9 -0
  313. package/dist/subagent/engineDelegatedPrompt.js +38 -7
  314. package/dist/subagent/engineRowStopGate.js +2 -2
  315. package/dist/subagent/engineSubagentResume.js +3 -3
  316. package/dist/subagent/engineTaskHandleWire.d.ts +1 -0
  317. package/dist/subagent/engineTaskHandleWire.js +10 -0
  318. package/dist/submitFailure.d.ts +8 -0
  319. package/dist/submitFailure.js +17 -0
  320. package/dist/supportFloor.d.ts +1 -0
  321. package/dist/supportFloor.js +7 -0
  322. package/dist/terminationIntent.d.ts +55 -0
  323. package/dist/terminationIntent.js +352 -0
  324. package/dist/thinkingLatch.d.ts +69 -0
  325. package/dist/thinkingLatch.js +255 -0
  326. package/dist/thinkingLatchWords.d.ts +7 -0
  327. package/dist/thinkingLatchWords.js +4 -0
  328. package/dist/toolHistoryMismatch.d.ts +8 -0
  329. package/dist/toolHistoryMismatch.js +37 -6
  330. package/dist/toolResult.d.ts +13 -3
  331. package/dist/toolResult.js +159 -32
  332. package/dist/toolResultContent.d.ts +13 -0
  333. package/dist/toolResultContent.js +82 -7
  334. package/dist/toolRoster.d.ts +18 -0
  335. package/dist/toolRoster.js +64 -0
  336. package/dist/turnFailurePresentation.js +27 -90
  337. package/dist/usageLimitAutoResume.d.ts +74 -0
  338. package/dist/usageLimitAutoResume.js +227 -0
  339. package/dist/userAttachmentEnvelope.js +1 -1
  340. package/dist/userAttachmentSeat.js +5 -5
  341. package/dist/userInvokedSkillsCapability.js +2 -2
  342. package/dist/webSearchBackendCapability.js +2 -2
  343. package/dist/wireErrorTriage.js +99 -50
  344. package/dist/wireFailureShape.d.ts +25 -1
  345. package/dist/wireFailureShape.js +92 -5
  346. package/dist/wireRefusalCopy.d.ts +24 -1
  347. package/dist/wireRefusalCopy.js +253 -32
  348. package/dist/wiringFleetDoctor.d.ts +3 -0
  349. package/dist/wiringFleetDoctor.js +21 -0
  350. package/dist/workflow.d.ts +2 -1
  351. package/dist/workflow.js +38 -1
  352. package/dist/workflowClient.d.ts +2 -7
  353. package/dist/workflowsJournalCapability.js +2 -2
  354. package/dist/writeProtectionCapability.js +2 -2
  355. package/docs/INTEGRATION-CLIENTS.md +907 -182
  356. package/package.json +14 -3
  357. package/dist/argvFlagValue.d.ts +0 -8
  358. package/dist/argvFlagValue.js +0 -37
@@ -0,0 +1,87 @@
1
+ import { type AnswerCapture, type TopCauseReading, type TopLocalCodeReading, type UnansweredCapture } from '../engineWireFor.js';
2
+ import { type AttributionLadderState, type AttributionLadderStep } from './attributionLadder.js';
3
+ import { type RefusalCarrier, type SafetyStopHead } from './hitlBridge.js';
4
+ export declare const PARKING_WAIT_CAP_MS = 5000;
5
+ export interface DeliveryTiming {
6
+ readonly delays?: readonly number[];
7
+ readonly budgetMs?: number;
8
+ readonly parkingDelayMs?: number;
9
+ }
10
+ export declare function setDeliveryTimingForTests(t?: DeliveryTiming): void;
11
+ export interface DeliveryTimingReading {
12
+ readonly delays: readonly number[];
13
+ readonly budgetMs: number;
14
+ readonly parkingDelayMs: number | undefined;
15
+ }
16
+ export declare function deliveryTiming(): DeliveryTimingReading;
17
+ export type TransportClass = 'aborted' | 'transport' | 'server_5xx' | 'verdict' | 'local_error';
18
+ export interface TransportReading {
19
+ readonly cls: TransportClass;
20
+ readonly answered?: AnswerCapture;
21
+ readonly unanswered?: UnansweredCapture;
22
+ readonly carrierReads?: readonly {
23
+ readonly thrown: object;
24
+ readonly read: RefusalCarrier;
25
+ }[];
26
+ readonly topLocalCode?: TopLocalCodeReading;
27
+ readonly bindingMismatchWrapper?: true;
28
+ readonly topCause?: TopCauseReading;
29
+ readonly safetyStop?: true;
30
+ }
31
+ export declare function transportReadingOf(e: {} | null | undefined, signal: AbortSignal | undefined): TransportReading;
32
+ export declare function settledTransportReadingOf(e: {} | null | undefined, signal: AbortSignal | undefined, tally: SendTally): TransportReading;
33
+ export declare function deliveryReadingOf(thrown: {} | null | undefined, tally: SendTally): TransportReading | undefined;
34
+ export declare function transportClassOf(e: {} | null | undefined, signal: AbortSignal | undefined): TransportClass;
35
+ export interface SendTally {
36
+ attempts: number;
37
+ retried: boolean;
38
+ readonly startedAt: number;
39
+ lastThrown: {
40
+ readonly thrown: {} | null | undefined;
41
+ readonly reading: TransportReading;
42
+ } | undefined;
43
+ }
44
+ export declare function newSendTally(): SendTally;
45
+ export declare function budgetSpent(tally: SendTally, extraMs: number): boolean;
46
+ export declare function isAborted(signal: AbortSignal | undefined): boolean;
47
+ export declare function sleepFor(ms: number, signal: AbortSignal | undefined): Promise<void>;
48
+ export declare function withTransportRetry<T>(send: (signal: AbortSignal | undefined) => Promise<T>, signal: AbortSignal | undefined, tally: SendTally, deadlineOnFirst?: boolean): Promise<T>;
49
+ export interface SettledFailureReading {
50
+ readonly thrown: {} | null | undefined;
51
+ readonly reading: TransportReading;
52
+ }
53
+ export declare function directFailureReadingOf(e: {} | null | undefined, triaged: TransportReading, topHead: SafetyStopHead): SettledFailureReading;
54
+ export interface ApprovalParkingFacts {
55
+ readonly approvalId: string;
56
+ readonly retryAfterMs?: number;
57
+ }
58
+ export declare function approvalParkingRetryWait(view: ApprovalParkingFacts, tally: SendTally, signal: AbortSignal | undefined): number | undefined;
59
+ export type ApprovalDelivery = {
60
+ readonly kind: 'answered';
61
+ readonly raw: {} | null | undefined;
62
+ readonly parkingRetried?: true;
63
+ } | {
64
+ readonly kind: 'thrown';
65
+ readonly error: {} | null | undefined;
66
+ readonly reading: TransportReading;
67
+ readonly transportExhausted: boolean;
68
+ readonly afterRetry: boolean;
69
+ readonly parkingRetried?: true;
70
+ };
71
+ export interface ApprovalDeliveryInput<B extends {
72
+ settledBy?: unknown;
73
+ decidedBy?: unknown;
74
+ }> {
75
+ readonly approvalId: string;
76
+ readonly body: B;
77
+ readonly send: (body: B, signal: AbortSignal | undefined) => Promise<{} | null | undefined | void>;
78
+ readonly signal: AbortSignal | undefined;
79
+ readonly tally: SendTally;
80
+ readonly ladder: AttributionLadderState;
81
+ readonly onLadderStep?: (step: AttributionLadderStep) => void;
82
+ readonly parkingOf: (raw: {} | null | undefined) => ApprovalParkingFacts | undefined;
83
+ }
84
+ export declare function deliverApprovalDecision<B extends {
85
+ settledBy?: unknown;
86
+ decidedBy?: unknown;
87
+ }>(input: ApprovalDeliveryInput<B>): Promise<ApprovalDelivery>;
@@ -0,0 +1,193 @@
1
+ import { abortableSleep } from '../abortableSleep.js';
2
+ import { classifyTurnWireError } from '../wireErrorTriage.js';
3
+ import { ownReadingSlot, triageReadingOf } from '../engineWireFor.js';
4
+ import { isSlotCarrier, readThrownSlot, THROWN_SLOT_UNREADABLE } from '../wireFailureShape.js';
5
+ import { deliverWithAttributionLadder, localCodeReadOf, topCauseReadOf } from './attributionLadder.js';
6
+ import { GATE_FAILURE_CODES, refusalCarrierOf, safetyStopHeadOf } from './hitlBridge.js';
7
+ const RETRY_DELAYS_MS = Object.freeze([500, 1_000, 2_000]);
8
+ const RETRY_BUDGET_MS = 8_000;
9
+ export const PARKING_WAIT_CAP_MS = 5_000;
10
+ let timingOverride;
11
+ export function setDeliveryTimingForTests(t) {
12
+ timingOverride = t;
13
+ }
14
+ export function deliveryTiming() {
15
+ return { delays: timingOverride?.delays ?? RETRY_DELAYS_MS, budgetMs: timingOverride?.budgetMs ?? RETRY_BUDGET_MS, parkingDelayMs: timingOverride?.parkingDelayMs };
16
+ }
17
+ function isAbortShaped(e) {
18
+ const name = readThrownSlot(e, 'name');
19
+ return name === 'TimeoutError' || name === 'AbortError';
20
+ }
21
+ export function transportReadingOf(e, signal) {
22
+ const reading = triageReadingOf(classifyTurnWireError(e));
23
+ const answered = ownReadingSlot(reading, 'answer');
24
+ const unanswered = ownReadingSlot(reading, 'unanswered');
25
+ const topLocalCode = ownReadingSlot(reading, 'topLocalCode');
26
+ const topCause = ownReadingSlot(reading, 'topCause');
27
+ const topFacts = { ...(topLocalCode !== undefined ? { topLocalCode } : {}), ...(topCause !== undefined ? { topCause } : {}) };
28
+ const layer = answered !== undefined && answered !== THROWN_SLOT_UNREADABLE ? { answered, ...topFacts } : unanswered !== undefined ? { unanswered, ...topFacts } : topFacts;
29
+ if (signal?.aborted === true)
30
+ return { cls: 'aborted', ...layer };
31
+ if (reading === undefined || answered === THROWN_SLOT_UNREADABLE)
32
+ return { cls: 'local_error', ...topFacts };
33
+ if (answered !== undefined)
34
+ return { cls: answered.status === 501 ? 'verdict' : answered.status >= 500 ? 'server_5xx' : 'verdict', ...layer };
35
+ return { cls: reading.transport || isAbortShaped(e) ? 'transport' : 'local_error', ...layer };
36
+ }
37
+ export function settledTransportReadingOf(e, signal, tally) {
38
+ const last = ownReadingSlot(tally, 'lastThrown');
39
+ if (last === undefined || last.thrown !== e)
40
+ return transportReadingOf(e, signal);
41
+ if (signal?.aborted === true)
42
+ return { ...last.reading, cls: 'aborted' };
43
+ return last.reading;
44
+ }
45
+ export function deliveryReadingOf(thrown, tally) {
46
+ const last = ownReadingSlot(tally, 'lastThrown');
47
+ return last !== undefined && last.thrown === thrown ? last.reading : undefined;
48
+ }
49
+ export function transportClassOf(e, signal) {
50
+ return transportReadingOf(e, signal).cls;
51
+ }
52
+ export function newSendTally() {
53
+ return { attempts: 0, retried: false, startedAt: Date.now(), lastThrown: undefined };
54
+ }
55
+ function attemptSignal(withDeadline, caller, startedAt, budgetMs) {
56
+ if (!withDeadline)
57
+ return caller;
58
+ const deadline = AbortSignal.timeout(Math.max(1, budgetMs - (Date.now() - startedAt)));
59
+ if (caller === undefined)
60
+ return deadline;
61
+ if (typeof AbortSignal.any === 'function')
62
+ return AbortSignal.any([caller, deadline]);
63
+ const ac = new AbortController();
64
+ const abort = (s) => ac.abort(s.reason);
65
+ if (caller.aborted)
66
+ abort(caller);
67
+ else
68
+ caller.addEventListener('abort', () => abort(caller), { once: true });
69
+ deadline.addEventListener('abort', () => abort(deadline), { once: true });
70
+ return ac.signal;
71
+ }
72
+ export function budgetSpent(tally, extraMs) {
73
+ return Date.now() - tally.startedAt + extraMs >= deliveryTiming().budgetMs;
74
+ }
75
+ export function isAborted(signal) {
76
+ return signal?.aborted === true;
77
+ }
78
+ export function sleepFor(ms, signal) {
79
+ return abortableSleep(ms, signal ?? new AbortController().signal);
80
+ }
81
+ export async function withTransportRetry(send, signal, tally, deadlineOnFirst = false) {
82
+ const { delays, budgetMs } = deliveryTiming();
83
+ const startedAt = tally.startedAt;
84
+ for (let attempt = 1;; attempt++) {
85
+ tally.attempts++;
86
+ try {
87
+ return await send(attemptSignal(attempt > 1 || deadlineOnFirst, signal, startedAt, budgetMs));
88
+ }
89
+ catch (e) {
90
+ const reading = transportReadingOf(e, signal);
91
+ const cls = reading.cls;
92
+ const delay = delays[attempt - 1] ?? 0;
93
+ const heads = localStopHeadsOf(e, reading);
94
+ const retriable = (cls === 'transport' || cls === 'server_5xx') && heads.safetyStop !== true;
95
+ const overBudget = Date.now() - startedAt + delay >= budgetMs;
96
+ if (!retriable || attempt > delays.length || overBudget)
97
+ throw answeredError(settledReadingOf(e, reading, heads), tally);
98
+ tally.retried = true;
99
+ await sleepFor(delay, signal);
100
+ if (signal?.aborted === true || Date.now() - startedAt >= budgetMs)
101
+ throw answeredError(settledReadingOf(e, reading, heads), tally);
102
+ }
103
+ }
104
+ }
105
+ function answeredError(settled, tally) {
106
+ tally.lastThrown = settled;
107
+ return settled.thrown;
108
+ }
109
+ function isLocalClosedCode(v) {
110
+ return typeof v === 'string' && GATE_FAILURE_CODES.includes(v);
111
+ }
112
+ function localStopHeadsOf(top, reading, known) {
113
+ const answered = ownReadingSlot(reading, 'answered')?.layer;
114
+ const deep = answered !== undefined && answered !== top ? answered : undefined;
115
+ const topCode = isSlotCarrier(top) ? localCodeReadOf(reading, top) : undefined;
116
+ const topHead = known ?? (!isSlotCarrier(top) ? undefined : topCode === undefined ? safetyStopHeadOf(top) : isLocalClosedCode(topCode.value) ? safetyStopHeadOf(top, topCode) : undefined);
117
+ const deepCode = deep !== undefined ? localCodeReadOf(reading, deep) : undefined;
118
+ const layerHead = deep !== undefined && deepCode !== undefined && isLocalClosedCode(deepCode.value) ? safetyStopHeadOf(deep, deepCode) : undefined;
119
+ const safetyStop = topHead?.local !== undefined || layerHead?.local !== undefined;
120
+ return Object.freeze({ ...(safetyStop ? { safetyStop: true } : {}), ...(topHead !== undefined ? { top: topHead } : {}), ...(layerHead !== undefined ? { layer: layerHead } : {}) });
121
+ }
122
+ function settledReadingOf(e, reading, heads) {
123
+ const top = e;
124
+ const layer = ownReadingSlot(reading, 'answered')?.layer;
125
+ const wrapper = isSlotCarrier(top) ? refusalCarrierOf(top, localCodeReadOf(reading, top), false, topCauseReadOf(reading, top), heads.top) : undefined;
126
+ const thrown = layer === undefined ? top : layer;
127
+ const reads = [];
128
+ if (wrapper !== undefined && isSlotCarrier(top))
129
+ reads.push(Object.freeze({ thrown: top, read: wrapper }));
130
+ if (layer !== undefined && layer !== top)
131
+ reads.push(Object.freeze({ thrown: layer, read: refusalCarrierOf(layer, localCodeReadOf(reading, layer), true, undefined, heads.layer) }));
132
+ const bindingMismatchWrapper = layer !== undefined && layer !== top && wrapper !== undefined && ownReadingSlot(wrapper, 'local') === 'binding_mismatch';
133
+ const safetyStop = heads.safetyStop === true;
134
+ const settled = reads.length > 0 || bindingMismatchWrapper || safetyStop
135
+ ? { ...reading, ...(reads.length > 0 ? { carrierReads: Object.freeze(reads) } : {}), ...(bindingMismatchWrapper ? { bindingMismatchWrapper: true } : {}), ...(safetyStop ? { safetyStop: true } : {}) }
136
+ : reading;
137
+ return { thrown, reading: settled };
138
+ }
139
+ export function directFailureReadingOf(e, triaged, topHead) {
140
+ return settledReadingOf(e, triaged, localStopHeadsOf(e, triaged, topHead));
141
+ }
142
+ export function approvalParkingRetryWait(view, tally, signal) {
143
+ const w = ownReadingSlot(view, 'retryAfterMs');
144
+ if (typeof w !== 'number' || !Number.isFinite(w) || w < 0)
145
+ return undefined;
146
+ if (w > PARKING_WAIT_CAP_MS)
147
+ return undefined;
148
+ if (isAborted(signal) || budgetSpent(tally, w))
149
+ return undefined;
150
+ return w;
151
+ }
152
+ function thrownFacts(e, signal, tally) {
153
+ const reading = settledTransportReadingOf(e, signal, tally);
154
+ return { reading, transportExhausted: reading.cls === 'transport' && tally.retried, afterRetry: tally.retried };
155
+ }
156
+ export async function deliverApprovalDecision(input) {
157
+ const { signal, tally } = input;
158
+ let last = input.body;
159
+ let raw;
160
+ try {
161
+ raw = (await deliverWithAttributionLadder(input.body, (b) => {
162
+ last = b;
163
+ return withTransportRetry((sig) => input.send(b, sig), signal, tally);
164
+ }, signal, input.ladder, input.onLadderStep, { kind: 'delivered', readingOf: (thrown) => deliveryReadingOf(thrown, tally) }));
165
+ }
166
+ catch (e) {
167
+ return { kind: 'thrown', error: e, ...thrownFacts(e, signal, tally) };
168
+ }
169
+ let parking;
170
+ try {
171
+ parking = input.parkingOf(raw);
172
+ }
173
+ catch {
174
+ parking = undefined;
175
+ }
176
+ if (parking === undefined || parking.approvalId !== input.approvalId)
177
+ return { kind: 'answered', raw };
178
+ const wait = approvalParkingRetryWait(parking, tally, signal);
179
+ if (wait === undefined)
180
+ return { kind: 'answered', raw };
181
+ await sleepFor(wait, signal);
182
+ if (isAborted(signal) || budgetSpent(tally, 0))
183
+ return { kind: 'answered', raw };
184
+ tally.retried = false;
185
+ const resent = last;
186
+ try {
187
+ const raw2 = (await withTransportRetry((sig) => input.send(resent, sig), signal, tally, true));
188
+ return { kind: 'answered', raw: raw2, parkingRetried: true };
189
+ }
190
+ catch (e) {
191
+ return { kind: 'thrown', error: e, ...thrownFacts(e, signal, tally), parkingRetried: true };
192
+ }
193
+ }
@@ -3,6 +3,7 @@ import { type HitlSafetyCode } from './hitlBridge.js';
3
3
  import type { AskAnsweredOutput } from './gateLedger.js';
4
4
  import type { ApprovalDenySettledBy, ToolApprovalRespondAckView, ToolApprovalRespondDecision, ToolApprovalRespondParkingView } from './toolApprovalWire.js';
5
5
  import { type DecisionRefusalReading, type RefusalRouteContext } from './decisionRefusal.js';
6
+ import { type DeliveredReading, type LadderSafetyStop } from './attributionLadder.js';
6
7
  export declare const APPROVAL_RESOLUTION_LANES: readonly ["respond", "decide", "ask"];
7
8
  export type ApprovalResolutionLane = (typeof APPROVAL_RESOLUTION_LANES)[number];
8
9
  export declare const APPROVAL_NOT_SENT_CAUSES: readonly ["retracted", "edit_refused", "no_pending", "wrong_gate", "fetch_failed", "no_input", "card_unavailable", "safety_stop"];
@@ -55,7 +56,17 @@ export interface DecisionFailureMint {
55
56
  readonly gatedCallId?: string | undefined;
56
57
  readonly detail?: string | undefined;
57
58
  readonly attributionCarried?: boolean | undefined;
59
+ readonly transportExhausted?: boolean | undefined;
60
+ readonly afterRetry?: boolean | undefined;
61
+ readonly delivered?: DeliveredReading | undefined;
62
+ readonly directStop?: LadderSafetyStop | undefined;
58
63
  }
59
64
  export declare function resolutionOfDecisionFailure(e: {} | null | undefined, m: DecisionFailureMint): ApprovalResolution;
65
+ export declare function directSafetyStopOf(e: {} | null | undefined): LadderSafetyStop | undefined;
66
+ export interface DirectFailureVerdict {
67
+ readonly yields: boolean;
68
+ readonly directStop?: LadderSafetyStop;
69
+ }
70
+ export declare function directFailureVerdictOf(e: {} | null | undefined, stop: LadderSafetyStop | undefined): DirectFailureVerdict;
60
71
  export declare function joinedResolution(r: ApprovalResolution, gatedCallId?: string): ApprovalResolution;
61
72
  export {};
@@ -1,6 +1,9 @@
1
- import { DecideTransportRetryExhaustedError } from './hitlBridge.js';
2
- import { mintDecisionRefusalReading, refusalCarrierOf } from './decisionRefusal.js';
3
- import { thrownIsInstanceOf } from '../wireFailureShape.js';
1
+ import { DecideTransportRetryExhaustedError, refusalCarrierOf, safetyStopHeadOf, safetyStopNamed } from './hitlBridge.js';
2
+ import { mintDecisionRefusalReading } from './decisionRefusal.js';
3
+ import { isSlotCarrier, thrownIsInstanceOf } from '../wireFailureShape.js';
4
+ import { carrierReadOf, isLocalSafetyStop, localCodeReadOf, topCauseReadOf } from './attributionLadder.js';
5
+ import { directFailureReadingOf, transportReadingOf } from './approvalDelivery.js';
6
+ import { ownReadingSlot } from '../engineWireFor.js';
4
7
  export const APPROVAL_RESOLUTION_LANES = Object.freeze(['respond', 'decide', 'ask']);
5
8
  export const APPROVAL_NOT_SENT_CAUSES = Object.freeze([
6
9
  'retracted',
@@ -91,29 +94,65 @@ export function approvalResolutionDetail(r) {
91
94
  return parts.length > 0 ? parts.join(' · ') : undefined;
92
95
  }
93
96
  export function unsettledCauseOfReading(reading) {
94
- if (reading.standing === 'ambiguous')
97
+ const standing = ownReadingSlot(reading, 'standing');
98
+ if (standing === 'ambiguous')
95
99
  return 'engine_error';
96
- return reading.standing === undefined ? 'no_answer' : 'engine_refused';
100
+ return standing === undefined ? 'no_answer' : 'engine_refused';
97
101
  }
98
102
  export function resolutionOfDecisionFailure(e, m) {
103
+ const gatedCallId = ownReadingSlot(m, 'gatedCallId');
99
104
  const base = {
100
105
  lane: m.lane,
101
- ...(m.gatedCallId !== undefined ? { gatedCallId: m.gatedCallId } : {}),
106
+ ...(gatedCallId !== undefined ? { gatedCallId } : {}),
102
107
  };
103
- const detail = m.detail !== undefined && m.detail.length > 0 ? { detail: m.detail } : {};
104
- const { local } = refusalCarrierOf(e);
105
- if (local !== undefined && local !== 'binding_mismatch') {
108
+ const mDetail = ownReadingSlot(m, 'detail');
109
+ const detail = mDetail !== undefined && mDetail.length > 0 ? { detail: mDetail } : {};
110
+ const delivered = ownReadingSlot(m, 'delivered');
111
+ const handed = ownReadingSlot(m, 'directStop');
112
+ const stop = delivered !== undefined ? undefined : handed !== undefined && handed.thrown === e ? handed : directSafetyStopOf(e);
113
+ const triaged = stop?.triaged;
114
+ const head = delivered !== undefined ? undefined : stop !== undefined ? stop.head : { named: false };
115
+ const direct = stop !== undefined && stop.head.local !== undefined ? (ownReadingSlot(stop, 'settled') ?? directFailureReadingOf(e, stop.triaged, stop.head)) : undefined;
116
+ const subject = direct !== undefined ? direct.thrown : e;
117
+ const reading = delivered ?? direct?.reading;
118
+ const carrierRead = reading !== undefined ? carrierReadOf(subject, reading) : refusalCarrierOf(e, undefined, false, triaged !== undefined && isSlotCarrier(e) ? topCauseReadOf(triaged, e) : undefined, head);
119
+ const local = ownReadingSlot(carrierRead, 'local');
120
+ if (local !== undefined && local !== 'binding_mismatch' && zeroByteProven(subject, reading, delivered !== undefined, ownReadingSlot(m, 'afterRetry') === true)) {
106
121
  if (local === 'no_pending' || local === 'wrong_gate')
107
122
  return { kind: 'not_sent', ...base, cause: local, ...detail };
108
123
  return { kind: 'not_sent', ...base, cause: 'safety_stop', safetyCode: local, ...detail };
109
124
  }
110
- const refusal = mintDecisionRefusalReading(e, { route: m.route }, m.attributionCarried);
125
+ const refusal = mintDecisionRefusalReading(subject, { route: m.route, ...(ownReadingSlot(m, 'afterRetry') === true ? { afterRetry: true } : {}) }, ownReadingSlot(m, 'attributionCarried'), reading, carrierRead);
111
126
  if (local === 'binding_mismatch')
112
127
  return { kind: 'unsettled', ...base, cause: 'engine_refused', safetyCode: 'binding_mismatch', refusal, ...detail };
113
- if (thrownIsInstanceOf(e, DecideTransportRetryExhaustedError))
128
+ if (ownReadingSlot(m, 'transportExhausted') === true || thrownIsInstanceOf(e, DecideTransportRetryExhaustedError))
114
129
  return { kind: 'unsettled', ...base, cause: 'transport_exhausted', refusal, ...detail };
115
130
  return { kind: 'unsettled', ...base, cause: unsettledCauseOfReading(refusal), refusal, ...detail };
116
131
  }
132
+ export function directSafetyStopOf(e) {
133
+ if (!isSlotCarrier(e) || !safetyStopNamed(e))
134
+ return undefined;
135
+ const triaged = transportReadingOf(e, undefined);
136
+ return Object.freeze({ thrown: e, head: safetyStopHeadOf(e, localCodeReadOf(triaged, e), true), triaged });
137
+ }
138
+ export function directFailureVerdictOf(e, stop) {
139
+ const settled = directFailureReadingOf(e, stop !== undefined ? stop.triaged : transportReadingOf(e, undefined), stop !== undefined ? stop.head : { named: false });
140
+ const yields = isLocalSafetyStop(carrierReadOf(settled.thrown, settled.reading), settled.reading);
141
+ return Object.freeze({ yields, ...(stop !== undefined ? { directStop: Object.freeze({ ...stop, settled }) } : {}) });
142
+ }
143
+ function bothAbsent(cause, status) {
144
+ return cause === 'absent' && status === 'absent';
145
+ }
146
+ function zeroByteProven(e, reading, viaDelivery, afterRetry) {
147
+ if (afterRetry)
148
+ return false;
149
+ if (reading === undefined)
150
+ return false;
151
+ if (viaDelivery && ownReadingSlot(reading, 'cls') === 'transport')
152
+ return false;
153
+ const u = ownReadingSlot(reading, 'unanswered');
154
+ return u !== undefined && u.layer === e && isSlotCarrier(e) && bothAbsent(ownReadingSlot(topCauseReadOf(reading, e), 'presence'), ownReadingSlot(u, 'statusSlot'));
155
+ }
117
156
  export function joinedResolution(r, gatedCallId) {
118
157
  const carry = r.gatedCallId === undefined && gatedCallId !== undefined && gatedCallId !== '' ? { gatedCallId } : {};
119
158
  return { ...r, ...carry, joinedInFlight: true };
@@ -14,3 +14,9 @@ export declare function readAskClassPair(v: object | null | undefined): {
14
14
  askClass: string;
15
15
  classes: readonly string[];
16
16
  } | undefined;
17
+ export interface AskClassReasonRow {
18
+ readonly askClass: string;
19
+ readonly reason: string;
20
+ }
21
+ export declare function askClassReasonOf(askClass: string | null | undefined): string | undefined;
22
+ export declare function askClassReasonsOf(carrier: object | null | undefined): readonly AskClassReasonRow[];
@@ -1,4 +1,5 @@
1
- import { CORE_ASK_CLASSES } from '../generated/engineFactTables.js';
1
+ import { appendOwnElement } from '../ownKey.js';
2
+ import { CORE_ASK_CLASSES, CORE_ASK_CLASS_REASONS } from '../generated/engineFactTables.js';
2
3
  export const DEPLOYMENT_LIST_ASK_CLASSES = Object.freeze(['ask_rule']);
3
4
  const ABSENT = Object.freeze({ state: 'absent' });
4
5
  const MALFORMED = Object.freeze({ state: 'malformed' });
@@ -24,13 +25,13 @@ export function readAskClassPairState(v) {
24
25
  const seen = new Set();
25
26
  for (let i = 0; i < length; i++) {
26
27
  const d = Object.getOwnPropertyDescriptor(raw, i);
27
- if (d === undefined || !('value' in d))
28
+ if (d === undefined || !Object.hasOwn(d, 'value'))
28
29
  return MALFORMED;
29
30
  const c = d.value;
30
31
  if (typeof c !== 'string' || c === '' || seen.has(c))
31
32
  return MALFORMED;
32
33
  seen.add(c);
33
- classes.push(c);
34
+ appendOwnElement(classes, c);
34
35
  }
35
36
  if (raw.length !== length)
36
37
  return MALFORMED;
@@ -57,3 +58,29 @@ export function readAskClassPair(v) {
57
58
  const r = readAskClassPairState(v);
58
59
  return r.state === 'pair' ? { askClass: r.askClass, classes: r.classes } : undefined;
59
60
  }
61
+ export function askClassReasonOf(askClass) {
62
+ if (typeof askClass !== 'string' || askClass === '')
63
+ return undefined;
64
+ return Object.hasOwn(CORE_ASK_CLASS_REASONS, askClass) ? CORE_ASK_CLASS_REASONS[askClass] : undefined;
65
+ }
66
+ export function askClassReasonsOf(carrier) {
67
+ let pair;
68
+ try {
69
+ pair = readAskClassPairState(carrier);
70
+ }
71
+ catch {
72
+ return Object.freeze([]);
73
+ }
74
+ if (pair.state !== 'pair')
75
+ return Object.freeze([]);
76
+ const seen = new Set();
77
+ const rows = [];
78
+ for (const askClass of pair.classes) {
79
+ const reason = askClassReasonOf(askClass);
80
+ if (reason === undefined || seen.has(reason))
81
+ continue;
82
+ seen.add(reason);
83
+ rows.push(Object.freeze({ askClass, reason }));
84
+ }
85
+ return Object.freeze(rows);
86
+ }
@@ -0,0 +1,30 @@
1
+ import type { UiLanguage } from '../env/uiLanguage.js';
2
+ export declare const ASK_PARK_AUTO_REOPEN_BLOCKS: readonly ["policy", "park_refused"];
3
+ export type AskParkAutoReopenBlock = (typeof ASK_PARK_AUTO_REOPEN_BLOCKS)[number];
4
+ export declare function askParkRefusalBlockOf(err: {} | null | undefined): AskParkAutoReopenBlock | undefined;
5
+ export declare function askParkBlockGeneration(sessionId?: string): string;
6
+ export interface AskParkDecideIdentity {
7
+ readonly taskId: string;
8
+ readonly sessionId: string;
9
+ readonly boundCallId?: string;
10
+ }
11
+ export declare function noteAskParkDecideSettled(identity: AskParkDecideIdentity, startedGeneration: string, outcome: {
12
+ readonly ok: true;
13
+ } | {
14
+ readonly ok: false;
15
+ readonly error: {} | null | undefined;
16
+ }): void;
17
+ export interface AskParkGate {
18
+ readonly callId: string;
19
+ readonly sessionId?: string;
20
+ }
21
+ export declare function askParkAutoReopenBlockOf(gate: AskParkGate): AskParkAutoReopenBlock | undefined;
22
+ export interface AskParkAutoReopenBlockNotice {
23
+ readonly kind: AskParkAutoReopenBlock;
24
+ readonly text: string;
25
+ delivered(): void;
26
+ }
27
+ export declare function claimAskParkAutoReopenBlockNotice(gate: AskParkGate, lane?: 'interactive' | 'print', lang?: UiLanguage): AskParkAutoReopenBlockNotice | undefined;
28
+ export declare function askParkAutoReopenBlockedContent(kind: AskParkAutoReopenBlock, taskId: string, lane?: 'interactive' | 'print', lang?: UiLanguage): string;
29
+ export declare function clearAskParkAutoReopenBlocks(sessionId?: string): void;
30
+ export declare function __resetAskParkAutoReopenBlocksForTests(): void;
@@ -0,0 +1,117 @@
1
+ import { hostLog } from '../host.js';
2
+ import { msg, renderMessage } from '../i18n/translate.js';
3
+ import { refusedParkBlockedContent, refusedParkFromError, resumePolicyBlockFromError } from '../resumeRefusalCopy.js';
4
+ export const ASK_PARK_AUTO_REOPEN_BLOCKS = Object.freeze(['policy', 'park_refused']);
5
+ export function askParkRefusalBlockOf(err) {
6
+ try {
7
+ if (resumePolicyBlockFromError(err) !== null)
8
+ return 'policy';
9
+ if (refusedParkFromError(err) !== null)
10
+ return 'park_refused';
11
+ return undefined;
12
+ }
13
+ catch {
14
+ return undefined;
15
+ }
16
+ }
17
+ const blocks = new Map();
18
+ const BLOCK_MAX = 64;
19
+ let generation = 0;
20
+ const sessionGenerations = new Map();
21
+ export function askParkBlockGeneration(sessionId) {
22
+ return `${generation}:${typeof sessionId === 'string' ? (sessionGenerations.get(sessionId) ?? 0) : 0}`;
23
+ }
24
+ export function noteAskParkDecideSettled(identity, startedGeneration, outcome) {
25
+ try {
26
+ if (startedGeneration !== askParkBlockGeneration(identity.sessionId))
27
+ return;
28
+ const callId = identity.boundCallId;
29
+ if (typeof callId !== 'string' || callId === '')
30
+ return;
31
+ if (outcome.ok) {
32
+ blocks.delete(callId);
33
+ return;
34
+ }
35
+ const kind = askParkRefusalBlockOf(outcome.error);
36
+ if (kind === undefined)
37
+ return;
38
+ const prev = blocks.get(callId);
39
+ blocks.delete(callId);
40
+ if (prev !== undefined && prev.kind === kind && prev.sessionId === identity.sessionId)
41
+ blocks.set(callId, prev);
42
+ else
43
+ blocks.set(callId, { kind, sessionId: identity.sessionId, taskId: identity.taskId, announced: false });
44
+ while (blocks.size > BLOCK_MAX) {
45
+ const oldest = blocks.keys().next();
46
+ if (oldest.done === true)
47
+ break;
48
+ blocks.delete(oldest.value);
49
+ }
50
+ }
51
+ catch (e) {
52
+ hostLog('debug', `askParkAutoReopenBlock.noteSettled: ${String(e).slice(0, 120)}`);
53
+ }
54
+ }
55
+ function entryFor(gate) {
56
+ if (typeof gate !== 'object' || gate === null || typeof gate.callId !== 'string' || gate.callId === '')
57
+ return undefined;
58
+ const e = blocks.get(gate.callId);
59
+ if (e === undefined)
60
+ return undefined;
61
+ if (typeof gate.sessionId === 'string' && gate.sessionId !== '' && e.sessionId !== undefined && e.sessionId !== gate.sessionId)
62
+ return undefined;
63
+ return e;
64
+ }
65
+ export function askParkAutoReopenBlockOf(gate) {
66
+ try {
67
+ return entryFor(gate)?.kind;
68
+ }
69
+ catch {
70
+ return undefined;
71
+ }
72
+ }
73
+ export function claimAskParkAutoReopenBlockNotice(gate, lane = 'interactive', lang) {
74
+ try {
75
+ const e = entryFor(gate);
76
+ if (e === undefined || e.announced)
77
+ return undefined;
78
+ const text = askParkAutoReopenBlockedContent(e.kind, e.taskId, lane, lang);
79
+ return Object.freeze({
80
+ kind: e.kind,
81
+ text,
82
+ delivered: () => {
83
+ const cur = entryFor(gate);
84
+ if (cur === e)
85
+ e.announced = true;
86
+ },
87
+ });
88
+ }
89
+ catch {
90
+ return undefined;
91
+ }
92
+ }
93
+ export function askParkAutoReopenBlockedContent(kind, taskId, lane = 'interactive', lang) {
94
+ if (kind === 'park_refused')
95
+ return refusedParkBlockedContent(taskId, lane, lang);
96
+ const run = typeof taskId === 'string' && taskId !== '' ? taskId : '<unknown>';
97
+ if (lane === 'print')
98
+ return renderMessage(msg('approval.askPark.autoReopenBlocked.policyPrint', { run, cancel: `POST /v1/runs/${run}/cancel` }), lang);
99
+ return renderMessage(msg('approval.askPark.autoReopenBlocked.policyInteractive', { run }), lang);
100
+ }
101
+ export function clearAskParkAutoReopenBlocks(sessionId) {
102
+ if (typeof sessionId !== 'string' || sessionId === '') {
103
+ generation++;
104
+ sessionGenerations.clear();
105
+ blocks.clear();
106
+ return;
107
+ }
108
+ sessionGenerations.set(sessionId, (sessionGenerations.get(sessionId) ?? 0) + 1);
109
+ for (const [k, e] of blocks)
110
+ if (e.sessionId === sessionId)
111
+ blocks.delete(k);
112
+ }
113
+ export function __resetAskParkAutoReopenBlocksForTests() {
114
+ blocks.clear();
115
+ sessionGenerations.clear();
116
+ generation = 0;
117
+ }
@@ -1,5 +1,5 @@
1
1
  import { askParkForeignGateKind, durableDecideLegOf } from '../adapter/activeRunSelfHeal.js';
2
- import { isAskTool } from './frameRouter.js';
2
+ import { isAskTool, questionCardVerdict } from './frameRouter.js';
3
3
  import { approvalCallKey } from './gateIdentity.js';
4
4
  import { askQuestionsFromPending, pendingRowIsOwnedByThisSession } from './parkOwnership.js';
5
5
  export const ASK_PARK_ROW_WAIT_MS = 15000;
@@ -39,6 +39,9 @@ export function askParkRowIdentity(taskId, row) {
39
39
  return { rowTaskId, gatedCallId, armedKey: approvalCallKey(gatedCallId, rowTaskId) };
40
40
  }
41
41
  export function askParkRowArm(row) {
42
+ const byCard = questionCardVerdict(row);
43
+ if (byCard !== undefined)
44
+ return byCard ? 'question' : 'tool-gate';
42
45
  const rowGateKind = askParkRowGateKind(row);
43
46
  const toolNameIsAsk = isAskTool(row.toolName ?? undefined);
44
47
  if (toolNameIsAsk)