@sema-agent/client-core 0.109.0 → 0.111.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 +342 -0
  2. package/README.md +88 -32
  3. package/dist/abortableSleep.d.ts +7 -0
  4. package/dist/abortableSleep.js +37 -0
  5. package/dist/adapt/arms.js +45 -11
  6. package/dist/adapt/toolCards.d.ts +3 -1
  7. package/dist/adapt/toolCards.js +4 -2
  8. package/dist/adapter/activeRunSelfHeal.d.ts +39 -0
  9. package/dist/adapter/activeRunSelfHeal.js +171 -3
  10. package/dist/adapter/downstream/eventToSdkMessage.js +20 -15
  11. package/dist/adapter/downstream/terminalToSdkResult.d.ts +2 -0
  12. package/dist/adapter/downstream/terminalToSdkResult.js +11 -0
  13. package/dist/adapter/runStream.d.ts +5 -0
  14. package/dist/adapter/runStream.js +15 -3
  15. package/dist/attachmentRoute.d.ts +20 -0
  16. package/dist/attachmentRoute.js +39 -0
  17. package/dist/attachmentsWireCaps.js +1 -1
  18. package/dist/builtinOutputStyles.d.ts +12 -0
  19. package/dist/builtinOutputStyles.js +147 -0
  20. package/dist/compactionStatus.d.ts +9 -0
  21. package/dist/compactionStatus.js +29 -5
  22. package/dist/controlRouter.js +2 -1
  23. package/dist/coreValuePorts.d.ts +39 -1
  24. package/dist/coreValuePorts.js +10 -0
  25. package/dist/declared/supportFloorDeclared.js +1 -1
  26. package/dist/displayUntrusted.d.ts +1 -0
  27. package/dist/displayUntrusted.js +138 -14
  28. package/dist/engineErrorCodes.d.ts +3 -0
  29. package/dist/engineErrorCodes.js +3 -0
  30. package/dist/engineHealthFacts.d.ts +20 -0
  31. package/dist/engineHealthFacts.js +42 -1
  32. package/dist/engineHealthProbeVerdict.d.ts +23 -0
  33. package/dist/engineHealthProbeVerdict.js +115 -0
  34. package/dist/engineInlineTaskStats.d.ts +4 -3
  35. package/dist/engineInlineTaskStats.js +18 -2
  36. package/dist/engineNoticeCodes.d.ts +10 -0
  37. package/dist/engineNoticeCodes.js +36 -6
  38. package/dist/engineRepoint.d.ts +147 -0
  39. package/dist/engineRepoint.js +310 -0
  40. package/dist/engineRowRef.d.ts +3 -0
  41. package/dist/engineRowRef.js +13 -1
  42. package/dist/engineSessionMessages.d.ts +2 -1
  43. package/dist/engineSessionMessages.js +5 -0
  44. package/dist/engineSwapCrossing.d.ts +57 -0
  45. package/dist/engineSwapCrossing.js +297 -0
  46. package/dist/engineUnavailable.d.ts +44 -0
  47. package/dist/engineUnavailable.js +492 -0
  48. package/dist/errorSupplementRoles.js +2 -1
  49. package/dist/eventLeg.js +3 -3
  50. package/dist/fleet/fleetProjection.js +3 -2
  51. package/dist/generated/engineFactTables.d.ts +2 -0
  52. package/dist/generated/engineFactTables.js +12 -0
  53. package/dist/generated/sdkFactTables.d.ts +2 -1
  54. package/dist/generated/sdkFactTables.js +5 -0
  55. package/dist/generated/settingsSchemaTables.d.ts +4 -0
  56. package/dist/generated/settingsSchemaTables.js +1 -0
  57. package/dist/hitl/approvalAskers.d.ts +6 -0
  58. package/dist/hitl/approvalAskers.js +30 -0
  59. package/dist/hitl/approvalCardReasons.js +6 -3
  60. package/dist/hitl/approvalDelivery.d.ts +1 -0
  61. package/dist/hitl/approvalDelivery.js +1 -1
  62. package/dist/hitl/approvalRequestFrameReading.d.ts +7 -0
  63. package/dist/hitl/approvalRequestFrameReading.js +11 -0
  64. package/dist/hitl/approvalResolution.d.ts +9 -2
  65. package/dist/hitl/approvalResolution.js +6 -1
  66. package/dist/hitl/askGateWire.js +5 -8
  67. package/dist/hitl/automaticAnswerVerdict.js +2 -2
  68. package/dist/hitl/decisionConflict.js +6 -3
  69. package/dist/hitl/decisionRefusal.d.ts +2 -0
  70. package/dist/hitl/decisionRefusal.js +8 -8
  71. package/dist/hitl/decisionRefusalCarrier.d.ts +3 -0
  72. package/dist/hitl/decisionRefusalCarrier.js +348 -0
  73. package/dist/hitl/decisionSend.d.ts +10 -0
  74. package/dist/hitl/decisionSend.js +57 -17
  75. package/dist/hitl/editedApprovalAcceptance.d.ts +25 -0
  76. package/dist/hitl/editedApprovalAcceptance.js +26 -0
  77. package/dist/hitl/elicitationRefusal.d.ts +4 -0
  78. package/dist/hitl/elicitationRefusal.js +23 -0
  79. package/dist/hitl/frameRouter.d.ts +2 -2
  80. package/dist/hitl/frameRouter.js +12 -33
  81. package/dist/hitl/gateIdentity.d.ts +5 -0
  82. package/dist/hitl/gateIdentity.js +23 -0
  83. package/dist/hitl/gateLedger.d.ts +0 -4
  84. package/dist/hitl/gateLedger.js +0 -19
  85. package/dist/hitl/hitlBridge.d.ts +7 -0
  86. package/dist/hitl/hitlBridge.js +14 -8
  87. package/dist/hitl/hitlHostSurface.d.ts +3 -1
  88. package/dist/hitl/hitlHostSurface.js +14 -4
  89. package/dist/hitl/hostWithdrawal.d.ts +15 -0
  90. package/dist/hitl/hostWithdrawal.js +38 -0
  91. package/dist/hitl/localAllowRedemption.d.ts +67 -0
  92. package/dist/hitl/localAllowRedemption.js +256 -0
  93. package/dist/hitl/parkResolver.js +32 -13
  94. package/dist/hitl/persistedRulesWire.d.ts +16 -0
  95. package/dist/hitl/persistedRulesWire.js +72 -2
  96. package/dist/hitl/planReviewWire.d.ts +3 -0
  97. package/dist/hitl/planReviewWire.js +37 -10
  98. package/dist/hitl/policyDenyCause.d.ts +1 -1
  99. package/dist/hitl/policyDenyCause.js +1 -1
  100. package/dist/hitl/resumeRunningCard.d.ts +1 -0
  101. package/dist/hitl/resumeRunningCard.js +1 -0
  102. package/dist/hitl/screenCardCarriers.d.ts +15 -0
  103. package/dist/hitl/screenCardCarriers.js +41 -0
  104. package/dist/hitl/screenDecisionCards.d.ts +98 -0
  105. package/dist/hitl/screenDecisionCards.js +362 -0
  106. package/dist/hitl/sessionPolicyWire.js +6 -4
  107. package/dist/hitl/standingRows.d.ts +4 -1
  108. package/dist/hitl/standingRows.js +33 -1
  109. package/dist/hitl/toolApprovalWire.d.ts +64 -15
  110. package/dist/hitl/toolApprovalWire.js +470 -125
  111. package/dist/hooksWireCaps.js +31 -1
  112. package/dist/hostSettingNoticeArm.d.ts +3 -0
  113. package/dist/hostSettingNoticeArm.js +12 -0
  114. package/dist/hostTurnSettings.d.ts +13 -4
  115. package/dist/hostTurnSettings.js +150 -10
  116. package/dist/humanTurnRead.js +11 -1
  117. package/dist/i18n/messages.en.d.ts +212 -0
  118. package/dist/i18n/messages.en.js +217 -5
  119. package/dist/i18n/messages.zh.js +235 -5
  120. package/dist/i18n/translate.d.ts +3 -0
  121. package/dist/i18n/translate.js +78 -10
  122. package/dist/i18n/zh.d.ts +1 -0
  123. package/dist/i18n/zh.js +1 -0
  124. package/dist/index.d.ts +56 -16
  125. package/dist/index.js +40 -12
  126. package/dist/inheritEnvCapability.js +2 -0
  127. package/dist/inputAuthor.d.ts +16 -0
  128. package/dist/inputAuthor.js +44 -0
  129. package/dist/interactiveHalt.js +2 -1
  130. package/dist/interactiveInterrupt.js +20 -2
  131. package/dist/interruptRefusalNote.d.ts +2 -0
  132. package/dist/interruptRefusalNote.js +17 -0
  133. package/dist/liveModelCatalog.d.ts +2 -0
  134. package/dist/liveModelCatalog.js +23 -9
  135. package/dist/liveQuestionStore.d.ts +4 -1
  136. package/dist/liveQuestionStore.js +12 -3
  137. package/dist/localEngineSeatReading.d.ts +2 -2
  138. package/dist/localEngineSeatReading.js +5 -3
  139. package/dist/localEngineSpawn.d.ts +0 -7
  140. package/dist/localEngineSpawn.js +0 -92
  141. package/dist/localEngineStep.d.ts +2 -2
  142. package/dist/localEngineStep.js +2 -0
  143. package/dist/mcpEngineLeg.d.ts +3 -0
  144. package/dist/mcpEngineLeg.js +38 -1
  145. package/dist/mcpPanel.js +2 -0
  146. package/dist/mcpReconnect.d.ts +9 -1
  147. package/dist/mcpReconnect.js +124 -19
  148. package/dist/mcpWireCaps.js +1 -1
  149. package/dist/model/engineModelWords.d.ts +3 -0
  150. package/dist/model/engineModelWords.js +13 -0
  151. package/dist/model/subagentModelWord.d.ts +21 -2
  152. package/dist/model/subagentModelWord.js +100 -29
  153. package/dist/modelCapabilityProbe.js +7 -43
  154. package/dist/modsFace.d.ts +8 -1
  155. package/dist/modsFace.js +27 -0
  156. package/dist/notifications.d.ts +36 -6
  157. package/dist/notifications.js +170 -20
  158. package/dist/ownKey.d.ts +6 -5
  159. package/dist/ownKey.js +31 -7
  160. package/dist/peerFrames.d.ts +40 -2
  161. package/dist/peerFrames.js +158 -3
  162. package/dist/pendingUserRow.d.ts +4 -0
  163. package/dist/pendingUserRow.js +16 -0
  164. package/dist/permissionsDeclaration.d.ts +1 -0
  165. package/dist/permissionsDeclaration.js +11 -1
  166. package/dist/planReviewCardFacts.d.ts +3 -0
  167. package/dist/planReviewCardFacts.js +52 -2
  168. package/dist/pluginHooksWire.d.ts +10 -1
  169. package/dist/pluginHooksWire.js +96 -7
  170. package/dist/printToolResultFrame.js +4 -2
  171. package/dist/promptBlockedCopy.js +11 -6
  172. package/dist/promptSuggestionBatch.d.ts +7 -0
  173. package/dist/promptSuggestionBatch.js +9 -0
  174. package/dist/promptSuggestionsTail.d.ts +39 -0
  175. package/dist/promptSuggestionsTail.js +116 -0
  176. package/dist/replayBody.js +10 -2
  177. package/dist/request/taskRequest.d.ts +5 -0
  178. package/dist/request/taskRequest.js +142 -21
  179. package/dist/requestCoordinate.d.ts +1 -0
  180. package/dist/requestCoordinate.js +13 -0
  181. package/dist/resumeRefusalCopy.d.ts +1 -3
  182. package/dist/resumeRefusalCopy.js +2 -1
  183. package/dist/retryStatus.d.ts +2 -2
  184. package/dist/retryStatus.js +2 -0
  185. package/dist/rewindArchiveReading.js +4 -4
  186. package/dist/runCancelContext.d.ts +2 -1
  187. package/dist/runCancelContext.js +1 -0
  188. package/dist/runPermissionModeSwitch.js +2 -2
  189. package/dist/scenarioRefusal.js +11 -13
  190. package/dist/scenarioSkills.js +11 -6
  191. package/dist/seam.d.ts +27 -2
  192. package/dist/seam.js +17 -1
  193. package/dist/seatContract.d.ts +189 -12
  194. package/dist/seatContract.js +401 -9
  195. package/dist/sessionBackground.js +2 -1
  196. package/dist/sessionBackgroundHandoff.js +2 -1
  197. package/dist/sessionCostReading.d.ts +70 -0
  198. package/dist/sessionCostReading.js +150 -0
  199. package/dist/sessionEngine.d.ts +2 -0
  200. package/dist/sessionEngine.js +111 -0
  201. package/dist/sessionHooksRoster.d.ts +4 -0
  202. package/dist/sessionHooksRoster.js +158 -0
  203. package/dist/sessionMemoryStatus.d.ts +2 -1
  204. package/dist/sessionMemoryStatus.js +2 -2
  205. package/dist/sessionReadRedaction.d.ts +7 -0
  206. package/dist/sessionReadRedaction.js +26 -0
  207. package/dist/sessionSyncFileHistory.d.ts +4 -0
  208. package/dist/sessionSyncFileHistory.js +27 -0
  209. package/dist/settingsHooksSalvage.js +2 -1
  210. package/dist/sseIdleTriage.d.ts +13 -1
  211. package/dist/sseIdleTriage.js +25 -6
  212. package/dist/storeDurabilityWord.d.ts +15 -0
  213. package/dist/storeDurabilityWord.js +18 -0
  214. package/dist/storePostureCapability.d.ts +7 -3
  215. package/dist/storePostureCapability.js +69 -39
  216. package/dist/subagent/engineSubagentResume.js +2 -2
  217. package/dist/subagent/engineSubagentTail.js +8 -1
  218. package/dist/subagentContentStore.d.ts +11 -0
  219. package/dist/subagentContentStore.js +28 -2
  220. package/dist/terminalStatuses.d.ts +1 -0
  221. package/dist/terminalStatuses.js +4 -1
  222. package/dist/toolResult.d.ts +1 -0
  223. package/dist/toolResult.js +2 -0
  224. package/dist/turnFailurePresentation.js +9 -2
  225. package/dist/typePins.d.ts +11 -0
  226. package/dist/usageAnalytics.d.ts +17 -0
  227. package/dist/usageAnalytics.js +44 -2
  228. package/dist/userAttachmentEnvelope.d.ts +2 -1
  229. package/dist/userAttachmentEnvelope.js +10 -0
  230. package/dist/wireErrorTriage.js +2 -1
  231. package/dist/wireFailureShape.d.ts +6 -5
  232. package/dist/wireFailureShape.js +150 -38
  233. package/dist/wireRefusalCopy.d.ts +16 -5
  234. package/dist/wireRefusalCopy.js +119 -86
  235. package/docs/INTEGRATION-CLIENTS.md +4228 -21
  236. package/package.json +7 -3
@@ -10,13 +10,13 @@ import { guardedRead, readOwnDataValue } from '../ownKey.js';
10
10
  import { parkHeldCallIdOf } from '../engineRowRef.js';
11
11
  import { inheritFrameBinding } from '../frameBinding.js';
12
12
  import { surfaceForCurrentSession, surfaceReplayedApprovalListUnreadable } from './hitlHostSurface.js';
13
- import { liveCardHoldOf, noteEngineClosedApproval, settleEngineClosedApproval } from './approvalHolds.js';
13
+ import { liveCardHoldOf, settleEngineClosedApproval } from './approvalHolds.js';
14
14
  import { approvalCompleteParked } from './approvalCompleteParked.js';
15
15
  import { liveFrameCallKey } from './gateIdentity.js';
16
16
  import { readPolicyDenyCause } from './policyDenyCause.js';
17
17
  import { msg, renderMessage } from '../i18n/translate.js';
18
18
  import { SEMA_DENIAL_KIND_KEY, hasLedgerPositionKey } from './gateLedger.js';
19
- import { replayedApprovalClosesCardFrame, replayedApprovalDisposition, settledApprovalDisposition } from './replayedApproval.js';
19
+ import { replayedApprovalDisposition, settledApprovalDisposition } from './replayedApproval.js';
20
20
  import { settleWithinDeadline } from '../abortableSleep.js';
21
21
  import { ccToolDenialKindForSettledBy } from '../gateVocabulary.js';
22
22
  import { REJECT_MESSAGE } from '../adapt/wireShapes.js';
@@ -89,6 +89,8 @@ function policyDenyHeadFor(cause) {
89
89
  return renderMessage(msg('approval.policyDeny.denyRule', { tail }));
90
90
  case 'engine_floor':
91
91
  return renderMessage(msg('approval.policyDeny.engineFloor', { tail }));
92
+ case 'hook':
93
+ return renderMessage(msg('approval.policyDeny.hook'));
92
94
  case 'no_approval_ui':
93
95
  case undefined:
94
96
  return HITL_POLICY_DENY_MESSAGE;
@@ -117,20 +119,6 @@ function denyStampedEnd(ev, attribution) {
117
119
  export const HITL_INTERRUPT_MESSAGE_FOR_TOOL_USE = '[Request interrupted by user for tool use]';
118
120
  const RUN_CANCELLED_ERROR_CODE = RUN_CANCELLED_CODE;
119
121
  export const ENGINE_ABORT_TOOL_RESULT = 'Operation aborted';
120
- const bridgeRunHandleFallbacks = new WeakMap();
121
- export function setBridgeRunHandleFallback(deps, read) {
122
- bridgeRunHandleFallbacks.set(deps, read);
123
- }
124
- export function bridgeRunHandleFallbackOf(deps) {
125
- try {
126
- const read = bridgeRunHandleFallbacks.get(deps);
127
- const v = read?.();
128
- return typeof v === 'string' && v !== '' ? v : undefined;
129
- }
130
- catch {
131
- return undefined;
132
- }
133
- }
134
122
  function isAskToolLoose(name) {
135
123
  return typeof name === 'string' && name.replace(/[\s_-]+/g, '').toLowerCase() === 'askuserquestion';
136
124
  }
@@ -349,7 +337,7 @@ async function routeToolApprovalFrame(ev, ctx) {
349
337
  return { kind: 'skip' };
350
338
  }
351
339
  const settledHere = settledApprovalDisposition(ev);
352
- if (settledHere !== undefined || (hasLedgerPositionKey(ev) && !led.preambleApprovals().has(ev.approvalId))) {
340
+ if (settledHere !== undefined || hasLedgerPositionKey(ev)) {
353
341
  const disposition = settledHere ?? (await judgeLedgerApprovalFrame(ev, ctx));
354
342
  if (disposition.kind !== 'live') {
355
343
  hostLog('debug', disposition.kind === 'decided' && disposition.settled !== undefined
@@ -357,8 +345,6 @@ async function routeToolApprovalFrame(ev, ctx) {
357
345
  : `liveHitlAskWire: tool_approval frame ${ev.approvalId} read back from the run event log is ${disposition.kind}` +
358
346
  `${disposition.kind === 'unknown' ? ` (${disposition.why})` : disposition.cause !== undefined ? ` (${disposition.cause})` : ''}` +
359
347
  ' — not raised as a question, no decision sent');
360
- if (settledHere === undefined && replayedApprovalClosesCardFrame(disposition))
361
- noteEngineClosedApproval(ev.approvalId, false);
362
348
  if (disposition.kind === 'unknown' && ctx.signal?.aborted !== true)
363
349
  surfaceReplayedApprovalListUnreadable();
364
350
  if (deps.onReplayedApproval !== undefined) {
@@ -373,7 +359,12 @@ async function routeToolApprovalFrame(ev, ctx) {
373
359
  const gatedCallId = fromSubagent ? undefined : frameCallId ?? led.lastPendingFsCall();
374
360
  const argsCallId = frameCallId === undefined ? gatedCallId : typeof ev.toolName === 'string' && toolNameIsFsWrite(ev.toolName) ? frameCallId : undefined;
375
361
  const runTaskId = ctx.taskId.current;
376
- const launched = surfaceToolApprovalFrameAndRespond(ev, deps.respondToolApproval, argsOfGatedStart(led, argsCallId), ctx.signal, deps.approvalLane, typeof runTaskId === 'string' && runTaskId !== '' ? { taskId: runTaskId } : undefined);
362
+ const streamGeneration = ctx.streamGeneration;
363
+ const runFacts = {
364
+ ...(typeof runTaskId === 'string' && runTaskId !== '' ? { taskId: runTaskId } : {}),
365
+ ...(streamGeneration !== undefined ? { sourceGeneration: streamGeneration } : {}),
366
+ };
367
+ const launched = surfaceToolApprovalFrameAndRespond(ev, deps.respondToolApproval, argsOfGatedStart(led, argsCallId), ctx.signal, deps.approvalLane, Object.keys(runFacts).length > 0 ? runFacts : undefined);
377
368
  const hold = liveCardHoldOf(liveFrameCallKey(ev.approvalId));
378
369
  const handled = launched.then((outcome) => settleLiveCardOutcome(ev, outcome, ctx, fromSubagent, gatedCallId), (e) => {
379
370
  hostLog('debug', `liveHitlAskWire: tool_approval card for ${ev.approvalId} failed: ${String(e).slice(0, 160)}`);
@@ -416,7 +407,7 @@ async function judgeLedgerApprovalFrame(ev, ctx) {
416
407
  .finally(release);
417
408
  });
418
409
  const approvals = got.kind === 'value' ? { read: 'ok', body: got.value } : { read: 'failed' };
419
- return replayedApprovalDisposition(ev, { preamble: ctx.led.preambleApprovals(), approvals });
410
+ return replayedApprovalDisposition(ev, { approvals });
420
411
  }
421
412
  function routeToolStart(ev, callId, led) {
422
413
  led.noteStart(callId, ev);
@@ -511,17 +502,5 @@ export async function routeFrame(ev, ctx) {
511
502
  if (ev.type === 'failed') {
512
503
  return { kind: 'end', events: [...flushHeldWithInterruptRewrite(led, { terminal: ev, signal: ctx.signal }), ev] };
513
504
  }
514
- if (ev.type === 'approval_request') {
515
- try {
516
- if (!hasLedgerPositionKey(ev)) {
517
- const id = ev.approvalId;
518
- if (typeof id === 'string' && id !== '')
519
- led.notePreambleApproval(id);
520
- }
521
- }
522
- catch (e) {
523
- hostLog('debug', `liveHitlAskWire: approval_request frame unreadable — not counted as preamble evidence: ${String(e).slice(0, 120)}`);
524
- }
525
- }
526
505
  return { kind: 'yield', events: [ev] };
527
506
  }
@@ -1,9 +1,14 @@
1
1
  export declare const PLAN_REVIEW_QUESTION_ID_PREFIX = "plan-review:";
2
2
  export declare const REOPEN_ID_TAIL = "#reopen-";
3
+ export declare const SCREEN_CARD_ORIGINS: readonly ["live-approval", "park-approval", "park-question", "plan-review", "host-reopen-question", "host-choice", "local-permission"];
4
+ export type ScreenCardOrigin = (typeof SCREEN_CARD_ORIGINS)[number];
3
5
  export declare function approvalCallKey(gatedCallId: string | undefined, taskId: string): string;
4
6
  export declare function askGateQuestionId(callKey: string): string;
5
7
  export declare function planReviewQuestionId(taskId: string): string;
6
8
  export declare function freshPlanReviewQuestionId(taskId: string, suffix: string): string;
9
+ export declare function hostReopenQuestionId(rowTaskId: string, suffix: string): string;
10
+ export declare function hostRunChoiceQuestionId(taskId: string, suffix: string): string;
11
+ export declare function questionCardOriginOf(questionId: {} | null | undefined): Extract<ScreenCardOrigin, 'park-question' | 'plan-review' | 'host-reopen-question' | 'host-choice'> | undefined;
7
12
  export declare function liveFrameCallKey(approvalId: string): string;
8
13
  export declare function taskIdFromPlanReviewQuestionId(questionId: string): string | undefined;
9
14
  export declare function armedKeyFromQuestionId(questionId: string): string;
@@ -2,6 +2,9 @@ const HITL_ASK_QUESTION_ID_PREFIX = 'hitl-ask:';
2
2
  export const PLAN_REVIEW_QUESTION_ID_PREFIX = 'plan-review:';
3
3
  const HITL_FRAME_CALL_KEY_PREFIX = 'hitl-frame:';
4
4
  export const REOPEN_ID_TAIL = '#reopen-';
5
+ const HOST_REOPEN_QUESTION_ID_PREFIX = 'ask-park:';
6
+ const HOST_RUN_CHOICE_QUESTION_ID_PREFIX = 'active-run:';
7
+ export const SCREEN_CARD_ORIGINS = Object.freeze(['live-approval', 'park-approval', 'park-question', 'plan-review', 'host-reopen-question', 'host-choice', 'local-permission']);
5
8
  export function approvalCallKey(gatedCallId, taskId) {
6
9
  return gatedCallId ?? taskId;
7
10
  }
@@ -14,6 +17,26 @@ export function planReviewQuestionId(taskId) {
14
17
  export function freshPlanReviewQuestionId(taskId, suffix) {
15
18
  return `${planReviewQuestionId(taskId)}${REOPEN_ID_TAIL}${suffix}`;
16
19
  }
20
+ export function hostReopenQuestionId(rowTaskId, suffix) {
21
+ return `${HOST_REOPEN_QUESTION_ID_PREFIX}${rowTaskId}${REOPEN_ID_TAIL}${suffix}`;
22
+ }
23
+ export function hostRunChoiceQuestionId(taskId, suffix) {
24
+ return `${HOST_RUN_CHOICE_QUESTION_ID_PREFIX}${taskId}${REOPEN_ID_TAIL}${suffix}`;
25
+ }
26
+ export function questionCardOriginOf(questionId) {
27
+ if (typeof questionId !== 'string')
28
+ return undefined;
29
+ const has = (prefix) => questionId.startsWith(prefix) && questionId.length > prefix.length;
30
+ if (has(HITL_ASK_QUESTION_ID_PREFIX))
31
+ return 'park-question';
32
+ if (has(PLAN_REVIEW_QUESTION_ID_PREFIX))
33
+ return 'plan-review';
34
+ if (has(HOST_REOPEN_QUESTION_ID_PREFIX))
35
+ return 'host-reopen-question';
36
+ if (has(HOST_RUN_CHOICE_QUESTION_ID_PREFIX))
37
+ return 'host-choice';
38
+ return undefined;
39
+ }
17
40
  export function liveFrameCallKey(approvalId) {
18
41
  return `${HITL_FRAME_CALL_KEY_PREFIX}${approvalId}`;
19
42
  }
@@ -18,14 +18,10 @@ export interface AskAnsweredOutput {
18
18
  export declare function durableSeqOf(ev: object): string | undefined;
19
19
  export declare const BODY_SEQ_OTHER_AXIS_EVENTS: readonly string[];
20
20
  export declare function hasLedgerPositionKey(ev: object): boolean;
21
- export declare const PREAMBLE_APPROVALS_MAX_ENTRIES = 4096;
22
21
  export interface GateLedger {
23
22
  noteSeq(ev: AgentEvent): void;
24
23
  lastSeq(): string | undefined;
25
24
  forgetRunScopedState(): void;
26
- notePreambleApproval(approvalId: string): void;
27
- preambleApprovals(): ReadonlySet<string>;
28
- beginStreamSegment(): void;
29
25
  trackLiveCard(phaseOf: () => 'card' | 'respond', handled: Promise<void>): void;
30
26
  answeringLiveCards(): Promise<void>[];
31
27
  liveCardsSettled(): Promise<void>;
@@ -21,7 +21,6 @@ export function hasLedgerPositionKey(ev) {
21
21
  const { id, seq } = ev;
22
22
  return (id !== undefined && id !== null) || (seq !== undefined && seq !== null);
23
23
  }
24
- export const PREAMBLE_APPROVALS_MAX_ENTRIES = 4096;
25
24
  export const START_ARGS_MAX_ENTRIES = 256;
26
25
  function normalizeDenyAttribution(a) {
27
26
  if (a === undefined)
@@ -108,7 +107,6 @@ export function createGateLedger() {
108
107
  let denyStampNextFsEnd = false;
109
108
  let denyStampAttribution;
110
109
  let seq;
111
- const preambleApprovalIds = new Set();
112
110
  const liveCards = new Set();
113
111
  return {
114
112
  noteSeq(ev) {
@@ -125,23 +123,6 @@ export function createGateLedger() {
125
123
  startArgsByCall.clear();
126
124
  gatedStartCalls.clear();
127
125
  },
128
- notePreambleApproval(approvalId) {
129
- if (typeof approvalId !== 'string' || approvalId === '')
130
- return;
131
- preambleApprovalIds.delete(approvalId);
132
- preambleApprovalIds.add(approvalId);
133
- if (preambleApprovalIds.size > PREAMBLE_APPROVALS_MAX_ENTRIES) {
134
- const oldest = preambleApprovalIds.values().next().value;
135
- if (oldest !== undefined)
136
- preambleApprovalIds.delete(oldest);
137
- }
138
- },
139
- preambleApprovals() {
140
- return preambleApprovalIds;
141
- },
142
- beginStreamSegment() {
143
- preambleApprovalIds.clear();
144
- },
145
126
  trackLiveCard(phaseOf, handled) {
146
127
  const entry = { phaseOf, handled };
147
128
  liveCards.add(entry);
@@ -138,6 +138,12 @@ export type FindPendingOutcome = {
138
138
  readonly kind: 'ok';
139
139
  }>;
140
140
  };
141
+ export interface PendingRowCallIdentity {
142
+ readonly taskId?: string | null;
143
+ readonly toolCallId?: string | null;
144
+ readonly boundCallId?: string | null;
145
+ }
146
+ export declare function pendingRowAnswersCall(row: PendingRowCallIdentity, taskId: string, callId: string): boolean;
141
147
  export declare function findPendingForTask(client: HitlClientLike, taskId: string, matches: (toolName: string | undefined) => boolean, opts?: {
142
148
  signal?: AbortSignal;
143
149
  }, callId?: string, identityAccepts?: (row: PendingCheckpoint) => boolean): Promise<FindPendingOutcome>;
@@ -160,6 +166,7 @@ export declare class HitlBridge {
160
166
  decision: 'approve';
161
167
  updatedInput?: unknown;
162
168
  remember?: 'session' | undefined;
169
+ feedback?: string | undefined;
163
170
  } | HitlDecideDenyOutcome, toolUseID?: string, opts?: {
164
171
  signal?: AbortSignal;
165
172
  operation?: DecideOperationSpan;
@@ -8,6 +8,7 @@ import { guardedRead, ownDataField, readOwnDataValue } from '../ownKey.js';
8
8
  import { PROTOCOL_ERROR_NAME, isSlotCarrier, protocolErrorNameReading, readBlockedBy, readThrownSlot, thrownIsInstanceOf, wireFailureTextsOf } from '../wireFailureShape.js';
9
9
  import { APPROVAL_BINDING_MISMATCH, CHECKPOINT_INVALID_OUTCOME, RESUME_POLICY_FOLD_CODE } from '../engineErrorCodes.js';
10
10
  import { suspendedReopenOf } from './suspendedReopen.js';
11
+ import { decisionConflictOf } from './decisionConflict.js';
11
12
  import { closeDecisionOp, decisionLedgerKeysOf, openDecisionOp } from './decisionLedger.js';
12
13
  import { askParkBlockGeneration, noteAskParkDecideSettled } from './askParkAutoReopenBlock.js';
13
14
  import { checkpointQueueRowSortOf, QUEUE_ROW_FAMILY_UNREADABLE_GATE } from './approvalQueueRow.js';
@@ -259,6 +260,9 @@ function notifyDecideObserver(observer, ev) {
259
260
  invokeHostCallbackIsolated(`hitlBridge: onDecideOperation(${ev.phase})`, () => observer(ev));
260
261
  }
261
262
  const ANY_TOOL_FAMILY = () => true;
263
+ export function pendingRowAnswersCall(row, taskId, callId) {
264
+ return row.taskId === taskId && (row.boundCallId === callId || row.toolCallId === callId);
265
+ }
262
266
  export async function findPendingForTask(client, taskId, matches, opts, callId, identityAccepts = (r) => matches(typeof r.toolName === 'string' ? r.toolName : undefined)) {
263
267
  let rows;
264
268
  try {
@@ -275,10 +279,10 @@ export async function findPendingForTask(client, taskId, matches, opts, callId,
275
279
  });
276
280
  const decidable = readings.filter((x) => x.foreign === null).map((x) => x.r);
277
281
  const identityRow = callId !== undefined
278
- ? decidable.find((r) => r.taskId === taskId && (r.boundCallId === callId || r.toolCallId === callId))
282
+ ? decidable.find((r) => pendingRowAnswersCall(r, taskId, callId))
279
283
  : undefined;
280
284
  const identityForeign = callId !== undefined && identityRow === undefined
281
- ? readings.find((x) => x.r.taskId === taskId && (x.r.boundCallId === callId || x.r.toolCallId === callId) && x.foreign !== null)
285
+ ? readings.find((x) => pendingRowAnswersCall(x.r, taskId, callId) && x.foreign !== null)
282
286
  : undefined;
283
287
  if (identityForeign !== undefined) {
284
288
  const identityBar = identityForeign.foreign === QUEUE_ROW_FAMILY_UNREADABLE_GATE ? checkpointRowBarOf(identityForeign.r) : undefined;
@@ -385,6 +389,7 @@ export class HitlBridge {
385
389
  ...this.bindingOf(pending),
386
390
  ...(outcome.updatedInput !== undefined ? { updatedInput: outcome.updatedInput } : {}),
387
391
  ...(outcome.remember !== undefined ? { remember: outcome.remember } : {}),
392
+ ...(outcome.feedback !== undefined ? { feedback: outcome.feedback } : {}),
388
393
  }
389
394
  : {
390
395
  decision: 'deny',
@@ -598,12 +603,13 @@ function bindingMismatchReading(e) {
598
603
  return 'not';
599
604
  const code = readWireErrorCodeReading(e);
600
605
  const nameReading = protocolErrorNameReading(e);
601
- const family = (code.state === 'code' && (code.code === APPROVAL_BINDING_MISMATCH || code.code === CHECKPOINT_INVALID_OUTCOME)) ||
602
- (nameReading.state === 'named' && nameReading.name === PROTOCOL_ERROR_NAME.ApprovalBindingMismatchError);
603
- if (family)
604
- return 'mismatch';
605
- if (nameReading.state === 'sdk-instance' && code.state !== 'code')
606
- return 'unreadable';
606
+ const codeReclassified = code.state === 'code' && code.code === CHECKPOINT_INVALID_OUTCOME;
607
+ const family = (code.state === 'code' && code.code === APPROVAL_BINDING_MISMATCH) ||
608
+ (!codeReclassified && nameReading.state === 'named' && nameReading.name === PROTOCOL_ERROR_NAME.ApprovalBindingMismatchError);
609
+ if (family) {
610
+ const captured = code.state === 'code' ? { state: 'read', wire: code.code } : code.state === 'absent' ? { state: 'read' } : { state: 'unreadable' };
611
+ return decisionConflictOf(e, captured, nameReading) === 'row_integrity' ? 'not' : 'mismatch';
612
+ }
607
613
  if (code.state === 'unreadable')
608
614
  return 'unreadable';
609
615
  return 'not';
@@ -22,12 +22,14 @@ export declare function hitlHostSurfaceMissesFor(sessionKey: string): number;
22
22
  export declare function hitlHostSurfaceFor(sessionKey: string): HitlHostSurface | null;
23
23
  export declare function _resetHitlHostSurfaceForTest(): void;
24
24
  export declare function surfaceForCurrentSession(): HitlHostSurface | null;
25
- export declare const CANCEL_DENY_BUDGET_MS = 2000;
25
+ export declare const CANCEL_DENY_BUDGET_MS = 8000;
26
+ export declare function interruptDenyLifetime(): AbortSignal;
26
27
  export declare const INTERRUPT_DENY_REASON = "Interrupted by user";
27
28
  export declare const CANCEL_DENY_WARN_TEXT = "could not cancel the pending question \u2014 the session may stay locked; the run may need engine-side recovery";
28
29
  export declare const REMEMBER_NOT_APPLIED_WARN_TEXT = "this session-wide allow was not remembered by the worker \u2014 you will be asked again for this tool";
29
30
  export declare const EDIT_NOT_FORWARDED_WARN_TEXT = "your edited tool input was NOT forwarded \u2014 the tool is running with the ORIGINAL input you saw before editing";
30
31
  export declare function surfaceRememberNotApplied(): void;
32
+ export declare function surfaceAllowNoteNotCarried(sentence: string): void;
31
33
  export declare function surfaceEditNotForwarded(): void;
32
34
  export declare const APPROVAL_PARKING_WARN_TEXT = "This approval is being parked; answer it again on the parked card when it appears.";
33
35
  export declare function approvalParkingNoticeText(retryAfterMs?: number): string;
@@ -2,7 +2,9 @@ import { createSessionSlot, DEFAULT_SESSION_KEY } from '../sessionSlot.js';
2
2
  import { hostLog } from '../host.js';
3
3
  import { unrefTimer } from '../unrefTimer.js';
4
4
  import { decideFailureNote } from '../decideFailureNote.js';
5
+ import { editedApprovalRefusedLine } from './editedApprovalAcceptance.js';
5
6
  import { decisionRefusalSaysAskGone } from './decisionRefusal.js';
7
+ import { deliveryTiming, RETRY_BUDGET_MS } from './approvalDelivery.js';
6
8
  const hostSurfaceByKey = createSessionSlot();
7
9
  const hostSurfaceMissesByKey = new Map();
8
10
  export function installHitlHostSurface(surface) {
@@ -38,7 +40,10 @@ function surfaceForSession(sessionKey) {
38
40
  }
39
41
  return hostSurface;
40
42
  }
41
- export const CANCEL_DENY_BUDGET_MS = 2000;
43
+ export const CANCEL_DENY_BUDGET_MS = RETRY_BUDGET_MS;
44
+ export function interruptDenyLifetime() {
45
+ return AbortSignal.timeout(Math.max(1, deliveryTiming().budgetMs));
46
+ }
42
47
  export const INTERRUPT_DENY_REASON = 'Interrupted by user';
43
48
  export const CANCEL_DENY_WARN_TEXT = 'could not cancel the pending question — the session may stay locked; the run may need engine-side recovery';
44
49
  const CANCEL_DENY_WARN_KEY = 'hitl-cancel-deny-warn';
@@ -73,6 +78,11 @@ const EDIT_NOT_FORWARDED_TIMEOUT_MS = 20_000;
73
78
  export function surfaceRememberNotApplied() {
74
79
  surfaceSelfClearingWarn(REMEMBER_NOT_APPLIED_KEY, REMEMBER_NOT_APPLIED_WARN_TEXT, REMEMBER_NOT_APPLIED_TIMEOUT_MS);
75
80
  }
81
+ const ALLOW_NOTE_NOT_CARRIED_KEY = 'hitl-allow-note-not-carried';
82
+ const ALLOW_NOTE_NOT_CARRIED_TIMEOUT_MS = 10_000;
83
+ export function surfaceAllowNoteNotCarried(sentence) {
84
+ surfaceSelfClearingWarn(ALLOW_NOTE_NOT_CARRIED_KEY, sentence, ALLOW_NOTE_NOT_CARRIED_TIMEOUT_MS);
85
+ }
76
86
  export function surfaceEditNotForwarded() {
77
87
  surfaceSelfClearingWarn(EDIT_NOT_FORWARDED_KEY, EDIT_NOT_FORWARDED_WARN_TEXT, EDIT_NOT_FORWARDED_TIMEOUT_MS);
78
88
  }
@@ -100,8 +110,7 @@ const REPLAYED_APPROVAL_LIST_UNREADABLE_TIMEOUT_MS = 10_000;
100
110
  export function surfaceReplayedApprovalListUnreadable() {
101
111
  surfaceSelfClearingWarn(REPLAYED_APPROVAL_LIST_UNREADABLE_KEY, REPLAYED_APPROVAL_LIST_UNREADABLE_WARN_TEXT, REPLAYED_APPROVAL_LIST_UNREADABLE_TIMEOUT_MS);
102
112
  }
103
- export const EDIT_REFUSED_ON_BLIND_ASK_WARN_TEXT = 'That approval was NOT sent: this request does not expose its tool arguments here, so an edited approval cannot be applied. ' +
104
- 'The request is still waiting — approve or deny it as it is.';
113
+ export const EDIT_REFUSED_ON_BLIND_ASK_WARN_TEXT = editedApprovalRefusedLine();
105
114
  const EDIT_REFUSED_ON_BLIND_ASK_KEY = 'hitl-edit-refused-blind-ask';
106
115
  export function surfaceEditRefusedOnBlindAsk() {
107
116
  surfaceSelfClearingWarn(EDIT_REFUSED_ON_BLIND_ASK_KEY, EDIT_REFUSED_ON_BLIND_ASK_WARN_TEXT, EDIT_NOT_FORWARDED_TIMEOUT_MS);
@@ -135,8 +144,9 @@ export function surfaceRuleArmRejected(why) {
135
144
  }
136
145
  export function observeCancelByDeny(settle, taskId) {
137
146
  let timer;
147
+ const budgetMs = deliveryTiming().budgetMs;
138
148
  const budget = new Promise((_, reject) => {
139
- timer = setTimeout(() => reject(new Error(`cancel-by-deny did not settle within ${CANCEL_DENY_BUDGET_MS}ms`)), CANCEL_DENY_BUDGET_MS);
149
+ timer = setTimeout(() => reject(new Error(`cancel-by-deny did not settle within ${budgetMs}ms`)), budgetMs);
140
150
  unrefTimer(timer);
141
151
  });
142
152
  void Promise.race([settle, budget])
@@ -0,0 +1,15 @@
1
+ import { type CheckpointRowBar } from '../checkpointRowVerdict.js';
2
+ export interface HostWithdrawal {
3
+ readonly toldBy: 'host';
4
+ readonly rowVerdict: CheckpointRowBar;
5
+ }
6
+ export declare function hostWithdrawalOf(v: object | null | undefined): HostWithdrawal | undefined;
7
+ export declare const PARK_QUESTION_WITHDRAW_REFUSALS: readonly ["malformed", "no_card", "not_withdrawable"];
8
+ export type ParkQuestionWithdrawRefusal = (typeof PARK_QUESTION_WITHDRAW_REFUSALS)[number];
9
+ export type ParkQuestionWithdrawal = {
10
+ readonly withdrawn: true;
11
+ } | {
12
+ readonly withdrawn: false;
13
+ readonly refusal: ParkQuestionWithdrawRefusal;
14
+ };
15
+ export declare function withdrawParkQuestion(questionId: string, withdrawal: HostWithdrawal): ParkQuestionWithdrawal;
@@ -0,0 +1,38 @@
1
+ import { slotReadOf } from '../wireFailureShape.js';
2
+ import { checkpointRowBarOf } from '../checkpointRowVerdict.js';
3
+ import { takeLocalQuestionWithdrawHook } from '../liveQuestionStore.js';
4
+ import { hostLog } from '../host.js';
5
+ export function hostWithdrawalOf(v) {
6
+ try {
7
+ if (typeof v !== 'object' || v === null)
8
+ return undefined;
9
+ const told = slotReadOf(v, 'toldBy');
10
+ if (told.presence !== 'present' || told.value !== 'host')
11
+ return undefined;
12
+ if (slotReadOf(v, 'rowVerdict').presence !== 'present')
13
+ return undefined;
14
+ const bar = checkpointRowBarOf(v);
15
+ return bar === undefined ? undefined : Object.freeze({ toldBy: 'host', rowVerdict: bar });
16
+ }
17
+ catch {
18
+ return undefined;
19
+ }
20
+ }
21
+ export const PARK_QUESTION_WITHDRAW_REFUSALS = Object.freeze(['malformed', 'no_card', 'not_withdrawable']);
22
+ const WITHDRAWN = Object.freeze({ withdrawn: true });
23
+ const refused = (refusal) => Object.freeze({ withdrawn: false, refusal });
24
+ export function withdrawParkQuestion(questionId, withdrawal) {
25
+ const told = hostWithdrawalOf(withdrawal);
26
+ if (told === undefined)
27
+ return refused('malformed');
28
+ const taken = takeLocalQuestionWithdrawHook(questionId);
29
+ if (taken === 'no_card' || taken === 'not_withdrawable')
30
+ return refused(taken);
31
+ try {
32
+ taken(told);
33
+ }
34
+ catch (e) {
35
+ hostLog('debug', `hostWithdrawal: withdraw-hook-threw card=${questionId} thrown=${e instanceof Error ? e.name : typeof e}`);
36
+ }
37
+ return WITHDRAWN;
38
+ }
@@ -0,0 +1,67 @@
1
+ import type { EngineCapState } from '../engineCapsCache.js';
2
+ import type { HostSettingsLayer, WorkspaceTrustState } from '../hostSettingsSource.js';
3
+ import { type LocalAllowRuleDeps } from './localAllowRule.js';
4
+ import { type ListAllPersistedRulesOutcome, type RulesFacade } from './persistedRulesWire.js';
5
+ export declare const LOCAL_ALLOW_NOT_REDEEMABLE_REASONS: readonly ["managed_only", "tighten_only", "no_scope_root", "no_consent", "road_closed"];
6
+ export type LocalAllowNotRedeemableReason = (typeof LOCAL_ALLOW_NOT_REDEEMABLE_REASONS)[number];
7
+ export declare const LOCAL_ALLOW_UNKNOWN_CAUSES: readonly ["input_unreadable", "policy_unreadable", "consent_unreadable", "road_unknown"];
8
+ export type LocalAllowUnknownCause = (typeof LOCAL_ALLOW_UNKNOWN_CAUSES)[number];
9
+ export type LocalAllowRedeemability = {
10
+ readonly kind: 'redeemable';
11
+ readonly via: 'layer' | 'consent';
12
+ } | {
13
+ readonly kind: 'not_redeemable';
14
+ readonly reason: LocalAllowNotRedeemableReason;
15
+ } | {
16
+ readonly kind: 'unknown';
17
+ readonly cause: LocalAllowUnknownCause;
18
+ };
19
+ export interface LocalAllowOfferedFacts {
20
+ readonly managedRulesOnly: boolean | 'unreadable';
21
+ readonly scopeRoot: string | undefined;
22
+ readonly road: EngineCapState;
23
+ }
24
+ export type LocalAllowRedeemabilityInput = ({
25
+ readonly subject: 'offered';
26
+ } & LocalAllowOfferedFacts) | {
27
+ readonly subject: 'declared';
28
+ readonly source: HostSettingsLayer;
29
+ readonly workspace: WorkspaceTrustState | 'unreadable';
30
+ readonly managedRulesOnly: boolean | 'unreadable';
31
+ readonly rule: string;
32
+ readonly scopeRoot: string | undefined;
33
+ readonly store: ListAllPersistedRulesOutcome;
34
+ };
35
+ export declare function localAllowRedeemability(input: LocalAllowRedeemabilityInput): LocalAllowRedeemability;
36
+ export declare const LOCAL_ALLOW_REDEMPTION_REFUSALS: readonly ["managed_only", "no_scope_root", "rule_shape", "request_refused", "preview_mismatch", "engine_refused", "ticket_dead"];
37
+ export type LocalAllowRedemptionRefusal = (typeof LOCAL_ALLOW_REDEMPTION_REFUSALS)[number];
38
+ export declare const LOCAL_ALLOW_REDEMPTION_UNAVAILABLE_CAUSES: readonly ["road_closed", "road_unknown", "policy_unreadable", "input_unreadable", "prepare_failed"];
39
+ export type LocalAllowRedemptionUnavailableCause = (typeof LOCAL_ALLOW_REDEMPTION_UNAVAILABLE_CAUSES)[number];
40
+ export declare const LOCAL_ALLOW_REDEMPTION_UNKNOWN_CAUSES: readonly ["redeem_unsettled", "receipt_unreadable"];
41
+ export type LocalAllowRedemptionUnknownCause = (typeof LOCAL_ALLOW_REDEMPTION_UNKNOWN_CAUSES)[number];
42
+ export type LocalAllowRedemptionReceipt = {
43
+ readonly kind: 'applied';
44
+ readonly outcome: 'persisted' | 'already_live';
45
+ readonly rule: string;
46
+ readonly scope: string;
47
+ } | {
48
+ readonly kind: 'refused';
49
+ readonly reason: LocalAllowRedemptionRefusal;
50
+ readonly detail?: string;
51
+ } | {
52
+ readonly kind: 'unavailable';
53
+ readonly cause: LocalAllowRedemptionUnavailableCause;
54
+ } | {
55
+ readonly kind: 'unknown';
56
+ readonly cause: LocalAllowRedemptionUnknownCause;
57
+ };
58
+ export type LocalAllowRedemptionFacade = Pick<RulesFacade, 'ccImportPrepare' | 'ccImportRedeem'>;
59
+ export interface ReadOnlyRuleOfferRedemption extends LocalAllowOfferedFacts {
60
+ readonly rule: string;
61
+ readonly expectedToolName?: string;
62
+ readonly settingsPath: string;
63
+ readonly deps: LocalAllowRuleDeps;
64
+ }
65
+ export declare function redeemReadOnlyRuleOffer(facade: LocalAllowRedemptionFacade, input: ReadOnlyRuleOfferRedemption, opts?: {
66
+ readonly signal?: AbortSignal;
67
+ }): Promise<LocalAllowRedemptionReceipt>;