@sema-agent/client-core 0.100.0 → 0.101.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 (335) hide show
  1. package/CHANGELOG.md +395 -0
  2. package/README.md +164 -117
  3. package/dist/adapt/arms.js +51 -16
  4. package/dist/adapt/textStream.js +7 -4
  5. package/dist/adapt/toolCards.js +9 -8
  6. package/dist/adapt.js +7 -1
  7. package/dist/adapter/activeRunSelfHeal.d.ts +24 -2
  8. package/dist/adapter/activeRunSelfHeal.js +108 -6
  9. package/dist/adapter/downstream/eventToSdkMessage.js +33 -12
  10. package/dist/adapter/downstream/terminalToSdkResult.d.ts +60 -1
  11. package/dist/adapter/downstream/terminalToSdkResult.js +209 -39
  12. package/dist/adapter/runStream.d.ts +4 -4
  13. package/dist/adapter/runStream.js +158 -43
  14. package/dist/agentsWireCaps.d.ts +2 -7
  15. package/dist/agentsWireCaps.js +1 -2
  16. package/dist/approvalDecidedByCapability.js +2 -2
  17. package/dist/approvalFrameFamilies.d.ts +33 -0
  18. package/dist/approvalFrameFamilies.js +120 -0
  19. package/dist/approvalsStreamLiveCapability.js +2 -2
  20. package/dist/attachmentsWireCaps.js +41 -13
  21. package/dist/callerCwdCapability.js +2 -2
  22. package/dist/centerWiringCapability.js +2 -2
  23. package/dist/clockReading.d.ts +2 -0
  24. package/dist/clockReading.js +4 -0
  25. package/dist/cloudConfigWireCaps.d.ts +19 -5
  26. package/dist/cloudConfigWireCaps.js +193 -56
  27. package/dist/coreValuePorts.d.ts +12 -2
  28. package/dist/coreValuePorts.js +9 -0
  29. package/dist/decideFailureNote.js +5 -3
  30. package/dist/decideReceipt.js +2 -2
  31. package/dist/deviceExecutorManagementCapability.js +2 -2
  32. package/dist/deviceFlowPolling.js +1 -1
  33. package/dist/disableSkillsWire.d.ts +1 -1
  34. package/dist/disableSkillsWire.js +4 -3
  35. package/dist/displayUntrusted.d.ts +1 -0
  36. package/dist/displayUntrusted.js +65 -8
  37. package/dist/engineCapReader.js +1 -1
  38. package/dist/engineConfigDrift.js +1 -1
  39. package/dist/engineErrorCodes.d.ts +14 -5
  40. package/dist/engineErrorCodes.js +27 -6
  41. package/dist/engineGenerationConvergence.d.ts +39 -0
  42. package/dist/engineGenerationConvergence.js +95 -0
  43. package/dist/engineGenerationPort.d.ts +61 -0
  44. package/dist/engineGenerationPort.js +144 -0
  45. package/dist/engineHealthFacts.d.ts +23 -0
  46. package/dist/engineHealthFacts.js +92 -0
  47. package/dist/engineIdentity.d.ts +4 -0
  48. package/dist/engineIdentity.js +11 -0
  49. package/dist/engineNoticeCodes.d.ts +2 -5
  50. package/dist/engineRowRef.js +3 -0
  51. package/dist/engineSessionMessages.js +2 -2
  52. package/dist/engineToolDirectory.js +2 -2
  53. package/dist/engineWireFor.d.ts +99 -0
  54. package/dist/engineWireFor.js +248 -6
  55. package/dist/engineWireTarget.d.ts +1 -0
  56. package/dist/engineWireTarget.js +8 -0
  57. package/dist/env/uiLanguage.js +1 -1
  58. package/dist/errorSupplementRoles.d.ts +3 -0
  59. package/dist/errorSupplementRoles.js +37 -0
  60. package/dist/executionLaneCapability.js +2 -2
  61. package/dist/fileHistoryCaptureCapability.js +3 -3
  62. package/dist/finalVerifyWire.d.ts +6 -3
  63. package/dist/finalVerifyWire.js +6 -23
  64. package/dist/flagInput.d.ts +4 -0
  65. package/dist/flagInput.js +24 -0
  66. package/dist/fleet/fleetLedger.js +5 -2
  67. package/dist/fleet/fleetProjection.d.ts +1 -0
  68. package/dist/fleet/fleetProjection.js +15 -2
  69. package/dist/gateVocabulary.js +3 -0
  70. package/dist/generated/engineFactTables.d.ts +7 -3
  71. package/dist/generated/engineFactTables.js +52 -0
  72. package/dist/generated/engineNoticeTables.js +12 -0
  73. package/dist/generated/settingsSchemaActiveTiers.d.ts +1 -0
  74. package/dist/generated/settingsSchemaActiveTiers.js +14 -0
  75. package/dist/generated/settingsSchemaCallerTextEcho.d.ts +1 -0
  76. package/dist/generated/settingsSchemaCallerTextEcho.js +8 -0
  77. package/dist/generated/settingsSchemaControlAndBidi.d.ts +1 -0
  78. package/dist/generated/settingsSchemaControlAndBidi.js +8 -0
  79. package/dist/generated/settingsSchemaDefaultModel.d.ts +11 -0
  80. package/dist/generated/settingsSchemaDefaultModel.js +25 -0
  81. package/dist/generated/settingsSchemaFns.d.ts +54 -0
  82. package/dist/generated/settingsSchemaFns.js +26 -1
  83. package/dist/generated/settingsSchemaMcpRequestEntry.d.ts +1 -1
  84. package/dist/generated/settingsSchemaMcpRequestEntry.js +1 -7
  85. package/dist/generated/settingsSchemaSafetyMergeSpec.d.ts +1 -0
  86. package/dist/generated/settingsSchemaSafetyMergeSpec.js +95 -0
  87. package/dist/generated/settingsSchemaSettingsSources.d.ts +1 -0
  88. package/dist/generated/settingsSchemaSettingsSources.js +58 -0
  89. package/dist/generated/settingsSchemaTables.d.ts +2 -0
  90. package/dist/generated/settingsSchemaTables.js +13 -0
  91. package/dist/generated/settingsSchemaUrlPattern.d.ts +1 -0
  92. package/dist/generated/settingsSchemaUrlPattern.js +183 -0
  93. package/dist/headlessPermissionModeWire.d.ts +18 -2
  94. package/dist/headlessPermissionModeWire.js +30 -19
  95. package/dist/hitl/allowRuleShadow.js +7 -5
  96. package/dist/hitl/approvalCardReading.d.ts +3 -0
  97. package/dist/hitl/approvalCardReading.js +17 -0
  98. package/dist/hitl/approvalCompleteParked.js +1 -1
  99. package/dist/hitl/approvalDelivery.d.ts +87 -0
  100. package/dist/hitl/approvalDelivery.js +193 -0
  101. package/dist/hitl/approvalResolution.d.ts +11 -0
  102. package/dist/hitl/approvalResolution.js +50 -11
  103. package/dist/hitl/askClassPair.d.ts +6 -0
  104. package/dist/hitl/askClassPair.js +30 -3
  105. package/dist/hitl/askParkAutoReopenBlock.d.ts +30 -0
  106. package/dist/hitl/askParkAutoReopenBlock.js +117 -0
  107. package/dist/hitl/askParkRowRouting.js +4 -1
  108. package/dist/hitl/attributionLadder.d.ts +42 -3
  109. package/dist/hitl/attributionLadder.js +79 -8
  110. package/dist/hitl/automaticAnswerVerdict.d.ts +6 -1
  111. package/dist/hitl/automaticAnswerVerdict.js +46 -11
  112. package/dist/hitl/crashConverged.js +2 -2
  113. package/dist/hitl/decisionConflict.d.ts +6 -2
  114. package/dist/hitl/decisionConflict.js +24 -9
  115. package/dist/hitl/decisionRefusal.d.ts +20 -10
  116. package/dist/hitl/decisionRefusal.js +99 -54
  117. package/dist/hitl/decisionSend.d.ts +3 -0
  118. package/dist/hitl/decisionSend.js +87 -103
  119. package/dist/hitl/frameRouter.d.ts +1 -0
  120. package/dist/hitl/frameRouter.js +9 -2
  121. package/dist/hitl/hitlBridge.d.ts +18 -6
  122. package/dist/hitl/hitlBridge.js +41 -37
  123. package/dist/hitl/livePendingAsk.js +4 -3
  124. package/dist/hitl/noAllowCause.js +1 -1
  125. package/dist/hitl/parkResolver.js +3 -2
  126. package/dist/hitl/persistedRulesWire.js +1 -0
  127. package/dist/hitl/planReviewWire.d.ts +4 -0
  128. package/dist/hitl/planReviewWire.js +59 -30
  129. package/dist/hitl/resumeRunningCard.d.ts +3 -2
  130. package/dist/hitl/resumeRunningCard.js +17 -11
  131. package/dist/hitl/sessionPolicyDeliverable.d.ts +5 -2
  132. package/dist/hitl/sessionPolicyDeliverable.js +62 -29
  133. package/dist/hitl/sessionPolicyWire.d.ts +13 -3
  134. package/dist/hitl/sessionPolicyWire.js +81 -16
  135. package/dist/hitl/standingRows.js +1 -1
  136. package/dist/hitl/toolApprovalWire.d.ts +9 -10
  137. package/dist/hitl/toolApprovalWire.js +72 -54
  138. package/dist/hookMatcherVerdict.d.ts +2 -0
  139. package/dist/hookMatcherVerdict.js +12 -0
  140. package/dist/hooksCompactTransition.d.ts +19 -0
  141. package/dist/hooksCompactTransition.js +41 -0
  142. package/dist/hooksWireCaps.d.ts +1 -1
  143. package/dist/hooksWireCaps.js +202 -203
  144. package/dist/host.d.ts +1 -14
  145. package/dist/host.js +0 -8
  146. package/dist/hostCallbackGuard.d.ts +1 -0
  147. package/dist/hostCallbackGuard.js +1 -1
  148. package/dist/hostSettingsSource.d.ts +172 -0
  149. package/dist/hostSettingsSource.js +675 -0
  150. package/dist/hostTurnSettings.d.ts +73 -17
  151. package/dist/hostTurnSettings.js +594 -97
  152. package/dist/httpHookPolicy.d.ts +37 -0
  153. package/dist/httpHookPolicy.js +176 -0
  154. package/dist/humanTurn.d.ts +2 -1
  155. package/dist/humanTurn.js +37 -7
  156. package/dist/humanTurnRead.js +4 -3
  157. package/dist/humanTurnSentences.d.ts +10 -0
  158. package/dist/humanTurnSentences.js +74 -0
  159. package/dist/i18n/messages.en.d.ts +184 -2
  160. package/dist/i18n/messages.en.js +187 -5
  161. package/dist/i18n/messages.zh.js +197 -5
  162. package/dist/i18n/translate.js +3 -3
  163. package/dist/index.d.ts +69 -15
  164. package/dist/index.js +45 -13
  165. package/dist/inheritEnvCapability.d.ts +3 -1
  166. package/dist/inheritEnvCapability.js +31 -17
  167. package/dist/inheritEnvWire.d.ts +2 -1
  168. package/dist/inheritEnvWire.js +11 -5
  169. package/dist/interactiveToolsWire.d.ts +4 -2
  170. package/dist/interactiveToolsWire.js +5 -5
  171. package/dist/jsonFaithful.d.ts +20 -0
  172. package/dist/jsonFaithful.js +152 -0
  173. package/dist/limitsWire.d.ts +7 -2
  174. package/dist/limitsWire.js +19 -13
  175. package/dist/liveInitToolFace.d.ts +6 -1
  176. package/dist/liveInitToolFace.js +5 -3
  177. package/dist/liveModelCatalog.d.ts +22 -0
  178. package/dist/liveModelCatalog.js +132 -18
  179. package/dist/mcpPanel.js +1 -1
  180. package/dist/mcpProbeCapability.js +2 -2
  181. package/dist/mcpStatusSupersetKeys.d.ts +24 -0
  182. package/dist/mcpStatusSupersetKeys.js +45 -0
  183. package/dist/mcpToolToggles.js +2 -1
  184. package/dist/mcpWireCaps.d.ts +39 -1
  185. package/dist/mcpWireCaps.js +254 -50
  186. package/dist/memoryComplianceCapability.js +2 -2
  187. package/dist/memoryOriginCapability.js +2 -2
  188. package/dist/model/catalogDefault.d.ts +24 -0
  189. package/dist/model/catalogDefault.js +4 -0
  190. package/dist/model/liveCatalogShape.js +5 -4
  191. package/dist/model/modelsPolicy.js +4 -3
  192. package/dist/model/onboardJudgement.d.ts +1 -0
  193. package/dist/model/onboardJudgement.js +1 -1
  194. package/dist/model/subagentModelWord.js +2 -2
  195. package/dist/modelCapabilityProbe.js +6 -6
  196. package/dist/modelIdentityResolvability.d.ts +10 -1
  197. package/dist/modelIdentityResolvability.js +62 -39
  198. package/dist/modsKernelIdentity.d.ts +10 -0
  199. package/dist/modsKernelIdentity.js +103 -0
  200. package/dist/modsKernelTransit.d.ts +8 -0
  201. package/dist/modsKernelTransit.js +6 -0
  202. package/dist/notifications.d.ts +30 -12
  203. package/dist/notifications.js +241 -53
  204. package/dist/outputStyleSeatCapability.js +2 -2
  205. package/dist/ownKey.d.ts +11 -0
  206. package/dist/ownKey.js +164 -3
  207. package/dist/panelReduce.js +1 -1
  208. package/dist/peerFrames.d.ts +1 -1
  209. package/dist/peerFrames.js +6 -2
  210. package/dist/peerLaneCapability.js +2 -2
  211. package/dist/permissionModesCapability.js +4 -4
  212. package/dist/permissionRuleIssue.js +2 -0
  213. package/dist/permissionRulesWriteCapability.js +2 -2
  214. package/dist/permissionsAllowGrantCapability.js +2 -2
  215. package/dist/permissionsDeclaration.d.ts +43 -4
  216. package/dist/permissionsDeclaration.js +102 -35
  217. package/dist/pluginHooksWire.d.ts +20 -4
  218. package/dist/pluginHooksWire.js +92 -53
  219. package/dist/prepareRefusal.d.ts +3 -2
  220. package/dist/prepareRefusal.js +27 -9
  221. package/dist/printInitToolFace.js +2 -2
  222. package/dist/printModelStatus.js +1 -1
  223. package/dist/projectMemory.d.ts +32 -0
  224. package/dist/projectMemory.js +70 -0
  225. package/dist/promptBlockedCopy.d.ts +2 -1
  226. package/dist/promptBlockedCopy.js +2 -1
  227. package/dist/promptDelivery.d.ts +23 -3
  228. package/dist/promptDelivery.js +169 -30
  229. package/dist/providerRejection.d.ts +19 -1
  230. package/dist/providerRejection.js +75 -4
  231. package/dist/queuedDelivery.d.ts +48 -0
  232. package/dist/queuedDelivery.js +233 -0
  233. package/dist/reattachWindow.d.ts +94 -0
  234. package/dist/reattachWindow.js +127 -0
  235. package/dist/request/printNotification.d.ts +1 -1
  236. package/dist/request/printNotification.js +5 -1
  237. package/dist/request/submissionIdentity.d.ts +37 -0
  238. package/dist/request/submissionIdentity.js +65 -0
  239. package/dist/request/taskRequest.d.ts +12 -4
  240. package/dist/request/taskRequest.js +221 -152
  241. package/dist/resultFrameKeys.d.ts +1 -0
  242. package/dist/resultFrameKeys.js +4 -1
  243. package/dist/retryStatus.d.ts +8 -0
  244. package/dist/retryStatus.js +57 -9
  245. package/dist/rewindArchiveCapability.js +2 -2
  246. package/dist/rewindEngineAction.d.ts +2 -0
  247. package/dist/rewindEngineAction.js +23 -1
  248. package/dist/rowKind.d.ts +36 -0
  249. package/dist/rowKind.js +97 -0
  250. package/dist/ruleCompileVerdict.d.ts +18 -0
  251. package/dist/ruleCompileVerdict.js +67 -2
  252. package/dist/ruleReadings.d.ts +58 -0
  253. package/dist/ruleReadings.js +132 -0
  254. package/dist/ruleRefusalSentence.d.ts +4 -0
  255. package/dist/ruleRefusalSentence.js +9 -3
  256. package/dist/runCancelContext.d.ts +0 -1
  257. package/dist/runCancelContext.js +1 -2
  258. package/dist/runTerminal.d.ts +5 -0
  259. package/dist/runTerminal.js +52 -17
  260. package/dist/sandboxWire.d.ts +1 -1
  261. package/dist/sandboxWire.js +4 -6
  262. package/dist/scenarioRefusal.js +1 -1
  263. package/dist/scenarioSkills.d.ts +20 -0
  264. package/dist/scenarioSkills.js +72 -0
  265. package/dist/scenarioWire.d.ts +5 -2
  266. package/dist/scenarioWire.js +9 -9
  267. package/dist/sealedKeyCapability.js +2 -2
  268. package/dist/seam.d.ts +2 -0
  269. package/dist/seam.js +2 -2
  270. package/dist/seatContract.d.ts +46 -1
  271. package/dist/seatContract.js +49 -19
  272. package/dist/selfOrchestrationDenial.js +1 -1
  273. package/dist/sessionPolicyCapability.js +2 -2
  274. package/dist/sessionRulesChildrenReadLive.d.ts +6 -0
  275. package/dist/sessionRulesChildrenReadLive.js +5 -0
  276. package/dist/sessionRulesNamespaceFormsCapability.d.ts +12 -0
  277. package/dist/sessionRulesNamespaceFormsCapability.js +29 -0
  278. package/dist/sessionSyncFileHistoryCapability.js +2 -2
  279. package/dist/settingsCredentialKeyPaths.js +60 -5
  280. package/dist/settingsHooksSalvage.d.ts +1 -0
  281. package/dist/settingsHooksSalvage.js +7 -1
  282. package/dist/settingsLayerAdmission.d.ts +4 -0
  283. package/dist/settingsLayerAdmission.js +16 -0
  284. package/dist/skillToolListsCapability.js +6 -5
  285. package/dist/skillsWireCaps.d.ts +14 -0
  286. package/dist/skillsWireCaps.js +47 -16
  287. package/dist/slashCommandGate.d.ts +24 -0
  288. package/dist/slashCommandGate.js +74 -0
  289. package/dist/slashCommandTable.d.ts +14 -0
  290. package/dist/slashCommandTable.js +99 -0
  291. package/dist/sqlEngineCapability.js +2 -2
  292. package/dist/steerPriorityCapability.js +2 -2
  293. package/dist/storePostureCapability.js +2 -2
  294. package/dist/subagent/agentStateDetail.js +1 -1
  295. package/dist/subagent/engineDelegatedPrompt.d.ts +9 -0
  296. package/dist/subagent/engineDelegatedPrompt.js +38 -7
  297. package/dist/subagent/engineRowStopGate.js +2 -2
  298. package/dist/subagent/engineSubagentResume.js +3 -3
  299. package/dist/subagent/engineTaskHandleWire.d.ts +1 -0
  300. package/dist/subagent/engineTaskHandleWire.js +10 -0
  301. package/dist/submitFailure.d.ts +8 -0
  302. package/dist/submitFailure.js +17 -0
  303. package/dist/supportFloor.d.ts +1 -0
  304. package/dist/supportFloor.js +7 -0
  305. package/dist/terminationIntent.d.ts +55 -0
  306. package/dist/terminationIntent.js +352 -0
  307. package/dist/toolHistoryMismatch.d.ts +8 -0
  308. package/dist/toolHistoryMismatch.js +37 -6
  309. package/dist/toolResult.d.ts +13 -3
  310. package/dist/toolResult.js +158 -9
  311. package/dist/toolResultContent.d.ts +13 -0
  312. package/dist/toolResultContent.js +82 -7
  313. package/dist/toolRoster.d.ts +18 -0
  314. package/dist/toolRoster.js +64 -0
  315. package/dist/turnFailurePresentation.js +27 -90
  316. package/dist/usageLimitAutoResume.d.ts +74 -0
  317. package/dist/usageLimitAutoResume.js +227 -0
  318. package/dist/userAttachmentEnvelope.js +1 -1
  319. package/dist/userAttachmentSeat.js +5 -5
  320. package/dist/userInvokedSkillsCapability.js +2 -2
  321. package/dist/webSearchBackendCapability.js +2 -2
  322. package/dist/wireErrorTriage.js +99 -50
  323. package/dist/wireFailureShape.d.ts +25 -1
  324. package/dist/wireFailureShape.js +92 -5
  325. package/dist/wireRefusalCopy.d.ts +24 -1
  326. package/dist/wireRefusalCopy.js +253 -32
  327. package/dist/wiringFleetDoctor.d.ts +3 -0
  328. package/dist/wiringFleetDoctor.js +21 -0
  329. package/dist/workflow.d.ts +2 -1
  330. package/dist/workflow.js +38 -1
  331. package/dist/workflowClient.d.ts +2 -7
  332. package/dist/workflowsJournalCapability.js +2 -2
  333. package/dist/writeProtectionCapability.js +2 -2
  334. package/docs/INTEGRATION-CLIENTS.md +607 -181
  335. package/package.json +14 -3
@@ -1,11 +1,11 @@
1
1
  import { msg, renderMessage } from './i18n/translate.js';
2
- import { classifyTurnWireError, effectiveWireErrorCode, isPreStreamDrainingReject } from './wireErrorTriage.js';
2
+ import { classifyTurnWireError, isPreStreamDrainingReject } from './wireErrorTriage.js';
3
3
  import { isSseIdleError } from './sseIdleTriage.js';
4
4
  import { isCodeClassifiedGateFailure } from './gateFailureCodes.js';
5
5
  import { CORRUPT_ROW_ERROR_CODE, CORRUPT_SESSION_ERROR_CODE, MEMORY_CONTROL_PLANE_CORRUPT, SCENARIO_ASSIGNMENT_UNKNOWN_ERROR_CODE } from './engineErrorCodes.js';
6
- import { admissionWallRefusalContent, admissionWallRefusalFromError, bodyShapeRefusalFromError, bodyShapeRefusalTouchesSettings, fleetLeaseUnavailableContent, fleetLeaseUnavailableFromError, hostPostureRefusalContent, hostPostureRefusalFromError, fieldLimitRefusalContent, fieldLimitRefusalFromError, toolDeclarationRefusalContent, toolDeclarationRefusalFromError, usageWindowExhaustedContent, usageWindowExhaustedFromError, userAttachmentRefusalFromError, } from './wireRefusalCopy.js';
6
+ import { admissionWallRefusalContent, admissionWallRefusalFromError, bodyShapeRefusalFromError, bodyShapeRefusalTouchesSettings, fleetLeaseUnavailableContent, fleetLeaseUnavailableFromError, hostPostureRefusalContent, hostPostureRefusalFromError, fieldLimitRefusalContent, fieldLimitRefusalFromError, toolDeclarationRefusalContent, toolDeclarationRefusalFromError, usageWindowExhaustedContent, usageWindowExhaustedFromError, quotaExhaustedContent, quotaExhaustedFromError, userAttachmentRefusalFromError, } from './wireRefusalCopy.js';
7
7
  import { THROWN_SLOT_UNREADABLE, readErrorNumber, readThrownSlot, wireFailureTextsOf } from './wireFailureShape.js';
8
- import { provablyNotSent } from './engineWireFor.js';
8
+ import { effectiveCodeOf, ownReadingSlot, provablyNotSent, triageReadingOf } from './engineWireFor.js';
9
9
  import { corruptStoredRowContent, scenarioDenyFromError, scenarioNotAllowedContent } from './wireErrorTriage.js';
10
10
  import { checkpointUnsupportedVersionContent, checkpointUnsupportedVersionFromError, requireExistingSessionRefusalContent, requireExistingSessionRefusalFromError, resumeContextUnavailableContent, resumeContextUnavailableFromError, resumePolicyBlockContent, resumePolicyBlockFromError, resumeRefusalContent, resumeRefusalFromError, } from './resumeRefusalCopy.js';
11
11
  import { resumeReopenContent, resumeReopenFromError } from './hitl/suspendedReopen.js';
@@ -33,6 +33,7 @@ const TURN_FAILURE_HEADLINE_KEYS = Object.freeze({
33
33
  timeout: 'notice.failure.headline.timeout',
34
34
  parked: 'notice.failure.headline.parked',
35
35
  internal: 'notice.failure.headline.internal',
36
+ cause_unreadable: 'notice.failure.headline.causeUnreadable',
36
37
  });
37
38
  function waitSecOf(err) {
38
39
  const ms = readThrownSlot(err, 'retryAfterMs', 'data');
@@ -61,12 +62,12 @@ function isIdleWatchdog(err) {
61
62
  }
62
63
  const DETERMINISTIC_SERVER_CODES = new Set([CORRUPT_SESSION_ERROR_CODE, CORRUPT_ROW_ERROR_CODE, SCENARIO_ASSIGNMENT_UNKNOWN_ERROR_CODE, MEMORY_CONTROL_PLANE_CORRUPT]);
63
64
  const BROWSER_FETCH_FAILURE = /\bfailed to fetch\b|\bnetworkerror\b|\bnetwork error\b|\bload failed\b/i;
64
- function httpShapeOf(err, verdict) {
65
+ function httpShapeOf(verdict, code) {
65
66
  const status = verdict.status;
66
- const code = effectiveWireErrorCode(err) ?? verdict.errorCode;
67
67
  if (verdict.sessionUnreadable === true || verdict.storedRowWhere !== undefined)
68
68
  return { category: 'server_error', offer: false };
69
- if (toolDeclarationRefusalFromError(err) !== null)
69
+ const facts = { status: verdict.status, ...(verdict.errorCode !== undefined ? { errorCode: verdict.errorCode } : {}) };
70
+ if (toolDeclarationRefusalFromError(facts) !== null)
70
71
  return { category: 'invalid_request', offer: false };
71
72
  if (code !== undefined && DETERMINISTIC_SERVER_CODES.has(code))
72
73
  return { category: 'server_error', offer: false };
@@ -74,7 +75,7 @@ function httpShapeOf(err, verdict) {
74
75
  return { category: 'rate_limited', offer: false };
75
76
  if (code === 'budget.precall' || code === 'budget.exceeded')
76
77
  return { category: 'billing', offer: false };
77
- if (code === 'draining' || verdict.leaseUnavailable === true || isPreStreamDrainingReject(err))
78
+ if (code === 'draining' || verdict.leaseUnavailable === true || isPreStreamDrainingReject(facts))
78
79
  return { category: 'server_error', offer: true };
79
80
  if (status === 501 || (code !== undefined && code.startsWith('capability.')))
80
81
  return { category: 'capability_unavailable', offer: false };
@@ -92,6 +93,13 @@ function httpShapeOf(err, verdict) {
92
93
  return { category: 'invalid_request', offer: false };
93
94
  return { category: 'internal', offer: false };
94
95
  }
96
+ function answeringSubjectOf(err, verdict) {
97
+ if (verdict.kind !== 'http')
98
+ return { subject: err, code: undefined };
99
+ const answered = triageReadingOf(verdict);
100
+ const a = ownReadingSlot(answered, 'answer');
101
+ return a !== undefined && a !== THROWN_SLOT_UNREADABLE ? { subject: a.layer, code: effectiveCodeOf(a.code) ?? verdict.errorCode } : { subject: err, code: verdict.errorCode };
102
+ }
95
103
  function connectionLostBeforeSend(err, evidence) {
96
104
  if (readThrownSlot(evidence, 'bound', 'data') === true || readThrownSlot(evidence, 'reopened', 'data') === true)
97
105
  return false;
@@ -99,12 +107,13 @@ function connectionLostBeforeSend(err, evidence) {
99
107
  }
100
108
  export function turnFailurePresentation(err, evidence, notesCtx, lang) {
101
109
  const verdict = classifyTurnWireError(err);
110
+ const { subject, code: httpCode } = answeringSubjectOf(err, verdict);
102
111
  let shape;
103
112
  let headlineKey;
104
113
  let detail;
105
114
  let name;
106
115
  if (verdict.kind === 'http') {
107
- shape = httpShapeOf(err, verdict);
116
+ shape = httpShapeOf(verdict, httpCode);
108
117
  detail = verdict.message;
109
118
  if (shape.category === 'internal')
110
119
  headlineKey = TURN_FAILURE_HEADLINE_KEYS.internal;
@@ -132,17 +141,19 @@ export function turnFailurePresentation(err, evidence, notesCtx, lang) {
132
141
  detail = verdict.detail;
133
142
  }
134
143
  else {
135
- shape = { category: 'internal', offer: false };
136
- headlineKey = TURN_FAILURE_HEADLINE_KEYS.internal;
144
+ const triaged = triageReadingOf(verdict);
145
+ const causeUnreadable = ownReadingSlot(triaged, 'answer') === THROWN_SLOT_UNREADABLE || ownReadingSlot(triaged, 'chainEnd') === 'unreadable';
146
+ shape = { category: 'internal', offer: causeUnreadable };
147
+ headlineKey = causeUnreadable ? TURN_FAILURE_HEADLINE_KEYS.cause_unreadable : TURN_FAILURE_HEADLINE_KEYS.internal;
137
148
  detail = verdict.detail;
138
149
  name = verdict.name;
139
150
  }
140
151
  const status = verdict.kind === 'http' ? verdict.status : undefined;
141
- const errorCode = verdict.kind === 'http' ? (effectiveWireErrorCode(err) ?? verdict.errorCode) : undefined;
142
- const wireRetriable = readThrownSlot(err, 'retriable', 'data') === true && !isCodeClassifiedGateFailure(errorCode, true);
152
+ const errorCode = verdict.kind === 'http' ? httpCode : undefined;
153
+ const wireRetriable = readThrownSlot(subject, 'retriable', 'data') === true && !isCodeClassifiedGateFailure(errorCode, true);
143
154
  const retry = wireRetriable && shape.category !== 'parked' ? { offer: true, basis: 'wire' } : { offer: shape.offer, basis: 'category' };
144
- const waitSec = waitSecOf(err);
145
- const chain = turnFailureNotesOf(err, verdict, notesCtx, waitSec, lang);
155
+ const waitSec = waitSecOf(subject);
156
+ const chain = turnFailureNotesOf(subject, verdict, notesCtx, waitSec, lang);
146
157
  const headline = headlineKey !== undefined ? renderMessage(msg(headlineKey), lang) : undefined;
147
158
  return Object.freeze({
148
159
  category: shape.category,
@@ -158,80 +169,6 @@ export function turnFailurePresentation(err, evidence, notesCtx, lang) {
158
169
  ...(chain.waitNote !== undefined ? { waitNote: chain.waitNote } : {}),
159
170
  });
160
171
  }
161
- function quotaDetailOf(err) {
162
- if (readThrownSlot(err, 'status', 'data') !== 429 || readThrownSlot(err, 'errorCode', 'data') !== 'quota_exhausted')
163
- return null;
164
- const detail = readThrownSlot(err, 'detail', 'data');
165
- const slot = (key) => (typeof detail === 'object' && detail !== null ? readThrownSlot(detail, key, 'data') : undefined);
166
- const windowType = slot('windowType');
167
- const remaining = slot('remaining');
168
- const resetAt = slot('resetAt');
169
- const isEstimate = slot('isEstimate');
170
- const pool = slot('pool');
171
- return {
172
- ...(windowType === 'fiveHour' || windowType === 'weekly' || windowType === 'budget' ? { windowType } : {}),
173
- ...(typeof remaining === 'number' && Number.isFinite(remaining) ? { remaining } : {}),
174
- ...(typeof resetAt === 'string' || resetAt === null ? { resetAt } : {}),
175
- ...(typeof isEstimate === 'boolean' ? { isEstimate } : {}),
176
- ...(typeof pool === 'string' && pool.length > 0 ? { pool } : {}),
177
- };
178
- }
179
- const MONTH_KEYS = [
180
- 'notice.failure.month.jan',
181
- 'notice.failure.month.feb',
182
- 'notice.failure.month.mar',
183
- 'notice.failure.month.apr',
184
- 'notice.failure.month.may',
185
- 'notice.failure.month.jun',
186
- 'notice.failure.month.jul',
187
- 'notice.failure.month.aug',
188
- 'notice.failure.month.sep',
189
- 'notice.failure.month.oct',
190
- 'notice.failure.month.nov',
191
- 'notice.failure.month.dec',
192
- ];
193
- function quotaResetInstant(resetAtIso, nowMs, lang) {
194
- const t = Date.parse(resetAtIso);
195
- if (!Number.isFinite(t))
196
- return undefined;
197
- const d = new Date(t);
198
- const now = new Date(nowMs);
199
- const hm = `${String(d.getHours()).padStart(2, '0')}:${String(d.getMinutes()).padStart(2, '0')}`;
200
- const sameDay = d.getFullYear() === now.getFullYear() && d.getMonth() === now.getMonth() && d.getDate() === now.getDate();
201
- if (sameDay)
202
- return hm;
203
- const monthKey = MONTH_KEYS[d.getMonth()];
204
- return renderMessage(msg('notice.failure.quota.instantOtherDay', { month: monthKey === undefined ? '' : msg(monthKey), day: d.getDate(), time: hm }), lang);
205
- }
206
- function quotaExhaustedLine(detail, nowMs, lang) {
207
- const part = (key, params) => renderMessage(msg(key, params), lang);
208
- const parts = [];
209
- if (detail.windowType === 'fiveHour')
210
- parts.push(part('notice.failure.quota.fiveHour'));
211
- else if (detail.windowType === 'weekly')
212
- parts.push(part('notice.failure.quota.weekly'));
213
- else if (detail.windowType === 'budget') {
214
- if (detail.pool === 'personal')
215
- parts.push(part('notice.failure.quota.budgetPersonal'));
216
- else if (detail.pool)
217
- parts.push(part('notice.failure.quota.budgetPool', { pool: detail.pool }));
218
- else
219
- parts.push(part('notice.failure.quota.budget'));
220
- }
221
- else
222
- parts.push(part('notice.failure.quota.usage'));
223
- if (typeof detail.remaining === 'number' && Number.isFinite(detail.remaining)) {
224
- parts.push(detail.windowType === 'budget'
225
- ? part('notice.failure.quota.remainingBudget', { amount: `$${(detail.remaining / 1_000_000).toFixed(2)}` })
226
- : part('notice.failure.quota.remainingTokens', { count: detail.remaining.toLocaleString('en-US') }));
227
- }
228
- const resetText = typeof detail.resetAt === 'string' ? quotaResetInstant(detail.resetAt, nowMs, lang) : undefined;
229
- if (resetText)
230
- parts.push(detail.isEstimate === false ? part('notice.failure.quota.resetAt', { time: resetText }) : part('notice.failure.quota.resetAround', { time: resetText }));
231
- parts.push(part('notice.failure.quota.refresh'));
232
- parts.push(part('notice.failure.quota.noBypass'));
233
- return parts.join(part('notice.failure.quota.join'));
234
- }
235
172
  function protectiveSettingsAtRisk(sent, lang) {
236
173
  const out = [];
237
174
  const permsRaw = sent.permissions;
@@ -282,9 +219,9 @@ function turnFailureNotesOf(err, verdict, ctx, waitSec, lang) {
282
219
  try {
283
220
  const sentRequest = ctx === undefined ? undefined : ctx.sentRequest;
284
221
  const nowMs = ctx !== undefined && typeof ctx.nowMs === 'number' && Number.isFinite(ctx.nowMs) ? ctx.nowMs : Date.now();
285
- const quota = quotaDetailOf(err);
222
+ const quota = quotaExhaustedFromError(err);
286
223
  if (quota)
287
- lines.push(quotaExhaustedLine(quota, nowMs, lang));
224
+ lines.push(quotaExhaustedContent(quota, nowMs, lang));
288
225
  const scenarioDeny = quota ? null : scenarioDenyFromError(err);
289
226
  if (scenarioDeny)
290
227
  lines.push(scenarioNotAllowedContent(scenarioDeny, ctx?.requestedScenario));
@@ -0,0 +1,74 @@
1
+ import type { UiLanguage } from './env/uiLanguage.js';
2
+ import { type QuotaExhaustedView } from './wireRefusalCopy.js';
3
+ export declare const AUTO_RESUME_HORIZON_MS: number;
4
+ export declare const AUTO_RESUME_REPEAT_BREAKER_HITS = 2;
5
+ export declare const AUTO_RESUME_IMMINENT_MS = 60000;
6
+ export type AutoResumePhase = 'idle' | 'offered' | 'armed' | 'fired' | 'stale' | 'disabled' | 'horizon';
7
+ export type AutoResumeReason = 'context-changed' | 'not-replayable' | 'user-escaped' | 'user-chose-wait' | 'user-cancelled-auto' | 'repeated-usage-limit-hits' | 'no-reset-instant' | 'reset-horizon-exceeded' | 'prompt-superseded' | 'reset-without-auto-resume';
8
+ export interface AutoResumeState {
9
+ readonly phase: AutoResumePhase;
10
+ readonly prompt: string | null;
11
+ readonly resumeAtMs: number | null;
12
+ readonly windowType: 'fiveHour' | 'weekly' | 'budget' | null;
13
+ readonly consecutiveHits: number;
14
+ readonly reason: AutoResumeReason | null;
15
+ readonly contextId: string | null;
16
+ }
17
+ export type RateLimitOption = 'cancel' | 'auto-resume' | 'cancel-auto-resume';
18
+ export type AutoResumeEvent = {
19
+ readonly type: 'usage-limit-hit';
20
+ readonly detail: QuotaExhaustedView;
21
+ readonly prompt: string;
22
+ readonly contextId?: string;
23
+ readonly replayable?: boolean;
24
+ } | {
25
+ readonly type: 'menu-choice';
26
+ readonly option: RateLimitOption;
27
+ readonly contextId?: string;
28
+ } | {
29
+ readonly type: 'escape';
30
+ } | {
31
+ readonly type: 'tick';
32
+ readonly contextId?: string;
33
+ } | {
34
+ readonly type: 'user-submitted';
35
+ } | {
36
+ readonly type: 'context-changed';
37
+ } | {
38
+ readonly type: 'turn-completed';
39
+ };
40
+ export declare const AUTO_RESUME_COPY_WORDS: readonly ["fired", "reset", "breaker", "superseded", "not-replayable", "context-changed", "escaped"];
41
+ export type AutoResumeCopyWord = (typeof AUTO_RESUME_COPY_WORDS)[number];
42
+ export type AutoResumeAction = {
43
+ readonly type: 'schedule';
44
+ readonly atMs: number;
45
+ } | {
46
+ readonly type: 'clear-schedule';
47
+ } | {
48
+ readonly type: 'resubmit';
49
+ readonly prompt: string;
50
+ } | {
51
+ readonly type: 'revoke-resubmit';
52
+ } | {
53
+ readonly type: 'notify';
54
+ readonly kind: 'fired' | 'stale' | 'disabled';
55
+ readonly copy: AutoResumeCopyWord;
56
+ readonly message: string;
57
+ };
58
+ export interface AutoResumeStep {
59
+ readonly state: AutoResumeState;
60
+ readonly actions: readonly AutoResumeAction[];
61
+ }
62
+ export declare function autoResumeCopy(word: AutoResumeCopyWord, lang?: UiLanguage): string;
63
+ export declare function autoResumeAtMs(resetAt: string | null | undefined): number | null;
64
+ export declare function initialAutoResumeState(): AutoResumeState;
65
+ export declare function autoResumeTransition(state: AutoResumeState, event: AutoResumeEvent, nowMs: number): AutoResumeStep;
66
+ export declare function autoResumeArmedRow(state: AutoResumeState, nowMs: number, lang?: UiLanguage): string | undefined;
67
+ export declare function autoResumeNoticeRow(state: AutoResumeState, lang?: UiLanguage): string | undefined;
68
+ export interface RateLimitOptionRow {
69
+ readonly value: RateLimitOption;
70
+ readonly label: string;
71
+ readonly disabled: boolean;
72
+ readonly disabledReason?: string;
73
+ }
74
+ export declare function rateLimitOptionRows(state: AutoResumeState, lang?: UiLanguage): readonly RateLimitOptionRow[];
@@ -0,0 +1,227 @@
1
+ import { msg, renderMessage } from './i18n/translate.js';
2
+ import { usableClockMs } from './clockReading.js';
3
+ import { quotaResetInstantText } from './wireRefusalCopy.js';
4
+ export const AUTO_RESUME_HORIZON_MS = 24 * 60 * 60 * 1000;
5
+ export const AUTO_RESUME_REPEAT_BREAKER_HITS = 2;
6
+ export const AUTO_RESUME_IMMINENT_MS = 60_000;
7
+ export const AUTO_RESUME_COPY_WORDS = Object.freeze(['fired', 'reset', 'breaker', 'superseded', 'not-replayable', 'context-changed', 'escaped']);
8
+ const COPY_KEYS = {
9
+ fired: 'notice.usageLimit.autoResume.fired',
10
+ reset: 'notice.usageLimit.autoResume.reset',
11
+ breaker: 'notice.usageLimit.autoResume.breaker',
12
+ superseded: 'notice.usageLimit.autoResume.superseded',
13
+ 'not-replayable': 'notice.usageLimit.autoResume.notReplayable',
14
+ 'context-changed': 'notice.usageLimit.autoResume.contextChanged',
15
+ escaped: 'notice.usageLimit.autoResume.escaped',
16
+ };
17
+ export function autoResumeCopy(word, lang) {
18
+ return Object.hasOwn(COPY_KEYS, word) ? renderMessage(msg(COPY_KEYS[word]), lang) : '';
19
+ }
20
+ const notifyAction = (kind, copy) => ({ type: 'notify', kind, copy, message: autoResumeCopy(copy) });
21
+ export function autoResumeAtMs(resetAt) {
22
+ if (typeof resetAt !== 'string')
23
+ return null;
24
+ const t = Date.parse(resetAt);
25
+ return Number.isFinite(t) ? t : null;
26
+ }
27
+ export function initialAutoResumeState() {
28
+ return Object.freeze({ phase: 'idle', prompt: null, resumeAtMs: null, windowType: null, consecutiveHits: 0, reason: null, contextId: null });
29
+ }
30
+ function noticeSchedule(resumeAtMs, nowMs) {
31
+ if (resumeAtMs === null || usableClockMs(nowMs) === null || resumeAtMs - nowMs > AUTO_RESUME_HORIZON_MS)
32
+ return [{ type: 'clear-schedule' }];
33
+ return [{ type: 'schedule', atMs: resumeAtMs }];
34
+ }
35
+ function freezeActions(actions) {
36
+ return Object.freeze(actions.map((a) => Object.freeze({ ...a })));
37
+ }
38
+ function settle(state, patch, actions = []) {
39
+ return Object.freeze({ state: Object.freeze({ ...state, ...patch }), actions: freezeActions(actions) });
40
+ }
41
+ const withActions = (state, actions) => Object.freeze({ state, actions: freezeActions(actions) });
42
+ const NO_ACTIONS = Object.freeze([]);
43
+ const NO_CHANGE = (state) => Object.freeze({ state, actions: NO_ACTIONS });
44
+ const ctxOf = (v) => (typeof v === 'string' ? v : undefined);
45
+ function snapshotDetail(d) {
46
+ if (typeof d !== 'object' || d === null)
47
+ return {};
48
+ const raw = d;
49
+ const resetAt = raw.resetAt;
50
+ const windowType = raw.windowType;
51
+ return {
52
+ ...(typeof resetAt === 'string' ? { resetAt } : {}),
53
+ ...(windowType === 'fiveHour' || windowType === 'weekly' || windowType === 'budget' ? { windowType } : {}),
54
+ };
55
+ }
56
+ export function autoResumeTransition(state, event, nowMs) {
57
+ try {
58
+ if (typeof event !== 'object' || event === null)
59
+ return NO_CHANGE(state);
60
+ const raw = event;
61
+ const facts = { type: raw.type, detail: raw.detail, prompt: raw.prompt, contextId: raw.contextId, replayable: raw.replayable, option: raw.option };
62
+ return transition(state, facts, nowMs);
63
+ }
64
+ catch {
65
+ return NO_CHANGE(state);
66
+ }
67
+ }
68
+ function transition(state, event, nowMs) {
69
+ const clockOk = usableClockMs(nowMs) !== null;
70
+ switch (event.type) {
71
+ case 'usage-limit-hit': {
72
+ if (!clockOk)
73
+ return NO_CHANGE(state);
74
+ const detail = snapshotDetail(event.detail);
75
+ const hits = state.consecutiveHits + 1;
76
+ const resumeAtMs = autoResumeAtMs(detail.resetAt);
77
+ const windowType = detail.windowType ?? null;
78
+ const contextId = ctxOf(event.contextId) ?? null;
79
+ const base = { consecutiveHits: hits, resumeAtMs, windowType, contextId };
80
+ const prompt = typeof event.prompt === 'string' ? event.prompt : null;
81
+ const isOurs = state.prompt !== null && prompt === state.prompt;
82
+ if (state.phase === 'armed')
83
+ return settle(state, { consecutiveHits: hits }, []);
84
+ if (state.phase === 'fired' && !isOurs)
85
+ return settle(state, { consecutiveHits: hits }, []);
86
+ if (state.phase === 'fired' && hits >= AUTO_RESUME_REPEAT_BREAKER_HITS) {
87
+ return settle(state, { ...base, phase: 'disabled', reason: 'repeated-usage-limit-hits', prompt: null }, [{ type: 'clear-schedule' }, notifyAction('disabled', 'breaker')]);
88
+ }
89
+ if (event.replayable === false || prompt === null) {
90
+ return settle(state, { ...base, phase: 'disabled', reason: 'not-replayable', prompt: null }, noticeSchedule(resumeAtMs, nowMs));
91
+ }
92
+ if (resumeAtMs === null) {
93
+ return settle(state, { ...base, phase: 'disabled', reason: 'no-reset-instant', prompt: null }, [{ type: 'clear-schedule' }]);
94
+ }
95
+ if (resumeAtMs - nowMs > AUTO_RESUME_HORIZON_MS) {
96
+ return settle(state, { ...base, phase: 'horizon', reason: 'reset-horizon-exceeded', prompt }, [{ type: 'clear-schedule' }]);
97
+ }
98
+ return settle(state, { ...base, phase: 'offered', reason: null, prompt }, noticeSchedule(resumeAtMs, nowMs));
99
+ }
100
+ case 'menu-choice': {
101
+ const revokeIfFired = state.phase === 'fired' ? [{ type: 'revoke-resubmit' }] : [];
102
+ if (event.option === 'cancel') {
103
+ return settle(state, { phase: 'disabled', reason: 'user-chose-wait', prompt: null }, [...revokeIfFired, ...noticeSchedule(state.resumeAtMs, nowMs)]);
104
+ }
105
+ if (event.option === 'cancel-auto-resume') {
106
+ if (state.phase !== 'armed' && state.phase !== 'fired')
107
+ return NO_CHANGE(state);
108
+ return settle(state, { phase: 'disabled', reason: 'user-cancelled-auto', prompt: null }, [{ type: 'clear-schedule' }, ...revokeIfFired]);
109
+ }
110
+ if (event.option !== 'auto-resume')
111
+ return NO_CHANGE(state);
112
+ if (state.phase === 'armed')
113
+ return NO_CHANGE(state);
114
+ if (state.phase !== 'offered' && state.phase !== 'horizon')
115
+ return NO_CHANGE(state);
116
+ if (state.resumeAtMs === null || state.prompt === null)
117
+ return NO_CHANGE(state);
118
+ if (!clockOk)
119
+ return NO_CHANGE(state);
120
+ const authorizedIn = ctxOf(event.contextId);
121
+ return settle(state, { phase: 'armed', reason: null, ...(authorizedIn !== undefined ? { contextId: authorizedIn } : {}) }, [{ type: 'schedule', atMs: state.resumeAtMs }]);
122
+ }
123
+ case 'escape': {
124
+ if (state.phase === 'fired')
125
+ return settle(state, { phase: 'disabled', reason: 'user-escaped', prompt: null }, [{ type: 'clear-schedule' }, { type: 'revoke-resubmit' }]);
126
+ if (state.phase !== 'armed')
127
+ return NO_CHANGE(state);
128
+ return settle(state, { phase: 'disabled', reason: 'user-escaped', prompt: null }, [{ type: 'clear-schedule' }]);
129
+ }
130
+ case 'tick': {
131
+ if (state.resumeAtMs === null)
132
+ return NO_CHANGE(state);
133
+ if (!clockOk)
134
+ return NO_CHANGE(state);
135
+ if (nowMs < state.resumeAtMs) {
136
+ if (state.phase === 'armed' || state.phase === 'offered' || state.phase === 'horizon' || state.phase === 'disabled') {
137
+ return withActions(state, [{ type: 'schedule', atMs: state.resumeAtMs }]);
138
+ }
139
+ return NO_CHANGE(state);
140
+ }
141
+ if (state.contextId !== null && ctxOf(event.contextId) !== state.contextId) {
142
+ return settle(state, { phase: 'stale', reason: 'context-changed', prompt: null }, state.phase === 'armed' ? [{ type: 'clear-schedule' }, notifyAction('stale', 'context-changed')] : [{ type: 'clear-schedule' }]);
143
+ }
144
+ if (state.phase === 'armed') {
145
+ if (state.prompt === null) {
146
+ return settle(state, { phase: 'stale', reason: 'reset-without-auto-resume' }, [{ type: 'clear-schedule' }, notifyAction('stale', 'reset')]);
147
+ }
148
+ return settle(state, { phase: 'fired', reason: null }, [{ type: 'clear-schedule' }, { type: 'resubmit', prompt: state.prompt }, notifyAction('fired', 'fired')]);
149
+ }
150
+ if (state.phase === 'offered' || state.phase === 'horizon' || state.phase === 'disabled') {
151
+ return settle(state, { phase: 'stale', reason: 'reset-without-auto-resume', prompt: null }, [{ type: 'clear-schedule' }, notifyAction('stale', 'reset')]);
152
+ }
153
+ return NO_CHANGE(state);
154
+ }
155
+ case 'user-submitted': {
156
+ if (state.phase !== 'armed' && state.phase !== 'fired')
157
+ return NO_CHANGE(state);
158
+ return settle(state, { phase: 'stale', reason: 'prompt-superseded', prompt: null }, state.phase === 'fired' ? [{ type: 'clear-schedule' }, { type: 'revoke-resubmit' }] : [{ type: 'clear-schedule' }]);
159
+ }
160
+ case 'context-changed': {
161
+ if (state.phase !== 'armed' && state.phase !== 'fired' && state.phase !== 'offered' && state.phase !== 'horizon')
162
+ return NO_CHANGE(state);
163
+ return settle(state, { phase: 'stale', reason: 'context-changed', prompt: null }, [
164
+ { type: 'clear-schedule' },
165
+ ...(state.phase === 'fired' ? [{ type: 'revoke-resubmit' }] : []),
166
+ notifyAction('stale', 'context-changed'),
167
+ ]);
168
+ }
169
+ case 'turn-completed': {
170
+ if (state.phase === 'fired')
171
+ return settle(state, { ...initialAutoResumeState() });
172
+ if (state.phase === 'stale' || state.phase === 'disabled' || state.phase === 'horizon')
173
+ return settle(state, { ...initialAutoResumeState() });
174
+ return settle(state, { consecutiveHits: 0 });
175
+ }
176
+ default:
177
+ return NO_CHANGE(state);
178
+ }
179
+ }
180
+ export function autoResumeArmedRow(state, nowMs, lang) {
181
+ if (state.phase !== 'armed' || state.resumeAtMs === null)
182
+ return undefined;
183
+ const remaining = state.resumeAtMs - nowMs;
184
+ const at = remaining > AUTO_RESUME_IMMINENT_MS ? quotaResetInstantText(new Date(state.resumeAtMs).toISOString(), nowMs, lang) : undefined;
185
+ return at !== undefined ? renderMessage(msg('notice.usageLimit.autoResume.armed.at', { time: at }), lang) : renderMessage(msg('notice.usageLimit.autoResume.armed.shortly'), lang);
186
+ }
187
+ export function autoResumeNoticeRow(state, lang) {
188
+ if (state.phase === 'stale') {
189
+ if (state.reason === 'prompt-superseded')
190
+ return autoResumeCopy('superseded', lang);
191
+ if (state.reason === 'context-changed')
192
+ return autoResumeCopy('context-changed', lang);
193
+ return autoResumeCopy('reset', lang);
194
+ }
195
+ if (state.phase === 'disabled' && state.reason === 'repeated-usage-limit-hits')
196
+ return autoResumeCopy('breaker', lang);
197
+ if (state.phase === 'disabled' && state.reason === 'not-replayable')
198
+ return autoResumeCopy('not-replayable', lang);
199
+ if (state.phase === 'disabled' && state.reason === 'user-escaped')
200
+ return autoResumeCopy('escaped', lang);
201
+ if (state.phase === 'horizon')
202
+ return renderMessage(msg('notice.usageLimit.autoResume.horizon'), lang);
203
+ return undefined;
204
+ }
205
+ export function rateLimitOptionRows(state, lang) {
206
+ const t = (key) => renderMessage(msg(key), lang);
207
+ const rows = [{ value: 'cancel', label: t('notice.usageLimit.autoResume.option.cancel'), disabled: false }];
208
+ if (state.phase === 'armed' || state.phase === 'fired') {
209
+ rows.push({ value: 'cancel-auto-resume', label: t('notice.usageLimit.autoResume.option.cancelAuto'), disabled: false });
210
+ return rows;
211
+ }
212
+ const armable = state.phase === 'offered' || state.phase === 'horizon';
213
+ let disabledReason;
214
+ if (state.reason === 'repeated-usage-limit-hits')
215
+ disabledReason = t('notice.usageLimit.autoResume.disabled.breaker');
216
+ else if (state.reason === 'not-replayable')
217
+ disabledReason = t('notice.usageLimit.autoResume.disabled.notReplayable');
218
+ else if (state.reason === 'context-changed')
219
+ disabledReason = t('notice.usageLimit.autoResume.disabled.contextChanged');
220
+ else if (state.resumeAtMs === null)
221
+ disabledReason = t('notice.usageLimit.autoResume.disabled.noResetInstant');
222
+ else if (!armable)
223
+ disabledReason = t('notice.usageLimit.autoResume.disabled.nothingWaiting');
224
+ const label = state.phase === 'horizon' ? t('notice.usageLimit.autoResume.option.autoHorizon') : t('notice.usageLimit.autoResume.option.auto');
225
+ rows.push({ value: 'auto-resume', label, disabled: disabledReason !== undefined, ...(disabledReason !== undefined ? { disabledReason } : {}) });
226
+ return rows;
227
+ }
@@ -165,7 +165,7 @@ const NOT_INCLUDED_REASON = Object.freeze({
165
165
  'too-large': "it is larger than the client's size limit for attaching files",
166
166
  unreadable: 'the client could not read it',
167
167
  'read-denied': "the user's permission rules do not allow reading it",
168
- 'approval-required': "this deployment's rules require approval before it is read, so the client did not attach it without asking",
168
+ 'approval-required': 'a read-approval rule applies to it, so the client did not attach it without asking',
169
169
  'server-not-connected': 'the MCP server it comes from is not connected',
170
170
  'resource-not-listed': 'the MCP server does not list that resource',
171
171
  'read-failed': 'reading it from the MCP server failed',
@@ -1,6 +1,6 @@
1
- import { engineWireTarget } from './engineWireTarget.js';
1
+ import { engineWireTargetBaseUrl } from './engineWireTarget.js';
2
2
  import { createEngineCapReader } from './engineCapReader.js';
3
- import { ownDataField, readOwnDataValue } from './ownKey.js';
3
+ import { appendOwnElement, ownDataField, readOwnDataValue } from './ownKey.js';
4
4
  const _seatPin = [true, true];
5
5
  void _seatPin;
6
6
  function stringList(v) {
@@ -12,9 +12,9 @@ function stringList(v) {
12
12
  const out = [];
13
13
  for (let i = 0; i < n; i += 1) {
14
14
  const d = Object.getOwnPropertyDescriptor(v, i);
15
- if (d === undefined || !('value' in d) || typeof d.value !== 'string')
15
+ if (d === undefined || !Object.hasOwn(d, 'value') || typeof d.value !== 'string')
16
16
  return undefined;
17
- out.push(d.value);
17
+ appendOwnElement(out, d.value);
18
18
  }
19
19
  return out;
20
20
  }
@@ -46,7 +46,7 @@ export function projectUserAttachmentSeatCapability(caps) {
46
46
  }
47
47
  }
48
48
  const reader = createEngineCapReader({ name: 'userAttachments', project: projectUserAttachmentSeatCapability });
49
- export function observedUserAttachmentSeat(baseUrl = engineWireTarget()?.baseUrl) {
49
+ export function observedUserAttachmentSeat(baseUrl = engineWireTargetBaseUrl()) {
50
50
  return reader.observed(baseUrl);
51
51
  }
52
52
  export function userAttachmentSeatAdmits(reading) {
@@ -1,4 +1,4 @@
1
- import { engineWireTarget } from './engineWireTarget.js';
1
+ import { engineWireTargetBaseUrl } from './engineWireTarget.js';
2
2
  import { createEngineCapReader, unreadableReadingDetail } from './engineCapReader.js';
3
3
  import { msg, renderMessage } from './i18n/translate.js';
4
4
  import { ownDataField, readOwnDataValue } from './ownKey.js';
@@ -21,7 +21,7 @@ const reader = createEngineCapReader({
21
21
  name: 'userInvokedSkills',
22
22
  project: projectUserInvokedSkillsCapability,
23
23
  });
24
- export function observedUserInvokedSkills(baseUrl = engineWireTarget()?.baseUrl) {
24
+ export function observedUserInvokedSkills(baseUrl = engineWireTargetBaseUrl()) {
25
25
  return reader.observed(baseUrl);
26
26
  }
27
27
  export function userInvokedSkillsAvailable(reading) {
@@ -1,5 +1,5 @@
1
1
  import { capForDisplay } from './fleetTaskDesc.js';
2
- import { engineWireTarget } from './engineWireTarget.js';
2
+ import { engineWireTargetBaseUrl } from './engineWireTarget.js';
3
3
  import { createEngineCapReader, unreadableReadingDetail } from './engineCapReader.js';
4
4
  import { ownDataField } from './ownKey.js';
5
5
  export const WEB_SEARCH_BACKEND_NONE = 'none';
@@ -29,7 +29,7 @@ const reader = createEngineCapReader({
29
29
  name: 'webSearch.backend',
30
30
  project: projectWebSearchBackendCapability,
31
31
  });
32
- export function observedWebSearchBackend(baseUrl = engineWireTarget()?.baseUrl) {
32
+ export function observedWebSearchBackend(baseUrl = engineWireTargetBaseUrl()) {
33
33
  return reader.observed(baseUrl);
34
34
  }
35
35
  const WS_DETAIL_MAX = 40;