@sema-agent/client-core 0.94.0 → 0.96.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 (332) hide show
  1. package/CHANGELOG.md +521 -0
  2. package/README.md +104 -57
  3. package/dist/adapt/arms.js +12 -7
  4. package/dist/adapt/panelTasks.js +4 -10
  5. package/dist/adapt/toolCards.d.ts +1 -0
  6. package/dist/adapt/toolCards.js +18 -5
  7. package/dist/adapt/wireShapes.js +5 -24
  8. package/dist/adapter/activeRunSelfHeal.d.ts +12 -3
  9. package/dist/adapter/activeRunSelfHeal.js +50 -16
  10. package/dist/adapter/downstream/eventToSdkMessage.js +33 -18
  11. package/dist/adapter/downstream/terminalToSdkResult.js +19 -12
  12. package/dist/adapter/runStream.js +30 -46
  13. package/dist/adapter/types.d.ts +7 -0
  14. package/dist/adapter/types.js +15 -0
  15. package/dist/agentSession/backgroundView.js +5 -1
  16. package/dist/agentSession/engineAgentRegistryRead.js +7 -5
  17. package/dist/agentSession/engineSessionBackgroundStop.js +25 -17
  18. package/dist/agentsWireCaps.d.ts +2 -0
  19. package/dist/agentsWireCaps.js +13 -2
  20. package/dist/approvalDecidedByCapability.d.ts +0 -1
  21. package/dist/approvalDecidedByCapability.js +2 -7
  22. package/dist/approvalsStreamLiveCapability.d.ts +0 -1
  23. package/dist/approvalsStreamLiveCapability.js +2 -6
  24. package/dist/atMostOnce.d.ts +8 -0
  25. package/dist/atMostOnce.js +36 -0
  26. package/dist/attachmentSeatCapability.d.ts +0 -1
  27. package/dist/attachmentSeatCapability.js +0 -3
  28. package/dist/attachmentsWireCaps.js +11 -6
  29. package/dist/bashExitReading.d.ts +10 -0
  30. package/dist/bashExitReading.js +12 -0
  31. package/dist/callerCwdCapability.d.ts +0 -5
  32. package/dist/callerCwdCapability.js +2 -13
  33. package/dist/centerWiringCapability.d.ts +1 -7
  34. package/dist/centerWiringCapability.js +18 -27
  35. package/dist/classifierStatus.js +4 -4
  36. package/dist/classifierVerdictWire.js +4 -16
  37. package/dist/clientSlice.js +1 -1
  38. package/dist/cloudConfigWireCaps.d.ts +3 -3
  39. package/dist/cloudConfigWireCaps.js +85 -43
  40. package/dist/compensations.js +1 -1
  41. package/dist/coreValuePorts.d.ts +11 -7
  42. package/dist/coreValuePorts.js +5 -8
  43. package/dist/credentialProvenance.d.ts +28 -0
  44. package/dist/credentialProvenance.js +76 -0
  45. package/dist/cycleOrder.d.ts +15 -0
  46. package/dist/cycleOrder.js +45 -0
  47. package/dist/decideFailureNote.js +7 -2
  48. package/dist/decideReceipt.d.ts +2 -1
  49. package/dist/decideReceipt.js +39 -14
  50. package/dist/declared/supportFloorDeclared.d.ts +1 -0
  51. package/dist/declared/supportFloorDeclared.js +5 -0
  52. package/dist/deviceExecutorManagementCapability.d.ts +0 -1
  53. package/dist/deviceExecutorManagementCapability.js +7 -16
  54. package/dist/deviceRebind.d.ts +88 -0
  55. package/dist/deviceRebind.js +242 -0
  56. package/dist/displayUntrusted.d.ts +8 -3
  57. package/dist/displayUntrusted.js +661 -63
  58. package/dist/engineAgentAbsence.d.ts +2 -2
  59. package/dist/engineAgentPanelStore.d.ts +8 -18
  60. package/dist/engineAgentPanelStore.js +19 -537
  61. package/dist/engineCapReader.d.ts +6 -6
  62. package/dist/engineCapReader.js +30 -43
  63. package/dist/engineCapsCache.d.ts +13 -2
  64. package/dist/engineCapsCache.js +276 -44
  65. package/dist/engineCredentialRequirement.d.ts +9 -0
  66. package/dist/engineCredentialRequirement.js +23 -0
  67. package/dist/engineDirectory.d.ts +79 -0
  68. package/dist/engineDirectory.js +186 -0
  69. package/dist/engineEnvSourcing.d.ts +53 -0
  70. package/dist/engineEnvSourcing.js +81 -0
  71. package/dist/engineErrorCodes.d.ts +28 -4
  72. package/dist/engineErrorCodes.js +68 -25
  73. package/dist/engineIdentity.js +2 -0
  74. package/dist/engineNoticeCodes.d.ts +17 -0
  75. package/dist/engineNoticeCodes.js +57 -3
  76. package/dist/engineWireSdk.js +2 -2
  77. package/dist/engineWordRenames.d.ts +8 -0
  78. package/dist/engineWordRenames.js +13 -0
  79. package/dist/executionLaneCapability.d.ts +2 -3
  80. package/dist/executionLaneCapability.js +18 -23
  81. package/dist/fileHistoryCaptureCapability.d.ts +14 -1
  82. package/dist/fileHistoryCaptureCapability.js +72 -6
  83. package/dist/fileHistoryLegNotice.d.ts +3 -2
  84. package/dist/fileHistoryLegNotice.js +51 -2
  85. package/dist/fleet/bgSubagentRow.d.ts +15 -0
  86. package/dist/fleet/bgSubagentRow.js +67 -0
  87. package/dist/fleet/fleetLedger.d.ts +3 -0
  88. package/dist/fleet/fleetLedger.js +153 -122
  89. package/dist/fleet/fleetProjection.d.ts +1 -3
  90. package/dist/fleet/fleetProjection.js +19 -19
  91. package/dist/fleetAgentPanelProjection.d.ts +4 -17
  92. package/dist/fleetAgentPanelProjection.js +7 -197
  93. package/dist/fleetAgentRowLike.d.ts +16 -0
  94. package/dist/fleetAgentRowLike.js +1 -0
  95. package/dist/fleetTaskDesc.js +4 -17
  96. package/dist/gateOutcome.d.ts +12 -1
  97. package/dist/gateOutcome.js +87 -18
  98. package/dist/gateVocabulary.d.ts +7 -2
  99. package/dist/gateVocabulary.js +5 -1
  100. package/dist/generated/engineAskFaceTables.js +1 -1
  101. package/dist/generated/engineFactTables.d.ts +5 -3
  102. package/dist/generated/engineFactTables.js +17 -4
  103. package/dist/generated/engineNoticeTables.js +12 -3
  104. package/dist/generated/sdkFactTables.d.ts +2 -0
  105. package/dist/generated/sdkFactTables.js +17 -0
  106. package/dist/generated/settingsSchemaFns.d.ts +13 -0
  107. package/dist/generated/settingsSchemaFns.js +75 -0
  108. package/dist/generated/toolNameTables.d.ts +1 -0
  109. package/dist/generated/toolNameTables.js +1 -0
  110. package/dist/headlessPermissionModeWire.d.ts +1 -1
  111. package/dist/headlessPermissionModeWire.js +1 -1
  112. package/dist/headlessReconnectWire.js +49 -20
  113. package/dist/hitl/allowRuleShadow.d.ts +1 -1
  114. package/dist/hitl/allowRuleShadow.js +49 -8
  115. package/dist/hitl/approvalCompleteParked.d.ts +1 -0
  116. package/dist/hitl/approvalCompleteParked.js +14 -0
  117. package/dist/hitl/approvalEndingCause.d.ts +7 -0
  118. package/dist/hitl/approvalEndingCause.js +71 -0
  119. package/dist/hitl/approvalHolds.d.ts +12 -2
  120. package/dist/hitl/approvalHolds.js +53 -2
  121. package/dist/hitl/approvalsFeed.js +23 -11
  122. package/dist/hitl/askGateWire.d.ts +2 -1
  123. package/dist/hitl/askGateWire.js +26 -1
  124. package/dist/hitl/askParkRowRouting.js +1 -1
  125. package/dist/hitl/automaticAnswerVerdict.d.ts +1 -1
  126. package/dist/hitl/automaticAnswerVerdict.js +15 -10
  127. package/dist/hitl/crashConverged.js +2 -0
  128. package/dist/hitl/decisionConflict.d.ts +3 -0
  129. package/dist/hitl/decisionConflict.js +41 -0
  130. package/dist/hitl/decisionRefusal.d.ts +12 -0
  131. package/dist/hitl/decisionRefusal.js +63 -4
  132. package/dist/hitl/frameRouter.d.ts +0 -1
  133. package/dist/hitl/frameRouter.js +32 -57
  134. package/dist/hitl/gateLedger.d.ts +5 -0
  135. package/dist/hitl/gateLedger.js +21 -0
  136. package/dist/hitl/hitlBridge.d.ts +17 -2
  137. package/dist/hitl/hitlBridge.js +91 -55
  138. package/dist/hitl/hitlHostSurface.js +3 -11
  139. package/dist/hitl/livePendingAsk.d.ts +16 -6
  140. package/dist/hitl/livePendingAsk.js +36 -4
  141. package/dist/hitl/localAllowRule.d.ts +1 -0
  142. package/dist/hitl/localAllowRule.js +2 -2
  143. package/dist/hitl/noAllowCause.d.ts +2 -1
  144. package/dist/hitl/noAllowCause.js +3 -2
  145. package/dist/hitl/parkExpiryJudgements.d.ts +19 -0
  146. package/dist/hitl/parkExpiryJudgements.js +46 -0
  147. package/dist/hitl/parkResolver.d.ts +4 -7
  148. package/dist/hitl/parkResolver.js +12 -34
  149. package/dist/hitl/parkRowBirthWait.d.ts +1 -0
  150. package/dist/hitl/parkRowBirthWait.js +2 -2
  151. package/dist/hitl/persistedRulesWire.js +5 -1
  152. package/dist/hitl/planReviewWire.d.ts +3 -2
  153. package/dist/hitl/planReviewWire.js +154 -50
  154. package/dist/hitl/replayedApproval.d.ts +9 -0
  155. package/dist/hitl/replayedApproval.js +139 -10
  156. package/dist/hitl/resumeRunningCard.d.ts +2 -0
  157. package/dist/hitl/resumeRunningCard.js +15 -4
  158. package/dist/hitl/sessionPolicyDeliverable.js +8 -6
  159. package/dist/hitl/standingRows.d.ts +18 -0
  160. package/dist/hitl/standingRows.js +127 -0
  161. package/dist/hitl/toolApprovalWire.d.ts +39 -7
  162. package/dist/hitl/toolApprovalWire.js +351 -61
  163. package/dist/hookMatcherVerdict.d.ts +1 -9
  164. package/dist/hookMatcherVerdict.js +21 -61
  165. package/dist/hooksWireCaps.js +40 -8
  166. package/dist/host.d.ts +5 -0
  167. package/dist/host.js +3 -1
  168. package/dist/hostCallbackGuard.d.ts +2 -0
  169. package/dist/hostCallbackGuard.js +31 -0
  170. package/dist/index.d.ts +48 -17
  171. package/dist/index.js +36 -15
  172. package/dist/interactiveInterrupt.d.ts +8 -0
  173. package/dist/interactiveInterrupt.js +54 -0
  174. package/dist/limitsWire.d.ts +5 -0
  175. package/dist/limitsWire.js +49 -3
  176. package/dist/liveModelCatalog.d.ts +95 -0
  177. package/dist/liveModelCatalog.js +297 -32
  178. package/dist/mcpEngineLeg.d.ts +25 -0
  179. package/dist/mcpEngineLeg.js +71 -15
  180. package/dist/mcpPanel.js +2 -1
  181. package/dist/mcpProbeCapability.d.ts +0 -5
  182. package/dist/mcpProbeCapability.js +2 -12
  183. package/dist/mcpReconnect.d.ts +1 -3
  184. package/dist/mcpReconnect.js +10 -5
  185. package/dist/memoryComplianceCapability.d.ts +0 -5
  186. package/dist/memoryComplianceCapability.js +2 -12
  187. package/dist/memoryOriginCapability.d.ts +0 -5
  188. package/dist/memoryOriginCapability.js +2 -12
  189. package/dist/memorySpecWire.js +2 -2
  190. package/dist/memoryVerbsWire.d.ts +1 -1
  191. package/dist/memoryVerbsWire.js +4 -0
  192. package/dist/model/liveCatalogShape.d.ts +14 -0
  193. package/dist/model/liveCatalogShape.js +71 -0
  194. package/dist/model/modelSupplyRules.d.ts +1 -0
  195. package/dist/model/modelSupplyRules.js +30 -9
  196. package/dist/model/modelsPolicy.d.ts +21 -0
  197. package/dist/model/modelsPolicy.js +90 -0
  198. package/dist/modelIdentityResolvability.d.ts +2 -2
  199. package/dist/modelIdentityResolvability.js +14 -12
  200. package/dist/modelSwitchFallback.d.ts +69 -0
  201. package/dist/modelSwitchFallback.js +206 -0
  202. package/dist/noticePresentation.d.ts +68 -0
  203. package/dist/noticePresentation.js +247 -0
  204. package/dist/notifications.js +12 -11
  205. package/dist/outputStyleSeatCapability.d.ts +0 -2
  206. package/dist/outputStyleSeatCapability.js +2 -10
  207. package/dist/ownKey.d.ts +8 -0
  208. package/dist/ownKey.js +66 -0
  209. package/dist/panelReduce.d.ts +114 -0
  210. package/dist/panelReduce.js +1135 -0
  211. package/dist/panelStateHolder.d.ts +17 -0
  212. package/dist/panelStateHolder.js +201 -0
  213. package/dist/peerFrames.js +13 -9
  214. package/dist/peerLaneCapability.d.ts +0 -1
  215. package/dist/peerLaneCapability.js +2 -6
  216. package/dist/permissionModesCapability.d.ts +0 -5
  217. package/dist/permissionModesCapability.js +5 -16
  218. package/dist/permissionRuleIssue.js +0 -3
  219. package/dist/permissionRulesWriteCapability.d.ts +0 -1
  220. package/dist/permissionRulesWriteCapability.js +2 -6
  221. package/dist/permissionsAllowGrantCapability.d.ts +0 -1
  222. package/dist/permissionsAllowGrantCapability.js +3 -9
  223. package/dist/permissionsDeclaration.d.ts +8 -0
  224. package/dist/permissionsDeclaration.js +101 -41
  225. package/dist/printPermissionOutcome.d.ts +12 -0
  226. package/dist/printPermissionOutcome.js +50 -0
  227. package/dist/printToolResultFrame.d.ts +1 -0
  228. package/dist/printToolResultFrame.js +5 -17
  229. package/dist/promptBlockedCopy.d.ts +5 -0
  230. package/dist/promptBlockedCopy.js +35 -0
  231. package/dist/promptDelivery.js +0 -8
  232. package/dist/protocolSegment.d.ts +9 -6
  233. package/dist/protocolSegment.js +31 -21
  234. package/dist/providerRejection.d.ts +4 -0
  235. package/dist/providerRejection.js +75 -14
  236. package/dist/replayBody.d.ts +12 -0
  237. package/dist/replayBody.js +25 -0
  238. package/dist/resumeRefusalCopy.d.ts +18 -1
  239. package/dist/resumeRefusalCopy.js +127 -32
  240. package/dist/retryStatus.d.ts +9 -1
  241. package/dist/retryStatus.js +9 -2
  242. package/dist/rewindArchiveCapability.d.ts +5 -14
  243. package/dist/rewindArchiveCapability.js +18 -61
  244. package/dist/rewindArchiveReading.d.ts +15 -0
  245. package/dist/rewindArchiveReading.js +56 -0
  246. package/dist/rewindEngineAction.d.ts +21 -0
  247. package/dist/rewindEngineAction.js +36 -0
  248. package/dist/rewindWireCaps.d.ts +2 -1
  249. package/dist/rewindWireCaps.js +1 -0
  250. package/dist/ruleCompileVerdict.d.ts +9 -1
  251. package/dist/ruleCompileVerdict.js +29 -4
  252. package/dist/runTerminal.d.ts +15 -12
  253. package/dist/runTerminal.js +60 -35
  254. package/dist/sandboxWire.js +13 -0
  255. package/dist/sdkRegistryTransit.d.ts +2 -1
  256. package/dist/sdkRegistryTransit.js +1 -0
  257. package/dist/sealedKeyCapability.d.ts +0 -5
  258. package/dist/sealedKeyCapability.js +3 -15
  259. package/dist/seam.js +4 -2
  260. package/dist/seatContract.d.ts +125 -34
  261. package/dist/seatContract.js +583 -179
  262. package/dist/sessionIdSegment.d.ts +1 -0
  263. package/dist/sessionIdSegment.js +11 -0
  264. package/dist/sessionMemoryErase.d.ts +1 -1
  265. package/dist/sessionMemoryErase.js +6 -1
  266. package/dist/sessionMemoryStatus.js +3 -2
  267. package/dist/sessionPolicyCapability.d.ts +0 -1
  268. package/dist/sessionPolicyCapability.js +2 -6
  269. package/dist/sessionReadRedactionCapability.d.ts +0 -5
  270. package/dist/sessionReadRedactionCapability.js +2 -13
  271. package/dist/sessionSyncFileHistory.d.ts +4 -0
  272. package/dist/sessionSyncFileHistory.js +66 -0
  273. package/dist/sessionSyncFileHistoryCapability.d.ts +0 -2
  274. package/dist/sessionSyncFileHistoryCapability.js +2 -9
  275. package/dist/skillToolListsCapability.d.ts +0 -2
  276. package/dist/skillToolListsCapability.js +2 -9
  277. package/dist/skillsWireCaps.d.ts +4 -0
  278. package/dist/skillsWireCaps.js +66 -1
  279. package/dist/sqlEngineCapability.d.ts +0 -1
  280. package/dist/sqlEngineCapability.js +9 -14
  281. package/dist/steerPriorityCapability.d.ts +0 -2
  282. package/dist/steerPriorityCapability.js +3 -12
  283. package/dist/storePostureCapability.d.ts +1 -5
  284. package/dist/storePostureCapability.js +16 -22
  285. package/dist/streamDrainingLegs.d.ts +6 -0
  286. package/dist/streamDrainingLegs.js +23 -0
  287. package/dist/subagent/engineCompactWire.js +13 -38
  288. package/dist/subagent/engineDelegatedPrompt.js +10 -6
  289. package/dist/subagent/engineSubagentOutput.d.ts +0 -1
  290. package/dist/subagent/engineSubagentOutput.js +5 -20
  291. package/dist/subagent/engineSubagentSteer.js +7 -5
  292. package/dist/subagent/engineSubagentTail.d.ts +0 -1
  293. package/dist/subagent/engineSubagentTail.js +7 -32
  294. package/dist/subagentContentStore.js +7 -18
  295. package/dist/supportFloor.d.ts +1 -0
  296. package/dist/supportFloor.js +15 -14
  297. package/dist/systemReminderTag.d.ts +1 -0
  298. package/dist/systemReminderTag.js +8 -0
  299. package/dist/terminalStatuses.d.ts +30 -0
  300. package/dist/terminalStatuses.js +67 -0
  301. package/dist/toolHistoryMismatch.d.ts +0 -3
  302. package/dist/toolHistoryMismatch.js +3 -7
  303. package/dist/toolResult.d.ts +6 -1
  304. package/dist/toolResult.js +90 -37
  305. package/dist/toolResultContent.d.ts +2 -0
  306. package/dist/toolResultContent.js +63 -0
  307. package/dist/types/engineState.d.ts +2 -1
  308. package/dist/usageAnalytics.d.ts +146 -0
  309. package/dist/usageAnalytics.js +335 -0
  310. package/dist/userInvokedSkillsCapability.d.ts +0 -2
  311. package/dist/userInvokedSkillsCapability.js +2 -9
  312. package/dist/webSearchBackendCapability.d.ts +0 -1
  313. package/dist/webSearchBackendCapability.js +3 -7
  314. package/dist/webSearchWireCaps.js +3 -11
  315. package/dist/wireErrorTriage.d.ts +2 -0
  316. package/dist/wireErrorTriage.js +34 -5
  317. package/dist/wireFailureShape.d.ts +23 -2
  318. package/dist/wireFailureShape.js +88 -43
  319. package/dist/wireRefusalCopy.js +2 -18
  320. package/dist/workflowClient.js +7 -11
  321. package/dist/workflowsJournalCapability.d.ts +0 -1
  322. package/dist/workflowsJournalCapability.js +2 -6
  323. package/dist/writeProtectionCapability.d.ts +0 -1
  324. package/dist/writeProtectionCapability.js +5 -10
  325. package/docs/INTEGRATION-CLIENTS.md +2279 -27
  326. package/package.json +5 -5
  327. package/dist/engineCapsGenerationGuard.d.ts +0 -4
  328. package/dist/engineCapsGenerationGuard.js +0 -19
  329. package/dist/panelRunningHistory.d.ts +0 -22
  330. package/dist/panelRunningHistory.js +0 -82
  331. package/dist/registryConflict.d.ts +0 -3
  332. package/dist/registryConflict.js +0 -44
@@ -1,7 +1,8 @@
1
- import { compileAllowList, hasCoreValuePort, protocolOf, retiredToolNames, ruleToolGrammarOf } from './coreValuePorts.js';
2
- import { clientOwnedServerPrefix, protocolSegmentOf } from './protocolSegment.js';
1
+ import { compileAllowList, hasCoreValuePort, protocolOf, ruleToolGrammarOf } from './coreValuePorts.js';
2
+ import { clientOwnedServerPrefix, mintedPrefixOf, ruleToolNameVerdictOf } from './protocolSegment.js';
3
3
  import { ruleCompileVerdict } from './ruleCompileVerdict.js';
4
4
  import { allowRulesGate, allowWireForm } from './permissionsAllowGrantCapability.js';
5
+ import { THROWN_SLOT_UNREADABLE, readThrownSlot } from './wireFailureShape.js';
5
6
  export const WIRE_RULE_TRUST_ORDER = Object.freeze([
6
7
  'policySettings',
7
8
  'cliArg',
@@ -73,22 +74,33 @@ function parseRule(rule) {
73
74
  return { toolName: normalizeLegacyToolName(toolName), ruleContent: unescapeRuleContent(rawContent) };
74
75
  }
75
76
  function requireRulePorts() {
76
- const required = ['MCP_NAMESPACE', 'RETIRED_TOOL_NAMES', 'protocolOf', 'ruleToolGrammarOf', 'validatePermissionRules'];
77
+ const required = ['MCP_NAMESPACE', 'judgeRuleToolName', 'protocolOf', 'ruleToolGrammarOf', 'validatePermissionRules'];
77
78
  const missing = required.filter((p) => !hasCoreValuePort(p));
78
79
  if (missing.length === 0)
79
80
  return;
80
81
  throw new Error(`permissionsDeclaration: 规则判据端口缺席(${missing.join(' / ')})—— 先用 installCoreValuePorts 装上 core 的同名实现。` +
81
82
  '缺席不等于全部合格:不判就发会让整份请求被引擎拒收,不判就删会静默丢掉 deny 规则,所以这里拒绝装配。');
82
83
  }
83
- function wireIssue(name) {
84
+ function nameCheck(name) {
84
85
  if (name.includes('('))
85
- return 'paren_in_tool_name';
86
- if (retiredToolNames().has(name))
87
- return 'retired_tool_name';
86
+ return { issue: 'paren_in_tool_name' };
87
+ const verdict = ruleToolNameVerdictOf(name);
88
+ if (verdict.kind === 'unknown') {
89
+ throw new Error('permissionsDeclaration: 规则工具名判官(judgeRuleToolName)答不上来(抛 / 回的不是 current · retired · unprefixed_namespace · unmintable_segment 之一)—— ' +
90
+ '装的必须是 core 的同名实现、原样装。判不出不等于够得着:不判就发会让整份请求被引擎拒收,不判就删会静默丢掉 deny 规则,所以这里拒绝装配。');
91
+ }
92
+ if (verdict.kind === 'retired')
93
+ return { issue: 'retired_tool_name' };
94
+ if (verdict.kind === 'unprefixed_namespace')
95
+ return { issue: 'unprefixed_namespaced_name' };
88
96
  const ns = protocolOf(name);
89
- if (ns === undefined)
90
- return name.includes('__') ? 'unprefixed_namespaced_name' : undefined;
91
- return ns.parse(name) !== undefined ? undefined : 'incomplete_protocol_name';
97
+ if (ns !== undefined && ns.parse(name) === undefined)
98
+ return { issue: 'incomplete_protocol_name' };
99
+ if (verdict.kind === 'unmintable_segment') {
100
+ const minted = mintedPrefixOf(name);
101
+ return { unminted: minted !== undefined ? { minted } : {} };
102
+ }
103
+ return { ok: true };
92
104
  }
93
105
  function wholeServerRuleName(name) {
94
106
  const read = name.trim();
@@ -100,11 +112,16 @@ function wholeServerRuleName(name) {
100
112
  }
101
113
  const compileVerdict = ruleCompileVerdict;
102
114
  const kept = (reason) => ({ sent: false, reason });
103
- function sentFate(wire, toolName, unchecked) {
104
- const segment = protocolSegmentOf(toolName);
105
- return segment.kind === 'unminted'
106
- ? { sent: true, wire, unchecked, unreachable: segment.minted !== undefined ? { minted: segment.minted } : {} }
107
- : { sent: true, wire, unchecked };
115
+ function compileRefused(verdict) {
116
+ return {
117
+ sent: false,
118
+ reason: 'compile_refused',
119
+ ...(verdict.code !== undefined ? { code: verdict.code } : {}),
120
+ ...(verdict.message !== undefined ? { message: verdict.message } : {}),
121
+ };
122
+ }
123
+ function sentFate(wire, check, unchecked) {
124
+ return 'unminted' in check ? { sent: true, wire, unchecked, unreachable: check.unminted } : { sent: true, wire, unchecked };
108
125
  }
109
126
  function judgeList(rules, behavior, allowForm = 'grant') {
110
127
  let portsChecked = false;
@@ -118,42 +135,34 @@ function judgeList(rules, behavior, allowForm = 'grant') {
118
135
  const parsed = parseRule(rule);
119
136
  if (parsed.ruleContent === undefined) {
120
137
  const name = wholeServerRuleName(parsed.toolName);
121
- const issue = wireIssue(name);
122
- if (issue !== undefined)
123
- return kept(issue);
124
- if (behavior === 'allow') {
125
- const segment = protocolSegmentOf(name);
126
- if (segment.kind === 'unminted')
127
- return kept('unminted_protocol_segment');
128
- if (segment.kind === 'unknown')
129
- return kept('judge_failed');
130
- }
138
+ const check = nameCheck(name);
139
+ if ('issue' in check)
140
+ return kept(check.issue);
141
+ if (behavior === 'allow' && 'unminted' in check)
142
+ return kept('unminted_protocol_segment');
131
143
  const verdict = compileVerdict(name, behavior === 'ask' ? 'ask' : 'deny');
132
- if (verdict === 'refused')
133
- return kept('compile_refused');
134
- if (verdict === 'unknown' && behavior === 'allow')
144
+ if (verdict.kind === 'refused')
145
+ return compileRefused(verdict);
146
+ if (verdict.kind === 'unknown' && behavior === 'allow')
135
147
  return kept('judge_failed');
136
- return behavior === 'allow' ? { sent: true, wire: name, unchecked: false } : sentFate(name, name, verdict === 'unknown');
148
+ return behavior === 'allow' ? { sent: true, wire: name, unchecked: false } : sentFate(name, check, verdict.kind === 'unknown');
137
149
  }
138
- const issue = wireIssue(parsed.toolName);
139
- if (issue !== undefined)
140
- return kept(issue);
150
+ const check = nameCheck(parsed.toolName);
151
+ if ('issue' in check)
152
+ return kept(check.issue);
141
153
  if (ruleToolGrammarOf(parsed.toolName) === 'path' && parsed.ruleContent.startsWith('~/'))
142
154
  return kept('home_relative_path');
143
155
  if (behavior === 'allow') {
144
156
  if (allowForm !== 'layer')
145
157
  return kept('content_form_not_grantable');
146
- const segment = protocolSegmentOf(parsed.toolName);
147
- if (segment.kind === 'unminted')
158
+ if ('unminted' in check)
148
159
  return kept('unminted_protocol_segment');
149
- if (segment.kind === 'unknown')
150
- return kept('judge_failed');
151
160
  return { sent: true, wire: rule, unchecked: false };
152
161
  }
153
162
  const verdict = compileVerdict(rule, behavior);
154
- if (verdict === 'refused')
155
- return kept('compile_refused');
156
- return sentFate(rule, parsed.toolName, verdict === 'unknown');
163
+ if (verdict.kind === 'refused')
164
+ return compileRefused(verdict);
165
+ return sentFate(rule, check, verdict.kind === 'unknown');
157
166
  });
158
167
  }
159
168
  function outsideSettingsFiles(origin) {
@@ -369,8 +378,15 @@ function assemble(input, caps) {
369
378
  for (const [bucket, slots, j] of rows) {
370
379
  slots.forEach((s, k) => {
371
380
  const f = j.fates[k];
372
- if (!f.sent)
373
- keptRows.push({ rule: s.rule, bucket, reason: f.reason });
381
+ if (!f.sent) {
382
+ keptRows.push({
383
+ rule: s.rule,
384
+ bucket,
385
+ reason: f.reason,
386
+ ...(f.code !== undefined ? { code: f.code } : {}),
387
+ ...(f.message !== undefined ? { message: f.message } : {}),
388
+ });
389
+ }
374
390
  });
375
391
  for (const wire of j.sent) {
376
392
  const winner = j.winnerOf.get(wire);
@@ -396,3 +412,47 @@ export function permissionsDeclarationReport(input, caps) {
396
412
  const { buckets, report } = assemble(input, caps);
397
413
  return { ...(Object.keys(buckets).length > 0 ? { permissions: buckets } : {}), ...report };
398
414
  }
415
+ const ALLOW_KEPT_ROWS_READ_MAX = 4096;
416
+ function allowHeldBySettingsReadCount(report) {
417
+ if (typeof report !== 'object' || report === null)
418
+ return 0;
419
+ const kept = readThrownSlot(report, 'kept');
420
+ if (typeof kept !== 'object' || kept === null)
421
+ return 0;
422
+ const length = readThrownSlot(kept, 'length');
423
+ if (typeof length !== 'number' || !Number.isInteger(length) || length <= 0)
424
+ return 0;
425
+ let n = 0;
426
+ for (let i = 0; i < Math.min(length, ALLOW_KEPT_ROWS_READ_MAX); i++) {
427
+ const row = readThrownSlot(kept, String(i));
428
+ if (typeof row === 'object' && row !== null && readThrownSlot(row, 'reason') === 'settings_read_not_clean')
429
+ n++;
430
+ }
431
+ return n;
432
+ }
433
+ export function permissionsAllowKeptNotice(report, settingsRead, facts) {
434
+ const held = allowHeldBySettingsReadCount(report);
435
+ if (held <= 0)
436
+ return undefined;
437
+ const readFact = (key) => {
438
+ if (typeof facts !== 'object' || facts === null)
439
+ return undefined;
440
+ const v = readThrownSlot(facts, key);
441
+ return v === THROWN_SLOT_UNREADABLE ? undefined : v;
442
+ };
443
+ const rawCount = readFact('problemCount');
444
+ const rawWhere = readFact('where');
445
+ const managedPending = readFact('managedPolicyPending') === true;
446
+ const count = typeof rawCount === 'number' && Number.isInteger(rawCount) && rawCount >= 1 ? rawCount : undefined;
447
+ const where = typeof rawWhere === 'string' && rawWhere.length >= 1 && rawWhere.length <= 200 && !/\p{Cc}/u.test(rawWhere) ? rawWhere : undefined;
448
+ const head = `${String(held)} permissions.allow rule${held === 1 ? ' was' : 's were'} not sent to the engine for this run because `;
449
+ if (settingsRead === 'partial' && managedPending && count === 1) {
450
+ return (`${head}the managed policy for your account has not been received yet (sema keeps fetching it; allow rules apply once it arrives). ` +
451
+ 'Run again once it has been received (deny and ask rules, and rules given with --allowedTools, are still sent).');
452
+ }
453
+ const why = settingsRead === 'partial'
454
+ ? `the settings read reported ${count === undefined ? 'problems' : `${String(count)} problem${count === 1 ? '' : 's'}`}${where === undefined ? '' : ` (${where})`}`
455
+ : 'the health of this settings read could not be checked';
456
+ return (`${head}${why}; an allow rule from a settings file is only sent from a settings read with no problems. Fix the reported settings, then run again ` +
457
+ '(deny and ask rules from this read, and rules given with --allowedTools, are still sent).');
458
+ }
@@ -0,0 +1,12 @@
1
+ import { type GateOutcomeView } from './gateOutcome.js';
2
+ import { type NoticeOutlet, type NoticeSeatClass } from './noticePresentation.js';
3
+ export declare const PRINT_PERMISSION_OUTCOME_FORMS: readonly ["mode_denied", "no_approver", "mode_released"];
4
+ export type PrintPermissionOutcomeForm = (typeof PRINT_PERMISSION_OUTCOME_FORMS)[number];
5
+ export interface PrintPermissionOutcome {
6
+ readonly form: PrintPermissionOutcomeForm;
7
+ readonly sentence: string;
8
+ readonly audience: 'user';
9
+ readonly outlet: NoticeOutlet;
10
+ readonly seatClass: NoticeSeatClass;
11
+ }
12
+ export declare function printPermissionOutcomeOf(gate: GateOutcomeView | undefined): PrintPermissionOutcome | undefined;
@@ -0,0 +1,50 @@
1
+ import { modeReleaseReasonSentence } from './gateOutcome.js';
2
+ import { noticeSeatClassOf } from './noticePresentation.js';
3
+ import { guardedRead, readOwnDataValue } from './ownKey.js';
4
+ export const PRINT_PERMISSION_OUTCOME_FORMS = Object.freeze(['mode_denied', 'no_approver', 'mode_released']);
5
+ const ALLOW_RULE_REMEDY = 'add an allow rule for the tool in settings (or pass --allowedTools)';
6
+ const SENTENCES = Object.freeze({
7
+ dontAsk: {
8
+ sentence: `the dontAsk permission mode denies tools that need approval unless a permission rule allows them — ${ALLOW_RULE_REMEDY}`,
9
+ outlet: 'present',
10
+ },
11
+ bypassPermissions: {
12
+ sentence: 'the bypassPermissions permission mode refused a call because it could not tell whether the write it makes lands on a protected path',
13
+ outlet: 'absent',
14
+ },
15
+ mode: { sentence: "the session's permission mode denied a call that needed approval", outlet: 'absent' },
16
+ no_approver: {
17
+ sentence: `print mode has no approval channel: tools that need approval are denied unless a permission rule allows them — ${ALLOW_RULE_REMEDY}, or pass --permission-mode acceptEdits or auto`,
18
+ outlet: 'present',
19
+ },
20
+ });
21
+ function outcomeOf(form, sentence, outlet) {
22
+ return Object.freeze({ form, sentence, audience: 'user', outlet, seatClass: noticeSeatClassOf('user', outlet) });
23
+ }
24
+ function slot(from, key) {
25
+ return typeof from === 'object' && from !== null ? guardedRead(() => readOwnDataValue(from, key)) : undefined;
26
+ }
27
+ export function printPermissionOutcomeOf(gate) {
28
+ const disposition = slot(gate, 'disposition');
29
+ const kind = slot(disposition, 'kind');
30
+ if (kind === 'denied') {
31
+ const deniedBy = slot(disposition, 'deniedBy');
32
+ if (deniedBy === 'mode') {
33
+ const mode = slot(disposition, 'mode');
34
+ const row = mode === 'dontAsk' ? SENTENCES.dontAsk : mode === 'bypassPermissions' ? SENTENCES.bypassPermissions : SENTENCES.mode;
35
+ return outcomeOf('mode_denied', row.sentence, row.outlet);
36
+ }
37
+ if (deniedBy === 'ask_resolution') {
38
+ const settled = slot(slot(gate, 'settlement'), 'kind');
39
+ if (settled === 'no_approver' || settled === 'approver_unavailable')
40
+ return outcomeOf('no_approver', SENTENCES.no_approver.sentence, SENTENCES.no_approver.outlet);
41
+ }
42
+ return undefined;
43
+ }
44
+ if (kind === 'allowed') {
45
+ const reason = slot(slot(disposition, 'released'), 'reason');
46
+ const sentence = typeof reason === 'string' ? modeReleaseReasonSentence(reason) : undefined;
47
+ return sentence === undefined ? undefined : outcomeOf('mode_released', sentence, 'absent');
48
+ }
49
+ return undefined;
50
+ }
@@ -13,6 +13,7 @@ export interface ToolEndResultArmLike {
13
13
  delivered?: unknown;
14
14
  gatedCallId?: unknown;
15
15
  _sema_denial_kind?: unknown;
16
+ notExecuted?: true;
16
17
  parentToolCallId?: unknown;
17
18
  uuid?: unknown;
18
19
  session_id?: unknown;
@@ -1,22 +1,8 @@
1
1
  import { isCcToolDenialKind } from './gateVocabulary.js';
2
2
  export { flattenWireOutput as flattenToolOutput } from './adapt/wireShapes.js';
3
3
  import { flattenWireOutput } from './adapt/wireShapes.js';
4
- import { parseModelFacingBash } from './toolResult.js';
5
4
  import { toolResultEnvelopeParts, toolResultOutcomeOf } from './adapt/toolCards.js';
6
- function bashExitCodeFailed(toolName, text, structured) {
7
- if (typeof toolName !== 'string' || toolName.toLowerCase() !== 'bash')
8
- return false;
9
- const st = structured;
10
- if (typeof st?.returnCodeInterpretation === 'string' && st.returnCodeInterpretation.length > 0)
11
- return false;
12
- const ec = st?.exitCode;
13
- if (typeof ec === 'number')
14
- return ec !== 0;
15
- if (parseModelFacingBash(text)?.note !== undefined)
16
- return false;
17
- const m = /^exit code: (\d+)\b/.exec(text);
18
- return m !== null && m[1] !== '0';
19
- }
5
+ import { readFrameTrueMark } from './ownKey.js';
20
6
  export function toolEndResultToUserFrame(arm) {
21
7
  if (typeof arm.toolCallId !== 'string' || arm.toolCallId.length === 0)
22
8
  return null;
@@ -29,6 +15,7 @@ export function toolEndResultToUserFrame(arm) {
29
15
  isError: arm.isError === true,
30
16
  }, undefined, parent === null ? 'leader' : 'subagent');
31
17
  const envelope = toolResultEnvelopeParts(outcome);
18
+ const content = Array.isArray(outcome.body.content) ? outcome.body.content : arm.truncated === true ? `${text}\n…(truncated)` : text;
32
19
  return {
33
20
  type: 'user',
34
21
  message: {
@@ -37,13 +24,14 @@ export function toolEndResultToUserFrame(arm) {
37
24
  {
38
25
  type: 'tool_result',
39
26
  tool_use_id: arm.toolCallId,
40
- content: arm.truncated === true ? `${text}\n…(truncated)` : text,
41
- is_error: arm.isError === true || bashExitCodeFailed(arm.toolName, text, arm.structured),
27
+ content,
28
+ is_error: outcome.body.isError,
42
29
  },
43
30
  ],
44
31
  },
45
32
  parent_tool_use_id: parent,
46
33
  ...(isCcToolDenialKind(arm._sema_denial_kind) ? { _sema_denial_kind: arm._sema_denial_kind } : {}),
34
+ ...(readFrameTrueMark(arm, 'notExecuted') ? { _sema_not_executed: true } : {}),
47
35
  ...(Object.hasOwn(envelope, 'tool_use_result') ? { tool_use_result: envelope.tool_use_result } : {}),
48
36
  ...(Object.hasOwn(envelope, '_sema_degraded') ? { _sema_degraded: envelope._sema_degraded } : {}),
49
37
  uuid: arm.uuid,
@@ -0,0 +1,5 @@
1
+ import type { RunTerminalRead } from './runTerminal.js';
2
+ export declare const PROMPT_BLOCKED_BY_HOOK_ROW_LEAD = "UserPromptSubmit operation blocked by hook";
3
+ export declare function runBlockedText(blocked: Extract<RunTerminalRead, {
4
+ kind: 'blocked';
5
+ }>): string;
@@ -0,0 +1,35 @@
1
+ import { displayUntrusted } from './displayUntrusted.js';
2
+ import { stripSystemReminderTagTokens, unwrapSystemReminder } from './systemReminderTag.js';
3
+ export const PROMPT_BLOCKED_BY_HOOK_ROW_LEAD = 'UserPromptSubmit operation blocked by hook';
4
+ const RUN_BLOCKED_REASONED = 'Run blocked';
5
+ const RUN_BLOCKED_NO_REASON = 'Run blocked (the agent reported it cannot proceed)';
6
+ const HOOK_WORDS_SHOWN_MAX = 1000;
7
+ const CAUSE_CLAUSE = Object.freeze({
8
+ crashed: 'the hook failed before it answered; the prompt was not submitted',
9
+ timeout: 'the hook did not answer in time; the prompt was not submitted',
10
+ cancelled: 'the run was cancelled while the hook was checking the prompt; the prompt was not submitted',
11
+ });
12
+ function shownHookWords(words) {
13
+ if (words === undefined)
14
+ return undefined;
15
+ const shown = stripSystemReminderTagTokens(displayUntrusted(stripSystemReminderTagTokens(words), { max: HOOK_WORDS_SHOWN_MAX })).trim();
16
+ return shown === '' ? undefined : shown;
17
+ }
18
+ export function runBlockedText(blocked) {
19
+ const detail = blocked.detail;
20
+ if (detail !== undefined && detail.kind === 'prompt_blocked_by_hook') {
21
+ const clause = detail.cause !== 'unrecognized' && Object.hasOwn(CAUSE_CLAUSE, detail.cause) ? CAUSE_CLAUSE[detail.cause] : undefined;
22
+ const words = shownHookWords(detail.hookReason);
23
+ if (clause !== undefined)
24
+ return `${PROMPT_BLOCKED_BY_HOOK_ROW_LEAD}: ${clause}${words !== undefined ? `\n${words}` : ''}`;
25
+ return words !== undefined ? `${PROMPT_BLOCKED_BY_HOOK_ROW_LEAD}:\n${words}` : PROMPT_BLOCKED_BY_HOOK_ROW_LEAD;
26
+ }
27
+ const reason = blocked.reason;
28
+ if (reason === undefined)
29
+ return RUN_BLOCKED_NO_REASON;
30
+ const unwrapped = unwrapSystemReminder(reason);
31
+ if (unwrapped === reason)
32
+ return `${RUN_BLOCKED_REASONED}: ${reason}`;
33
+ const body = stripSystemReminderTagTokens(unwrapped).trim();
34
+ return body === '' ? RUN_BLOCKED_NO_REASON : `${RUN_BLOCKED_REASONED}: ${body}`;
35
+ }
@@ -132,14 +132,6 @@ export function frameProvesDelivery(event) {
132
132
  const type = event.type;
133
133
  if (typeof type !== 'string' || type.length === 0 || PRE_RUN_FRAME_TYPES.has(type))
134
134
  return false;
135
- if (type === 'done') {
136
- const result = event.result;
137
- if (typeof result === 'object' && result !== null && !Array.isArray(result) && result.status === undefined) {
138
- const r = result;
139
- if (activeRunBusySignal({ type: 'failed', errorCode: r.errorCode, activeTaskId: r.activeTaskId }) !== null)
140
- return false;
141
- }
142
- }
143
135
  return activeRunBusySignal(event) === null;
144
136
  }
145
137
  catch {
@@ -1,12 +1,15 @@
1
- export type ProtocolSegment = {
2
- readonly kind: 'ok';
1
+ export type RuleToolNameReading = {
2
+ readonly kind: 'current';
3
3
  } | {
4
- readonly kind: 'empty';
4
+ readonly kind: 'retired';
5
+ readonly currentName?: string;
5
6
  } | {
6
- readonly kind: 'unminted';
7
- readonly minted?: string;
7
+ readonly kind: 'unprefixed_namespace';
8
+ } | {
9
+ readonly kind: 'unmintable_segment';
8
10
  } | {
9
11
  readonly kind: 'unknown';
10
12
  };
11
- export declare function protocolSegmentOf(name: string): ProtocolSegment;
13
+ export declare function ruleToolNameVerdictOf(name: string): RuleToolNameReading;
14
+ export declare function mintedPrefixOf(name: string): string | undefined;
12
15
  export declare function clientOwnedServerPrefix(server: string): string | undefined;
@@ -1,33 +1,43 @@
1
- import { hasCoreValuePort, mcpNamespace, mintNamespacePrefix, protocolOf } from './coreValuePorts.js';
2
- import { CORE_PROTOCOL_PREFIXES } from './generated/toolNameTables.js';
3
- export function protocolSegmentOf(name) {
4
- if (CORE_PROTOCOL_PREFIXES.some((prefix) => name.startsWith(prefix) && name.slice(prefix.length).split('__')[0] === ''))
5
- return { kind: 'empty' };
6
- const ns = protocolOf(name);
7
- if (ns === undefined)
8
- return hasCoreValuePort('protocolOf') ? { kind: 'ok' } : { kind: 'unknown' };
9
- let parsed;
1
+ import { mcpNamespace, mintNamespacePrefix, protocolOf, ruleToolNameJudgement } from './coreValuePorts.js';
2
+ export function ruleToolNameVerdictOf(name) {
3
+ let kind;
4
+ let currentName;
10
5
  try {
11
- parsed = ns.parse(name);
6
+ const v = ruleToolNameJudgement(name, new Set());
7
+ if (v === null || typeof v !== 'object')
8
+ return { kind: 'unknown' };
9
+ kind = v.kind;
10
+ if (kind === 'retired')
11
+ currentName = v.currentName;
12
12
  }
13
13
  catch {
14
14
  return { kind: 'unknown' };
15
15
  }
16
- const peer = parsed?.peer;
17
- if (typeof peer !== 'string')
18
- return { kind: 'ok' };
19
- if (peer.includes('*'))
20
- return { kind: 'unminted' };
21
- let minted;
16
+ switch (kind) {
17
+ case 'current':
18
+ case 'unprefixed_namespace':
19
+ case 'unmintable_segment':
20
+ return { kind };
21
+ case 'retired':
22
+ return typeof currentName === 'string' && currentName !== '' ? { kind, currentName } : { kind };
23
+ default:
24
+ return { kind: 'unknown' };
25
+ }
26
+ }
27
+ export function mintedPrefixOf(name) {
22
28
  try {
23
- minted = mintNamespacePrefix(ns, peer);
29
+ const ns = protocolOf(name);
30
+ if (ns === undefined)
31
+ return undefined;
32
+ const peer = ns.parse(name)?.peer;
33
+ if (typeof peer !== 'string' || peer.includes('*'))
34
+ return undefined;
35
+ const minted = mintNamespacePrefix(ns, peer);
36
+ return typeof minted === 'string' ? minted : undefined;
24
37
  }
25
38
  catch {
26
- return { kind: 'unknown' };
39
+ return undefined;
27
40
  }
28
- if (typeof minted !== 'string')
29
- return { kind: 'unknown' };
30
- return minted === `${ns.prefix}${peer}__` ? { kind: 'ok' } : { kind: 'unminted', minted };
31
41
  }
32
42
  export function clientOwnedServerPrefix(server) {
33
43
  try {
@@ -1,8 +1,12 @@
1
1
  import { type RunTerminalFailureDetail } from './runTerminal.js';
2
2
  import { type ToolHistoryErrorCarrier } from './toolHistoryMismatch.js';
3
+ export declare const PROVIDER_REJECTION_KINDS: readonly ["schema_invalid", "auth", "rate_limited", "resend_eligible", "unknown"];
4
+ export type ProviderRejectionKind = (typeof PROVIDER_REJECTION_KINDS)[number];
3
5
  export interface ProviderRejectionResend {
4
6
  resend: 'edit_and_resend' | 'not_by_editing';
5
7
  text: string;
8
+ kind: ProviderRejectionKind;
6
9
  }
7
10
  export declare function readProviderRejectionResendKey(v: object | null | undefined): ProviderRejectionResend | undefined;
8
11
  export declare function providerRejectionResend(detail: RunTerminalFailureDetail | null | undefined, carrier?: ToolHistoryErrorCarrier | null): ProviderRejectionResend | undefined;
12
+ export declare function providerRejectionKind(detail: RunTerminalFailureDetail | null | undefined): ProviderRejectionKind;
@@ -18,6 +18,28 @@ function providerStatusTier(status) {
18
18
  return UNTIERED;
19
19
  }
20
20
  const EDITABLE_TIER = 'invalid_request';
21
+ export const PROVIDER_REJECTION_KINDS = Object.freeze(['schema_invalid', 'auth', 'rate_limited', 'resend_eligible', 'unknown']);
22
+ const SCHEMA_INVALID_CODES = new Set([
23
+ 'invalid_type',
24
+ 'missing_required_parameter',
25
+ 'unknown_parameter',
26
+ 'unsupported_parameter',
27
+ 'invalid_function_parameters',
28
+ 'invalid_json_schema',
29
+ ]);
30
+ function schemaTierStatus(status) {
31
+ return status === 400 || status === 422;
32
+ }
33
+ function kindOfStatus(status, code) {
34
+ const tier = providerStatusTier(status);
35
+ if (tier === 'authentication_failed')
36
+ return 'auth';
37
+ if (tier === 'rate_limit')
38
+ return 'rate_limited';
39
+ if (tier === EDITABLE_TIER)
40
+ return code !== undefined && schemaTierStatus(status) && SCHEMA_INVALID_CODES.has(code) ? 'schema_invalid' : 'resend_eligible';
41
+ return 'unknown';
42
+ }
21
43
  const NOT_BY_EDITING_TAIL = new Map([
22
44
  ['authentication_failed', ': check the provider credentials or access for this account.'],
23
45
  ['model_not_found', ': the model is not available from this provider — choose another model.'],
@@ -30,26 +52,40 @@ function toolHistoryMismatchCarrier(carrier) {
30
52
  }
31
53
  const PROVIDER_REJECTED = 'provider_rejected';
32
54
  const RESEND_TEXT_STATUS = /\(HTTP (\d{3})\)/;
55
+ function ownDataOf(o, key) {
56
+ const d = Object.getOwnPropertyDescriptor(o, key);
57
+ return d !== undefined && Object.hasOwn(d, 'value') ? d.value : undefined;
58
+ }
33
59
  export function readProviderRejectionResendKey(v) {
34
60
  try {
35
61
  if (typeof v !== 'object' || v === null || Array.isArray(v))
36
62
  return undefined;
37
- const got = v;
38
- const resend = got.resend;
39
- const text = got.text;
63
+ const resend = ownDataOf(v, 'resend');
64
+ const text = ownDataOf(v, 'text');
65
+ const kind = ownDataOf(v, 'kind');
40
66
  if (typeof text !== 'string' || (resend !== 'edit_and_resend' && resend !== 'not_by_editing'))
41
67
  return undefined;
42
68
  const hit = RESEND_TEXT_STATUS.exec(text);
43
69
  if (hit === null || hit[1] === undefined)
44
70
  return undefined;
45
- const again = providerRejectionResend({ kind: PROVIDER_REJECTED, status: Number(hit[1]) });
46
- return again !== undefined && again.resend === resend && again.text === text ? { resend: again.resend, text: again.text } : undefined;
71
+ const rej = readRejection({ kind: PROVIDER_REJECTED, status: Number(hit[1]) });
72
+ if (rej === undefined)
73
+ return undefined;
74
+ let wanted;
75
+ if (kind === undefined)
76
+ wanted = kindOfStatus(rej.status, undefined);
77
+ else if (typeof kind === 'string' && PROVIDER_REJECTION_KINDS.includes(kind))
78
+ wanted = kind;
79
+ else
80
+ return undefined;
81
+ const again = verdictOf(rej.status, wanted);
82
+ return again !== undefined && again.resend === resend && again.text === text ? { resend: again.resend, text: again.text, kind: again.kind } : undefined;
47
83
  }
48
84
  catch {
49
85
  return undefined;
50
86
  }
51
87
  }
52
- export function providerRejectionResend(detail, carrier) {
88
+ function readRejection(detail) {
53
89
  let read;
54
90
  try {
55
91
  const r = readRunTerminal({ terminal: { kind: 'failed', detail } });
@@ -63,16 +99,41 @@ export function providerRejectionResend(detail, carrier) {
63
99
  const status = Object.hasOwn(read, 'status') ? read.status : undefined;
64
100
  if (status === undefined)
65
101
  return undefined;
66
- if (toolHistoryMismatchCarrier(carrier))
102
+ return { status, code: Object.hasOwn(read, 'code') ? read.code : undefined };
103
+ }
104
+ function schemaInvalidText(status) {
105
+ return `The model provider rejected the structure of this request (HTTP ${status}) — rewording the message will not fix this. Check that the configured model and endpoint accept this kind of request, or report the problem to whoever runs the engine.`;
106
+ }
107
+ function verdictOf(status, kind) {
108
+ if (kind === 'schema_invalid') {
109
+ if (providerStatusTier(status) !== EDITABLE_TIER || !schemaTierStatus(status))
110
+ return undefined;
111
+ return { resend: 'not_by_editing', text: schemaInvalidText(status), kind };
112
+ }
113
+ if (kind !== kindOfStatus(status, undefined))
67
114
  return undefined;
68
- const tier = providerStatusTier(status);
69
- return tier === EDITABLE_TIER
70
- ? {
115
+ if (kind === 'resend_eligible') {
116
+ return {
71
117
  resend: 'edit_and_resend',
72
118
  text: `The model provider rejected this request as sent (HTTP ${status}). Change it — for example shorten it or remove an attachment — and send it again.`,
73
- }
74
- : {
75
- resend: 'not_by_editing',
76
- text: `The model provider refused this request (HTTP ${status})${NOT_BY_EDITING_TAIL.get(tier) ?? NOT_BY_EDITING_TAIL.get(UNTIERED) ?? ''}`,
119
+ kind,
77
120
  };
121
+ }
122
+ return {
123
+ resend: 'not_by_editing',
124
+ text: `The model provider refused this request (HTTP ${status})${NOT_BY_EDITING_TAIL.get(providerStatusTier(status)) ?? NOT_BY_EDITING_TAIL.get(UNTIERED) ?? ''}`,
125
+ kind,
126
+ };
127
+ }
128
+ export function providerRejectionResend(detail, carrier) {
129
+ const r = readRejection(detail);
130
+ if (r === undefined)
131
+ return undefined;
132
+ if (toolHistoryMismatchCarrier(carrier))
133
+ return undefined;
134
+ return verdictOf(r.status, kindOfStatus(r.status, r.code));
135
+ }
136
+ export function providerRejectionKind(detail) {
137
+ const r = readRejection(detail);
138
+ return r === undefined ? 'unknown' : kindOfStatus(r.status, r.code);
78
139
  }
@@ -0,0 +1,12 @@
1
+ export interface ReplayRowView {
2
+ readonly status?: string;
3
+ readonly errorCode?: string;
4
+ readonly error?: string;
5
+ readonly sessionId?: string;
6
+ }
7
+ export interface DoneResultView {
8
+ readonly replay: boolean;
9
+ readonly engine: unknown;
10
+ readonly row?: ReplayRowView;
11
+ }
12
+ export declare function doneResultView(result: unknown): DoneResultView;
@@ -0,0 +1,25 @@
1
+ function guarded(o, k) {
2
+ try {
3
+ return o[k];
4
+ }
5
+ catch {
6
+ return undefined;
7
+ }
8
+ }
9
+ function guardedString(o, k) {
10
+ const v = guarded(o, k);
11
+ return typeof v === 'string' && v.length > 0 ? v : undefined;
12
+ }
13
+ export function doneResultView(result) {
14
+ if (typeof result !== 'object' || result === null || Array.isArray(result))
15
+ return { replay: false, engine: result };
16
+ if (guarded(result, 'replay') !== true)
17
+ return { replay: false, engine: result };
18
+ const row = {};
19
+ for (const k of ['status', 'errorCode', 'error', 'sessionId']) {
20
+ const v = guardedString(result, k);
21
+ if (v !== undefined)
22
+ row[k] = v;
23
+ }
24
+ return { replay: true, engine: guarded(result, 'result'), row };
25
+ }