@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
@@ -1,6 +1,17 @@
1
1
  import { atMostOnceVerdictOf } from './atMostOnce.js';
2
2
  import { readOwnDataValue } from './ownKey.js';
3
3
  import { noteInteractiveStopRequested, ownSlotOf } from './sessionBackground.js';
4
+ function isLocalBodyShapeRefusal(e) {
5
+ if (e === null || typeof e !== 'object')
6
+ return false;
7
+ try {
8
+ const d = Object.getOwnPropertyDescriptor(e, 'errorCode');
9
+ return d !== undefined && Object.hasOwn(d, 'value') && d.value === 'request.body_shape';
10
+ }
11
+ catch {
12
+ return false;
13
+ }
14
+ }
4
15
  function guardedSlot(e, key) {
5
16
  if (e === null || (typeof e !== 'object' && typeof e !== 'function'))
6
17
  return undefined;
@@ -59,10 +70,17 @@ export async function fireInteractiveInterrupt(runs, taskId, opts = {}) {
59
70
  };
60
71
  let receipt;
61
72
  try {
62
- receipt = await verb.call(runs, taskId, undefined, callOpts);
73
+ receipt = await verb.call(runs, taskId, callOpts);
63
74
  }
64
75
  catch (e) {
65
- return outcomeOfFailure(e);
76
+ if (!isLocalBodyShapeRefusal(e))
77
+ return outcomeOfFailure(e);
78
+ try {
79
+ receipt = await verb.call(runs, taskId, undefined, callOpts);
80
+ }
81
+ catch (e2) {
82
+ return outcomeOfFailure(e2);
83
+ }
66
84
  }
67
85
  const turnCut = turnCutOf(receipt);
68
86
  return { kind: 'halted', ...(turnCut !== undefined ? { turnCut } : {}) };
@@ -0,0 +1,2 @@
1
+ import type { UiLanguage } from './env/uiLanguage.js';
2
+ export declare function interruptRefusalNote(reason: string | null | undefined, lang?: UiLanguage): string;
@@ -0,0 +1,17 @@
1
+ import { INTERRUPT_NOT_HELD, INTERRUPT_NOTHING_IN_FLIGHT, STEERING_NOT_RUNNING } from './engineErrorCodes.js';
2
+ import { msg, renderMessage } from './i18n/translate.js';
3
+ function interruptRefusalKeyOf(reason) {
4
+ switch (reason) {
5
+ case INTERRUPT_NOTHING_IN_FLIGHT:
6
+ return 'session.interruptRefusal.nothingInFlight';
7
+ case INTERRUPT_NOT_HELD:
8
+ return 'session.interruptRefusal.notHeld';
9
+ case STEERING_NOT_RUNNING:
10
+ return 'session.interruptRefusal.notRunning';
11
+ default:
12
+ return 'session.interruptRefusal.unrecognised';
13
+ }
14
+ }
15
+ export function interruptRefusalNote(reason, lang) {
16
+ return renderMessage(msg(interruptRefusalKeyOf(reason)), lang);
17
+ }
@@ -36,6 +36,8 @@ export declare function imageVisionReadingOf(model: string | undefined, catalog?
36
36
  readonly vision: ImageVision;
37
37
  readonly model?: string;
38
38
  };
39
+ export type ModelReasoning = 'yes' | 'no' | 'unknown';
40
+ export declare function modelReasoningOf(model: string | undefined, catalog?: LiveModelCatalog | null): ModelReasoning;
39
41
  export type EffortLevelsReading = {
40
42
  readonly kind: 'clamped';
41
43
  readonly levels: readonly string[];
@@ -2,7 +2,7 @@ import { appendOwnElement, readOwnDataValue } from './ownKey.js';
2
2
  import { frozenJsonCopyOf, liveDefaultModelCopy, liveModelRowCopy } from './model/liveCatalogShape.js';
3
3
  import { msg, renderMessage } from './i18n/translate.js';
4
4
  import { quoteUntrustedForSentence } from './displayUntrusted.js';
5
- import { CC_TIER_ALIASES, TIER_ORDER } from './model/tierVocabulary.js';
5
+ import { engineModelWordKindOf } from './model/engineModelWords.js';
6
6
  let catalog = null;
7
7
  let refresher = null;
8
8
  export function setLiveModelCatalog(next) {
@@ -46,6 +46,9 @@ function ownDataOf(o, key) {
46
46
  return undefined;
47
47
  }
48
48
  }
49
+ function capabilityWordOf(declared) {
50
+ return declared === true ? 'yes' : declared === false ? 'no' : 'unknown';
51
+ }
49
52
  function liveModelRowOf(cat, ref) {
50
53
  const rows = catalogRowsOf(cat);
51
54
  if (rows === undefined)
@@ -92,8 +95,7 @@ export function imageVisionReadingOf(model, catalog = getLiveModelCatalog()) {
92
95
  const target = targetRowOf(model, catalog);
93
96
  if (target.kind !== 'row')
94
97
  return { vision: 'unknown' };
95
- const vision = ownDataOf(target.row, 'vision');
96
- const word = vision === true ? 'yes' : vision === false ? 'no' : 'unknown';
98
+ const word = capabilityWordOf(ownDataOf(target.row, 'vision'));
97
99
  const name = ownDataOf(target.row, 'name');
98
100
  return typeof name === 'string' && name.length > 0 ? { vision: word, model: name } : { vision: word };
99
101
  }
@@ -101,6 +103,18 @@ export function imageVisionReadingOf(model, catalog = getLiveModelCatalog()) {
101
103
  return { vision: 'unknown' };
102
104
  }
103
105
  }
106
+ export function modelReasoningOf(model, catalog = getLiveModelCatalog()) {
107
+ try {
108
+ const target = targetRowOf(model, catalog);
109
+ return target.kind === 'row' ? reasoningWordOfRow(target.row) : 'unknown';
110
+ }
111
+ catch {
112
+ return 'unknown';
113
+ }
114
+ }
115
+ function reasoningWordOfRow(row) {
116
+ return capabilityWordOf(ownDataOf(row, 'reasoning'));
117
+ }
104
118
  const NOT_CLAMPED = Object.freeze({ kind: 'not_clamped' });
105
119
  const NOT_APPLICABLE = Object.freeze({ kind: 'not_applicable' });
106
120
  const unknownEffort = (why) => Object.freeze({ kind: 'unknown', why });
@@ -127,10 +141,10 @@ export function effortLevelsOf(model, catalog = getLiveModelCatalog()) {
127
141
  }
128
142
  return Object.freeze({ kind: 'clamped', levels: Object.freeze(out) });
129
143
  }
130
- const reasoning = ownDataOf(row, 'reasoning');
131
- if (reasoning === true)
144
+ const reasoning = reasoningWordOfRow(row);
145
+ if (reasoning === 'yes')
132
146
  return NOT_CLAMPED;
133
- if (reasoning === false)
147
+ if (reasoning === 'no')
134
148
  return NOT_APPLICABLE;
135
149
  return unknownEffort('reasoning_unreported');
136
150
  }
@@ -157,7 +171,7 @@ export function liveDefaultModelName() {
157
171
  return d.kind === 'listed' ? d.name : d.kind === 'not_listed' ? d.id : null;
158
172
  }
159
173
  function isReservedModelWord(word) {
160
- return word === 'default' || TIER_ORDER.includes(word) || Object.hasOwn(CC_TIER_ALIASES, word);
174
+ return engineModelWordKindOf(word) !== undefined;
161
175
  }
162
176
  function droppedDisabledNamed(dropped, name) {
163
177
  if (dropped.kind !== 'reported')
@@ -747,14 +761,14 @@ export function liveModelRowsOf(catalog = getLiveModelCatalog()) {
747
761
  seen.add(name);
748
762
  const id = nonEmptyString(ownDataOf(row, 'id'));
749
763
  const provider = nonEmptyString(ownDataOf(row, 'provider'));
750
- const reasoning = ownDataOf(row, 'reasoning');
764
+ const reasoning = reasoningWordOfRow(row);
751
765
  const contextWindow = positiveFinite(ownDataOf(row, 'contextWindow'));
752
766
  const maxOutputTokens = positiveFinite(ownDataOf(row, 'maxOutputTokens'));
753
767
  out.push(Object.freeze({
754
768
  name,
755
769
  ...(id !== undefined ? { id } : {}),
756
770
  ...(provider !== undefined ? { provider } : {}),
757
- ...(typeof reasoning === 'boolean' ? { reasoning } : {}),
771
+ ...(reasoning !== 'unknown' ? { reasoning: reasoning === 'yes' } : {}),
758
772
  ...(contextWindow !== undefined ? { contextWindow } : {}),
759
773
  ...(maxOutputTokens !== undefined ? { maxOutputTokens } : {}),
760
774
  isDefault: def.kind === 'listed' && def.name === name,
@@ -1,10 +1,13 @@
1
1
  import type { AskQuestion, AskQuestionOption, QuestionAnswer, QuestionFrame } from '@sema-agent/sdk';
2
2
  export type { AskQuestion, AskQuestionOption, QuestionAnswer, QuestionFrame };
3
+ import type { HostWithdrawal } from './hitl/hostWithdrawal.js';
3
4
  type QuestionFrameHandler = (frame: QuestionFrame) => void;
4
5
  type RespondFn = (id: string, answer: QuestionAnswer, opts?: {
5
6
  signal?: AbortSignal;
6
7
  }) => Promise<unknown>;
7
- export declare function registerLocalQuestionResponder(id: string, fn: RespondFn): () => void;
8
+ type WithdrawHook = (withdrawal: HostWithdrawal) => void;
9
+ export declare function registerLocalQuestionResponder(id: string, fn: RespondFn, onWithdraw?: WithdrawHook): () => void;
10
+ export declare function takeLocalQuestionWithdrawHook(id: string): WithdrawHook | 'no_card' | 'not_withdrawable';
8
11
  export declare function unregisterLocalQuestionResponder(id: string): boolean;
9
12
  export declare function hasLocalQuestionResponder(id: string): boolean;
10
13
  export declare function publishQuestionFrame(frame: QuestionFrame): void;
@@ -2,12 +2,21 @@ import { createSessionSlot, DEFAULT_SESSION_KEY } from './sessionSlot.js';
2
2
  const frameHandlerByKey = createSessionSlot();
3
3
  let respondFn = null;
4
4
  const localResponders = new Map();
5
- export function registerLocalQuestionResponder(id, fn) {
6
- localResponders.set(id, fn);
5
+ export function registerLocalQuestionResponder(id, fn, onWithdraw) {
6
+ localResponders.set(id, typeof onWithdraw === 'function' ? { respond: fn, withdraw: onWithdraw } : { respond: fn });
7
7
  return () => {
8
8
  localResponders.delete(id);
9
9
  };
10
10
  }
11
+ export function takeLocalQuestionWithdrawHook(id) {
12
+ const entry = localResponders.get(id);
13
+ if (entry === undefined)
14
+ return 'no_card';
15
+ if (entry.withdraw === undefined)
16
+ return 'not_withdrawable';
17
+ localResponders.delete(id);
18
+ return entry.withdraw;
19
+ }
11
20
  export function unregisterLocalQuestionResponder(id) {
12
21
  return localResponders.delete(id);
13
22
  }
@@ -50,7 +59,7 @@ export function respondToQuestion(id, answer, opts) {
50
59
  const local = localResponders.get(id);
51
60
  if (local) {
52
61
  localResponders.delete(id);
53
- return local(id, answer, opts);
62
+ return local.respond(id, answer, opts);
54
63
  }
55
64
  if (!respondFn) {
56
65
  return Promise.reject(new Error('no live question respond wired (offline/mock path)'));
@@ -14,9 +14,9 @@ export declare function localEngineSeatSentence(reading: LocalEngineSeatReading,
14
14
  export declare function localEngineNoticeText(notice: LocalEngineNotice, lang?: UiLanguage): string | undefined;
15
15
  export declare function localEngineFailText(code: LocalEngineFailCode, lang?: UiLanguage): string | undefined;
16
16
  export declare function engineTargetLocalOf(input: {
17
- readonly lifecycle: LocalEngineSeatReading;
17
+ readonly lifecycle: LocalEngineSeatReading | undefined;
18
18
  readonly mcp?: SeatLocalMcpReading;
19
- }, lang?: UiLanguage): EngineTargetLocal;
19
+ }, lang?: UiLanguage): EngineTargetLocal | undefined;
20
20
  export interface EngineRestartOperation {
21
21
  readonly before: LocalEngineState;
22
22
  readonly after: LocalEngineState;
@@ -95,7 +95,7 @@ export function localEngineSeatReadingOf(state, host) {
95
95
  return undefined;
96
96
  }
97
97
  }
98
- const STATE_DOWN = Object.freeze(['lock-unavailable', 'spawn-failed', 'spawn-refused', 'stop-failed', 'crash-loop', 'high-water-unreadable']);
98
+ const STATE_DOWN = Object.freeze(['lock-unavailable', 'spawn-failed', 'spawn-refused', 'stop-failed', 'crash-loop', 'high-water-unreadable', 'exited-once']);
99
99
  const DOWN_KEYS = Object.freeze({
100
100
  'lock-unavailable': 'localEngine.down.lockUnavailable',
101
101
  'spawn-failed': 'localEngine.down.spawnFailed',
@@ -103,6 +103,7 @@ const DOWN_KEYS = Object.freeze({
103
103
  'stop-failed': 'localEngine.down.stopFailed',
104
104
  'crash-loop': 'localEngine.down.crashLoop',
105
105
  'high-water-unreadable': 'localEngine.down.highWaterUnreadable',
106
+ 'exited-once': 'localEngine.down.exitedOnce',
106
107
  });
107
108
  function downSentence(reason, lang) {
108
109
  if (reason === 'principal-unknown')
@@ -207,6 +208,7 @@ const FAIL_KEYS = Object.freeze({
207
208
  'local_engine.stop_failed': 'localEngine.down.stopFailed',
208
209
  'local_engine.crash_loop': 'localEngine.down.crashLoop',
209
210
  'local_engine.high_water_unreadable': 'localEngine.down.highWaterUnreadable',
211
+ 'local_engine.exited_once': 'localEngine.down.exitedOnce',
210
212
  });
211
213
  export function localEngineFailText(code, lang) {
212
214
  try {
@@ -224,7 +226,7 @@ export function engineTargetLocalOf(input, lang) {
224
226
  const lifecycle = raw === undefined ? undefined : ownSnapshotTyped(raw);
225
227
  const phase = own(lifecycle, 'phase');
226
228
  if (lifecycle === undefined || typeof phase !== 'string')
227
- return Object.freeze({});
229
+ return undefined;
228
230
  const out = { lifecycle };
229
231
  if (phase === 'down') {
230
232
  const line = downSentence(own(lifecycle, 'reason'), lang);
@@ -238,7 +240,7 @@ export function engineTargetLocalOf(input, lang) {
238
240
  return deepFreeze(out);
239
241
  }
240
242
  catch {
241
- return Object.freeze({});
243
+ return undefined;
242
244
  }
243
245
  }
244
246
  function attachedId(s) {
@@ -103,11 +103,4 @@ export interface LocalEnginePrincipalView {
103
103
  }
104
104
  export declare function localEnginePrincipalOf(view: LocalEnginePrincipalView): LocalEnginePrincipal;
105
105
  export declare function localEnginePrincipalSentence(p: LocalEnginePrincipal, lang?: UiLanguage): string | undefined;
106
- export interface LocalEngineBootRefusal {
107
- readonly code?: string;
108
- readonly hint?: string;
109
- readonly text: string;
110
- }
111
- export declare function engineBootRefusalOf(lines: readonly string[], scrub: (s: string) => string): LocalEngineBootRefusal | undefined;
112
- export declare function engineBootRefusalSentence(refusal: LocalEngineBootRefusal, lang?: UiLanguage): string | undefined;
113
106
  export declare function localEngineFirstShareSentence(lang?: UiLanguage): string;
@@ -61,14 +61,6 @@ function stringOf(x) {
61
61
  return undefined;
62
62
  }
63
63
  }
64
- function parseJsonLine(t) {
65
- try {
66
- return JSON.parse(t);
67
- }
68
- catch {
69
- return undefined;
70
- }
71
- }
72
64
  function freezeRecord(rows) {
73
65
  const out = {};
74
66
  for (const [k, v] of rows)
@@ -397,90 +389,6 @@ export function localEnginePrincipalSentence(p, lang) {
397
389
  return undefined;
398
390
  }
399
391
  }
400
- const BOOT_REFUSAL_MAX_CHARS = 800;
401
- const BOOT_REFUSAL_MAX_HINTS = 2;
402
- const CONFIG_CODE = /^config\.[A-Za-z0-9_.-]+$/;
403
- function capSentence(s) {
404
- const t = s.trim();
405
- return t.length > BOOT_REFUSAL_MAX_CHARS ? `${t.slice(0, BOOT_REFUSAL_MAX_CHARS)}…` : t;
406
- }
407
- export function engineBootRefusalOf(lines, scrub) {
408
- try {
409
- const clean = (s) => {
410
- try {
411
- const out = scrub(s);
412
- return typeof out === 'string' ? out : undefined;
413
- }
414
- catch {
415
- return undefined;
416
- }
417
- };
418
- const hints = [];
419
- let code;
420
- let hint;
421
- let fatal;
422
- const list = Array.isArray(lines) ? [...lines] : [];
423
- for (const raw of list) {
424
- if (typeof raw !== 'string')
425
- continue;
426
- const line = clean(raw);
427
- if (line === undefined)
428
- continue;
429
- const t = line.trim();
430
- if (!t.startsWith('{'))
431
- continue;
432
- const o = parseJsonLine(t);
433
- if (!isRecord(o))
434
- continue;
435
- const m = own(o, 'msg');
436
- const err = own(o, 'err');
437
- if (m === 'fatal' && typeof err === 'string' && err.trim() !== '') {
438
- const full = clean(err);
439
- const s = full === undefined ? undefined : full.replace(/^\s*Error:\s*/, '');
440
- if (s !== undefined && s.trim() !== '')
441
- fatal = capSentence(s);
442
- continue;
443
- }
444
- const c = own(o, 'code');
445
- const h = own(o, 'hint');
446
- if (typeof c === 'string' && CONFIG_CODE.test(c) && typeof h === 'string' && h.trim() !== '') {
447
- const model = own(o, 'model');
448
- const who = typeof model === 'string' && model !== '' ? `"${model}": ` : '';
449
- const s = clean(`${who}${h}`);
450
- const cc = clean(c);
451
- if (s === undefined || cc === undefined || !CONFIG_CODE.test(cc))
452
- continue;
453
- const sentence = capSentence(s);
454
- code = cc;
455
- const ch = clean(h);
456
- hint = ch === undefined ? undefined : capSentence(ch);
457
- if (hints.includes(sentence))
458
- continue;
459
- hints.push(sentence);
460
- if (hints.length > BOOT_REFUSAL_MAX_HINTS)
461
- hints.shift();
462
- }
463
- }
464
- const parts = [...hints, ...(fatal !== undefined ? [fatal] : [])];
465
- if (parts.length === 0)
466
- return undefined;
467
- return Object.freeze({ ...(code !== undefined ? { code } : {}), ...(hint !== undefined ? { hint } : {}), text: parts.join('\n') });
468
- }
469
- catch {
470
- return undefined;
471
- }
472
- }
473
- export function engineBootRefusalSentence(refusal, lang) {
474
- try {
475
- const text = own(refusal, 'text');
476
- if (typeof text !== 'string' || text.trim() === '')
477
- return undefined;
478
- return renderMessage(msg('localEngine.bootRefusal', { reason: text }), lang);
479
- }
480
- catch {
481
- return undefined;
482
- }
483
- }
484
392
  export function localEngineFirstShareSentence(lang) {
485
393
  return renderMessage(msg('localEngine.firstShare'), lang);
486
394
  }
@@ -14,7 +14,7 @@ export interface LocalEngineStepOccupancy extends LocalEngineOccupancy {
14
14
  readonly bgIds: readonly string[] | null;
15
15
  }
16
16
  export type LocalEngineTarget = EngineSwapCardTarget;
17
- export type LocalEngineStateDownReason = 'lock-unavailable' | 'spawn-failed' | 'spawn-refused' | 'stop-failed' | 'crash-loop' | 'high-water-unreadable';
17
+ export type LocalEngineStateDownReason = 'lock-unavailable' | 'spawn-failed' | 'spawn-refused' | 'stop-failed' | 'crash-loop' | 'high-water-unreadable' | 'exited-once';
18
18
  export interface LocalEngineCauseEntry {
19
19
  readonly cause: LocalEngineSwapCause;
20
20
  readonly fingerprint: string;
@@ -189,7 +189,7 @@ export type LocalEngineEvent = {
189
189
  readonly clean: boolean | 'unknown';
190
190
  readonly nowMs: number;
191
191
  };
192
- export declare const LOCAL_ENGINE_FAIL_CODES: readonly ["local_engine.behind", "local_engine.legacy_below_floor", "local_engine.unresponsive", "local_engine.swap_pending", "local_engine.drain_overdue", "local_engine.unanswered_unverifiable", "local_engine.lock_unavailable", "local_engine.spawn_failed", "local_engine.spawn_refused", "local_engine.stop_failed", "local_engine.crash_loop", "local_engine.high_water_unreadable", "local_engine.principal_unknown"];
192
+ export declare const LOCAL_ENGINE_FAIL_CODES: readonly ["local_engine.behind", "local_engine.legacy_below_floor", "local_engine.unresponsive", "local_engine.swap_pending", "local_engine.drain_overdue", "local_engine.unanswered_unverifiable", "local_engine.lock_unavailable", "local_engine.spawn_failed", "local_engine.spawn_refused", "local_engine.stop_failed", "local_engine.crash_loop", "local_engine.high_water_unreadable", "local_engine.exited_once", "local_engine.principal_unknown"];
193
193
  export type LocalEngineFailCode = (typeof LOCAL_ENGINE_FAIL_CODES)[number];
194
194
  export type LocalEngineNotice = {
195
195
  readonly key: 'versionUnknown';
@@ -18,6 +18,7 @@ export const LOCAL_ENGINE_FAIL_CODES = Object.freeze([
18
18
  'local_engine.stop_failed',
19
19
  'local_engine.crash_loop',
20
20
  'local_engine.high_water_unreadable',
21
+ 'local_engine.exited_once',
21
22
  'local_engine.principal_unknown',
22
23
  ]);
23
24
  function isRecord(v) {
@@ -210,6 +211,7 @@ const DOWN_FAIL = Object.freeze({
210
211
  'stop-failed': 'local_engine.stop_failed',
211
212
  'crash-loop': 'local_engine.crash_loop',
212
213
  'high-water-unreadable': 'local_engine.high_water_unreadable',
214
+ 'exited-once': 'local_engine.exited_once',
213
215
  });
214
216
  function showCard(p, hold, occ, fx, policy) {
215
217
  if (headless(policy)) {
@@ -1,5 +1,6 @@
1
1
  import type { WiringManifestMcpEntryView } from './adapter/downstream/eventToSdkMessage.js';
2
2
  import { type McpAuthorizationView } from './mcpLiveness.js';
3
+ import type { UiLanguage } from './env/uiLanguage.js';
3
4
  export type McpEngineLegLiveness = {
4
5
  kind: 'unobserved';
5
6
  } | {
@@ -43,6 +44,8 @@ export type McpEngineLegConnection = {
43
44
  status: string;
44
45
  };
45
46
  export declare function mcpEngineLegConnectionOf(serverName: string, rows: readonly WiringManifestMcpEntryView[] | null | undefined): McpEngineLegConnection;
47
+ export declare function mcpNeedsReauth(reading: {} | null | undefined): boolean | undefined;
48
+ export declare function mcpFailureStatusSuffix(reading: {} | null | undefined, lang?: UiLanguage): string;
46
49
  export interface McpDetailLegNoteInput {
47
50
  localClientFailed: boolean;
48
51
  engineHostedToolCount: number | undefined;
@@ -1,5 +1,7 @@
1
- import { isMcpLivenessState, readMcpAuthorization } from './mcpLiveness.js';
1
+ import { isMcpLivenessState, MCP_FAILURE_UNAUTHORIZED, readMcpAuthorization } from './mcpLiveness.js';
2
2
  import { mcpSectionDroppedNamedRowsOf } from './ownKey.js';
3
+ import { slotReadOf } from './wireFailureShape.js';
4
+ import { msg, renderMessage } from './i18n/translate.js';
3
5
  void true;
4
6
  void true;
5
7
  void true;
@@ -132,6 +134,41 @@ export function mcpEngineLegConnectionOf(serverName, rows) {
132
134
  ...(authorization.kind === 'record' ? { authorization: authorization.authorization } : authorizationUnreadable ? { authorizationUnreadable: true } : {}),
133
135
  };
134
136
  }
137
+ export function mcpNeedsReauth(reading) {
138
+ try {
139
+ if (reading === null || typeof reading !== 'object' || Array.isArray(reading))
140
+ return undefined;
141
+ const slot = slotReadOf(reading, 'errorCode');
142
+ if (slot.presence === 'absent')
143
+ return false;
144
+ if (slot.presence !== 'present')
145
+ return undefined;
146
+ const code = slot.value;
147
+ if (typeof code !== 'string' || code === '')
148
+ return undefined;
149
+ return code === MCP_FAILURE_UNAUTHORIZED;
150
+ }
151
+ catch {
152
+ return undefined;
153
+ }
154
+ }
155
+ export function mcpFailureStatusSuffix(reading, lang) {
156
+ try {
157
+ if (reading === null || typeof reading !== 'object' || Array.isArray(reading))
158
+ return '';
159
+ const slot = slotReadOf(reading, 'httpStatus');
160
+ const status = slot.presence === 'present' && typeof slot.value === 'number' && Number.isInteger(slot.value) && slot.value > 0 ? slot.value : undefined;
161
+ const number = status === undefined ? '' : ` ${status}`;
162
+ if (mcpNeedsReauth(reading) === true)
163
+ return `${number}${renderMessage(msg('session.mcpFailure.reauthorizeSuffix'), lang)}`;
164
+ if (status !== undefined && status >= 500 && status <= 599)
165
+ return `${number}${renderMessage(msg('session.mcpFailure.serverDownSuffix'), lang)}`;
166
+ return number;
167
+ }
168
+ catch {
169
+ return '';
170
+ }
171
+ }
135
172
  const rosterReadingOf = (v) => {
136
173
  if (v === UNREADABLE_CELL)
137
174
  return 'unreadable';
package/dist/mcpPanel.js CHANGED
@@ -122,6 +122,8 @@ const _mcpPanelShapePin = (p) => p;
122
122
  void _mcpPanelShapePin;
123
123
  const _mcpPanelRefusalPin = (p) => p;
124
124
  void _mcpPanelRefusalPin;
125
+ const _pinMcpPanel = [true, true, true, true, true, true, true, true, true, true];
126
+ void _pinMcpPanel;
125
127
  export function mcpEngineLegPresence(view) {
126
128
  if (view === undefined)
127
129
  return 'unknown';
@@ -1,4 +1,5 @@
1
1
  import { type McpAuthorizationView } from './mcpLiveness.js';
2
+ import type { UiLanguage } from './env/uiLanguage.js';
2
3
  export declare const MCP_RECONNECT_OUTCOMES: readonly string[];
3
4
  export declare const MCP_RECONNECT_TRANSACTION_NOTICE: string;
4
5
  export declare const MCP_RECONNECT_UNSETTLED_NOTICE: string;
@@ -76,4 +77,11 @@ export declare function reconnectMcpServer(client: McpReconnectClientLike, sessi
76
77
  signal?: AbortSignal;
77
78
  }): Promise<McpReconnectVerdict>;
78
79
  export declare function projectMcpReconnectCapability(caps: unknown): 'available' | 'unavailable' | 'not_reported' | undefined;
79
- export declare function mcpReconnectOutcomeDetail(view: McpReconnectResultView): string;
80
+ export declare function mcpReconnectOutcomeDetail(view: McpReconnectResultView, lang?: UiLanguage): string;
81
+ export type McpReconnectNotSentVerdict = {
82
+ readonly kind: 'no_session';
83
+ } | {
84
+ readonly kind: 'unavailable';
85
+ };
86
+ export type McpReconnectDetailVerdict = McpReconnectVerdict | McpReconnectNotSentVerdict;
87
+ export declare function mcpReconnectVerdictDetail(verdict: McpReconnectDetailVerdict, server: string, lang?: UiLanguage): string | undefined;