@sema-agent/client-core 0.104.1 → 0.106.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 (175) hide show
  1. package/CHANGELOG.md +310 -0
  2. package/README.md +36 -14
  3. package/dist/adapt/arms.js +23 -6
  4. package/dist/adapter/activeRunSelfHeal.d.ts +14 -2
  5. package/dist/adapter/activeRunSelfHeal.js +90 -12
  6. package/dist/adapter/downstream/eventToSdkMessage.d.ts +0 -5
  7. package/dist/adapter/downstream/eventToSdkMessage.js +24 -23
  8. package/dist/adapter/downstream/terminalToSdkResult.js +2 -3
  9. package/dist/adapter/downstream/wiringManifestView.d.ts +7 -3
  10. package/dist/adapter/downstream/wiringManifestView.js +25 -1
  11. package/dist/adapter/runStream.js +8 -5
  12. package/dist/approvalReachWire.d.ts +1 -0
  13. package/dist/approvalReachWire.js +4 -1
  14. package/dist/approvalSeat.d.ts +21 -0
  15. package/dist/approvalSeat.js +73 -0
  16. package/dist/assistantInbox.d.ts +2 -0
  17. package/dist/assistantInbox.js +3 -0
  18. package/dist/checkpointRowVerdict.d.ts +23 -0
  19. package/dist/checkpointRowVerdict.js +89 -0
  20. package/dist/cloudConfigWireCaps.js +3 -0
  21. package/dist/compensations.js +6 -6
  22. package/dist/coreValuePorts.d.ts +14 -1
  23. package/dist/coreValuePorts.js +14 -0
  24. package/dist/decideFailureNote.js +3 -1
  25. package/dist/decideReceipt.d.ts +9 -0
  26. package/dist/decideReceipt.js +29 -1
  27. package/dist/declared/supportFloorDeclared.js +2 -2
  28. package/dist/deviceRebind.d.ts +7 -0
  29. package/dist/deviceRebind.js +39 -5
  30. package/dist/displayUntrusted.d.ts +4 -2
  31. package/dist/displayUntrusted.js +45 -22
  32. package/dist/engineAddress.d.ts +3 -0
  33. package/dist/engineAddress.js +25 -0
  34. package/dist/engineDirectory.js +9 -17
  35. package/dist/engineErrorCodes.d.ts +8 -0
  36. package/dist/engineErrorCodes.js +8 -0
  37. package/dist/engineGenerationPort.d.ts +11 -2
  38. package/dist/engineGenerationPort.js +63 -9
  39. package/dist/engineHealthFacts.d.ts +5 -0
  40. package/dist/engineHealthFacts.js +11 -0
  41. package/dist/engineNoticeCodes.d.ts +26 -3
  42. package/dist/engineNoticeCodes.js +52 -7
  43. package/dist/engineRowRef.js +1 -1
  44. package/dist/errorSupplementRoles.js +2 -0
  45. package/dist/eventLeg.d.ts +3 -3
  46. package/dist/eventLeg.js +25 -4
  47. package/dist/fleet/fleetProjection.js +26 -5
  48. package/dist/generated/engineFactTables.d.ts +3 -1
  49. package/dist/generated/engineFactTables.js +4 -1
  50. package/dist/generated/engineNoticeTables.js +19 -4
  51. package/dist/generated/sdkFactTables.d.ts +5 -0
  52. package/dist/generated/sdkFactTables.js +24 -0
  53. package/dist/generated/settingsSchemaFns.d.ts +11 -0
  54. package/dist/generated/settingsSchemaFns.js +2 -1
  55. package/dist/generated/settingsSchemaSafetyMergeSpec.js +1 -1
  56. package/dist/generated/settingsSchemaSettingsSources.d.ts +1 -1
  57. package/dist/generated/settingsSchemaSettingsSources.js +22 -2
  58. package/dist/headlessReconnectWire.js +31 -4
  59. package/dist/hitl/approvalLiveFace.d.ts +17 -0
  60. package/dist/hitl/approvalLiveFace.js +35 -0
  61. package/dist/hitl/approvalQueueRow.d.ts +21 -0
  62. package/dist/hitl/approvalQueueRow.js +69 -0
  63. package/dist/hitl/approvalsFeed.d.ts +5 -4
  64. package/dist/hitl/approvalsFeed.js +38 -6
  65. package/dist/hitl/askGateWire.js +26 -2
  66. package/dist/hitl/askParkRowRouting.d.ts +4 -3
  67. package/dist/hitl/askParkRowRouting.js +15 -3
  68. package/dist/hitl/automaticAnswerVerdict.js +13 -10
  69. package/dist/hitl/crashConverged.d.ts +5 -1
  70. package/dist/hitl/decisionConflict.js +2 -1
  71. package/dist/hitl/decisionRefusal.js +1 -1
  72. package/dist/hitl/decisionSend.d.ts +1 -0
  73. package/dist/hitl/decisionSend.js +14 -2
  74. package/dist/hitl/frameRouter.d.ts +4 -0
  75. package/dist/hitl/frameRouter.js +18 -5
  76. package/dist/hitl/gateIdentity.d.ts +1 -0
  77. package/dist/hitl/gateIdentity.js +3 -0
  78. package/dist/hitl/hitlBridge.d.ts +1 -1
  79. package/dist/hitl/hitlBridge.js +26 -5
  80. package/dist/hitl/livePendingAsk.d.ts +5 -0
  81. package/dist/hitl/livePendingAsk.js +6 -1
  82. package/dist/hitl/planReviewCard.d.ts +23 -0
  83. package/dist/hitl/planReviewCard.js +250 -0
  84. package/dist/hitl/planReviewWire.d.ts +39 -14
  85. package/dist/hitl/planReviewWire.js +450 -163
  86. package/dist/hitl/sessionAllowRoute.d.ts +2 -0
  87. package/dist/hitl/sessionAllowRoute.js +7 -0
  88. package/dist/hitl/sessionPolicyWire.d.ts +1 -7
  89. package/dist/hitl/sessionPolicyWire.js +3 -43
  90. package/dist/hitl/subagentSource.d.ts +1 -0
  91. package/dist/hitl/subagentSource.js +13 -0
  92. package/dist/hitl/toolApprovalWire.d.ts +3 -2
  93. package/dist/hitl/toolApprovalWire.js +79 -37
  94. package/dist/hostSettingsSource.d.ts +5 -2
  95. package/dist/hostSettingsSource.js +19 -10
  96. package/dist/hostTurnSettings.d.ts +5 -6
  97. package/dist/hostTurnSettings.js +106 -26
  98. package/dist/i18n/messages.en.d.ts +85 -12
  99. package/dist/i18n/messages.en.js +85 -12
  100. package/dist/i18n/messages.zh.js +88 -12
  101. package/dist/index.d.ts +35 -4
  102. package/dist/index.js +19 -2
  103. package/dist/liveInitToolFace.js +0 -1
  104. package/dist/liveModelCatalog.d.ts +15 -0
  105. package/dist/liveModelCatalog.js +40 -0
  106. package/dist/mcpTransportKindsCapability.d.ts +18 -0
  107. package/dist/mcpTransportKindsCapability.js +75 -0
  108. package/dist/mcpWireCaps.d.ts +4 -1
  109. package/dist/mcpWireCaps.js +25 -14
  110. package/dist/modelCapabilityProbe.js +66 -33
  111. package/dist/notifications.d.ts +9 -0
  112. package/dist/notifications.js +11 -2
  113. package/dist/ownKey.d.ts +4 -1
  114. package/dist/ownKey.js +8 -2
  115. package/dist/permissionModeWriteCapability.d.ts +13 -0
  116. package/dist/permissionModeWriteCapability.js +35 -0
  117. package/dist/permissionsAllowGrantCapability.d.ts +3 -0
  118. package/dist/permissionsAllowGrantCapability.js +26 -3
  119. package/dist/permissionsDeclaration.d.ts +25 -3
  120. package/dist/permissionsDeclaration.js +69 -41
  121. package/dist/planReviewCardFacts.d.ts +116 -0
  122. package/dist/planReviewCardFacts.js +469 -0
  123. package/dist/projectSeed.d.ts +39 -0
  124. package/dist/projectSeed.js +80 -0
  125. package/dist/promptDelivery.js +1 -1
  126. package/dist/reattachWindow.d.ts +8 -1
  127. package/dist/reattachWindow.js +44 -12
  128. package/dist/replayBody.d.ts +7 -6
  129. package/dist/replayBody.js +62 -7
  130. package/dist/request/taskRequest.js +3 -4
  131. package/dist/ruleCompileVerdict.d.ts +0 -2
  132. package/dist/ruleCompileVerdict.js +0 -31
  133. package/dist/ruleRefusalSentence.js +0 -3
  134. package/dist/runFollow.d.ts +30 -0
  135. package/dist/runFollow.js +117 -0
  136. package/dist/runLedgerSnapshot.d.ts +20 -0
  137. package/dist/runLedgerSnapshot.js +272 -0
  138. package/dist/runPermissionModeSwitch.d.ts +57 -0
  139. package/dist/runPermissionModeSwitch.js +135 -0
  140. package/dist/runReattachPolicy.d.ts +16 -5
  141. package/dist/runReattachPolicy.js +72 -24
  142. package/dist/runTerminal.js +30 -8
  143. package/dist/sandboxWire.d.ts +0 -3
  144. package/dist/sandboxWire.js +0 -9
  145. package/dist/seam.d.ts +17 -7
  146. package/dist/seam.js +13 -1
  147. package/dist/seatContract.d.ts +57 -7
  148. package/dist/seatContract.js +133 -3
  149. package/dist/serverSupportRange.d.ts +18 -0
  150. package/dist/serverSupportRange.js +25 -0
  151. package/dist/sessionEngine.d.ts +156 -0
  152. package/dist/sessionEngine.js +464 -0
  153. package/dist/sessionMap.d.ts +11 -1
  154. package/dist/sessionMap.js +35 -9
  155. package/dist/sessionMemoryErase.d.ts +1 -1
  156. package/dist/sessionMemoryErase.js +5 -0
  157. package/dist/sessionMemoryStatus.d.ts +27 -1
  158. package/dist/sessionMemoryStatus.js +117 -0
  159. package/dist/sessionMemorySync.d.ts +31 -0
  160. package/dist/sessionMemorySync.js +95 -0
  161. package/dist/sessionRowTag.d.ts +4 -0
  162. package/dist/sessionRowTag.js +18 -0
  163. package/dist/settingsLayerAdmission.d.ts +1 -0
  164. package/dist/settingsLayerAdmission.js +4 -1
  165. package/dist/sseIdleTriage.d.ts +3 -1
  166. package/dist/sseIdleTriage.js +19 -4
  167. package/dist/subagent/engineSubagentTail.js +2 -0
  168. package/dist/subagentContentStore.d.ts +3 -0
  169. package/dist/subagentContentStore.js +10 -1
  170. package/dist/toolResult.js +1 -1
  171. package/dist/turnFailurePresentation.d.ts +5 -2
  172. package/dist/turnFailurePresentation.js +12 -4
  173. package/dist/wireRefusalCopy.js +2 -6
  174. package/docs/INTEGRATION-CLIENTS.md +1507 -18
  175. package/package.json +5 -5
package/dist/index.js CHANGED
@@ -66,6 +66,9 @@ export * from './steerPriorityCapability.js';
66
66
  export * from './permissionModesCapability.js';
67
67
  export * from './approvalDecidedByCapability.js';
68
68
  export * from './outputStyleSeatCapability.js';
69
+ export * from './permissionModeWriteCapability.js';
70
+ export { setRunPermissionMode, runPermissionModeSwitchLine } from './runPermissionModeSwitch.js';
71
+ export { observedMcpTransportKinds, projectMcpTransportKindsCapability } from './mcpTransportKindsCapability.js';
69
72
  export * from './mcpProbeWire.js';
70
73
  export * from './connectorStatus.js';
71
74
  export * from './effectiveFacts.js';
@@ -88,6 +91,7 @@ export * from './classifierStatus.js';
88
91
  export * from './engineToolLabelStore.js';
89
92
  export * from './fleetTaskDesc.js';
90
93
  export { displayUntrusted, displayUntrustedMarks, displayConfiguredUrl, queryCarriesCredential, cleanUntrustedScalar } from './displayUntrusted.js';
94
+ export { DISPLAY_DECISION_BODY } from './displayUntrusted.js';
91
95
  export { isDiagnosticValueWord } from './displayUntrusted.js';
92
96
  export * from './hostEnv.js';
93
97
  export * from './unrefTimer.js';
@@ -99,7 +103,7 @@ export * from './engineWireSdk.js';
99
103
  export * from './classifierVerdictWire.js';
100
104
  export { stripSystemReminderBlocks, unwrapSystemReminder } from './systemReminderTag.js';
101
105
  export { findSystemReminderOpenTag } from './systemReminderTag.js';
102
- export { ACTIVE_RUN_BUSY_ERROR_CODE, APPROVAL_EXPIRED, ASK_GONE, asModelFallbackReason, CAPABILITY_IMAGE_INDEX_REQUIRED, CAPABILITY_K8S_LANE_REQUIRED, CAPABILITY_OPERATOR_PRINCIPALS_REQUIRED, CAPABILITY_SELF_ORCHESTRATION_REQUIRED, CONFIG_AGENT_UNKNOWN_TOOL, CONFIG_DELEGATION_ENTRY_CAPS, CONFIG_IMAGE_INVALID, CONFIG_LEGACY_TOOL_NAME, CONFIG_LIMIT_INVALID, CONFIG_LIMIT_UNKNOWN_KEY, CONFIG_MCP_SERVER_NAME_COLLISION, CONFIG_MEMORY_PROJECT_KEY_SPELLING, CONFIG_MEMORY_WRITE_SCOPE_MISMATCH, CONFIG_OUTPUT_STYLE_INVALID, CONFIG_TOOL_FACE_CONTROL, CONFLICT_IDEMPOTENCY_PAYLOAD_MISMATCH, CORRUPT_SESSION_ERROR_CODE, DECIDE_CLAIM_LOST, DECIDE_GATE_MOVED, DECIDE_NOT_PARKED, DECIDE_PARK_MOVED_CODES, DECIDE_ROW_UNREVIVABLE, DECIDE_WORKFLOW_HOST_UNKNOWN, DECIDE_WORKFLOW_LANE_CODES, DECIDE_WORKFLOW_PARK_FORKED, DECIDE_WORKFLOW_PARKS_UNREADABLE, DECIDE_WORKFLOW_REMEMBER_UNSUPPORTED, DELEGATION_CAP_CODES, DELEGATION_CONCURRENCY_CAP, DELEGATION_SESSION_CAP, delegationCapDispositionOf, DRAINING_ERROR_CODE, ENGINE_STOP_REASONS, engineStopReasonToCc, ENV_LIFETIME_EXPIRED, FLEET_LEASE_UNAVAILABLE, GATE_PARKED_ERROR_CODE, idempotencyPayloadMismatchContent, isConfigRefusalCode, isCorruptSessionCode, isDecideParkMovedCode, isDecideRowUnrevivableCode, isDelegationCapCode, isIdempotencyPayloadMismatchCode, isInterruptedToolEndCode, isLimitsExceededCode, isRewindFamilyCode, isRulesRefusalCode, isStatusDerivedCoarseCode, isWorkflowParkRefusalCode, LIMITS_MAX_COST_EXCEEDED, LIMITS_MAX_TOKENS_EXCEEDED, LIMITS_MAX_TURNS_EXCEEDED, LIMITS_MAX_WALLTIME_EXCEEDED, MCP_SERVER_REVOKED, MCP_TOOL_DECLARATION_CHANGED, MCP_TOOL_LISTING_UNREACHED, MODEL_FALLBACK_INHERIT_NO_TIER_BINDING, operatorGateRefusalContent, OUTPUT_INVALID, PARKED_RESUME_STARTUP_FAILED, PROMPT_ASSEMBLED_ROLE_REFUSED, REQUEST_AUTONOMY_LANE_REFUSED, RESUME_AT_ERROR_CODE_PREFIX, RESUME_CONTEXT_UNAVAILABLE, RESUME_ENV_FAILED, RESUME_PLACEMENT_MISMATCH, RESUME_POLICY_FOLD_CODE, RESUME_PREFLIGHT_REJECTED, RESUME_REOPEN_CODES, RESUME_RETRY_LATER_CODES, RESUME_TOOL_CONTRACT_MISMATCH, RESUME_TOOL_UNAVAILABLE, RESUME_USAGE_WINDOW_EXHAUSTED, REWIND_ERROR_CODE_PREFIXES, RUN_ORPHANED, RUN_STALLED, runDeathVerdictNoteOf, SCENARIO_ASSIGNMENT_UNKNOWN_ERROR_CODE, SCENARIO_NOT_ALLOWED_ERROR_CODE, STREAM_MAX_DURATION, TOOL_END_INTERRUPTED_NEVER_STARTED, TOOL_END_INTERRUPTED_OUTCOME_UNKNOWN, USAGE_WINDOW_EXHAUSTED, USER_ATTACHMENT_INVALID_ERROR_CODE, USER_INVOKED_SKILL_UNKNOWN_ERROR_CODE, WORKFLOW_PARK_REFUSAL_CODES, } from './engineErrorCodes.js';
106
+ export { ACTIVE_RUN_BUSY_ERROR_CODE, APPROVAL_EXPIRED, ASK_GONE, asModelFallbackReason, CAPABILITY_IMAGE_INDEX_REQUIRED, CAPABILITY_K8S_LANE_REQUIRED, CAPABILITY_OPERATOR_PRINCIPALS_REQUIRED, CAPABILITY_SELF_ORCHESTRATION_REQUIRED, CONFIG_AGENT_UNKNOWN_TOOL, CONFIG_DELEGATION_ENTRY_CAPS, CONFIG_IMAGE_INVALID, CONFIG_LEGACY_TOOL_NAME, CONFIG_LIMIT_INVALID, CONFIG_LIMIT_UNKNOWN_KEY, CONFIG_MCP_SERVER_NAME_COLLISION, CONFIG_MEMORY_PROJECT_KEY_SPELLING, CONFIG_MEMORY_WRITE_SCOPE_MISMATCH, CONFIG_OUTPUT_STYLE_INVALID, CONFIG_TOOL_FACE_CONTROL, CONFLICT_IDEMPOTENCY_PAYLOAD_MISMATCH, CORRUPT_SESSION_ERROR_CODE, DECIDE_CLAIM_LOST, DECIDE_GATE_MOVED, DECIDE_NOT_PARKED, DECIDE_PARK_MOVED_CODES, DECIDE_ROW_UNREVIVABLE, DECIDE_WORKFLOW_HOST_UNKNOWN, DECIDE_WORKFLOW_LANE_CODES, DECIDE_WORKFLOW_PARK_FORKED, DECIDE_WORKFLOW_PARKS_UNREADABLE, DECIDE_WORKFLOW_REMEMBER_UNSUPPORTED, DELEGATION_CAP_CODES, DELEGATION_CONCURRENCY_CAP, DELEGATION_SESSION_CAP, delegationCapDispositionOf, DRAINING_ERROR_CODE, ENGINE_STOP_REASONS, engineStopReasonToCc, ENV_LIFETIME_EXPIRED, FLEET_LEASE_UNAVAILABLE, GATE_PARKED_ERROR_CODE, idempotencyPayloadMismatchContent, isConfigRefusalCode, isCorruptSessionCode, isDecideParkMovedCode, isDecideRowUnrevivableCode, isDelegationCapCode, isIdempotencyPayloadMismatchCode, isInterruptedToolEndCode, isLimitsExceededCode, isRewindFamilyCode, isRulesRefusalCode, isStatusDerivedCoarseCode, isWorkflowParkRefusalCode, LIMITS_MAX_COST_EXCEEDED, LIMITS_MAX_TOKENS_EXCEEDED, LIMITS_MAX_TURNS_EXCEEDED, LIMITS_MAX_WALLTIME_EXCEEDED, MCP_SERVER_REVOKED, MCP_TOOL_DECLARATION_CHANGED, MCP_TOOL_LISTING_UNREACHED, MODEL_FALLBACK_INHERIT_NO_TIER_BINDING, operatorGateRefusalContent, OUTPUT_INVALID, PARKED_RESUME_STARTUP_FAILED, PROMPT_ASSEMBLED_ROLE_REFUSED, REQUEST_AUTONOMY_LANE_REFUSED, RESUME_AT_ERROR_CODE_PREFIX, RESUME_CONTEXT_UNAVAILABLE, RESUME_ENV_FAILED, RESUME_PLACEMENT_MISMATCH, RESUME_POLICY_FOLD_CODE, RESUME_PREFLIGHT_REJECTED, RESUME_REOPEN_CODES, RESUME_RETRY_LATER_CODES, RESUME_TOOL_CONTRACT_MISMATCH, RESUME_TOOL_UNAVAILABLE, RESUME_USAGE_WINDOW_EXHAUSTED, REWIND_ERROR_CODE_PREFIXES, RUN_ORPHANED, RUN_STALLED, runDeathVerdictNoteOf, SCENARIO_ASSIGNMENT_UNKNOWN_ERROR_CODE, SCENARIO_NOT_ALLOWED_ERROR_CODE, STREAM_MAX_DURATION, TOOL_END_INTERRUPTED_NEVER_STARTED, TOOL_END_INTERRUPTED_OUTCOME_UNKNOWN, USAGE_WINDOW_EXHAUSTED, USER_ATTACHMENT_INVALID_ERROR_CODE, USER_INVOKED_SKILL_UNKNOWN_ERROR_CODE, WORKFLOW_PARK_REFUSAL_CODES, ATTACHMENT_BOUND_ELSEWHERE, ATTACHMENT_BUNDLE_INVALID, ATTACHMENT_BUNDLE_LANE_NOT_ISOLATED, ATTACHMENT_BUNDLE_SEED_FIXED, CONFLICT_SESSION_MEMORY_UNOBSERVED, CONFLICT_SESSION_ARCHIVE_STAMPED, ENV_HOME_UNCONFIRMED, } from './engineErrorCodes.js';
103
107
  export { prepareRefusalCodeOf, prepareRefusalNoteOf } from './prepareRefusal.js';
104
108
  export * from './agentsWireCaps.js';
105
109
  export { engineToolDirectoryOf } from './engineToolDirectory.js';
@@ -152,6 +156,7 @@ export * from './adapter/activeRunSelfHeal.js';
152
156
  export * from './request/taskRequest.js';
153
157
  export { disableSkillsDeclaration, disableSkillsDeclarationSettled } from './disableSkillsWire.js';
154
158
  export { approvalReachDeclaration, approvalReachDeclarationSettled } from './approvalReachWire.js';
159
+ export { approvalSeatOf, APPROVAL_SEAT_STATES, APPROVAL_SEAT_BASES } from './approvalSeat.js';
155
160
  export { PERMISSIONS_KEPT_REASONS, WIRE_RULE_TRUST_ORDER, permissionsAllowKeptNotice, permissionsDeclaration, permissionsDeclarationReport } from './permissionsDeclaration.js';
156
161
  export { ASSEMBLY_REFUSAL_CAUSES, assemblyRefusalOf } from './wireFailureShape.js';
157
162
  export * from './clientSlice.js';
@@ -191,7 +196,8 @@ export { guardedRead, readOwnDataFiniteNumber, readOwnDataNonEmptyString } from
191
196
  export { contextUsageReadingOf } from './ownKey.js';
192
197
  export { TURN_FAILURE_CATEGORIES, turnFailurePresentation } from './turnFailurePresentation.js';
193
198
  export { readSeatTurnFailure, seatTurnFailureOf } from './turnFailurePresentation.js';
194
- export { REATTACH_BUDGET_FRESH, REATTACH_MAX_TRIES, runReattachPolicy, } from './runReattachPolicy.js';
199
+ export { REATTACH_BUDGET_FRESH, REATTACH_BUDGET_NONE, REATTACH_MAX_TRIES, STREAM_CAP_CREDIBLE_AFTER_MS, runReattachPolicy, } from './runReattachPolicy.js';
200
+ export { runNotFollowedNotice, runNotFollowedOf } from './runFollow.js';
195
201
  export * from './corruptSession.js';
196
202
  export * from './corruptSessionCopy.js';
197
203
  export { SEMA_TOOL_HISTORY_ACCEPTED_KEY, classifyToolHistoryMismatch, readToolHistoryAcceptedKey, readToolHistoryMismatchKey, resolveToolHistoryRewindTarget } from './toolHistoryMismatch.js';
@@ -218,6 +224,7 @@ export { POISON_FRAME_RAW_MAX, REATTACH_BACKOFF_CAP_MS, REATTACH_BACKOFF_START_M
218
224
  export * from './inheritEnvWire.js';
219
225
  export * from './inheritEnvCapability.js';
220
226
  export { SUPPORT_FLOOR, supportFloorOf, engineVersionTier, engineSupportFloorEffective, coreVersionTier, compareReleaseVersions } from './supportFloor.js';
227
+ export { SERVER_SUPPORT_RANGE_REASONS, serverSupportRangeVerdict, serverSupportRangeSentence } from './serverSupportRange.js';
221
228
  export * from './decideReceipt.js';
222
229
  export * from './sessionMap.js';
223
230
  export * from './detachWire.js';
@@ -254,6 +261,9 @@ export * from './coreValuePorts.js';
254
261
  export { ruleToolNameVerdictOf } from './protocolSegment.js';
255
262
  export * from './hitl/askGateWire.js';
256
263
  export * from './hitl/planReviewWire.js';
264
+ export { planReviewBodyOf } from './planReviewCardFacts.js';
265
+ export { planReviewCardNote } from './hitl/planReviewCard.js';
266
+ export { readRunLedgerSnapshot } from './runLedgerSnapshot.js';
257
267
  export { decisionInFlightOf, decisionReadMark } from './hitl/decisionLedger.js';
258
268
  export { ASK_PARK_AUTO_REOPEN_BLOCKS, askParkAutoReopenBlockedContent, askParkAutoReopenBlockOf, askParkRefusalBlockOf, claimAskParkAutoReopenBlockNotice, clearAskParkAutoReopenBlocks, } from './hitl/askParkAutoReopenBlock.js';
259
269
  export { HITL_DECISION_FAMILIES, HITL_DECISION_NOT_APPLIED_CAUSES, HITL_DECISION_NOT_SENT_CAUSES, HITL_DECISION_UNCONFIRMED_CAUSES, sendHitlDecision, hitlDecisionOutcomeContent, } from './hitl/decisionSend.js';
@@ -300,6 +310,9 @@ export * from './compensations.js';
300
310
  export * from './request/printNotification.js';
301
311
  export * from './seatContract.js';
302
312
  export { sessionRowTagOf, sessionRowPatchRefusalOf } from './sessionRowTag.js';
313
+ export { sessionRowUnreadableOf } from './sessionRowTag.js';
314
+ export { projectSeedGateContent, projectSeedGateOf, projectSeedRefusalContent, projectSeedRefusalOf } from './projectSeed.js';
315
+ export { sessionMemorySyncNotice, sessionMemorySyncStateOf } from './sessionMemorySync.js';
303
316
  export { mcpToolTogglesToExcludeTools } from './mcpToolToggles.js';
304
317
  export { readThinkingLatch, writeThinkingLatch, thinkingLatchView, thinkingLatchSentence, thinkingLatchRowWordOf, readSeatThinkingLatch } from './thinkingLatch.js';
305
318
  export { devicesFaceOf, devicesWritesAllowed, devicesFaceDetail } from './devicesFace.js';
@@ -308,6 +321,8 @@ export { KEY_SLOT_PREFIX, keyEnvNameForEntry, onboardBaseUrlProblem, onboardRefu
308
321
  export * from './agentSession/contract.js';
309
322
  export * from './agentSession/backgroundView.js';
310
323
  export { readAssistantInbox } from './assistantInbox.js';
324
+ export { checkpointRowVerdictOf } from './checkpointRowVerdict.js';
325
+ export { checkpointRequirementsDamagedOf } from './checkpointRowVerdict.js';
311
326
  export { READ_CREDENTIAL_NOT_ACCEPTED_NOTICE, isReadCredentialRefusal } from './readCredentialRefusal.js';
312
327
  export { readEngineAgentRegistry, isEngineAgentRegistryListingSuperseded } from './agentSession/engineAgentRegistryRead.js';
313
328
  export { stopEngineSessionBackground, engineSessionBackgroundReceiptReadingOf, ENGINE_SESSION_BACKGROUND_RECEIPT_STATES, } from './agentSession/engineSessionBackgroundStop.js';
@@ -342,3 +357,5 @@ export { PROJECT_MEMORY_WORDS, projectMemoryOf, observedProjectMemoryCapability,
342
357
  export { sessionRulesChildrenReadLiveOf } from './sessionRulesChildrenReadLive.js';
343
358
  export { scenarioSkillsOf, observedScenarioSkillsCapability } from './scenarioSkills.js';
344
359
  export { observedApprovalFrameFamilies, approvalFrameFamiliesDeclaration } from './approvalFrameFamilies.js';
360
+ export { sessionEngineBindingFor, commitSessionEngine, readSessionEngine, sessionDispatchTarget } from './sessionEngine.js';
361
+ export { foldSessionPlacement } from './deviceRebind.js';
@@ -40,7 +40,6 @@ export const ENGINE_RUNNER_FACE = [
40
40
  'SendMessage',
41
41
  'ListAgents',
42
42
  'Skill',
43
- 'TaskOutput',
44
43
  'TaskStop',
45
44
  'ToolSearch',
46
45
  'Workflow',
@@ -22,6 +22,7 @@ export interface LiveModelCatalog {
22
22
  };
23
23
  droppedEntries?: readonly LiveModelDroppedEntry[];
24
24
  candidateRejected?: unknown;
25
+ modelPlane?: {} | null;
25
26
  }
26
27
  export declare function setLiveModelCatalog(next: LiveModelCatalog | null): void;
27
28
  export declare function setLiveModelCatalogRefresher(fn: (() => Promise<LiveModelCatalog | null>) | null): void;
@@ -103,6 +104,20 @@ export type ModelCandidateRejectedReading = {
103
104
  readonly kind: 'unreadable';
104
105
  };
105
106
  export declare function modelCandidateRejectedOf(catalog?: LiveModelCatalog | null): ModelCandidateRejectedReading;
107
+ export declare const MODEL_PLANE_SERVED_TABLES: readonly ["env", "catalog"];
108
+ export type ModelPlaneServedTable = (typeof MODEL_PLANE_SERVED_TABLES)[number];
109
+ export declare const MODEL_PLANE_CATALOG_STANCES: readonly ["absent", "adopted", "refused"];
110
+ export type ModelPlaneCatalogStance = (typeof MODEL_PLANE_CATALOG_STANCES)[number];
111
+ export type ModelPlaneReading = {
112
+ readonly kind: 'not_reported';
113
+ } | {
114
+ readonly kind: 'read';
115
+ readonly servedTable?: ModelPlaneServedTable;
116
+ readonly catalog?: ModelPlaneCatalogStance;
117
+ } | {
118
+ readonly kind: 'unreadable';
119
+ };
120
+ export declare function modelPlaneOf(catalog?: LiveModelCatalog | null): ModelPlaneReading;
106
121
  export declare function modelCandidateRejectedContent(reading: ModelCandidateRejectedReading, lang?: UiLanguage): string | undefined;
107
122
  export interface RoutePairingVerdict {
108
123
  verdict: 'ok' | 'broken' | 'unknown';
@@ -383,6 +383,43 @@ export function modelCandidateRejectedOf(catalog = getLiveModelCatalog()) {
383
383
  return unreadable;
384
384
  }
385
385
  }
386
+ export const MODEL_PLANE_SERVED_TABLES = Object.freeze(['env', 'catalog']);
387
+ export const MODEL_PLANE_CATALOG_STANCES = Object.freeze(['absent', 'adopted', 'refused']);
388
+ const inWords = (words, v) => typeof v === 'string' && words.includes(v);
389
+ export function modelPlaneOf(catalog = getLiveModelCatalog()) {
390
+ const unreadable = Object.freeze({ kind: 'unreadable' });
391
+ try {
392
+ if (catalog === null || typeof catalog !== 'object' || Array.isArray(catalog))
393
+ return Object.freeze({ kind: 'not_reported' });
394
+ if (!Object.hasOwn(catalog, 'modelPlane'))
395
+ return Object.freeze({ kind: 'not_reported' });
396
+ const d = Object.getOwnPropertyDescriptor(catalog, 'modelPlane');
397
+ if (d === undefined || !(Object.hasOwn(d, 'value')))
398
+ return unreadable;
399
+ const v = d.value;
400
+ if (v === undefined)
401
+ return Object.freeze({ kind: 'not_reported' });
402
+ if (v === null || typeof v !== 'object' || Array.isArray(v))
403
+ return unreadable;
404
+ const proto = Object.getPrototypeOf(v);
405
+ if (proto !== Object.prototype && proto !== null)
406
+ return unreadable;
407
+ const dServed = Object.getOwnPropertyDescriptor(v, 'servedTable');
408
+ const dStance = Object.getOwnPropertyDescriptor(v, 'catalog');
409
+ if ((dServed !== undefined && !Object.hasOwn(dServed, 'value')) || (dStance !== undefined && !Object.hasOwn(dStance, 'value')))
410
+ return unreadable;
411
+ const servedTable = dServed?.value;
412
+ const stance = dStance?.value;
413
+ return Object.freeze({
414
+ kind: 'read',
415
+ ...(inWords(MODEL_PLANE_SERVED_TABLES, servedTable) ? { servedTable } : {}),
416
+ ...(inWords(MODEL_PLANE_CATALOG_STANCES, stance) ? { catalog: stance } : {}),
417
+ });
418
+ }
419
+ catch {
420
+ return unreadable;
421
+ }
422
+ }
386
423
  const CONFIG_DOMAIN_WORD = /^[a-z][a-z0-9_.-]{0,63}$/;
387
424
  export function modelCandidateRejectedContent(reading, lang) {
388
425
  try {
@@ -429,6 +466,7 @@ export function readLiveModelCatalog(body) {
429
466
  const defaultModelKey = envelopeKey(body, 'defaultModel');
430
467
  const droppedKey = envelopeKey(body, 'droppedEntries');
431
468
  const candidateKey = envelopeKey(body, 'candidateRejected');
469
+ const planeKey = envelopeKey(body, 'modelPlane');
432
470
  const raw = modelsKey.present ? modelsKey.value : undefined;
433
471
  if (!Array.isArray(raw))
434
472
  return unreadableCatalog('models_not_array');
@@ -464,6 +502,8 @@ export function readLiveModelCatalog(body) {
464
502
  }
465
503
  if (candidateKey.present && candidateKey.value !== undefined)
466
504
  out.candidateRejected = frozenJsonCopyOf(candidateKey.value) ?? null;
505
+ if (planeKey.present && planeKey.value !== undefined)
506
+ out.modelPlane = frozenJsonCopyOf(planeKey.value) ?? null;
467
507
  return Object.freeze({ kind: 'read', catalog: Object.freeze(out), unreadableRows, ...(defaultModelMalformed ? { defaultModelMalformed: true } : {}) });
468
508
  }
469
509
  catch {
@@ -0,0 +1,18 @@
1
+ import type { McpServerSpec } from '@sema-agent/sdk';
2
+ export type McpRequestTransportKind = McpServerSpec['transport']['kind'];
3
+ export declare const MCP_TRANSPORT_KINDS_WHEN_NOT_STATED: readonly ["stdio", "http"];
4
+ export type McpTransportKindsReading = {
5
+ readonly kind: 'stated';
6
+ readonly kinds: readonly McpRequestTransportKind[];
7
+ readonly unrecognized: readonly string[];
8
+ } | {
9
+ readonly kind: 'not_stated';
10
+ readonly kinds: readonly McpRequestTransportKind[];
11
+ } | {
12
+ readonly kind: 'unreadable';
13
+ } | {
14
+ readonly kind: 'unobserved';
15
+ };
16
+ export declare function projectMcpTransportKindsCapability(caps: unknown): McpTransportKindsReading | undefined;
17
+ export declare function observedMcpTransportKinds(baseUrl?: string | undefined): McpTransportKindsReading;
18
+ export declare function mcpTransportNotAdvertised(reading: McpTransportKindsReading | undefined, transportKind: string): readonly McpRequestTransportKind[] | undefined;
@@ -0,0 +1,75 @@
1
+ import { engineWireTargetBaseUrl } from './engineWireTarget.js';
2
+ import { createEngineCapReader } from './engineCapReader.js';
3
+ import { appendOwnElement, ownDataField } from './ownKey.js';
4
+ export const MCP_TRANSPORT_KINDS_WHEN_NOT_STATED = Object.freeze(['stdio', 'http']);
5
+ const _kindsEqRequestFace = true;
6
+ void _kindsEqRequestFace;
7
+ const KNOWN = new Set(MCP_TRANSPORT_KINDS_WHEN_NOT_STATED);
8
+ export function projectMcpTransportKindsCapability(caps) {
9
+ try {
10
+ if (caps === null || typeof caps !== 'object' || Array.isArray(caps))
11
+ return undefined;
12
+ const v = ownDataField(caps, 'mcpTransportKinds');
13
+ if (v === undefined)
14
+ return { kind: 'not_stated', kinds: MCP_TRANSPORT_KINDS_WHEN_NOT_STATED };
15
+ if (!Array.isArray(v))
16
+ return undefined;
17
+ const len = ownDataField(v, 'length');
18
+ if (typeof len !== 'number' || !Number.isSafeInteger(len) || len < 0 || len > 1000)
19
+ return undefined;
20
+ const kinds = [];
21
+ const unrecognized = [];
22
+ for (let i = 0; i < len; i++) {
23
+ if (!Object.hasOwn(v, i))
24
+ return undefined;
25
+ const w = ownDataField(v, String(i));
26
+ if (typeof w !== 'string')
27
+ return undefined;
28
+ if (KNOWN.has(w)) {
29
+ if (!kinds.includes(w))
30
+ appendOwnElement(kinds, w);
31
+ }
32
+ else if (!unrecognized.includes(w))
33
+ appendOwnElement(unrecognized, w);
34
+ }
35
+ return { kind: 'stated', kinds, unrecognized };
36
+ }
37
+ catch {
38
+ return undefined;
39
+ }
40
+ }
41
+ const reader = createEngineCapReader({
42
+ name: 'mcpTransportKinds',
43
+ project: projectMcpTransportKindsCapability,
44
+ });
45
+ export function observedMcpTransportKinds(baseUrl = engineWireTargetBaseUrl()) {
46
+ return reader.observed(baseUrl);
47
+ }
48
+ export function mcpTransportNotAdvertised(reading, transportKind) {
49
+ try {
50
+ if (reading === null || reading === undefined || typeof reading !== 'object' || Array.isArray(reading))
51
+ return undefined;
52
+ if (ownDataField(reading, 'kind') !== 'stated')
53
+ return undefined;
54
+ const kinds = ownDataField(reading, 'kinds');
55
+ if (!Array.isArray(kinds))
56
+ return undefined;
57
+ const len = ownDataField(kinds, 'length');
58
+ if (typeof len !== 'number' || !Number.isSafeInteger(len) || len < 0 || len > MCP_TRANSPORT_KINDS_WHEN_NOT_STATED.length)
59
+ return undefined;
60
+ const list = [];
61
+ for (let i = 0; i < len; i++) {
62
+ if (!Object.hasOwn(kinds, i))
63
+ return undefined;
64
+ const k = ownDataField(kinds, String(i));
65
+ if (typeof k !== 'string' || !KNOWN.has(k))
66
+ return undefined;
67
+ if (!list.includes(k))
68
+ appendOwnElement(list, k);
69
+ }
70
+ return list.includes(transportKind) ? undefined : Object.freeze([...list]);
71
+ }
72
+ catch {
73
+ return undefined;
74
+ }
75
+ }
@@ -1,5 +1,6 @@
1
1
  import type { McpServerSpec } from '@sema-agent/sdk';
2
2
  import type { McpEntryKeyIssue } from './generated/settingsSchemaTypes.js';
3
+ import { type McpTransportKindsReading } from './mcpTransportKindsCapability.js';
3
4
  import type { UiLanguage } from './env/uiLanguage.js';
4
5
  export type { McpServerSpec };
5
6
  export interface McpConfigLike {
@@ -16,6 +17,7 @@ export interface McpConfigLike {
16
17
  toolFaces?: unknown;
17
18
  toolAxes?: unknown;
18
19
  startupTimeoutMs?: number;
20
+ sessionMetaKey?: string;
19
21
  }
20
22
  export type McpTransportEntryLike = Pick<McpConfigLike, 'type' | 'command' | 'args' | 'env' | 'url' | 'headers' | 'principalHeader' | 'assertionHeader'>;
21
23
  export type McpTransportVerdict = {
@@ -72,7 +74,7 @@ export type McpAllowToolsVerdict = {
72
74
  readonly problem: string;
73
75
  };
74
76
  export declare function mcpAllowToolsVerdict(read: () => {} | null | undefined, keyPrefix?: string): McpAllowToolsVerdict;
75
- export type McpConfigDropReason = 'name_blank' | 'name_edge_whitespace' | 'name_collides_after_trim' | 'name_too_long' | 'name_reserved' | 'transport_invalid' | 'identity_headers_both_set' | 'tool_axes_invalid' | 'tool_faces_invalid' | 'elicitation_invalid' | 'allow_tools_invalid' | 'entry_not_object' | 'entry_unreadable';
77
+ export type McpConfigDropReason = 'name_blank' | 'name_edge_whitespace' | 'name_collides_after_trim' | 'name_too_long' | 'name_reserved' | 'transport_invalid' | 'identity_headers_both_set' | 'tool_axes_invalid' | 'tool_faces_invalid' | 'elicitation_invalid' | 'allow_tools_invalid' | 'entry_not_object' | 'entry_unreadable' | 'transport_not_advertised';
76
78
  export type McpServerNameUnusableReason = 'name_blank' | 'name_edge_whitespace' | 'name_collides_after_trim' | 'name_too_long' | 'name_reserved';
77
79
  export type McpServerNameVerdict = {
78
80
  readonly usable: true;
@@ -100,6 +102,7 @@ export interface McpConfigProjection {
100
102
  }
101
103
  export interface ProjectMcpConfigsOptions {
102
104
  readonly sourceLabel?: (serverName: string) => string | undefined;
105
+ readonly transportKinds?: McpTransportKindsReading;
103
106
  readonly lang?: UiLanguage;
104
107
  }
105
108
  export declare function projectMcpConfigs(servers: Record<string, McpConfigLike> | undefined, opts?: ProjectMcpConfigsOptions): McpConfigProjection;
@@ -4,14 +4,16 @@ import { appendOwnElement, guardedRead } from './ownKey.js';
4
4
  import { readMcpToolAxes, readToolFaces } from './coreValuePorts.js';
5
5
  import { capForDisplay } from './fleetTaskDesc.js';
6
6
  import { msg, renderMessage } from './i18n/translate.js';
7
+ import { mcpTransportNotAdvertised } from './mcpTransportKindsCapability.js';
7
8
  const _mcpServerSpecPin = true;
8
9
  void _mcpServerSpecPin;
9
- function transparentKeys(startupTimeoutMs, axes, faces, elicitation) {
10
+ function transparentKeys(startupTimeoutMs, axes, faces, elicitation, sessionMetaKey) {
10
11
  return {
11
12
  ...(faces !== undefined ? { toolFaces: faces } : {}),
12
13
  ...(axes !== undefined ? { toolAxes: axes } : {}),
13
14
  ...(elicitation !== undefined ? { elicitation } : {}),
14
15
  ...(startupTimeoutMs !== undefined ? { startupTimeoutMs } : {}),
16
+ ...(sessionMetaKey !== undefined ? { sessionMetaKey } : {}),
15
17
  };
16
18
  }
17
19
  export function readMcpHttpIdentityHeaders(transport) {
@@ -36,7 +38,7 @@ function entryShapeOf(c) {
36
38
  function readEntryOwnKeys(c) {
37
39
  try {
38
40
  const allowTools = c.allowTools;
39
- return { toolAxes: c.toolAxes, elicitation: c.elicitation, allowTools, startupTimeoutMs: c.startupTimeoutMs };
41
+ return { toolAxes: c.toolAxes, elicitation: c.elicitation, allowTools, startupTimeoutMs: c.startupTimeoutMs, sessionMetaKey: c.sessionMetaKey };
40
42
  }
41
43
  catch {
42
44
  return undefined;
@@ -153,7 +155,7 @@ function specOf(name, c, own, axes, faces, elicitation, allowTools) {
153
155
  name,
154
156
  transport: t.transport,
155
157
  ...(allowTools !== undefined ? { allowTools } : {}),
156
- ...transparentKeys(own.startupTimeoutMs, axes, faces, elicitation),
158
+ ...transparentKeys(own.startupTimeoutMs, axes, faces, elicitation, own.sessionMetaKey),
157
159
  };
158
160
  return { kind: 'ok', spec, lost: t.lost };
159
161
  }
@@ -305,7 +307,7 @@ const DROP_LABEL_SHOWN = 140;
305
307
  const DROP_PROBLEM_SHOWN = 300;
306
308
  const DROP_BAD_NAME_SHOWN = 160;
307
309
  const DEGRADED_LOST_SHOWN = 400;
308
- function dropNotice(name, reason, problem, opts, path) {
310
+ function dropNotice(name, reason, problem, opts, path, transportKind) {
309
311
  let label;
310
312
  try {
311
313
  label = opts?.sourceLabel?.(name);
@@ -332,15 +334,17 @@ function dropNotice(name, reason, problem, opts, path) {
332
334
  ? msg('config.mcp.identityHeadersBothSet', { name: quoted, where })
333
335
  : reason === 'transport_invalid'
334
336
  ? msg('config.mcp.transportInvalid', { name: quoted, where, path: capForDisplay(path ?? 'transport', DROP_NAME_SHOWN), problem: capForDisplay(problem ?? '', DROP_PROBLEM_SHOWN) })
335
- : reason === 'name_blank'
336
- ? msg('config.mcp.nameBlank', { name: badName(), where })
337
- : reason === 'name_collides_after_trim'
338
- ? msg('config.mcp.nameCollides', { name: badName(), where })
339
- : reason === 'name_too_long'
340
- ? msg('config.mcp.nameTooLong', { name: badName(), where })
341
- : reason === 'name_reserved'
342
- ? msg('config.mcp.nameReserved', { name: badName(), where })
343
- : msg('config.mcp.nameEdgeWhitespace', { name: badName(), where });
337
+ : reason === 'transport_not_advertised'
338
+ ? msg('config.mcp.transportNotAdvertised', { name: quoted, where, kind: capForDisplay(transportKind ?? '', DROP_NAME_SHOWN), supported: problem !== undefined && problem.length > 0 ? problem : renderMessage(msg('config.mcp.transportsNone'), opts?.lang) })
339
+ : reason === 'name_blank'
340
+ ? msg('config.mcp.nameBlank', { name: badName(), where })
341
+ : reason === 'name_collides_after_trim'
342
+ ? msg('config.mcp.nameCollides', { name: badName(), where })
343
+ : reason === 'name_too_long'
344
+ ? msg('config.mcp.nameTooLong', { name: badName(), where })
345
+ : reason === 'name_reserved'
346
+ ? msg('config.mcp.nameReserved', { name: badName(), where })
347
+ : msg('config.mcp.nameEdgeWhitespace', { name: badName(), where });
344
348
  return renderMessage(ref, opts?.lang);
345
349
  }
346
350
  function degradedNotice(name, lost, opts) {
@@ -381,6 +385,13 @@ export function projectMcpConfigs(servers, opts) {
381
385
  }
382
386
  const out = slotUnreadable ? { spec: null, entryUnreadable: true } : mcpConfigEntry(name, c);
383
387
  if (out.spec !== null) {
388
+ const kind = out.spec.transport.kind;
389
+ const supported = opts?.transportKinds === undefined ? undefined : mcpTransportNotAdvertised(opts.transportKinds, kind);
390
+ if (supported !== undefined) {
391
+ const listed = supported.join(', ');
392
+ dropped.push({ name, reason: 'transport_not_advertised', path: 'transport.kind', problem: listed, notice: dropNotice(name, 'transport_not_advertised', listed, opts, 'transport.kind', kind) });
393
+ continue;
394
+ }
384
395
  specs.push(out.spec);
385
396
  if (out.transportLost !== undefined)
386
397
  degraded.push({ name, lost: Object.freeze([...out.transportLost]), notice: degradedNotice(name, out.transportLost, opts) });
@@ -437,6 +448,6 @@ export function mcpAssertionHeaderNotSentNotice(specs) {
437
448
  const parts = distinct.slice(0, ASSERTION_NOTICE_NAMES_SHOWN).map((x) => `"${x}"`);
438
449
  if (distinct.length > ASSERTION_NOTICE_NAMES_SHOWN)
439
450
  parts.push(`+${distinct.length - ASSERTION_NOTICE_NAMES_SHOWN} more`);
440
- return (`MCP servers that declare an assertion header (assertionHeader): ${parts.join(', ')} — server versions up to 7.139.0 accept this setting but do not send the header, ` +
451
+ return (`MCP servers that declare an assertion header (assertionHeader): ${parts.join(', ')} — server versions up to 7.144.0 accept this setting but do not send the header, ` +
441
452
  'and this client cannot tell whether the engine it uses sends it; a connector that requires the header will refuse requests from these servers');
442
453
  }
@@ -155,15 +155,48 @@ function isBusyStatus(status) {
155
155
  function looksBusyError(apiError) {
156
156
  return apiError !== undefined && /overload|rate.?limit|too many requests|too busy|server busy|capacity/i.test(apiError);
157
157
  }
158
- function apiErrorOf(parsed) {
159
- const e = parsed?.error;
160
- if (!e || typeof e !== 'object')
158
+ function wordOf(v) {
159
+ if (typeof v === 'string')
160
+ return v.trim() === '' ? undefined : v;
161
+ return typeof v === 'number' && Number.isFinite(v) && v !== 0 ? String(v) : undefined;
162
+ }
163
+ function hasContent(v, depth = 0) {
164
+ if (typeof v === 'string')
165
+ return v.trim() !== '';
166
+ if (typeof v === 'number')
167
+ return Number.isFinite(v) && v !== 0;
168
+ if (v === true)
169
+ return true;
170
+ if (v === null || typeof v !== 'object')
171
+ return false;
172
+ if (depth >= 2)
173
+ return true;
174
+ return (Array.isArray(v) ? v : Object.values(v)).some((x) => hasContent(x, depth + 1));
175
+ }
176
+ function errorBodyOf(parsed) {
177
+ if (parsed === null || typeof parsed !== 'object')
161
178
  return undefined;
162
- return [e.code ?? e.type, e.message].filter(Boolean).join(': ') || undefined;
179
+ const e = parsed.error;
180
+ const o = e;
181
+ if (o !== null && o !== undefined && typeof o === 'object' && !Array.isArray(o)) {
182
+ const legacy = [o.code ?? o.type, o.message].filter(Boolean).join(': ');
183
+ if (legacy !== '')
184
+ return { words: legacy, standard: true };
185
+ }
186
+ if (!hasContent(e))
187
+ return undefined;
188
+ if (typeof e !== 'object' || e === null) {
189
+ const words = wordOf(e);
190
+ return words === undefined ? { standard: false } : { words, standard: false };
191
+ }
192
+ if (Array.isArray(e))
193
+ return { standard: false };
194
+ const words = [wordOf(o?.code) ?? wordOf(o?.type) ?? wordOf(o?.status), wordOf(o?.message) ?? wordOf(o?.detail)].filter((x) => x !== undefined).join(': ');
195
+ return { ...(words !== '' ? { words } : {}), standard: false };
163
196
  }
164
- function extractApiError(body) {
197
+ function extractErrorBody(body) {
165
198
  try {
166
- return apiErrorOf(JSON.parse(body));
199
+ return errorBodyOf(JSON.parse(body));
167
200
  }
168
201
  catch {
169
202
  return undefined;
@@ -189,12 +222,10 @@ function shownApiError(raw, redact) {
189
222
  const shown = displayUntrusted(masked, { max: 200 });
190
223
  return shown.trim() === '' ? undefined : shown;
191
224
  }
192
- function looksLikeModelError(status, apiError) {
225
+ function namesModel(status, apiError) {
193
226
  if (status !== 400 && status !== 404 && status !== 422)
194
227
  return false;
195
- if (!apiError)
196
- return status === 404;
197
- return /model/i.test(apiError);
228
+ return apiError !== undefined && /model/i.test(apiError);
198
229
  }
199
230
  const MESSAGES_PATH = '/v1/messages';
200
231
  const COMPLETIONS_PATH = '/chat/completions';
@@ -204,33 +235,33 @@ function verdictRequestBody(modelId) {
204
235
  return JSON.stringify({ model: modelId ?? '', max_tokens: 1, messages: [{ role: 'user', content: 'hi' }], stream: true });
205
236
  }
206
237
  function judgeMessagesFailure(status, body, hasModelId, near, redact) {
207
- if (status === 401 || status === 403)
208
- return { verdict: 'auth', httpStatus: status, path: MESSAGES_PATH };
209
- const apiError = extractApiError(body);
238
+ const eb = extractErrorBody(body);
239
+ const apiError = eb?.words;
240
+ const standard = eb?.standard === true;
210
241
  const shown = shownApiError(apiError, redact);
211
242
  const ev = { httpStatus: status, path: MESSAGES_PATH, ...(shown !== undefined ? { apiError: shown } : {}) };
243
+ if (status === 401 || status === 403)
244
+ return { verdict: 'auth', ...ev };
212
245
  if (isBusyStatus(status) || looksBusyError(apiError))
213
246
  return { verdict: 'busy', ...ev };
214
- if (status === 404 && !apiError)
215
- return { verdict: 'shape', httpStatus: status, path: MESSAGES_PATH };
216
- if (looksLikeModelError(status, apiError)) {
217
- if (!hasModelId)
218
- return { verdict: 'ok', httpStatus: status, path: MESSAGES_PATH };
219
- return { verdict: 'model', ...ev, ...(near !== undefined ? { nearModelId: near } : {}) };
220
- }
221
- if (!hasModelId && status >= 400 && status < 500 && apiError)
247
+ if (!hasModelId && standard && status >= 400 && status < 500)
222
248
  return { verdict: 'ok', httpStatus: status, path: MESSAGES_PATH };
249
+ if (hasModelId && namesModel(status, apiError))
250
+ return { verdict: 'model', ...ev, ...(near !== undefined ? { nearModelId: near } : {}) };
251
+ if (status === 404 && !standard)
252
+ return { verdict: 'shape', ...ev };
223
253
  return { verdict: 'other', ...ev };
224
254
  }
225
255
  function judgeCompletionsFailure(status, body, near, redact) {
226
- if (status === 401 || status === 403)
227
- return { verdict: 'auth', httpStatus: status, path: COMPLETIONS_PATH };
228
- const apiError = extractApiError(body);
256
+ const eb = extractErrorBody(body);
257
+ const apiError = eb?.words;
229
258
  const shown = shownApiError(apiError, redact);
230
259
  const ev = { httpStatus: status, path: COMPLETIONS_PATH, ...(shown !== undefined ? { apiError: shown } : {}) };
260
+ if (status === 401 || status === 403)
261
+ return { verdict: 'auth', ...ev };
231
262
  if (isBusyStatus(status) || looksBusyError(apiError))
232
263
  return { verdict: 'busy', ...ev };
233
- if (looksLikeModelError(status, apiError))
264
+ if (namesModel(status, apiError) || (status === 404 && eb?.standard !== true))
234
265
  return { verdict: 'model', ...ev, ...(near !== undefined ? { nearModelId: near } : {}) };
235
266
  return { verdict: 'other', ...ev };
236
267
  }
@@ -318,9 +349,9 @@ function judgeJsonBody(text, contentType, api) {
318
349
  if (obj === null || typeof obj !== 'object')
319
350
  return { kind: 'not_model', contentType };
320
351
  const o = obj;
321
- const apiError = apiErrorOf(o);
322
- if (apiError !== undefined || o.type === 'error')
323
- return { kind: 'error', ...(apiError !== undefined ? { apiError } : {}) };
352
+ const eb = errorBodyOf(o);
353
+ if (eb !== undefined || o.type === 'error')
354
+ return { kind: 'error', ...(eb?.words !== undefined ? { apiError: eb.words } : {}) };
324
355
  const usage = (o.usage ?? null);
325
356
  if (api === 'anthropic-messages') {
326
357
  if (o.type !== 'message' && !Array.isArray(o.content))
@@ -365,9 +396,9 @@ function createAnswerScanner(contentType, api) {
365
396
  if (obj === null || typeof obj !== 'object')
366
397
  return;
367
398
  const o = obj;
368
- const apiError = apiErrorOf(o);
369
- if (ev === 'error' || o.type === 'error' || apiError !== undefined) {
370
- settled = { kind: 'error', ...(apiError !== undefined ? { apiError } : {}) };
399
+ const eb = errorBodyOf(o);
400
+ if (ev === 'error' || o.type === 'error' || eb !== undefined) {
401
+ settled = { kind: 'error', ...(eb?.words !== undefined ? { apiError: eb.words } : {}) };
371
402
  return;
372
403
  }
373
404
  if (isTokenFrame(o, api))
@@ -667,8 +698,10 @@ async function livenessOf(input) {
667
698
  }
668
699
  }
669
700
  const gate = await getCatalogText(fetchIt, urlOf(MODELS_PATH_OPENAI), getHeaders, catalogBudget, input.signal);
670
- if (gate.status === 401 || gate.status === 403)
671
- return { verdict: 'auth', httpStatus: gate.status, path: '/models' };
701
+ if (gate.status === 401 || gate.status === 403) {
702
+ const shown = shownApiError(extractErrorBody(gate.text)?.words, redact);
703
+ return { verdict: 'auth', httpStatus: gate.status, path: '/models', ...(shown !== undefined ? { apiError: shown } : {}) };
704
+ }
672
705
  if (isBusyStatus(gate.status))
673
706
  return { verdict: 'busy', httpStatus: gate.status, path: '/models' };
674
707
  if (gate.status < 200 || gate.status >= 300)
@@ -42,6 +42,14 @@ export declare function taskNotificationDedupKey(n: {
42
42
  seq?: number | string;
43
43
  taskType?: string;
44
44
  }): string;
45
+ export interface TaskNotificationRenderKeyInput {
46
+ taskId: string;
47
+ status: string;
48
+ seq?: number | string;
49
+ taskType?: string;
50
+ completionId?: string;
51
+ }
52
+ export declare function taskNotificationRenderKeys(n: TaskNotificationRenderKeyInput): readonly [selfKey: string, ...completionKey: string[]];
45
53
  export declare function taskNotificationDedupKeyFromWire(raw: Record<string, unknown>): string;
46
54
  export interface TranscriptNotificationSeeds {
47
55
  renderedKeys: string[];
@@ -120,6 +128,7 @@ export interface EngineWorkflowCompletion {
120
128
  runId: string;
121
129
  status: 'completed' | 'failed';
122
130
  summary: string;
131
+ completionId?: string;
123
132
  }
124
133
  export declare function enqueueBgChildNotification(raw: {
125
134
  taskId: string;
@@ -5,7 +5,7 @@ import { panelEndFact } from './panelReduce.js';
5
5
  import { isCoreTaskNotificationTerminal, isCoreTaskNotificationTerminalNotSuccess } from './terminalStatuses.js';
6
6
  import { cycleSeqValue } from './cycleOrder.js';
7
7
  import { CORE_ENGINE_AUTHORITY_ENVELOPE_TAGS } from './generated/engineFactTables.js';
8
- import { guardedRead, ownSnapshot, ownSnapshotRecord, ownSnapshotTyped, readOwnDataValue } from './ownKey.js';
8
+ import { guardedRead, ownSnapshot, ownSnapshotRecord, ownSnapshotTyped, readOwnDataValue, workflowCompletionExtrasOf } from './ownKey.js';
9
9
  function escapeXml(v) {
10
10
  return v.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
11
11
  }
@@ -244,6 +244,14 @@ export function taskNotificationDedupKey(n) {
244
244
  const lane = n.taskType === 'external' ? 'external:' : '';
245
245
  return `${lane}${n.taskId}:${n.status}${seq ? `:${seq}` : ''}`;
246
246
  }
247
+ const COMPLETION_KEY_PREFIX = 'completion:';
248
+ export function taskNotificationRenderKeys(n) {
249
+ const own = taskNotificationDedupKey(n);
250
+ const id = n.completionId;
251
+ if (n.taskType === 'external' || !isCoreTaskNotificationTerminal(n.status) || typeof id !== 'string' || id.length === 0)
252
+ return [own];
253
+ return [own, `${COMPLETION_KEY_PREFIX}${id}`];
254
+ }
247
255
  export function taskNotificationDedupKeyFromWire(raw) {
248
256
  const n = ownSnapshotRecord(raw) ?? {};
249
257
  return taskNotificationDedupKey({
@@ -830,6 +838,7 @@ function enqueueBgChild(n, identity) {
830
838
  ...identity,
831
839
  }));
832
840
  }
841
+ const completionIdOnly = (x) => (x.completionId !== undefined ? { completionId: x.completionId } : {});
833
842
  export function enqueueEngineWorkflowNotification(raw) {
834
843
  const c = ownSnapshotRecord(raw);
835
844
  if (c === undefined) {
@@ -843,7 +852,7 @@ export function enqueueEngineWorkflowNotification(raw) {
843
852
  }
844
853
  markRunNotified(c.runId);
845
854
  cardEnqueuedRunIds.add(c.runId);
846
- port()?.enqueuePendingNotification(taskNotificationQueueCommand({ taskId: c.runId, taskType: 'workflow', status: c.status, summary: c.summary }));
855
+ port()?.enqueuePendingNotification(taskNotificationQueueCommand({ taskId: c.runId, taskType: 'workflow', status: c.status, summary: c.summary, ...completionIdOnly(workflowCompletionExtrasOf(c)) }));
847
856
  }
848
857
  export function _resetEngineTaskNotificationForTest() {
849
858
  notifiedRunIds.clear();