@sema-agent/client-core 0.97.1 → 0.99.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 (353) hide show
  1. package/CHANGELOG.md +607 -0
  2. package/README.md +96 -46
  3. package/dist/adapt/arms.d.ts +1 -0
  4. package/dist/adapt/arms.js +188 -53
  5. package/dist/adapt/ids.d.ts +12 -1
  6. package/dist/adapt/ids.js +59 -8
  7. package/dist/adapt/instanceLedger.d.ts +50 -0
  8. package/dist/adapt/instanceLedger.js +147 -0
  9. package/dist/adapt/panelTasks.d.ts +1 -1
  10. package/dist/adapt/panelTasks.js +2 -2
  11. package/dist/adapt/textStream.d.ts +1 -0
  12. package/dist/adapt/textStream.js +24 -7
  13. package/dist/adapt/toolCards.d.ts +27 -5
  14. package/dist/adapt/toolCards.js +39 -6
  15. package/dist/adapt/wireShapes.js +6 -2
  16. package/dist/adapt.d.ts +2 -0
  17. package/dist/adapt.js +8 -3
  18. package/dist/adapter/activeRunSelfHeal.d.ts +9 -3
  19. package/dist/adapter/activeRunSelfHeal.js +205 -313
  20. package/dist/adapter/downstream/eventToSdkMessage.d.ts +2 -5
  21. package/dist/adapter/downstream/eventToSdkMessage.js +77 -36
  22. package/dist/adapter/downstream/terminalToSdkResult.js +11 -4
  23. package/dist/adapter/downstream/turnUsageToModelUsage.d.ts +5 -2
  24. package/dist/adapter/downstream/turnUsageToModelUsage.js +2 -0
  25. package/dist/adapter/runStream.js +79 -48
  26. package/dist/adapter/types.d.ts +4 -4
  27. package/dist/adapter/types.js +2 -1
  28. package/dist/agentSession/backgroundView.js +2 -1
  29. package/dist/agentSession/engineAgentRegistryRead.d.ts +2 -2
  30. package/dist/agentSession/engineAgentRegistryRead.js +12 -13
  31. package/dist/agentSession/engineSessionBackgroundStop.js +16 -8
  32. package/dist/agentsWireCaps.d.ts +8 -11
  33. package/dist/agentsWireCaps.js +196 -194
  34. package/dist/approvalDecidedByCapability.d.ts +0 -4
  35. package/dist/approvalDecidedByCapability.js +0 -6
  36. package/dist/approvalsStreamLiveCapability.d.ts +0 -4
  37. package/dist/approvalsStreamLiveCapability.js +0 -6
  38. package/dist/assistantInbox.d.ts +34 -0
  39. package/dist/assistantInbox.js +118 -0
  40. package/dist/centerWiringCapability.js +9 -1
  41. package/dist/clientSlice.d.ts +0 -9
  42. package/dist/clientSlice.js +0 -3
  43. package/dist/cloudConfigWireCaps.d.ts +5 -3
  44. package/dist/cloudConfigWireCaps.js +106 -64
  45. package/dist/compensations.js +1 -1
  46. package/dist/connectorStatus.d.ts +21 -0
  47. package/dist/connectorStatus.js +112 -0
  48. package/dist/controlRouter.d.ts +18 -3
  49. package/dist/controlRouter.js +106 -67
  50. package/dist/coreValuePorts.d.ts +29 -4
  51. package/dist/coreValuePorts.js +10 -0
  52. package/dist/corruptSessionCopy.d.ts +2 -1
  53. package/dist/corruptSessionCopy.js +3 -3
  54. package/dist/decideReceipt.d.ts +2 -2
  55. package/dist/decideReceipt.js +5 -2
  56. package/dist/declared/supportFloorDeclared.js +3 -3
  57. package/dist/detachWire.js +3 -2
  58. package/dist/deviceExecutorManagementCapability.d.ts +0 -4
  59. package/dist/deviceExecutorManagementCapability.js +0 -6
  60. package/dist/deviceRebind.d.ts +49 -1
  61. package/dist/deviceRebind.js +221 -3
  62. package/dist/devicesFace.d.ts +34 -0
  63. package/dist/devicesFace.js +90 -0
  64. package/dist/displayUntrusted.d.ts +2 -0
  65. package/dist/displayUntrusted.js +253 -76
  66. package/dist/engineAgentAbsence.d.ts +1 -1
  67. package/dist/engineAgentPanelStore.d.ts +12 -4
  68. package/dist/engineAgentPanelStore.js +16 -11
  69. package/dist/engineCapReader.d.ts +2 -5
  70. package/dist/engineCapReader.js +8 -10
  71. package/dist/engineCapsCache.d.ts +12 -0
  72. package/dist/engineCapsCache.js +76 -18
  73. package/dist/engineCapsChange.d.ts +2 -0
  74. package/dist/engineCapsChange.js +9 -0
  75. package/dist/engineClosedSets.d.ts +1 -0
  76. package/dist/engineClosedSets.js +4 -1
  77. package/dist/engineErrorCodes.d.ts +11 -3
  78. package/dist/engineErrorCodes.js +11 -8
  79. package/dist/engineIdentity.d.ts +1 -0
  80. package/dist/engineIdentity.js +8 -0
  81. package/dist/engineRowRef.d.ts +28 -0
  82. package/dist/engineRowRef.js +114 -0
  83. package/dist/engineSessionMessages.d.ts +68 -0
  84. package/dist/engineSessionMessages.js +370 -0
  85. package/dist/engineTargetSeat.d.ts +27 -0
  86. package/dist/engineTargetSeat.js +199 -0
  87. package/dist/engineToolDirectory.d.ts +0 -9
  88. package/dist/engineToolDirectory.js +1 -94
  89. package/dist/engineUrl.d.ts +18 -0
  90. package/dist/engineUrl.js +52 -0
  91. package/dist/engineWireFor.js +3 -8
  92. package/dist/env/uiLanguage.d.ts +11 -1
  93. package/dist/env/uiLanguage.js +38 -2
  94. package/dist/eventLeg.d.ts +100 -0
  95. package/dist/eventLeg.js +305 -0
  96. package/dist/executionLaneCapability.d.ts +0 -4
  97. package/dist/executionLaneCapability.js +3 -16
  98. package/dist/fileHistoryCaptureCapability.d.ts +2 -5
  99. package/dist/fileHistoryCaptureCapability.js +13 -21
  100. package/dist/fileHistoryLegNotice.d.ts +2 -1
  101. package/dist/fileHistoryLegNotice.js +3 -3
  102. package/dist/fleet/fleetLedger.d.ts +0 -3
  103. package/dist/fleet/fleetLedger.js +21 -36
  104. package/dist/fleet/fleetProjection.d.ts +2 -2
  105. package/dist/fleet/fleetProjection.js +10 -8
  106. package/dist/frameBinding.d.ts +8 -0
  107. package/dist/frameBinding.js +35 -0
  108. package/dist/gateFailureCodes.d.ts +2 -0
  109. package/dist/gateFailureCodes.js +15 -0
  110. package/dist/gateOutcome.d.ts +3 -1
  111. package/dist/gateOutcome.js +41 -8
  112. package/dist/gateVocabulary.d.ts +10 -4
  113. package/dist/gateVocabulary.js +107 -47
  114. package/dist/generated/engineAskFaceTables.js +2 -2
  115. package/dist/generated/engineFactTables.d.ts +22 -3
  116. package/dist/generated/engineFactTables.js +51 -4
  117. package/dist/generated/engineNoticeTables.js +18 -3
  118. package/dist/generated/settingsSchemaFns.d.ts +6 -0
  119. package/dist/generated/settingsSchemaFns.js +57 -0
  120. package/dist/generated/settingsSchemaHooksClassifier.d.ts +2 -0
  121. package/dist/generated/settingsSchemaHooksClassifier.js +254 -0
  122. package/dist/generated/settingsSchemaTables.d.ts +1 -0
  123. package/dist/generated/settingsSchemaTables.js +4 -0
  124. package/dist/generated/settingsSchemaTypes.d.ts +105 -0
  125. package/dist/generated/settingsSchemaTypes.js +1 -0
  126. package/dist/generated/toolNameTables.d.ts +1 -0
  127. package/dist/generated/toolNameTables.js +1 -0
  128. package/dist/hitl/allowRuleShadow.d.ts +8 -2
  129. package/dist/hitl/allowRuleShadow.js +36 -29
  130. package/dist/hitl/approvalCardReading.d.ts +15 -0
  131. package/dist/hitl/approvalCardReading.js +154 -0
  132. package/dist/hitl/approvalCardReasons.d.ts +14 -0
  133. package/dist/hitl/approvalCardReasons.js +119 -0
  134. package/dist/hitl/approvalHolds.d.ts +50 -15
  135. package/dist/hitl/approvalHolds.js +177 -27
  136. package/dist/hitl/approvalResolution.d.ts +51 -26
  137. package/dist/hitl/approvalResolution.js +86 -122
  138. package/dist/hitl/approvalsFeed.js +6 -18
  139. package/dist/hitl/askClassPair.d.ts +2 -0
  140. package/dist/hitl/askClassPair.js +17 -0
  141. package/dist/hitl/askGateWire.d.ts +20 -2
  142. package/dist/hitl/askGateWire.js +50 -1
  143. package/dist/hitl/askParkRowRouting.d.ts +5 -0
  144. package/dist/hitl/askParkRowRouting.js +32 -1
  145. package/dist/hitl/askSettlementLine.d.ts +28 -0
  146. package/dist/hitl/askSettlementLine.js +99 -0
  147. package/dist/hitl/automaticAnswerVerdict.d.ts +3 -2
  148. package/dist/hitl/automaticAnswerVerdict.js +29 -13
  149. package/dist/hitl/crashConverged.d.ts +11 -20
  150. package/dist/hitl/crashConverged.js +56 -0
  151. package/dist/hitl/crashConvergedNotice.d.ts +6 -3
  152. package/dist/hitl/crashConvergedNotice.js +48 -24
  153. package/dist/hitl/decisionConflict.js +3 -10
  154. package/dist/hitl/decisionRefusal.d.ts +40 -1
  155. package/dist/hitl/decisionRefusal.js +199 -42
  156. package/dist/hitl/frameRouter.d.ts +5 -2
  157. package/dist/hitl/frameRouter.js +27 -24
  158. package/dist/hitl/gateLedger.d.ts +2 -0
  159. package/dist/hitl/gateLedger.js +50 -13
  160. package/dist/hitl/hitlBridge.d.ts +2 -2
  161. package/dist/hitl/hitlBridge.js +13 -10
  162. package/dist/hitl/livePendingAsk.d.ts +3 -3
  163. package/dist/hitl/livePendingAsk.js +7 -18
  164. package/dist/hitl/parkResolver.d.ts +2 -24
  165. package/dist/hitl/parkResolver.js +61 -97
  166. package/dist/hitl/persistedRulesWire.d.ts +25 -0
  167. package/dist/hitl/persistedRulesWire.js +104 -2
  168. package/dist/hitl/planReviewWire.d.ts +31 -13
  169. package/dist/hitl/planReviewWire.js +120 -78
  170. package/dist/hitl/refusedToolNameProse.d.ts +0 -1
  171. package/dist/hitl/refusedToolNameProse.js +0 -3
  172. package/dist/hitl/replayedApproval.d.ts +4 -3
  173. package/dist/hitl/replayedApproval.js +7 -4
  174. package/dist/hitl/sessionPolicyDeliverable.d.ts +2 -0
  175. package/dist/hitl/sessionPolicyDeliverable.js +48 -7
  176. package/dist/hitl/sessionPolicyWire.d.ts +34 -21
  177. package/dist/hitl/sessionPolicyWire.js +179 -70
  178. package/dist/hitl/standingRows.d.ts +20 -2
  179. package/dist/hitl/standingRows.js +69 -8
  180. package/dist/hitl/suspendedReopen.d.ts +2 -1
  181. package/dist/hitl/suspendedReopen.js +7 -10
  182. package/dist/hitl/toolApprovalWire.d.ts +103 -156
  183. package/dist/hitl/toolApprovalWire.js +661 -411
  184. package/dist/hookMatcherVerdict.d.ts +6 -1
  185. package/dist/hookMatcherVerdict.js +14 -7
  186. package/dist/hooksWireCaps.d.ts +2 -2
  187. package/dist/hooksWireCaps.js +174 -81
  188. package/dist/host.d.ts +21 -0
  189. package/dist/hostTurnSettings.d.ts +71 -0
  190. package/dist/hostTurnSettings.js +291 -0
  191. package/dist/humanTurn.d.ts +14 -1
  192. package/dist/humanTurn.js +100 -12
  193. package/dist/humanTurnRead.d.ts +2 -0
  194. package/dist/humanTurnRead.js +22 -1
  195. package/dist/i18n/messages.en.d.ts +703 -0
  196. package/dist/i18n/messages.en.js +701 -0
  197. package/dist/i18n/messages.zh.d.ts +3 -0
  198. package/dist/i18n/messages.zh.js +837 -0
  199. package/dist/i18n/translate.d.ts +25 -0
  200. package/dist/i18n/translate.js +127 -0
  201. package/dist/index.d.ts +78 -29
  202. package/dist/index.js +54 -18
  203. package/dist/inheritEnvCapability.d.ts +32 -0
  204. package/dist/inheritEnvCapability.js +104 -0
  205. package/dist/inheritEnvWire.d.ts +3 -2
  206. package/dist/inheritEnvWire.js +12 -14
  207. package/dist/interactiveHalt.js +17 -6
  208. package/dist/liveModelCatalog.d.ts +3 -3
  209. package/dist/liveModelCatalog.js +15 -13
  210. package/dist/liveQuestionStore.d.ts +2 -21
  211. package/dist/mcpLiveness.d.ts +2 -1
  212. package/dist/mcpPanel.d.ts +10 -1
  213. package/dist/mcpPanel.js +40 -13
  214. package/dist/mcpProbeCapability.d.ts +2 -1
  215. package/dist/mcpProbeCapability.js +7 -11
  216. package/dist/mcpProbeWire.d.ts +9 -2
  217. package/dist/mcpProbeWire.js +6 -1
  218. package/dist/mcpWireCaps.d.ts +47 -2
  219. package/dist/mcpWireCaps.js +164 -16
  220. package/dist/memoryEntriesWire.d.ts +4 -9
  221. package/dist/memoryEntriesWire.js +5 -10
  222. package/dist/model/modelSupplyRules.d.ts +0 -2
  223. package/dist/model/modelSupplyRules.js +3 -12
  224. package/dist/model/modelsPolicy.d.ts +0 -5
  225. package/dist/model/modelsPolicy.js +6 -36
  226. package/dist/model/onboardJudgement.d.ts +93 -0
  227. package/dist/model/onboardJudgement.js +415 -0
  228. package/dist/model/subagentModelWord.d.ts +31 -0
  229. package/dist/model/subagentModelWord.js +261 -0
  230. package/dist/model/tierVocabulary.d.ts +2 -0
  231. package/dist/model/tierVocabulary.js +17 -5
  232. package/dist/modelCapabilityProbe.d.ts +64 -0
  233. package/dist/modelCapabilityProbe.js +600 -0
  234. package/dist/modelIdentityResolvability.d.ts +3 -0
  235. package/dist/modelIdentityResolvability.js +26 -17
  236. package/dist/notifications.d.ts +6 -0
  237. package/dist/notifications.js +71 -23
  238. package/dist/outputStyleSeatCapability.d.ts +0 -3
  239. package/dist/outputStyleSeatCapability.js +0 -3
  240. package/dist/ownKey.d.ts +22 -0
  241. package/dist/ownKey.js +94 -3
  242. package/dist/panelReduce.d.ts +21 -10
  243. package/dist/panelReduce.js +728 -550
  244. package/dist/panelStateHolder.d.ts +3 -7
  245. package/dist/panelStateHolder.js +14 -130
  246. package/dist/peerLaneCapability.d.ts +0 -4
  247. package/dist/peerLaneCapability.js +0 -6
  248. package/dist/permissionRuleIssue.js +2 -0
  249. package/dist/permissionRulesWriteCapability.d.ts +2 -5
  250. package/dist/permissionRulesWriteCapability.js +8 -12
  251. package/dist/permissionWireCaps.d.ts +2 -2
  252. package/dist/permissionWireCaps.js +2 -0
  253. package/dist/permissionsAllowGrantCapability.d.ts +0 -4
  254. package/dist/permissionsAllowGrantCapability.js +0 -6
  255. package/dist/permissionsDeclaration.d.ts +0 -11
  256. package/dist/permissionsDeclaration.js +60 -53
  257. package/dist/pluginHooksWire.d.ts +46 -3
  258. package/dist/pluginHooksWire.js +219 -16
  259. package/dist/preemptWire.d.ts +44 -0
  260. package/dist/preemptWire.js +83 -0
  261. package/dist/printModelStatus.d.ts +63 -0
  262. package/dist/printModelStatus.js +155 -0
  263. package/dist/printToolResultFrame.js +15 -4
  264. package/dist/replayBody.d.ts +3 -0
  265. package/dist/replayBody.js +14 -0
  266. package/dist/request/taskRequest.d.ts +11 -6
  267. package/dist/request/taskRequest.js +112 -19
  268. package/dist/resumeRefusalCopy.d.ts +13 -9
  269. package/dist/resumeRefusalCopy.js +81 -118
  270. package/dist/retryStatus.d.ts +45 -0
  271. package/dist/retryStatus.js +185 -1
  272. package/dist/rewindArchiveCapability.d.ts +0 -4
  273. package/dist/rewindArchiveCapability.js +2 -10
  274. package/dist/rewindArchiveReading.d.ts +0 -1
  275. package/dist/rewindArchiveReading.js +0 -3
  276. package/dist/runCancelContext.d.ts +2 -1
  277. package/dist/runCancelContext.js +4 -2
  278. package/dist/runReattachPolicy.d.ts +31 -0
  279. package/dist/runReattachPolicy.js +46 -0
  280. package/dist/runTerminal.d.ts +3 -6
  281. package/dist/runTerminal.js +8 -9
  282. package/dist/sandboxWire.d.ts +3 -1
  283. package/dist/sandboxWire.js +76 -27
  284. package/dist/scenarioRefusal.d.ts +9 -0
  285. package/dist/scenarioRefusal.js +111 -0
  286. package/dist/scenarioWire.js +1 -1
  287. package/dist/seam.d.ts +48 -2
  288. package/dist/seam.js +25 -4
  289. package/dist/seatContract.d.ts +311 -18
  290. package/dist/seatContract.js +824 -100
  291. package/dist/selfOrchestrationDenial.js +7 -19
  292. package/dist/sessionIdSegment.d.ts +6 -0
  293. package/dist/sessionIdSegment.js +24 -0
  294. package/dist/sessionMemoryStatus.js +6 -11
  295. package/dist/sessionPolicyCapability.d.ts +2 -5
  296. package/dist/sessionPolicyCapability.js +8 -12
  297. package/dist/sessionSyncFileHistoryCapability.d.ts +0 -3
  298. package/dist/sessionSyncFileHistoryCapability.js +0 -3
  299. package/dist/settingsHooksSalvage.d.ts +44 -0
  300. package/dist/settingsHooksSalvage.js +211 -0
  301. package/dist/skillToolListsCapability.d.ts +2 -4
  302. package/dist/skillToolListsCapability.js +8 -9
  303. package/dist/sqlEngineCapability.d.ts +0 -4
  304. package/dist/sqlEngineCapability.js +0 -6
  305. package/dist/sseIdleTriage.js +3 -2
  306. package/dist/steerPriorityCapability.d.ts +0 -3
  307. package/dist/steerPriorityCapability.js +0 -3
  308. package/dist/streamDrainingLegs.d.ts +4 -0
  309. package/dist/streamDrainingLegs.js +6 -1
  310. package/dist/subagent/engineCompactWire.d.ts +0 -1
  311. package/dist/subagent/engineCompactWire.js +7 -5
  312. package/dist/subagent/engineSubagentResume.js +15 -9
  313. package/dist/subagent/engineTaskHandleWire.js +4 -7
  314. package/dist/subagentContentStore.d.ts +3 -0
  315. package/dist/subagentContentStore.js +22 -10
  316. package/dist/submitReopen.d.ts +24 -0
  317. package/dist/submitReopen.js +75 -0
  318. package/dist/terminalStatuses.d.ts +3 -0
  319. package/dist/terminalStatuses.js +10 -2
  320. package/dist/toolHistoryMismatch.js +3 -2
  321. package/dist/toolResult.d.ts +10 -1
  322. package/dist/toolResult.js +34 -6
  323. package/dist/toolRoster.d.ts +3 -4
  324. package/dist/toolRoster.js +21 -22
  325. package/dist/turnFailurePresentation.d.ts +39 -0
  326. package/dist/turnFailurePresentation.js +402 -0
  327. package/dist/usageAnalytics.js +6 -11
  328. package/dist/userAttachmentEnvelope.d.ts +1 -0
  329. package/dist/userAttachmentEnvelope.js +37 -7
  330. package/dist/userAttachmentSeat.d.ts +21 -0
  331. package/dist/userAttachmentSeat.js +75 -0
  332. package/dist/userInvokedSkillsCapability.d.ts +11 -4
  333. package/dist/userInvokedSkillsCapability.js +31 -10
  334. package/dist/webSearchBackendCapability.d.ts +0 -4
  335. package/dist/webSearchBackendCapability.js +0 -6
  336. package/dist/wireErrorTriage.d.ts +7 -0
  337. package/dist/wireErrorTriage.js +26 -23
  338. package/dist/wireFailureShape.d.ts +62 -5
  339. package/dist/wireFailureShape.js +106 -5
  340. package/dist/wireRefusalCopy.d.ts +25 -3
  341. package/dist/wireRefusalCopy.js +74 -80
  342. package/dist/workflowsJournalCapability.d.ts +2 -5
  343. package/dist/workflowsJournalCapability.js +8 -12
  344. package/dist/writeProtectionCapability.d.ts +0 -4
  345. package/dist/writeProtectionCapability.js +0 -6
  346. package/docs/INTEGRATION-CLIENTS.md +1775 -56
  347. package/package.json +6 -5
  348. package/dist/attachmentSeatCapability.d.ts +0 -12
  349. package/dist/attachmentSeatCapability.js +0 -23
  350. package/dist/hitl/approvalOutcomeNote.d.ts +0 -10
  351. package/dist/hitl/approvalOutcomeNote.js +0 -29
  352. package/dist/sessionReadRedactionCapability.d.ts +0 -13
  353. package/dist/sessionReadRedactionCapability.js +0 -35
@@ -0,0 +1,118 @@
1
+ import { errCodes } from './controlRouter.js';
2
+ import { readOwnDataValue } from './ownKey.js';
3
+ import { isReadCredentialRefusal } from './readCredentialRefusal.js';
4
+ import { wireFailureShapeOf } from './wireFailureShape.js';
5
+ export function isAssistantLaneAbsent(err) {
6
+ try {
7
+ return errCodes(err).status === 501;
8
+ }
9
+ catch {
10
+ return false;
11
+ }
12
+ }
13
+ const SEVERITIES = new Set([1, 2, 3, 4, 5]);
14
+ function own(v, key) {
15
+ try {
16
+ return readOwnDataValue(v, key);
17
+ }
18
+ catch {
19
+ return undefined;
20
+ }
21
+ }
22
+ function nonEmptyString(v) {
23
+ return typeof v === 'string' && v !== '' ? v : undefined;
24
+ }
25
+ function finiteNonNeg(v) {
26
+ return typeof v === 'number' && Number.isFinite(v) && v >= 0 ? v : undefined;
27
+ }
28
+ function entryOf(raw) {
29
+ if (raw === null || typeof raw !== 'object')
30
+ return null;
31
+ const sessionId = nonEmptyString(own(raw, 'sessionId'));
32
+ if (sessionId === undefined)
33
+ return null;
34
+ const scope = nonEmptyString(own(raw, 'scope'));
35
+ const gateKind = nonEmptyString(own(raw, 'gateKind'));
36
+ const sev = own(raw, 'severity');
37
+ const severity = typeof sev === 'number' && SEVERITIES.has(sev) ? sev : undefined;
38
+ const spent = finiteNonNeg(own(raw, 'spentMicroUsd'));
39
+ const deadline = finiteNonNeg(own(raw, 'deadline'));
40
+ const created = finiteNonNeg(own(raw, 'createdAt'));
41
+ const objective = nonEmptyString(own(raw, 'objective'));
42
+ const input = own(raw, 'input');
43
+ const inputPreview = typeof input === 'string' && input !== '' ? input : undefined;
44
+ return Object.freeze({
45
+ sessionId,
46
+ ...(scope !== undefined ? { scope } : {}),
47
+ ...(gateKind !== undefined ? { gateKind } : {}),
48
+ ...(severity !== undefined ? { severity } : {}),
49
+ ...(spent !== undefined ? { spentMicroUsd: spent } : {}),
50
+ ...(deadline !== undefined ? { deadlineMs: deadline } : {}),
51
+ ...(created !== undefined ? { createdAtMs: created } : {}),
52
+ ...(objective !== undefined ? { objective } : {}),
53
+ ...(inputPreview !== undefined ? { inputPreview } : {}),
54
+ ...(own(raw, 'requiresRealApproval') === true ? { requiresRealApproval: true } : {}),
55
+ ...(own(raw, 'mandated') === true ? { mandated: true } : {}),
56
+ ...(own(raw, 'hasBidiControls') === true ? { hasBidiControls: true } : {}),
57
+ });
58
+ }
59
+ function isArraySafely(v) {
60
+ try {
61
+ return Array.isArray(v);
62
+ }
63
+ catch {
64
+ return false;
65
+ }
66
+ }
67
+ function unavailable(reason, e) {
68
+ if (e === undefined)
69
+ return Object.freeze({ kind: 'unavailable', reason });
70
+ const { status, errorCode } = wireFailureShapeOf(e);
71
+ return Object.freeze({
72
+ kind: 'unavailable',
73
+ reason,
74
+ ...(status !== undefined ? { status } : {}),
75
+ ...(errorCode !== undefined && errorCode !== '' ? { errorCode } : {}),
76
+ });
77
+ }
78
+ export async function readAssistantInbox(assistant, opts) {
79
+ let verb;
80
+ let signal;
81
+ try {
82
+ verb = assistant === null || assistant === undefined ? undefined : Reflect.get(assistant, 'inbox');
83
+ const s = opts === undefined ? undefined : opts.signal;
84
+ if (s !== undefined && s !== null)
85
+ signal = s;
86
+ }
87
+ catch {
88
+ return Object.freeze({ kind: 'not-reported', via: 'unarmed' });
89
+ }
90
+ if (typeof verb !== 'function')
91
+ return Object.freeze({ kind: 'not-reported', via: 'unarmed' });
92
+ let body;
93
+ try {
94
+ body = await verb.call(assistant, signal !== undefined ? { signal } : undefined);
95
+ }
96
+ catch (e) {
97
+ if (isAssistantLaneAbsent(e))
98
+ return Object.freeze({ kind: 'not-reported', via: 'lane-absent' });
99
+ return unavailable(isReadCredentialRefusal(e) ? 'unauthorized' : 'failed', e);
100
+ }
101
+ const raw = body !== null && typeof body === 'object' ? own(body, 'inbox') : undefined;
102
+ if (!isArraySafely(raw))
103
+ return unavailable('unreadable');
104
+ const entries = [];
105
+ let dropped = 0;
106
+ const lenRaw = own(raw, 'length');
107
+ if (typeof lenRaw !== 'number' || !Number.isInteger(lenRaw) || lenRaw < 0)
108
+ return unavailable('unreadable');
109
+ const len = lenRaw;
110
+ for (let i = 0; i < len; i++) {
111
+ const e = entryOf(own(raw, String(i)));
112
+ if (e === null)
113
+ dropped++;
114
+ else
115
+ entries.push(e);
116
+ }
117
+ return Object.freeze({ kind: 'present', entries: Object.freeze(entries), dropped });
118
+ }
@@ -83,9 +83,17 @@ function projectCenterWiringOf(caps) {
83
83
  },
84
84
  };
85
85
  }
86
+ function projectCenterWiringForCache(caps) {
87
+ const r = projectCenterWiringCapability(caps);
88
+ if (r === undefined || r.kind !== 'present' || r.view.caller === undefined)
89
+ return r;
90
+ const view = { ...r.view };
91
+ delete view.caller;
92
+ return { kind: 'present', view };
93
+ }
86
94
  const reader = createEngineCapReader({
87
95
  name: 'centerWiring',
88
- project: projectCenterWiringCapability,
96
+ project: projectCenterWiringForCache,
89
97
  });
90
98
  export function observedCenterWiring(baseUrl = engineWireTarget()?.baseUrl) {
91
99
  return reader.observed(baseUrl);
@@ -35,10 +35,6 @@ export interface ClientSliceLike {
35
35
  }): Promise<unknown>;
36
36
  readSession(sessionId: string): Promise<unknown>;
37
37
  capabilities(): Promise<unknown>;
38
- probeHealth(): Promise<{
39
- ok: boolean;
40
- version?: string;
41
- }>;
42
38
  }
43
39
  export declare const CLIENT_VERBS: readonly [{
44
40
  readonly verb: "streamTask";
@@ -88,14 +84,9 @@ export declare const CLIENT_VERBS: readonly [{
88
84
  readonly verb: "capabilities";
89
85
  readonly required: true;
90
86
  readonly duty: "引擎 caps(所有能力门的数据源;不实现 = 门全判假)";
91
- }, {
92
- readonly verb: "probeHealth";
93
- readonly required: false;
94
- readonly duty: "健康探测";
95
87
  }];
96
88
  type _MissingFromTable = Exclude<keyof ClientSliceLike, (typeof CLIENT_VERBS)[number]['verb']>;
97
89
  type _ExtraInTable = Exclude<(typeof CLIENT_VERBS)[number]['verb'], keyof ClientSliceLike>;
98
90
  type _MustBeNever<T extends never> = T;
99
91
  export type _VerbTableClosure = [_MustBeNever<_MissingFromTable>, _MustBeNever<_ExtraInTable>];
100
- export declare const PROBE_HEALTH_DIVERGENCE: string;
101
92
  export {};
@@ -11,7 +11,4 @@ export const CLIENT_VERBS = [
11
11
  { verb: 'listSessions', required: false, duty: 'resume 选单' },
12
12
  { verb: 'readSession', required: false, duty: '读历史转录' },
13
13
  { verb: 'capabilities', required: true, duty: '引擎 caps(所有能力门的数据源;不实现 = 门全判假)' },
14
- { verb: 'probeHealth', required: false, duty: '健康探测' },
15
14
  ];
16
- export const PROBE_HEALTH_DIVERGENCE = 'probeHealth: SDK 要求 status==="ok",壳侧 limitsWire:225 / detachWire:82 手拼只要 res.ok。' +
17
- 'B4 保旧行为(res.ok),差异待定 —— 换成 SDK 语义会让"自报 degraded 但可用"的引擎少发 detach 头。';
@@ -4,7 +4,7 @@ import type { EnvLike } from './hostEnv.js';
4
4
  export type { McpServerSpec };
5
5
  type Rec = Record<string, unknown>;
6
6
  export type { EnvLike };
7
- export type CloudMcpDropReason = 'disabled' | 'missing-field' | 'unknown-transport' | 'capped' | 'principal-and-assertion-header';
7
+ export type CloudMcpDropReason = 'disabled' | 'missing-field' | 'unknown-transport' | 'capped' | 'principal-and-assertion-header' | 'tool-axes-invalid' | 'elicitation-invalid';
8
8
  export interface CloudMcpDroppedServer {
9
9
  name?: string;
10
10
  reason: CloudMcpDropReason;
@@ -20,7 +20,7 @@ export interface CloudModelRefIssue {
20
20
  readonly key: 'models' | 'roles' | 'atMention' | 'tierGroups' | 'activeTierGroup';
21
21
  readonly at?: string;
22
22
  readonly target?: string;
23
- readonly reason: 'dangling' | 'rejected' | 'unreadable' | 'unsupported' | 'duplicate' | 'shadowed' | 'unvouched';
23
+ readonly reason: 'dangling' | 'rejected' | 'unreadable' | 'unsupported' | 'duplicate' | 'unvouched';
24
24
  readonly outcome: 'dropped' | 'kept';
25
25
  }
26
26
  export interface CloudModelsDocOptions {
@@ -123,4 +123,6 @@ export interface CloudEffectiveNotice {
123
123
  readonly level: 'warn' | 'info';
124
124
  readonly text: string;
125
125
  }
126
- export declare function cloudEffectiveNotices(p: Pick<CloudProjection, 'effectiveWarnings' | 'budget' | 'runtimeCaps' | 'modelRefIssues' | 'droppedMcpServers'>): CloudEffectiveNotice[];
126
+ export declare function cloudEffectiveNotices(p: Pick<CloudProjection, 'effectiveWarnings' | 'budget' | 'runtimeCaps' | 'modelRefIssues' | 'droppedMcpServers'> & {
127
+ readonly mcp?: readonly McpServerSpec[];
128
+ }): CloudEffectiveNotice[];
@@ -1,8 +1,10 @@
1
- import { MCP_CAPS } from './mcpWireCaps.js';
1
+ import { MCP_CAPS, mcpAssertionHeaderNotSentNotice, mcpElicitationVerdict, mcpToolAxesVerdict, readMcpHttpIdentityHeaders } from './mcpWireCaps.js';
2
2
  import { toCappedSpec } from './skillsWireCaps.js';
3
+ import { msg, renderMessage } from './i18n/translate.js';
3
4
  import { TIER_ORDER } from './model/tierVocabulary.js';
4
5
  import { SETTINGS_NARROW_AT_MENTION } from './generated/settingsSchemaFns.js';
5
6
  import { modelsPolicyOf } from './model/modelsPolicy.js';
7
+ import { normalizeEngineBaseUrl } from './engineUrl.js';
6
8
  import { guardedRead, readOwnDataNonEmptyString, readOwnDataValue } from './ownKey.js';
7
9
  import { SETTINGS_BUDGET_NUMBER_KEYS, SETTINGS_BUDGET_PER_MODEL_NUMBER_KEYS, SETTINGS_BUDGET_STRING_KEYS, SETTINGS_TIER_GROUP_NAME_RE, } from './generated/settingsSchemaTables.js';
8
10
  const asRec = (v) => (typeof v === 'object' && v !== null && !Array.isArray(v) ? v : undefined);
@@ -63,7 +65,8 @@ export function cloudMcpToSpecs(servers, env) {
63
65
  drop(name, 'missing-field');
64
66
  continue;
65
67
  }
66
- if (asStr(t.principalHeader) && asStr(t.assertionHeader)) {
68
+ const identity = readMcpHttpIdentityHeaders(t);
69
+ if (identity.kind === 'both_set') {
67
70
  drop(name, 'principal-and-assertion-header');
68
71
  continue;
69
72
  }
@@ -78,26 +81,39 @@ export function cloudMcpToSpecs(servers, env) {
78
81
  else
79
82
  headers[headerName] = v;
80
83
  }
81
- const principalHeader = asStr(t.principalHeader);
82
84
  transport = {
83
85
  kind: 'http',
84
86
  url,
85
87
  ...(Object.keys(headers).length > 0 ? { headers } : {}),
86
- ...(principalHeader ? { principalHeader } : {}),
88
+ ...(identity.principalHeader !== undefined ? { principalHeader: identity.principalHeader } : {}),
89
+ ...(identity.assertionHeader !== undefined ? { assertionHeader: identity.assertionHeader } : {}),
87
90
  };
88
91
  }
89
92
  else {
90
93
  drop(name, 'unknown-transport');
91
94
  continue;
92
95
  }
96
+ const axesDeclared = s.toolAxes;
97
+ const axesVerdict = mcpToolAxesVerdict(axesDeclared);
98
+ if (axesVerdict.kind === 'bad') {
99
+ drop(name, 'tool-axes-invalid');
100
+ continue;
101
+ }
102
+ const axesShipped = axesVerdict.kind === 'ok' ? axesVerdict.toolAxes : axesDeclared;
103
+ const elVerdict = mcpElicitationVerdict(s.elicitation);
104
+ if (elVerdict.kind === 'bad') {
105
+ drop(name, 'elicitation-invalid');
106
+ continue;
107
+ }
108
+ const allowToolsWritten = Array.isArray(s.allowTools);
93
109
  const allowTools = asArr(s.allowTools).filter((a) => typeof a === 'string');
94
110
  specs.push({
95
111
  name,
96
112
  transport,
97
- ...(allowTools.length > 0 ? { allowTools } : {}),
98
- ...(s.elicitation === true ? { elicitation: true } : {}),
113
+ ...(allowToolsWritten ? { allowTools } : {}),
114
+ ...(elVerdict.elicitation !== undefined ? { elicitation: elVerdict.elicitation } : {}),
99
115
  ...(s.toolFaces !== undefined ? { toolFaces: s.toolFaces } : {}),
100
- ...(s.toolAxes !== undefined ? { toolAxes: s.toolAxes } : {}),
116
+ ...(axesShipped !== undefined ? { toolAxes: axesShipped } : {}),
101
117
  });
102
118
  }
103
119
  return { specs, missingEnv: [...new Set(missingEnv)], droppedServers };
@@ -145,17 +161,54 @@ const setOwn = (o, k, v) => {
145
161
  function modelsDocPositionOf(m, key) {
146
162
  return guardedRead(() => (Object.hasOwn(m, key) ? { value: m[key] } : 'absent')) ?? 'unreadable';
147
163
  }
164
+ function writtenCopyOf(v, pinned) {
165
+ try {
166
+ if (pinned === undefined) {
167
+ const enc = JSON.stringify(v);
168
+ return enc === undefined ? undefined : { value: JSON.parse(enc) };
169
+ }
170
+ const src = asRec(v);
171
+ if (src === undefined)
172
+ return undefined;
173
+ const out = {};
174
+ for (const k of Object.keys(src)) {
175
+ const enc = JSON.stringify(k === pinned.key ? pinned.value : src[k]);
176
+ if (enc !== undefined)
177
+ setOwn(out, k, JSON.parse(enc));
178
+ }
179
+ return { value: out };
180
+ }
181
+ catch {
182
+ return undefined;
183
+ }
184
+ }
148
185
  function modelsDocOf(models, opts) {
149
186
  const m = asRec(models);
150
- if (!m || !Array.isArray(m.models))
187
+ const rawModels = m === undefined ? undefined : guarded(() => m.models);
188
+ if (!m || !Array.isArray(rawModels))
151
189
  return { doc: null, issues: [] };
152
- const entries = m.models.filter((e) => {
190
+ const copyFailures = [];
191
+ const copied = [];
192
+ for (const raw of rawModels) {
193
+ const c = writtenCopyOf(raw);
194
+ if (c !== undefined) {
195
+ copied.push(c.value);
196
+ continue;
197
+ }
198
+ const nm = guarded(() => asStr(asRec(raw)?.name));
199
+ if (nm !== undefined)
200
+ copyFailures.push({ key: 'models', target: nm, reason: 'rejected', outcome: 'dropped' });
201
+ }
202
+ if (copied.length === 0 && copyFailures.length > 0) {
203
+ throw new Error('cloud config: no model entry served to you could be read as data, so the models setting cannot be written; the previous one is kept');
204
+ }
205
+ const entries = copied.filter((e) => {
153
206
  const r = asRec(e);
154
207
  return !!r && !!asStr(r.name) && !!asStr(r.id);
155
208
  });
156
209
  const stripped = entries.map(withoutRegistryAnnotations);
157
210
  const allNames = new Set(entries.map((e) => e.name));
158
- const rawNames = new Set(m.models.map((e) => asStr(asRec(e)?.name)).filter((n) => !!n));
211
+ const rawNames = new Set([...copied.map((e) => asStr(asRec(e)?.name)), ...copyFailures.map((i) => i.target)].filter((n) => !!n));
159
212
  const accept = typeof opts?.entryAccepted === 'function' ? opts.entryAccepted : undefined;
160
213
  const acceptedName = (e) => {
161
214
  try {
@@ -168,7 +221,7 @@ function modelsDocOf(models, opts) {
168
221
  };
169
222
  const acceptedFlags = accept ? stripped.map(acceptedName) : undefined;
170
223
  const names = acceptedFlags ? new Set(stripped.filter((_, i) => acceptedFlags[i]).map((e) => e.name)) : allNames;
171
- const issues = [];
224
+ const issues = [...copyFailures];
172
225
  const drop = (i) => {
173
226
  issues.push({ ...i, outcome: 'dropped' });
174
227
  };
@@ -193,49 +246,22 @@ function modelsDocOf(models, opts) {
193
246
  drop({ key: 'roles', at: 'default', reason: 'unreadable' });
194
247
  drop({ key: 'atMention', at: 'models', reason: 'unreadable' });
195
248
  }
196
- if (policy.defaultUnreadable)
197
- drop({ key: 'roles', at: 'default', reason: 'unreadable' });
198
- const dm = policy.defaultModel;
199
- let defaultRole;
200
- let defaultWinner;
201
- if (dm !== undefined && dm.from === 'default') {
202
- const verdict = modelRefVerdict(dm.name);
203
- if (verdict === 'accepted')
204
- defaultRole = { model: dm.name };
205
- else
206
- drop({ key: 'roles', at: 'default', target: dm.name, reason: verdict });
207
- if (verdict === 'accepted' || verdict === 'unvouched')
208
- defaultWinner = dm.name;
209
- }
210
- const roles = asRec(m.roles);
249
+ const rolesRead = guarded(() => ({ value: m.roles }));
250
+ const roleEntries = rolesRead === undefined ? undefined : guarded(() => Object.entries(asRec(rolesRead.value) ?? {}));
251
+ if (roleEntries === undefined)
252
+ drop({ key: 'roles', at: 'models', reason: 'unreadable' });
211
253
  const keptRoles = {};
212
- let sameModelDefaultRole;
213
- for (const [role, t] of Object.entries(roles ?? {})) {
214
- if (role === 'default' && defaultWinner !== undefined) {
215
- const tr = asRec(t);
216
- let model;
217
- let snapshot;
218
- try {
219
- model = tr && Object.hasOwn(tr, 'model') ? tr.model : undefined;
220
- if (tr !== undefined && typeof model === 'string' && model === defaultWinner) {
221
- snapshot = {};
222
- for (const [k, v] of Object.entries(tr))
223
- setOwn(snapshot, k, v);
224
- setOwn(snapshot, 'model', model);
225
- }
226
- }
227
- catch {
228
- model = undefined;
229
- snapshot = undefined;
230
- }
231
- if (snapshot !== undefined)
232
- sameModelDefaultRole = snapshot;
233
- else
234
- drop({ key: 'roles', at: 'default', ...refOf(model), reason: 'shadowed' });
254
+ for (const [role, t] of roleEntries ?? []) {
255
+ const first = guarded(() => {
256
+ const r = asRec(t);
257
+ const has = r !== undefined && Object.hasOwn(r, 'model');
258
+ return { tr: r, has, model: has ? r.model : undefined };
259
+ });
260
+ if (first === undefined) {
261
+ drop({ key: 'roles', at: role, reason: 'unreadable' });
235
262
  continue;
236
263
  }
237
- const tr = asRec(t);
238
- const model = tr && Object.hasOwn(tr, 'model') ? tr.model : undefined;
264
+ const { tr, has, model } = first;
239
265
  if (typeof model === 'string') {
240
266
  const verdict = modelRefVerdict(model);
241
267
  if (verdict !== 'accepted') {
@@ -243,12 +269,15 @@ function modelsDocOf(models, opts) {
243
269
  continue;
244
270
  }
245
271
  }
246
- setOwn(keptRoles, role, t);
272
+ const copy = writtenCopyOf(t, tr !== undefined && has ? { key: 'model', value: model } : undefined);
273
+ if (copy === undefined) {
274
+ drop({ key: 'roles', at: role, ...refOf(model), reason: 'unreadable' });
275
+ continue;
276
+ }
277
+ setOwn(keptRoles, role, copy.value);
247
278
  }
248
279
  const rolesOut = {};
249
- if (defaultRole !== undefined)
250
- setOwn(rolesOut, 'default', sameModelDefaultRole ?? defaultRole);
251
- else if (Object.hasOwn(keptRoles, 'default'))
280
+ if (Object.hasOwn(keptRoles, 'default'))
252
281
  setOwn(rolesOut, 'default', keptRoles.default);
253
282
  for (const [k, v] of Object.entries(keptRoles))
254
283
  if (k !== 'default')
@@ -257,11 +286,9 @@ function modelsDocOf(models, opts) {
257
286
  doc.roles = rolesOut;
258
287
  const am = policy.atMention;
259
288
  if (am?.kind === 'unreadable') {
260
- drop({ key: 'atMention', at: am.from, reason: 'unreadable' });
289
+ drop({ key: 'atMention', at: 'atMention', reason: 'unreadable' });
261
290
  }
262
291
  else if (am !== undefined) {
263
- for (let i = 0; i < am.unreadableEntries; i += 1)
264
- drop({ key: 'atMention', reason: 'unreadable' });
265
292
  const v = am.value;
266
293
  if (v.mode === 'only') {
267
294
  for (const n of v.models)
@@ -341,7 +368,7 @@ function modelsDocOf(models, opts) {
341
368
  drop({ key: 'activeTierGroup', ...refOf(a), reason: typeof a === 'string' && a !== '' ? (rawGroupNames.has(a) ? 'rejected' : 'dangling') : 'unreadable' });
342
369
  }
343
370
  }
344
- return { doc, issues };
371
+ return { doc, issues, entriesRead: copied };
345
372
  }
346
373
  export function cloudModelsToDoc(models, opts) {
347
374
  return modelsDocOf(models, opts).doc;
@@ -385,6 +412,10 @@ export function cloudModelMissingKeyEnv(doc, env) {
385
412
  }
386
413
  return [...out];
387
414
  }
415
+ function mirrorUrlOf(raw) {
416
+ const r = normalizeEngineBaseUrl(raw);
417
+ return r.ok ? r.url : raw;
418
+ }
388
419
  export function cloudExecutionToPolicy(execution) {
389
420
  const e = asRec(execution);
390
421
  const lanes = asArr(e?.allowedLanes).filter((l) => typeof l === 'string' && l.length > 0);
@@ -393,7 +424,7 @@ export function cloudExecutionToPolicy(execution) {
393
424
  return {
394
425
  required: e?.required === true,
395
426
  allowedLanes: lanes.length > 0 ? lanes : ['host'],
396
- sessionMirror: mirrorUrl ? { engineUrl: mirrorUrl.replace(/\/+$/, ''), required: m?.required === true } : null,
427
+ sessionMirror: mirrorUrl ? { engineUrl: mirrorUrlOf(mirrorUrl), required: m?.required === true } : null,
397
428
  };
398
429
  }
399
430
  export function cloudRosterNames(rostersValue) {
@@ -549,7 +580,7 @@ export function projectEffectiveBody(body, skillBodies, env, rostersValue, opts)
549
580
  return name && hash && skillBodies[hash] === undefined ? name : undefined;
550
581
  })
551
582
  .filter((n) => !!n);
552
- const { doc: modelsDoc, issues: modelRefIssues } = modelsDocOf(config.models, opts);
583
+ const { doc: modelsDoc, issues: modelRefIssues, entriesRead } = modelsDocOf(config.models, opts);
553
584
  const view = viewModeOf(b);
554
585
  return {
555
586
  mcp,
@@ -561,7 +592,7 @@ export function projectEffectiveBody(body, skillBodies, env, rostersValue, opts)
561
592
  scope: asStr(b.scope) ?? 'global',
562
593
  skillsMissingBody,
563
594
  droppedMcpServers,
564
- droppedModels: cloudModelsDropped(config.models),
595
+ droppedModels: entriesRead === undefined ? [] : cloudModelsDropped({ models: entriesRead }),
565
596
  execution: cloudExecutionToPolicy(config.execution),
566
597
  effectiveWarnings: effectiveWarningsOf(b),
567
598
  budget: budgetOf(b, view),
@@ -597,12 +628,12 @@ function droppedRefNotice(d) {
597
628
  case 'models':
598
629
  return { level: 'warn', text: `cloud config: ${t === undefined ? 'a model entry' : `model "${t}"`} ${ENTRY_REJECTED} — it was left out of the local catalog` };
599
630
  case 'roles':
631
+ if (d.at === 'models')
632
+ return { level: 'warn', text: 'cloud config: the role settings served to you could not be read by this client — they were left out, so no roles are set on the local engine' };
600
633
  if (d.at === 'default' && d.reason === 'unreadable')
601
634
  return { level: 'warn', text: 'cloud config: the default model setting could not be read, so it was left out — the local engine picks its default from roles and tiers instead' };
602
635
  if (d.reason === 'unvouched')
603
636
  return { level: 'warn', text: `cloud config: role "${d.at ?? ''}" points at model "${t ?? ''}", but this client was given no way to check that the local engine can use that model — the role was left out and falls back along the engine's role chain` };
604
- if (d.reason === 'shadowed')
605
- return { level: 'warn', text: `cloud config: the "${d.at ?? ''}" role${t === undefined ? '' : ` ("${t}")`} is overridden by the default model setting served to you — only one default model can be set, so that role entry was left out` };
606
637
  return { level: 'warn', text: `cloud config: role "${d.at ?? ''}" ${t === undefined ? 'names no readable model' : `points at model "${t}", which ${notServed}`} — the role was left out and falls back along the engine's role chain` };
607
638
  case 'atMention':
608
639
  if (d.at === 'atMention' && d.reason === 'dangling')
@@ -637,6 +668,14 @@ const MCP_DROP_SENTENCES = {
637
668
  level: 'warn',
638
669
  text: (who) => `cloud config: MCP server entries left out because they set both principalHeader and assertionHeader, which name the same identity header — keep only one of the two: ${who}`,
639
670
  },
671
+ 'tool-axes-invalid': {
672
+ level: 'warn',
673
+ text: (who) => renderMessage(msg('config.mcp.cloudToolAxesInvalid', { who })),
674
+ },
675
+ 'elicitation-invalid': {
676
+ level: 'warn',
677
+ text: (who) => renderMessage(msg('config.mcp.cloudElicitationInvalid', { who })),
678
+ },
640
679
  capped: {
641
680
  level: 'warn',
642
681
  text: (who) => `cloud config: MCP server entries left out because more than ${MCP_CAPS.items} were served to you and this client passes at most ${MCP_CAPS.items} to the engine: ${who}`,
@@ -790,6 +829,9 @@ export function cloudEffectiveNotices(p) {
790
829
  });
791
830
  }
792
831
  out.push(...droppedMcpNotices(p));
832
+ const assertionLine = mcpAssertionHeaderNotSentNotice(guarded(() => readOwnDataValue(p, 'mcp')) ?? []);
833
+ if (assertionLine !== undefined)
834
+ out.push({ level: 'warn', text: `cloud config: ${assertionLine}` });
793
835
  out.push(budgetNotice(p.budget));
794
836
  out.push(runtimeCapsNotice(p.runtimeCaps));
795
837
  return out;
@@ -89,7 +89,7 @@ export const MIGRATED_COMPENSATIONS = [
89
89
  what: '从落盘转录的 `<task-notification>` XML 反解回植去重键 —— 去重面纯内存,重启即蒸发,' +
90
90
  '「通知 user-turn 已落盘、ack 未落」的 crash 窗口会二次喂模型(#63)',
91
91
  disposition: 'in-library',
92
- libraryHalf: 'notifications.ts parseTranscriptNotificationSeeds(**唯一一份**解析)+ ' +
92
+ libraryHalf: 'notifications.ts parseTranscriptNotificationSeeds(**唯一一份**解析;0.98.0 起逐块解析归线性块解析器,单条口 readTaskNotificationXml 读同一只)+ ' +
93
93
  'adapt.ts importLedgerFromTranscript(消费口)',
94
94
  chromeArm: null,
95
95
  hostHalf: null,
@@ -0,0 +1,21 @@
1
+ import type { ReaderMintedStatus } from '@sema-agent/connectors-contract';
2
+ import type { McpDeploymentOutcome } from './mcpProbeWire.js';
3
+ export type { ReaderMintedState, ReaderMintedStatus } from '@sema-agent/connectors-contract';
4
+ export declare const CONNECTOR_STATUS_UNKNOWN_WHYS: readonly ["name_unreadable", "mount_face_unreadable", "ambiguous", "unobserved", "probe_face_unreadable", "probe_undecided"];
5
+ export type ConnectorStatusUnknownWhy = (typeof CONNECTOR_STATUS_UNKNOWN_WHYS)[number];
6
+ export interface ConnectorStatusInput {
7
+ name: string;
8
+ mountFace: McpDeploymentOutcome;
9
+ }
10
+ export type ConnectorStatusReading = {
11
+ readonly kind: 'reader';
12
+ readonly status: Readonly<ReaderMintedStatus>;
13
+ } | {
14
+ readonly kind: 'self_reported';
15
+ readonly state: 'unknown';
16
+ } | {
17
+ readonly kind: 'unknown';
18
+ readonly why: ConnectorStatusUnknownWhy;
19
+ };
20
+ export declare function connectorStatusOf(input: ConnectorStatusInput): ConnectorStatusReading;
21
+ export declare function connectorStatusLine(reading: ConnectorStatusReading, lang?: string): string;
@@ -0,0 +1,112 @@
1
+ import { mcpEngineLegLivenessOf } from './mcpEngineLeg.js';
2
+ export const CONNECTOR_STATUS_UNKNOWN_WHYS = Object.freeze([
3
+ 'name_unreadable',
4
+ 'mount_face_unreadable',
5
+ 'ambiguous',
6
+ 'unobserved',
7
+ 'probe_face_unreadable',
8
+ 'probe_undecided',
9
+ ]);
10
+ void true;
11
+ const readerReading = (state) => Object.freeze({ kind: 'reader', status: Object.freeze({ state }) });
12
+ const READER_READINGS = Object.freeze({
13
+ unmounted: readerReading('unmounted'),
14
+ unreachable: readerReading('unreachable'),
15
+ });
16
+ const SELF_REPORTED = Object.freeze({ kind: 'self_reported', state: 'unknown' });
17
+ const UNKNOWN_READINGS = Object.freeze(Object.fromEntries(CONNECTOR_STATUS_UNKNOWN_WHYS.map((why) => [why, Object.freeze({ kind: 'unknown', why })])));
18
+ const BY_LIVENESS = Object.freeze({
19
+ reachable: SELF_REPORTED,
20
+ unreachable: READER_READINGS.unreachable,
21
+ unknown: UNKNOWN_READINGS.probe_undecided,
22
+ });
23
+ const UNREADABLE = Symbol('connectorStatus.unreadable');
24
+ function ownField(o, key) {
25
+ if (o === null || typeof o !== 'object')
26
+ return undefined;
27
+ try {
28
+ if (!Object.hasOwn(o, key))
29
+ return undefined;
30
+ return o[key];
31
+ }
32
+ catch {
33
+ return UNREADABLE;
34
+ }
35
+ }
36
+ function mountRowsOf(outcome) {
37
+ if (ownField(outcome, 'status') !== 'face')
38
+ return undefined;
39
+ if (ownField(outcome, 'declaredBy') !== 'deployment')
40
+ return undefined;
41
+ const faceView = ownField(outcome, 'face');
42
+ const servers = ownField(faceView, 'servers');
43
+ if (servers === UNREADABLE || servers === undefined)
44
+ return undefined;
45
+ return servers;
46
+ }
47
+ function readingOfLiveness(lv) {
48
+ switch (lv.kind) {
49
+ case 'not-listed':
50
+ return READER_READINGS.unmounted;
51
+ case 'unobserved':
52
+ return UNKNOWN_READINGS.mount_face_unreadable;
53
+ case 'ambiguous':
54
+ return UNKNOWN_READINGS.ambiguous;
55
+ case 'absent':
56
+ return UNKNOWN_READINGS.unobserved;
57
+ case 'unreadable':
58
+ return UNKNOWN_READINGS.probe_face_unreadable;
59
+ case 'observed':
60
+ return Object.hasOwn(BY_LIVENESS, lv.state) ? BY_LIVENESS[lv.state] : UNKNOWN_READINGS.probe_face_unreadable;
61
+ default: {
62
+ const exhaustive = lv;
63
+ void exhaustive;
64
+ return UNKNOWN_READINGS.mount_face_unreadable;
65
+ }
66
+ }
67
+ }
68
+ export function connectorStatusOf(input) {
69
+ const name = ownField(input, 'name');
70
+ if (typeof name !== 'string' || name === '')
71
+ return UNKNOWN_READINGS.name_unreadable;
72
+ const rows = mountRowsOf(ownField(input, 'mountFace'));
73
+ if (rows === undefined)
74
+ return UNKNOWN_READINGS.mount_face_unreadable;
75
+ let lv;
76
+ try {
77
+ lv = mcpEngineLegLivenessOf(name, rows);
78
+ }
79
+ catch {
80
+ return UNKNOWN_READINGS.mount_face_unreadable;
81
+ }
82
+ return readingOfLiveness(lv);
83
+ }
84
+ const READER_LINES = Object.freeze({
85
+ unmounted: "This connector is not mounted by default: this deployment's default MCP server list does not include it.",
86
+ unreachable: 'This connector is mounted, but the engine could not reach it when it last tried.',
87
+ });
88
+ const SELF_REPORTED_LINE = 'This connector is mounted and the engine reached it. Whether it is authorized is for the connector itself to report, and this client does not read that report.';
89
+ const UNKNOWN_LINES = Object.freeze({
90
+ name_unreadable: "This client cannot tell this connector's status: it was not given a server name to look up.",
91
+ mount_face_unreadable: "This client could not read this deployment's MCP server list, so it cannot tell whether this connector is mounted.",
92
+ ambiguous: "This deployment lists more than one MCP server under this connector's name, so this client cannot tell which one it is.",
93
+ unobserved: 'This connector is mounted, but the engine has no reachability reading for it.',
94
+ probe_face_unreadable: "This connector is mounted, but this client could not read the engine's reachability reading for it.",
95
+ probe_undecided: 'This connector is mounted; the engine tried to reach it but could not tell whether it is reachable.',
96
+ });
97
+ const FALLBACK_LINE = "This client cannot tell this connector's status.";
98
+ export function connectorStatusLine(reading, lang) {
99
+ void lang;
100
+ const kind = ownField(reading, 'kind');
101
+ if (kind === 'reader') {
102
+ const state = ownField(ownField(reading, 'status'), 'state');
103
+ return typeof state === 'string' && Object.hasOwn(READER_LINES, state) ? READER_LINES[state] : FALLBACK_LINE;
104
+ }
105
+ if (kind === 'self_reported')
106
+ return ownField(reading, 'state') === 'unknown' ? SELF_REPORTED_LINE : FALLBACK_LINE;
107
+ if (kind === 'unknown') {
108
+ const why = ownField(reading, 'why');
109
+ return typeof why === 'string' && Object.hasOwn(UNKNOWN_LINES, why) ? UNKNOWN_LINES[why] : FALLBACK_LINE;
110
+ }
111
+ return FALLBACK_LINE;
112
+ }