@sema-agent/client-core 0.98.0 → 0.100.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 (236) hide show
  1. package/CHANGELOG.md +376 -0
  2. package/README.md +61 -35
  3. package/dist/adapt/arms.js +120 -55
  4. package/dist/adapt/panelTasks.d.ts +3 -2
  5. package/dist/adapt/panelTasks.js +34 -11
  6. package/dist/adapt/textStream.d.ts +1 -1
  7. package/dist/adapt/textStream.js +51 -28
  8. package/dist/adapter/activeRunSelfHeal.d.ts +11 -3
  9. package/dist/adapter/activeRunSelfHeal.js +210 -294
  10. package/dist/adapter/downstream/eventToSdkMessage.d.ts +25 -6
  11. package/dist/adapter/downstream/eventToSdkMessage.js +176 -12
  12. package/dist/adapter/downstream/terminalToSdkResult.js +10 -0
  13. package/dist/adapter/downstream/wiringManifestView.d.ts +3 -1
  14. package/dist/adapter/downstream/wiringManifestView.js +1 -0
  15. package/dist/adapter/runStream.js +82 -40
  16. package/dist/adapter/types.d.ts +2 -0
  17. package/dist/adapter/types.js +2 -1
  18. package/dist/agentSession/engineSessionBackgroundStop.js +16 -8
  19. package/dist/agentsWireCaps.d.ts +7 -3
  20. package/dist/agentsWireCaps.js +133 -39
  21. package/dist/cloudConfigWireCaps.d.ts +10 -1
  22. package/dist/cloudConfigWireCaps.js +181 -65
  23. package/dist/compactionStatus.d.ts +34 -0
  24. package/dist/compactionStatus.js +196 -0
  25. package/dist/controlRouter.d.ts +4 -2
  26. package/dist/controlRouter.js +39 -51
  27. package/dist/coreValuePorts.d.ts +26 -1
  28. package/dist/coreValuePorts.js +10 -0
  29. package/dist/corruptSessionCopy.d.ts +2 -1
  30. package/dist/corruptSessionCopy.js +3 -3
  31. package/dist/decideFailureNote.js +3 -3
  32. package/dist/declared/supportFloorDeclared.js +1 -1
  33. package/dist/detachWire.js +3 -2
  34. package/dist/devicesFace.d.ts +34 -0
  35. package/dist/devicesFace.js +90 -0
  36. package/dist/displayUntrusted.d.ts +1 -0
  37. package/dist/displayUntrusted.js +153 -5
  38. package/dist/engineAgentPanelStore.d.ts +14 -4
  39. package/dist/engineAgentPanelStore.js +14 -0
  40. package/dist/engineCapReader.d.ts +2 -1
  41. package/dist/engineCapReader.js +7 -5
  42. package/dist/engineCapsCache.d.ts +8 -0
  43. package/dist/engineCapsCache.js +59 -6
  44. package/dist/engineCapsChange.d.ts +2 -0
  45. package/dist/engineCapsChange.js +9 -0
  46. package/dist/engineErrorCodes.d.ts +11 -2
  47. package/dist/engineErrorCodes.js +11 -12
  48. package/dist/engineRowRef.js +4 -0
  49. package/dist/engineSessionMessages.d.ts +1 -0
  50. package/dist/engineSessionMessages.js +7 -1
  51. package/dist/engineTargetSeat.d.ts +27 -0
  52. package/dist/engineTargetSeat.js +199 -0
  53. package/dist/engineToolDirectory.d.ts +3 -0
  54. package/dist/engineToolDirectory.js +4 -2
  55. package/dist/engineWireFor.js +3 -8
  56. package/dist/env/uiLanguage.d.ts +2 -1
  57. package/dist/env/uiLanguage.js +3 -2
  58. package/dist/eventLeg.d.ts +7 -5
  59. package/dist/eventLeg.js +68 -49
  60. package/dist/fileHistoryCaptureCapability.d.ts +2 -4
  61. package/dist/fileHistoryCaptureCapability.js +12 -22
  62. package/dist/fileHistoryLegNotice.d.ts +2 -1
  63. package/dist/fileHistoryLegNotice.js +3 -3
  64. package/dist/frameBinding.d.ts +3 -0
  65. package/dist/frameBinding.js +12 -0
  66. package/dist/gateOutcome.js +16 -2
  67. package/dist/gateVocabulary.d.ts +8 -7
  68. package/dist/gateVocabulary.js +71 -73
  69. package/dist/generated/engineFactTables.d.ts +18 -1
  70. package/dist/generated/engineFactTables.js +56 -0
  71. package/dist/generated/engineNoticeTables.js +12 -3
  72. package/dist/generated/settingsSchemaFns.d.ts +18 -0
  73. package/dist/generated/settingsSchemaFns.js +70 -0
  74. package/dist/generated/settingsSchemaHooksClassifier.d.ts +2 -0
  75. package/dist/generated/settingsSchemaHooksClassifier.js +254 -0
  76. package/dist/generated/settingsSchemaMcpRequestEntry.d.ts +1 -0
  77. package/dist/generated/settingsSchemaMcpRequestEntry.js +162 -0
  78. package/dist/generated/settingsSchemaTables.d.ts +2 -0
  79. package/dist/generated/settingsSchemaTables.js +9 -0
  80. package/dist/generated/settingsSchemaTypes.d.ts +133 -0
  81. package/dist/generated/settingsSchemaTypes.js +1 -0
  82. package/dist/hitl/allowRuleShadow.d.ts +2 -1
  83. package/dist/hitl/allowRuleShadow.js +18 -15
  84. package/dist/hitl/approvalCardReasons.d.ts +3 -2
  85. package/dist/hitl/approvalCardReasons.js +29 -30
  86. package/dist/hitl/approvalHolds.d.ts +17 -0
  87. package/dist/hitl/approvalHolds.js +114 -29
  88. package/dist/hitl/askClassPair.d.ts +2 -2
  89. package/dist/hitl/askClassPair.js +16 -0
  90. package/dist/hitl/askGateWire.js +2 -1
  91. package/dist/hitl/askSettlementLine.d.ts +14 -4
  92. package/dist/hitl/askSettlementLine.js +67 -47
  93. package/dist/hitl/attributionLadder.d.ts +23 -0
  94. package/dist/hitl/attributionLadder.js +67 -0
  95. package/dist/hitl/automaticAnswerVerdict.d.ts +2 -1
  96. package/dist/hitl/automaticAnswerVerdict.js +8 -8
  97. package/dist/hitl/crashConvergedNotice.d.ts +5 -4
  98. package/dist/hitl/crashConvergedNotice.js +28 -41
  99. package/dist/hitl/decisionLedger.d.ts +55 -0
  100. package/dist/hitl/decisionLedger.js +156 -0
  101. package/dist/hitl/decisionRefusal.d.ts +1 -0
  102. package/dist/hitl/decisionRefusal.js +1 -1
  103. package/dist/hitl/decisionSend.d.ts +113 -0
  104. package/dist/hitl/decisionSend.js +579 -0
  105. package/dist/hitl/frameRouter.js +7 -8
  106. package/dist/hitl/hitlBridge.d.ts +1 -0
  107. package/dist/hitl/hitlBridge.js +21 -9
  108. package/dist/hitl/persistedRulesWire.d.ts +6 -5
  109. package/dist/hitl/persistedRulesWire.js +55 -73
  110. package/dist/hitl/planReviewWire.d.ts +5 -0
  111. package/dist/hitl/planReviewWire.js +53 -76
  112. package/dist/hitl/sessionPolicyDeliverable.d.ts +2 -0
  113. package/dist/hitl/sessionPolicyDeliverable.js +49 -9
  114. package/dist/hitl/sessionPolicyWire.d.ts +2 -1
  115. package/dist/hitl/sessionPolicyWire.js +23 -24
  116. package/dist/hitl/suspendedReopen.d.ts +2 -1
  117. package/dist/hitl/suspendedReopen.js +7 -10
  118. package/dist/hitl/toolApprovalWire.d.ts +17 -5
  119. package/dist/hitl/toolApprovalWire.js +120 -147
  120. package/dist/hooksWireCaps.js +145 -56
  121. package/dist/host.d.ts +21 -0
  122. package/dist/hostTurnSettings.d.ts +110 -0
  123. package/dist/hostTurnSettings.js +692 -0
  124. package/dist/humanTurn.d.ts +15 -1
  125. package/dist/humanTurn.js +100 -12
  126. package/dist/humanTurnRead.d.ts +2 -0
  127. package/dist/humanTurnRead.js +22 -1
  128. package/dist/i18n/messages.en.d.ts +713 -0
  129. package/dist/i18n/messages.en.js +713 -0
  130. package/dist/i18n/messages.zh.js +854 -1
  131. package/dist/index.d.ts +45 -13
  132. package/dist/index.js +27 -9
  133. package/dist/inheritEnvCapability.d.ts +4 -2
  134. package/dist/inheritEnvCapability.js +12 -5
  135. package/dist/inheritEnvWire.d.ts +3 -2
  136. package/dist/inheritEnvWire.js +14 -16
  137. package/dist/injectionLaneNotice.d.ts +5 -0
  138. package/dist/injectionLaneNotice.js +46 -0
  139. package/dist/interactiveHalt.js +17 -6
  140. package/dist/liveModelCatalog.d.ts +2 -1
  141. package/dist/liveModelCatalog.js +14 -8
  142. package/dist/mcpPanel.d.ts +10 -1
  143. package/dist/mcpPanel.js +42 -13
  144. package/dist/mcpProbeCapability.d.ts +2 -1
  145. package/dist/mcpProbeCapability.js +7 -11
  146. package/dist/mcpProbeWire.d.ts +3 -1
  147. package/dist/mcpProbeWire.js +5 -0
  148. package/dist/mcpReconnect.js +2 -2
  149. package/dist/mcpToolToggles.d.ts +6 -0
  150. package/dist/mcpToolToggles.js +46 -0
  151. package/dist/mcpWireCaps.d.ts +43 -3
  152. package/dist/mcpWireCaps.js +194 -59
  153. package/dist/mcpWireTransport.d.ts +4 -0
  154. package/dist/mcpWireTransport.js +18 -0
  155. package/dist/memoryEntriesWire.js +5 -10
  156. package/dist/model/onboardJudgement.d.ts +93 -0
  157. package/dist/model/onboardJudgement.js +415 -0
  158. package/dist/model/tierVocabulary.d.ts +2 -0
  159. package/dist/model/tierVocabulary.js +17 -5
  160. package/dist/modelCapabilityProbe.d.ts +65 -0
  161. package/dist/modelCapabilityProbe.js +601 -0
  162. package/dist/modelIdentityResolvability.d.ts +5 -0
  163. package/dist/modelIdentityResolvability.js +49 -22
  164. package/dist/ownKey.d.ts +33 -0
  165. package/dist/ownKey.js +109 -0
  166. package/dist/panelReduce.d.ts +11 -1
  167. package/dist/panelReduce.js +95 -16
  168. package/dist/panelStateHolder.d.ts +1 -0
  169. package/dist/panelStateHolder.js +10 -1
  170. package/dist/permissionRuleIssue.d.ts +2 -1
  171. package/dist/permissionRuleIssue.js +23 -20
  172. package/dist/permissionRulesWriteCapability.d.ts +2 -1
  173. package/dist/permissionRulesWriteCapability.js +8 -6
  174. package/dist/pluginHooksWire.d.ts +46 -3
  175. package/dist/pluginHooksWire.js +220 -12
  176. package/dist/prepareRefusal.d.ts +8 -0
  177. package/dist/prepareRefusal.js +72 -0
  178. package/dist/printModelStatus.d.ts +63 -0
  179. package/dist/printModelStatus.js +155 -0
  180. package/dist/request/taskRequest.d.ts +16 -10
  181. package/dist/request/taskRequest.js +195 -58
  182. package/dist/resumeRefusalCopy.d.ts +14 -9
  183. package/dist/resumeRefusalCopy.js +89 -144
  184. package/dist/retryStatus.d.ts +55 -0
  185. package/dist/retryStatus.js +155 -19
  186. package/dist/ruleRefusalSentence.d.ts +4 -0
  187. package/dist/ruleRefusalSentence.js +58 -0
  188. package/dist/sandboxWire.d.ts +2 -1
  189. package/dist/sandboxWire.js +55 -21
  190. package/dist/scenarioRefusal.d.ts +10 -0
  191. package/dist/scenarioRefusal.js +111 -0
  192. package/dist/seam.d.ts +48 -9
  193. package/dist/seam.js +54 -5
  194. package/dist/seatContract.d.ts +272 -14
  195. package/dist/seatContract.js +711 -23
  196. package/dist/selfOrchestrationDenial.js +7 -19
  197. package/dist/sessionIdSegment.d.ts +6 -0
  198. package/dist/sessionIdSegment.js +24 -0
  199. package/dist/sessionMemoryStatus.js +6 -11
  200. package/dist/sessionPolicyCapability.d.ts +2 -1
  201. package/dist/sessionPolicyCapability.js +8 -6
  202. package/dist/settingsCredentialKeyPaths.d.ts +8 -0
  203. package/dist/settingsCredentialKeyPaths.js +219 -0
  204. package/dist/settingsHooksSalvage.d.ts +44 -0
  205. package/dist/settingsHooksSalvage.js +211 -0
  206. package/dist/skillToolListsCapability.d.ts +2 -1
  207. package/dist/skillToolListsCapability.js +8 -6
  208. package/dist/skillsWireCaps.d.ts +0 -3
  209. package/dist/skillsWireCaps.js +1 -2
  210. package/dist/sseIdleTriage.js +3 -2
  211. package/dist/subagent/engineSubagentResume.js +15 -9
  212. package/dist/subagentContentStore.d.ts +4 -0
  213. package/dist/subagentContentStore.js +157 -27
  214. package/dist/toolHistoryMismatch.js +3 -2
  215. package/dist/toolRoster.d.ts +3 -2
  216. package/dist/toolRoster.js +21 -20
  217. package/dist/toolsFlagNames.d.ts +8 -0
  218. package/dist/toolsFlagNames.js +110 -0
  219. package/dist/turnFailurePresentation.d.ts +12 -1
  220. package/dist/turnFailurePresentation.js +220 -15
  221. package/dist/usageAnalytics.js +6 -11
  222. package/dist/userAttachmentEnvelope.d.ts +1 -0
  223. package/dist/userAttachmentEnvelope.js +37 -7
  224. package/dist/userAttachmentSeat.d.ts +21 -0
  225. package/dist/userAttachmentSeat.js +75 -0
  226. package/dist/userInvokedSkillsCapability.d.ts +11 -1
  227. package/dist/userInvokedSkillsCapability.js +31 -7
  228. package/dist/wireErrorTriage.d.ts +7 -0
  229. package/dist/wireErrorTriage.js +23 -1
  230. package/dist/wireFailureShape.js +2 -1
  231. package/dist/wireRefusalCopy.d.ts +62 -16
  232. package/dist/wireRefusalCopy.js +307 -148
  233. package/dist/workflowsJournalCapability.d.ts +2 -1
  234. package/dist/workflowsJournalCapability.js +8 -6
  235. package/docs/INTEGRATION-CLIENTS.md +951 -42
  236. package/package.json +5 -5
@@ -0,0 +1,23 @@
1
+ export declare function shouldResendWithoutAttribution(e: {} | null | undefined, sentAttributionKey: boolean, signal?: AbortSignal): boolean;
2
+ export declare function shouldResendUnderSuccessorKey(e: {} | null | undefined, lastSendCarriedRetiredKey: boolean, signal?: AbortSignal): boolean;
3
+ export declare function carriesAttributionKey(body: object): boolean;
4
+ export declare function withoutAttributionKey<T extends {
5
+ settledBy?: unknown;
6
+ decidedBy?: unknown;
7
+ }>(body: T): Omit<T, 'settledBy' | 'decidedBy'>;
8
+ export declare function withAttributionKeyRenamed<T extends {
9
+ settledBy?: unknown;
10
+ decidedBy?: unknown;
11
+ }>(body: T): Omit<T, 'settledBy' | 'decidedBy'> & {
12
+ decidedBy?: Exclude<T['settledBy'], undefined>;
13
+ };
14
+ export interface AttributionLadderState {
15
+ lastCarried: boolean;
16
+ dropped: boolean;
17
+ renamed: boolean;
18
+ }
19
+ export type AttributionLadderStep = 'dropped' | 'renamed' | 'renamed_then_dropped';
20
+ export declare function deliverWithAttributionLadder<B extends {
21
+ settledBy?: unknown;
22
+ decidedBy?: unknown;
23
+ }, R>(body: B, send: (b: B) => Promise<R>, signal: AbortSignal | undefined, state: AttributionLadderState, onStep?: (step: AttributionLadderStep) => void): Promise<R>;
@@ -0,0 +1,67 @@
1
+ import { denyAttributionRefusalFromError } from '../wireRefusalCopy.js';
2
+ export function shouldResendWithoutAttribution(e, sentAttributionKey, signal) {
3
+ if (!sentAttributionKey)
4
+ return false;
5
+ if (signal?.aborted === true)
6
+ return false;
7
+ return denyAttributionRefusalFromError(e, true)?.kind === 'not_in_proof';
8
+ }
9
+ export function shouldResendUnderSuccessorKey(e, lastSendCarriedRetiredKey, signal) {
10
+ if (!lastSendCarriedRetiredKey)
11
+ return false;
12
+ if (signal?.aborted === true)
13
+ return false;
14
+ return denyAttributionRefusalFromError(e, true)?.kind === 'retired_key';
15
+ }
16
+ export function carriesAttributionKey(body) {
17
+ return Object.hasOwn(body, 'settledBy') || Object.hasOwn(body, 'decidedBy');
18
+ }
19
+ export function withoutAttributionKey(body) {
20
+ const { settledBy: _droppedSettledBy, decidedBy: _droppedDecidedBy, ...rest } = body;
21
+ void _droppedSettledBy;
22
+ void _droppedDecidedBy;
23
+ return rest;
24
+ }
25
+ export function withAttributionKeyRenamed(body) {
26
+ const { settledBy, decidedBy: _replaced, ...rest } = body;
27
+ void _replaced;
28
+ return settledBy === undefined ? rest : { ...rest, decidedBy: settledBy };
29
+ }
30
+ export async function deliverWithAttributionLadder(body, send, signal, state, onStep) {
31
+ state.lastCarried = carriesAttributionKey(body);
32
+ state.dropped = false;
33
+ state.renamed = false;
34
+ try {
35
+ return await send(body);
36
+ }
37
+ catch (first) {
38
+ if (shouldResendWithoutAttribution(first, state.lastCarried, signal)) {
39
+ const withoutAttribution = withoutAttributionKey(body);
40
+ state.lastCarried = false;
41
+ onStep?.('dropped');
42
+ const r = await send(withoutAttribution);
43
+ state.dropped = true;
44
+ return r;
45
+ }
46
+ if (shouldResendUnderSuccessorKey(first, Object.hasOwn(body, 'settledBy'), signal)) {
47
+ const renamed = withAttributionKeyRenamed(body);
48
+ onStep?.('renamed');
49
+ try {
50
+ const r = await send(renamed);
51
+ state.renamed = true;
52
+ return r;
53
+ }
54
+ catch (second) {
55
+ if (!shouldResendWithoutAttribution(second, true, signal))
56
+ throw second;
57
+ const renamedWithoutAttribution = withoutAttributionKey(renamed);
58
+ state.lastCarried = false;
59
+ onStep?.('renamed_then_dropped');
60
+ const r = await send(renamedWithoutAttribution);
61
+ state.dropped = true;
62
+ return r;
63
+ }
64
+ }
65
+ throw first;
66
+ }
67
+ }
@@ -1,5 +1,6 @@
1
1
  import { type CoreModeArbitrationRow } from '../generated/engineFactTables.js';
2
2
  import { CORE_ASK_FACES } from '../generated/engineAskFaceTables.js';
3
+ import type { UiLanguage } from '../env/uiLanguage.js';
3
4
  export type AutomaticAnswerLane = 'mode_posture' | 'standing_rule' | 'permission_request_hook';
4
5
  export type AutomaticAnswerAskFace = (typeof CORE_ASK_FACES)[number];
5
6
  export interface AutomaticAnswerFacts {
@@ -22,6 +23,6 @@ export type AutomaticAnswerVerdict = {
22
23
  export declare const MODE_ARBITRATION: Readonly<Record<"hook" | "write_protection" | "mode" | "target_unresolved" | "content_question" | "ancestor" | "dangerous_delete" | "unverifiable_delete" | "unverifiable_shell_text" | "transcript_write" | "org_rule" | "rule_unreadable" | "ask_rule" | "denial_limit_fallback" | "classifier_no_ruling" | "requires_user_interaction" | "operator_forced" | "shell_floor" | "probe" | "tool_marks_mcp" | "tool_marks_a2a" | "policy_rra" | "artifact_shared_read" | "unstated" | "ordinary", CoreModeArbitrationRow>>;
23
24
  export declare function foldModeArbitrationRow(classes: Iterable<string>, askFace?: AutomaticAnswerAskFace): CoreModeArbitrationRow;
24
25
  export declare function automaticAnswerVerdict(card: object | null | undefined, lane: AutomaticAnswerLane, facts?: AutomaticAnswerFacts | null): AutomaticAnswerVerdict;
25
- export declare function mandatedApprovalDetailOf(card: object | null | undefined): string;
26
+ export declare function mandatedApprovalDetailOf(card: object | null | undefined, lang?: UiLanguage): string;
26
27
  export type PermissionRequestHookScope = 'allow_or_deny' | 'deny_only' | 'skip';
27
28
  export declare function permissionRequestHookScope(verdict: AutomaticAnswerVerdict | null | undefined): PermissionRequestHookScope;
@@ -1,6 +1,7 @@
1
1
  import { CORE_MODE_ARBITRATION, CORE_MODE_RELEASE_REASONS } from '../generated/engineFactTables.js';
2
2
  import { CORE_RELEASABLE_ASK_CLASSES_BY_FACE, CORE_SHELL_FACE_TOOL_NAMES } from '../generated/engineAskFaceTables.js';
3
3
  import { mandatedApprovalDetail } from '../gateVocabulary.js';
4
+ import { msg, renderMessage } from '../i18n/translate.js';
4
5
  import { readAskOrigin, readOwnNonEmptyString } from '../ownKey.js';
5
6
  import { readAskClassPairState } from './askClassPair.js';
6
7
  import { readRequiresRealApproval } from './approvalCardReading.js';
@@ -179,26 +180,25 @@ export function automaticAnswerVerdict(card, lane, facts) {
179
180
  return UNKNOWN.card_unreadable;
180
181
  }
181
182
  }
182
- export function mandatedApprovalDetailOf(card) {
183
+ export function mandatedApprovalDetailOf(card, lang) {
183
184
  try {
184
185
  if (typeof card !== 'object' || card === null)
185
- return mandatedApprovalDetail();
186
+ return mandatedApprovalDetail(lang);
186
187
  const pair = readAskClassPairState(card);
187
188
  if (pair.state !== 'pair')
188
- return mandatedApprovalDetail();
189
+ return mandatedApprovalDetail(lang);
189
190
  const classes = pair.classes;
190
191
  if (classes.some((c) => !Object.hasOwn(TABLE, c)))
191
- return mandatedApprovalDetail();
192
+ return mandatedApprovalDetail(lang);
192
193
  const row = foldModeArbitrationRow(classes);
193
194
  if (row.classifierEligible || row.sandboxAdmission)
194
- return mandatedApprovalDetail();
195
- return MANDATED_NO_AUTOMATIC_CHECK_DETAIL;
195
+ return mandatedApprovalDetail(lang);
196
+ return renderMessage(msg('approval.mandate.noAutomaticCheck'), lang);
196
197
  }
197
198
  catch {
198
- return mandatedApprovalDetail();
199
+ return mandatedApprovalDetail(lang);
199
200
  }
200
201
  }
201
- const MANDATED_NO_AUTOMATIC_CHECK_DETAIL = 'no saved allow rule and no remembered answer can retire this question, and no automatic check answers it; each call is settled on its own, by you here, and an answer covers only that call';
202
202
  export function permissionRequestHookScope(verdict) {
203
203
  try {
204
204
  const kind = typeof verdict === 'object' && verdict !== null ? verdict.kind : undefined;
@@ -1,6 +1,7 @@
1
+ import type { UiLanguage } from '../env/uiLanguage.js';
1
2
  import type { CrashConvergedProjection, CrashConvergedRowReading } from './crashConverged.js';
2
3
  export declare const NEEDS_HUMAN_REASON_ORDER: readonly ["approved_then_interrupted", "pending_unsafe", "contradictory", "unstable_row"];
3
- export declare function crashConvergedNeedsHumanSentence(reason: string | undefined, n: number, total: number): string | undefined;
4
- export declare function crashConvergedNotice(projection: CrashConvergedProjection | undefined): string | undefined;
5
- export declare function crashConvergedRowSentence(projection: CrashConvergedProjection | undefined, row: Pick<CrashConvergedRowReading, 'approvalId'>): string | undefined;
6
- export declare function crashConvergedCauseSentence(cause: string | undefined): string | undefined;
4
+ export declare function crashConvergedNeedsHumanSentence(reason: string | undefined, n: number, total: number, lang?: UiLanguage): string | undefined;
5
+ export declare function crashConvergedNotice(projection: CrashConvergedProjection | undefined, lang?: UiLanguage): string | undefined;
6
+ export declare function crashConvergedRowSentence(projection: CrashConvergedProjection | undefined, row: Pick<CrashConvergedRowReading, 'approvalId'>, lang?: UiLanguage): string | undefined;
7
+ export declare function crashConvergedCauseSentence(cause: string | undefined, lang?: UiLanguage): string | undefined;
@@ -1,3 +1,4 @@
1
+ import { msg, renderMessage } from '../i18n/translate.js';
1
2
  import { askEndingCauseClause } from './askSettlementLine.js';
2
3
  import { crashConvergedRowInProjection, isCrashConvergedCause, readCrashConvergedNoticeFacts } from './crashConverged.js';
3
4
  export const NEEDS_HUMAN_REASON_ORDER = Object.freeze(['approved_then_interrupted', 'pending_unsafe', 'contradictory', 'unstable_row']);
@@ -7,53 +8,40 @@ const _orderHasNoDuplicate = true;
7
8
  void _orderCoversReasons;
8
9
  void _orderInsideReasons;
9
10
  void _orderHasNoDuplicate;
10
- const RECORDED = 'based on what was recorded';
11
- const NO_AUTO_RERUN = 'sema has not re-run anything';
12
11
  const plural = (n, one, many) => (n === 1 ? one : many);
13
12
  const NEEDS_HUMAN_CLAUSES = Object.freeze({
14
- approved_then_interrupted: {
15
- one: 'had already been approved and may have been running when the previous engine run ended, so a side effect may have partly landed',
16
- many: 'had already been approved and may have been running when the previous engine run ended, so a side effect may have partly landed',
17
- },
18
- pending_unsafe: {
19
- one: `had not started, ${RECORDED}, but the engine did not mark it as safe to re-run`,
20
- many: `had not started, ${RECORDED}, but the engine did not mark them as safe to re-run`,
21
- },
22
- contradictory: { one: 'has a contradictory record', many: 'have contradictory records' },
23
- unstable_row: {
24
- one: 'has a record that read differently each time it was read',
25
- many: 'have records that read differently each time they were read',
26
- },
13
+ approved_then_interrupted: { one: 'session.crashConverged.reason.approvedThenInterrupted.one', many: 'session.crashConverged.reason.approvedThenInterrupted.many' },
14
+ pending_unsafe: { one: 'session.crashConverged.reason.pendingUnsafe.one', many: 'session.crashConverged.reason.pendingUnsafe.many' },
15
+ contradictory: { one: 'session.crashConverged.reason.contradictory.one', many: 'session.crashConverged.reason.contradictory.many' },
16
+ unstable_row: { one: 'session.crashConverged.reason.unstableRow.one', many: 'session.crashConverged.reason.unstableRow.many' },
27
17
  });
28
- const FALLBACK_CLAUSE = Object.freeze({
29
- one: 'had already been approved, or cannot be accounted for, so a side effect may have partly landed',
30
- many: 'had already been approved, or cannot be accounted for, so a side effect may have partly landed',
31
- });
32
- const RESUME_SAFE_CLAUSE = `had not started, ${RECORDED}, and can be re-run`;
33
- const countedClause = (clause, n, total) => `${n} of ${total} ${n === 1 ? clause.one : clause.many}`;
18
+ const FALLBACK_CLAUSE = Object.freeze({ one: 'session.crashConverged.fallback.one', many: 'session.crashConverged.fallback.many' });
19
+ const RESUME_SAFE_CLAUSE = 'session.crashConverged.resumeSafe';
20
+ const countedClause = (clause, n, total, lang) => renderMessage(msg('session.crashConverged.counted', { n, total, clause: msg(n === 1 ? clause.one : clause.many) }), lang);
34
21
  const isNeedsHumanReason = (v) => typeof v === 'string' && Object.hasOwn(NEEDS_HUMAN_CLAUSES, v);
35
- export function crashConvergedNeedsHumanSentence(reason, n, total) {
22
+ export function crashConvergedNeedsHumanSentence(reason, n, total, lang) {
36
23
  if (!isNeedsHumanReason(reason))
37
24
  return undefined;
38
25
  if (typeof n !== 'number' || !Number.isSafeInteger(n) || n < 1)
39
26
  return undefined;
40
27
  if (typeof total !== 'number' || !Number.isSafeInteger(total) || total < n)
41
28
  return undefined;
42
- return countedClause(NEEDS_HUMAN_CLAUSES[reason], n, total);
29
+ return countedClause(NEEDS_HUMAN_CLAUSES[reason], n, total, lang);
43
30
  }
44
- function needsHumanClauses(reasons, total) {
31
+ function needsHumanClauses(reasons, total, lang) {
45
32
  const clauses = [];
46
33
  for (const reason of NEEDS_HUMAN_REASON_ORDER) {
47
34
  const n = reasons.filter((r) => r === reason).length;
48
35
  if (n > 0)
49
- clauses.push(countedClause(NEEDS_HUMAN_CLAUSES[reason], n, total));
36
+ clauses.push(countedClause(NEEDS_HUMAN_CLAUSES[reason], n, total, lang));
50
37
  }
51
38
  const fallback = reasons.filter((r) => !isNeedsHumanReason(r)).length;
52
39
  if (fallback > 0)
53
- clauses.push(countedClause(FALLBACK_CLAUSE, fallback, total));
54
- return `${clauses.join('; ')} — check ${plural(reasons.length, 'it', 'them')} by hand before re-running`;
40
+ clauses.push(countedClause(FALLBACK_CLAUSE, fallback, total, lang));
41
+ const joined = clauses.join(renderMessage(msg('session.crashConverged.clauseJoin'), lang));
42
+ return renderMessage(msg(plural(reasons.length, 'session.crashConverged.needsHumanBody.one', 'session.crashConverged.needsHumanBody.many'), { clauses: joined }), lang);
55
43
  }
56
- export function crashConvergedNotice(projection) {
44
+ export function crashConvergedNotice(projection, lang) {
57
45
  const facts = readCrashConvergedNoticeFacts(projection);
58
46
  if (facts === undefined)
59
47
  return undefined;
@@ -61,16 +49,15 @@ export function crashConvergedNotice(projection) {
61
49
  if (total === 0 && dropped === 0)
62
50
  return undefined;
63
51
  if (total === 0) {
64
- return `the previous session left ${dropped} crash-converged approval ${plural(dropped, 'record', 'records')} that this version could not read. ${NO_AUTO_RERUN}.`;
52
+ return renderMessage(msg(plural(dropped, 'session.crashConverged.droppedOnly.one', 'session.crashConverged.droppedOnly.many'), { count: dropped }), lang);
65
53
  }
66
- const recordedAs = causes !== undefined && causes.length > 0 ? ` (recorded as ${causes.join(', ')})` : '';
67
- const head = `the previous engine run ended with ${total} ${plural(total, 'approval', 'approvals')} still waiting${recordedAs}, ` +
68
- `and the engine converged ${plural(total, 'it', 'them')} to denied`;
69
- const body = needsHumanReasons.length > 0 ? needsHumanClauses(needsHumanReasons, total) : `${RECORDED}, ${plural(total, 'it', 'they')} can be re-run`;
70
- const droppedClause = dropped > 0 ? ` (${dropped} further ${plural(dropped, 'record', 'records')} could not be read.)` : '';
71
- return `${head}; ${body}. ${NO_AUTO_RERUN}.${droppedClause}`;
54
+ const recordedAs = causes !== undefined && causes.length > 0 ? msg('session.crashConverged.recordedAs', { causes: causes.join(', ') }) : '';
55
+ const head = renderMessage(msg(plural(total, 'session.crashConverged.head.one', 'session.crashConverged.head.many'), { total, recorded: recordedAs }), lang);
56
+ const body = needsHumanReasons.length > 0 ? needsHumanClauses(needsHumanReasons, total, lang) : renderMessage(msg(plural(total, 'session.crashConverged.rerunnable.one', 'session.crashConverged.rerunnable.many')), lang);
57
+ const droppedClause = dropped > 0 ? msg(plural(dropped, 'session.crashConverged.droppedTail.one', 'session.crashConverged.droppedTail.many'), { count: dropped }) : '';
58
+ return renderMessage(msg('session.crashConverged.line', { head, body, dropped: droppedClause }), lang);
72
59
  }
73
- export function crashConvergedRowSentence(projection, row) {
60
+ export function crashConvergedRowSentence(projection, row, lang) {
74
61
  const hit = crashConvergedRowInProjection(projection, row);
75
62
  if (hit === undefined)
76
63
  return undefined;
@@ -82,13 +69,13 @@ export function crashConvergedRowSentence(projection, row) {
82
69
  return undefined;
83
70
  }
84
71
  if (hit.bucket === 'resumeSafe')
85
- return descriptor === undefined ? RESUME_SAFE_CLAUSE : undefined;
72
+ return descriptor === undefined ? renderMessage(msg(RESUME_SAFE_CLAUSE), lang) : undefined;
86
73
  const reason = descriptor !== undefined && Object.hasOwn(descriptor, 'value') ? descriptor.value : undefined;
87
- return (isNeedsHumanReason(reason) ? NEEDS_HUMAN_CLAUSES[reason] : FALLBACK_CLAUSE).one;
74
+ return renderMessage(msg((isNeedsHumanReason(reason) ? NEEDS_HUMAN_CLAUSES[reason] : FALLBACK_CLAUSE).one), lang);
88
75
  }
89
- export function crashConvergedCauseSentence(cause) {
76
+ export function crashConvergedCauseSentence(cause, lang) {
90
77
  if (typeof cause !== 'string' || cause === '')
91
78
  return undefined;
92
- const clause = isCrashConvergedCause(cause) ? askEndingCauseClause(cause) : undefined;
93
- return clause === undefined ? 'the decision converged automatically' : `${clause}, and the decision converged automatically`;
79
+ const clause = isCrashConvergedCause(cause) ? askEndingCauseClause(cause, lang) : undefined;
80
+ return renderMessage(clause === undefined ? msg('session.crashConverged.cause.neutral') : msg('session.crashConverged.cause.withClause', { clause }), lang);
94
81
  }
@@ -0,0 +1,55 @@
1
+ export declare const DECISION_LEDGER_FAMILIES: readonly ["plan_review", "tool_approval", "elicitation"];
2
+ export type DecisionLedgerFamily = (typeof DECISION_LEDGER_FAMILIES)[number];
3
+ export type DecisionLedgerPhase = 'handed' | 'posting' | 'landed';
4
+ export type DecisionLedgerSettler = 'host' | 'package' | 'gate_left';
5
+ export interface DecisionLedgerOp {
6
+ readonly family: DecisionLedgerFamily;
7
+ keys: readonly string[];
8
+ readonly handedAt: number;
9
+ settledAt: number | null;
10
+ settler: DecisionLedgerSettler | null;
11
+ phase: DecisionLedgerPhase;
12
+ notApplied: boolean;
13
+ ownCallOpen: boolean;
14
+ }
15
+ export interface DecisionLedgerIdentityParts {
16
+ readonly taskId?: string | undefined;
17
+ readonly planTaskId?: string | undefined;
18
+ readonly approvalId?: string | undefined;
19
+ readonly callId?: string | undefined;
20
+ readonly askId?: string | undefined;
21
+ readonly elicitationId?: string | undefined;
22
+ }
23
+ export declare function decisionLedgerKeysOf(parts: DecisionLedgerIdentityParts): string[];
24
+ export declare function planDecisionKey(taskId: string): string;
25
+ export declare function nextDecisionLedgerTick(): number;
26
+ export declare function decisionOpsWithKey(family: DecisionLedgerFamily, key: string): DecisionLedgerOp[];
27
+ export declare function decisionOpsOfFamily(family: DecisionLedgerFamily): readonly DecisionLedgerOp[];
28
+ export declare function openDecisionOp(family: DecisionLedgerFamily, keys: readonly string[], phase: DecisionLedgerPhase, ownCallOpen: boolean): DecisionLedgerOp;
29
+ export declare function settleDecisionOp(op: DecisionLedgerOp, by: DecisionLedgerSettler): void;
30
+ export declare function closeDecisionOp(op: DecisionLedgerOp, by: DecisionLedgerSettler): void;
31
+ export declare function addDecisionOpKeys(op: DecisionLedgerOp, keys: readonly string[]): void;
32
+ export declare function dropDecisionOp(op: DecisionLedgerOp): void;
33
+ export declare function markLatestDecisionNotApplied(family: DecisionLedgerFamily, key: string): void;
34
+ export declare function settleDecisionOpsOnGateLeft(family: DecisionLedgerFamily, key: string): void;
35
+ export declare function latestDecisionHandedMark(family: DecisionLedgerFamily, key: string): number | null;
36
+ export declare function readMarkOf(v: number | undefined): number | undefined;
37
+ export declare function decisionKeyInFlight(key: string, mark: number | undefined): boolean;
38
+ export type DecisionIdentity = {
39
+ readonly gate: 'plan_review';
40
+ readonly taskId: string;
41
+ } | {
42
+ readonly gate: 'tool_approval';
43
+ readonly approvalId?: string;
44
+ readonly callId?: string;
45
+ readonly askId?: string;
46
+ } | {
47
+ readonly gate: 'elicitation';
48
+ readonly elicitationId: string;
49
+ } | {
50
+ readonly gate: 'run';
51
+ readonly taskId: string;
52
+ };
53
+ export declare function decisionInFlightOf(identity: DecisionIdentity, readMark?: number): boolean;
54
+ export declare function decisionReadMark(): number;
55
+ export declare function __resetDecisionLedgerForTests(family?: DecisionLedgerFamily): void;
@@ -0,0 +1,156 @@
1
+ import { guardedRead, readOwnDataNonEmptyString } from '../ownKey.js';
2
+ export const DECISION_LEDGER_FAMILIES = Object.freeze(['plan_review', 'tool_approval', 'elicitation']);
3
+ const FAMILY_CAPACITY = Object.freeze({ plan_review: 32, tool_approval: 64, elicitation: 64 });
4
+ const KEY_PREFIX = Object.freeze({ run: 'run\u0000', plan: 'plan\u0000', approval: 'approval\u0000', call: 'call\u0000', ask: 'ask\u0000', elicitation: 'elicitation\u0000' });
5
+ const nonEmpty = (v) => typeof v === 'string' && v !== '';
6
+ export function decisionLedgerKeysOf(parts) {
7
+ const out = [];
8
+ const add = (prefix, v) => {
9
+ if (nonEmpty(v) && !out.includes(prefix + v))
10
+ out.push(prefix + v);
11
+ };
12
+ add(KEY_PREFIX.run, parts.taskId);
13
+ add(KEY_PREFIX.plan, parts.planTaskId);
14
+ add(KEY_PREFIX.approval, parts.approvalId);
15
+ add(KEY_PREFIX.call, parts.callId);
16
+ add(KEY_PREFIX.ask, parts.askId);
17
+ add(KEY_PREFIX.elicitation, parts.elicitationId);
18
+ return out;
19
+ }
20
+ export function planDecisionKey(taskId) {
21
+ return KEY_PREFIX.plan + taskId;
22
+ }
23
+ const ledger = Object.freeze({ plan_review: [], tool_approval: [], elicitation: [] });
24
+ let ledgerClock = 0;
25
+ export function nextDecisionLedgerTick() {
26
+ return ++ledgerClock;
27
+ }
28
+ export function decisionOpsWithKey(family, key) {
29
+ return ledger[family].filter((op) => op.keys.includes(key));
30
+ }
31
+ export function decisionOpsOfFamily(family) {
32
+ return ledger[family];
33
+ }
34
+ export function openDecisionOp(family, keys, phase, ownCallOpen) {
35
+ const op = {
36
+ family,
37
+ keys: Object.freeze([...keys]),
38
+ handedAt: ++ledgerClock,
39
+ settledAt: null,
40
+ settler: null,
41
+ phase,
42
+ notApplied: false,
43
+ ownCallOpen,
44
+ };
45
+ const rows = ledger[family];
46
+ rows.push(op);
47
+ while (rows.length > FAMILY_CAPACITY[family]) {
48
+ let victim = rows.findIndex((o) => o.settledAt !== null && !o.ownCallOpen);
49
+ if (victim < 0)
50
+ victim = rows.findIndex((o) => o !== op && o.phase === 'handed' && !o.ownCallOpen);
51
+ if (victim < 0)
52
+ break;
53
+ rows.splice(victim, 1);
54
+ }
55
+ return op;
56
+ }
57
+ export function settleDecisionOp(op, by) {
58
+ if (op.settledAt !== null)
59
+ return;
60
+ op.settledAt = ++ledgerClock;
61
+ op.settler = by;
62
+ }
63
+ export function closeDecisionOp(op, by) {
64
+ if (op.phase === 'posting')
65
+ op.phase = 'landed';
66
+ settleDecisionOp(op, by);
67
+ op.ownCallOpen = false;
68
+ }
69
+ export function addDecisionOpKeys(op, keys) {
70
+ const extra = keys.filter((k) => !op.keys.includes(k));
71
+ if (extra.length > 0)
72
+ op.keys = Object.freeze([...op.keys, ...extra]);
73
+ }
74
+ export function dropDecisionOp(op) {
75
+ const rows = ledger[op.family];
76
+ const i = rows.indexOf(op);
77
+ if (i >= 0)
78
+ rows.splice(i, 1);
79
+ }
80
+ export function markLatestDecisionNotApplied(family, key) {
81
+ const ops = decisionOpsWithKey(family, key);
82
+ if (ops.some((op) => op.settledAt === null))
83
+ return;
84
+ let latest;
85
+ for (const op of ops)
86
+ if (latest === undefined || op.handedAt > latest.handedAt)
87
+ latest = op;
88
+ if (latest !== undefined)
89
+ latest.notApplied = true;
90
+ }
91
+ export function settleDecisionOpsOnGateLeft(family, key) {
92
+ for (const op of decisionOpsWithKey(family, key))
93
+ settleDecisionOp(op, 'gate_left');
94
+ }
95
+ export function latestDecisionHandedMark(family, key) {
96
+ let mark = null;
97
+ for (const op of decisionOpsWithKey(family, key))
98
+ if (mark === null || op.handedAt > mark)
99
+ mark = op.handedAt;
100
+ return mark;
101
+ }
102
+ function anyInFlight(keys, mark) {
103
+ if (keys.length === 0)
104
+ return false;
105
+ for (const family of DECISION_LEDGER_FAMILIES) {
106
+ for (const op of ledger[family]) {
107
+ if (!op.keys.some((k) => keys.includes(k)))
108
+ continue;
109
+ if (op.settledAt === null)
110
+ return true;
111
+ if (mark !== undefined && op.settledAt > mark && !op.notApplied)
112
+ return true;
113
+ }
114
+ }
115
+ return false;
116
+ }
117
+ export function readMarkOf(v) {
118
+ return typeof v === 'number' && Number.isFinite(v) ? v : undefined;
119
+ }
120
+ export function decisionKeyInFlight(key, mark) {
121
+ return anyInFlight([key], mark);
122
+ }
123
+ function queryKeysOf(identity) {
124
+ if (typeof identity !== 'object' || identity === null)
125
+ return [];
126
+ const gate = guardedRead(() => readOwnDataNonEmptyString(identity, 'gate'));
127
+ const s = (key) => guardedRead(() => readOwnDataNonEmptyString(identity, key));
128
+ switch (gate) {
129
+ case 'plan_review':
130
+ return decisionLedgerKeysOf({ planTaskId: s('taskId') });
131
+ case 'run':
132
+ return decisionLedgerKeysOf({ taskId: s('taskId') });
133
+ case 'tool_approval':
134
+ return decisionLedgerKeysOf({ approvalId: s('approvalId'), callId: s('callId'), askId: s('askId') });
135
+ case 'elicitation':
136
+ return decisionLedgerKeysOf({ elicitationId: s('elicitationId') });
137
+ default:
138
+ return [];
139
+ }
140
+ }
141
+ export function decisionInFlightOf(identity, readMark) {
142
+ try {
143
+ return anyInFlight(queryKeysOf(identity), readMarkOf(readMark));
144
+ }
145
+ catch {
146
+ return false;
147
+ }
148
+ }
149
+ export function decisionReadMark() {
150
+ return ++ledgerClock;
151
+ }
152
+ export function __resetDecisionLedgerForTests(family) {
153
+ for (const f of DECISION_LEDGER_FAMILIES)
154
+ if (family === undefined || f === family)
155
+ ledger[f].length = 0;
156
+ }
@@ -2,6 +2,7 @@ import { type GateCurrentPending, type HitlSafetyCode } from './hitlBridge.js';
2
2
  import { type DecisionRefusalConflict } from './decisionConflict.js';
3
3
  import { type ProtocolErrorName } from '../wireFailureShape.js';
4
4
  import { type DenyAttributionRefusalDetail } from '../wireRefusalCopy.js';
5
+ export declare const ASK_DECIDED_CODE = "conflict.ask_decided";
5
6
  export type DecisionRefusalStanding = 'settled-elsewhere' | 'ambiguous' | 'refused-pending';
6
7
  export type { DecisionRefusalConflict } from './decisionConflict.js';
7
8
  export interface RefusalCarrier {
@@ -7,7 +7,7 @@ import { readLivePendingRows } from './livePendingAsk.js';
7
7
  import { guardedRead, ownDataField, readOwnDataValue } from '../ownKey.js';
8
8
  import { PROTOCOL_ERROR_NAME, isDisplayableWireCode, protocolErrorNameReading, readErrorRecord, readRefusalField } from '../wireFailureShape.js';
9
9
  import { denyAttributionRefusalFromError } from '../wireRefusalCopy.js';
10
- const ASK_DECIDED_CODE = 'conflict.ask_decided';
10
+ export const ASK_DECIDED_CODE = 'conflict.ask_decided';
11
11
  const TRANSIENT_STATUSES = new Set([408, 425, 429, 502, 503, 504]);
12
12
  export function refusalCarrierOf(err) {
13
13
  if (typeof err !== 'object' || err === null)
@@ -0,0 +1,113 @@
1
+ import type { AgentClient, ElicitResponse } from '@sema-agent/sdk';
2
+ import { type AskGoneDetail } from '../decideReceipt.js';
3
+ import type { ApprovalDecidedByReading } from '../approvalDecidedByCapability.js';
4
+ import { type DecisionNoteAudit } from './approvalDecisionNoteAudit.js';
5
+ import { type DecisionRefusalClassified, type LiveAskPendingReading } from './decisionRefusal.js';
6
+ import { type HostApprovalCardHold } from './approvalHolds.js';
7
+ import { type ApprovalCardDecision, type ToolApprovalRespondAckView, type ToolApprovalRespondParkingView } from './toolApprovalWire.js';
8
+ export declare const HITL_DECISION_FAMILIES: readonly ["approval", "ask", "elicitation"];
9
+ export type HitlDecisionFamily = (typeof HITL_DECISION_FAMILIES)[number];
10
+ export declare const HITL_DECISION_NOT_APPLIED_CAUSES: readonly ["gone", "parked", "parking", "lane_disabled", "refused", "idempotency_crossed"];
11
+ export type HitlDecisionNotAppliedCause = (typeof HITL_DECISION_NOT_APPLIED_CAUSES)[number];
12
+ export declare const HITL_DECISION_UNCONFIRMED_CAUSES: readonly ["transport", "server_error", "local_error", "aborted", "gone_after_retry"];
13
+ export type HitlDecisionUnconfirmedCause = (typeof HITL_DECISION_UNCONFIRMED_CAUSES)[number];
14
+ export declare const HITL_DECISION_NOT_SENT_CAUSES: readonly ["aborted", "duplicate_in_flight", "invalid_request", "no_verb", "not_an_answer"];
15
+ export type HitlDecisionNotSentCause = (typeof HITL_DECISION_NOT_SENT_CAUSES)[number];
16
+ export interface HitlApprovalDecisionRequest {
17
+ readonly family: 'approval';
18
+ readonly approvalId: string;
19
+ readonly taskId?: string;
20
+ readonly toolCallId?: string;
21
+ readonly answer: ApprovalCardDecision;
22
+ }
23
+ export interface HitlAskDecisionRequest {
24
+ readonly family: 'ask';
25
+ readonly taskId: string;
26
+ readonly askId: string;
27
+ readonly approvalId?: string;
28
+ readonly toolCallId?: string;
29
+ readonly answer: ApprovalCardDecision;
30
+ }
31
+ export interface HitlElicitationDecisionRequest {
32
+ readonly family: 'elicitation';
33
+ readonly elicitationId: string;
34
+ readonly taskId?: string;
35
+ readonly response: ElicitResponse;
36
+ }
37
+ export type HitlDecisionSendRequest = HitlApprovalDecisionRequest | HitlAskDecisionRequest | HitlElicitationDecisionRequest;
38
+ export interface HitlDecisionSendClient {
39
+ readonly toolApprovals?: Partial<Pick<AgentClient['toolApprovals'], 'respond' | 'decideAsk'>>;
40
+ readonly elicitations?: Partial<Pick<AgentClient['elicitations'], 'respond'>>;
41
+ }
42
+ export interface HitlDecisionGate {
43
+ readonly family: HitlDecisionFamily;
44
+ readonly approvalId?: string;
45
+ readonly askId?: string;
46
+ readonly taskId?: string;
47
+ readonly elicitationId?: string;
48
+ }
49
+ export interface HitlDecisionSendDeps {
50
+ readonly client: HitlDecisionSendClient;
51
+ readonly signal?: AbortSignal;
52
+ readonly approvalDecisionNoteCapable?: boolean;
53
+ readonly approvalDecidedBy?: ApprovalDecidedByReading;
54
+ readonly readPending?: (gate: HitlDecisionGate, opts: {
55
+ readonly signal: AbortSignal;
56
+ }) => Promise<LiveAskPendingReading>;
57
+ readonly hold?: HostApprovalCardHold;
58
+ }
59
+ interface HitlDecisionOutcomeBase {
60
+ readonly family: HitlDecisionFamily;
61
+ readonly attempts: number;
62
+ readonly fallback?: 'approval';
63
+ readonly noteDropped?: true;
64
+ readonly rememberDropped?: true;
65
+ readonly attributionDropped?: true;
66
+ readonly attributionRenamed?: true;
67
+ readonly pending?: LiveAskPendingReading;
68
+ }
69
+ export interface HitlDecisionApplied extends HitlDecisionOutcomeBase {
70
+ readonly kind: 'applied';
71
+ readonly ack?: ToolApprovalRespondAckView;
72
+ readonly noteAudit?: DecisionNoteAudit;
73
+ }
74
+ export interface HitlDecisionSettledElsewhere extends HitlDecisionOutcomeBase {
75
+ readonly kind: 'settled_elsewhere';
76
+ readonly firstDecision?: 'approve' | 'deny';
77
+ readonly contrary?: true;
78
+ readonly decidedAtMs?: number;
79
+ readonly actorLabel?: string;
80
+ readonly noteAudit?: DecisionNoteAudit;
81
+ }
82
+ export interface HitlDecisionNotApplied extends HitlDecisionOutcomeBase {
83
+ readonly kind: 'not_applied';
84
+ readonly cause: HitlDecisionNotAppliedCause;
85
+ readonly errorCode?: string;
86
+ readonly status?: number;
87
+ readonly sessionId?: string;
88
+ readonly gone?: AskGoneDetail;
89
+ readonly retryAfterMs?: number;
90
+ readonly parking?: ToolApprovalRespondParkingView;
91
+ readonly refusal?: DecisionRefusalClassified;
92
+ readonly closesOut?: true;
93
+ }
94
+ export interface HitlDecisionUnconfirmed extends HitlDecisionOutcomeBase {
95
+ readonly kind: 'unconfirmed';
96
+ readonly cause: HitlDecisionUnconfirmedCause;
97
+ readonly status?: number;
98
+ }
99
+ export interface HitlDecisionNotSent extends HitlDecisionOutcomeBase {
100
+ readonly kind: 'not_sent';
101
+ readonly cause: HitlDecisionNotSentCause;
102
+ }
103
+ export type HitlDecisionSendOutcome = HitlDecisionApplied | HitlDecisionSettledElsewhere | HitlDecisionNotApplied | HitlDecisionUnconfirmed | HitlDecisionNotSent;
104
+ export declare const HITL_DECISION_READBACK_BUDGET_MS = 4000;
105
+ export interface HitlDecisionSendTiming {
106
+ readonly delays?: readonly number[];
107
+ readonly budgetMs?: number;
108
+ readonly parkingDelayMs?: number;
109
+ }
110
+ export declare function __setHitlDecisionSendTimingForTests(t?: HitlDecisionSendTiming): void;
111
+ export declare function hitlAskIdempotencyKey(askId: string, verdict: 'approve' | 'deny'): string;
112
+ export declare function sendHitlDecision(request: HitlDecisionSendRequest, deps: HitlDecisionSendDeps): Promise<HitlDecisionSendOutcome>;
113
+ export {};