@sema-agent/client-core 0.109.0 → 0.111.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (236) hide show
  1. package/CHANGELOG.md +342 -0
  2. package/README.md +88 -32
  3. package/dist/abortableSleep.d.ts +7 -0
  4. package/dist/abortableSleep.js +37 -0
  5. package/dist/adapt/arms.js +45 -11
  6. package/dist/adapt/toolCards.d.ts +3 -1
  7. package/dist/adapt/toolCards.js +4 -2
  8. package/dist/adapter/activeRunSelfHeal.d.ts +39 -0
  9. package/dist/adapter/activeRunSelfHeal.js +171 -3
  10. package/dist/adapter/downstream/eventToSdkMessage.js +20 -15
  11. package/dist/adapter/downstream/terminalToSdkResult.d.ts +2 -0
  12. package/dist/adapter/downstream/terminalToSdkResult.js +11 -0
  13. package/dist/adapter/runStream.d.ts +5 -0
  14. package/dist/adapter/runStream.js +15 -3
  15. package/dist/attachmentRoute.d.ts +20 -0
  16. package/dist/attachmentRoute.js +39 -0
  17. package/dist/attachmentsWireCaps.js +1 -1
  18. package/dist/builtinOutputStyles.d.ts +12 -0
  19. package/dist/builtinOutputStyles.js +147 -0
  20. package/dist/compactionStatus.d.ts +9 -0
  21. package/dist/compactionStatus.js +29 -5
  22. package/dist/controlRouter.js +2 -1
  23. package/dist/coreValuePorts.d.ts +39 -1
  24. package/dist/coreValuePorts.js +10 -0
  25. package/dist/declared/supportFloorDeclared.js +1 -1
  26. package/dist/displayUntrusted.d.ts +1 -0
  27. package/dist/displayUntrusted.js +138 -14
  28. package/dist/engineErrorCodes.d.ts +3 -0
  29. package/dist/engineErrorCodes.js +3 -0
  30. package/dist/engineHealthFacts.d.ts +20 -0
  31. package/dist/engineHealthFacts.js +42 -1
  32. package/dist/engineHealthProbeVerdict.d.ts +23 -0
  33. package/dist/engineHealthProbeVerdict.js +115 -0
  34. package/dist/engineInlineTaskStats.d.ts +4 -3
  35. package/dist/engineInlineTaskStats.js +18 -2
  36. package/dist/engineNoticeCodes.d.ts +10 -0
  37. package/dist/engineNoticeCodes.js +36 -6
  38. package/dist/engineRepoint.d.ts +147 -0
  39. package/dist/engineRepoint.js +310 -0
  40. package/dist/engineRowRef.d.ts +3 -0
  41. package/dist/engineRowRef.js +13 -1
  42. package/dist/engineSessionMessages.d.ts +2 -1
  43. package/dist/engineSessionMessages.js +5 -0
  44. package/dist/engineSwapCrossing.d.ts +57 -0
  45. package/dist/engineSwapCrossing.js +297 -0
  46. package/dist/engineUnavailable.d.ts +44 -0
  47. package/dist/engineUnavailable.js +492 -0
  48. package/dist/errorSupplementRoles.js +2 -1
  49. package/dist/eventLeg.js +3 -3
  50. package/dist/fleet/fleetProjection.js +3 -2
  51. package/dist/generated/engineFactTables.d.ts +2 -0
  52. package/dist/generated/engineFactTables.js +12 -0
  53. package/dist/generated/sdkFactTables.d.ts +2 -1
  54. package/dist/generated/sdkFactTables.js +5 -0
  55. package/dist/generated/settingsSchemaTables.d.ts +4 -0
  56. package/dist/generated/settingsSchemaTables.js +1 -0
  57. package/dist/hitl/approvalAskers.d.ts +6 -0
  58. package/dist/hitl/approvalAskers.js +30 -0
  59. package/dist/hitl/approvalCardReasons.js +6 -3
  60. package/dist/hitl/approvalDelivery.d.ts +1 -0
  61. package/dist/hitl/approvalDelivery.js +1 -1
  62. package/dist/hitl/approvalRequestFrameReading.d.ts +7 -0
  63. package/dist/hitl/approvalRequestFrameReading.js +11 -0
  64. package/dist/hitl/approvalResolution.d.ts +9 -2
  65. package/dist/hitl/approvalResolution.js +6 -1
  66. package/dist/hitl/askGateWire.js +5 -8
  67. package/dist/hitl/automaticAnswerVerdict.js +2 -2
  68. package/dist/hitl/decisionConflict.js +6 -3
  69. package/dist/hitl/decisionRefusal.d.ts +2 -0
  70. package/dist/hitl/decisionRefusal.js +8 -8
  71. package/dist/hitl/decisionRefusalCarrier.d.ts +3 -0
  72. package/dist/hitl/decisionRefusalCarrier.js +348 -0
  73. package/dist/hitl/decisionSend.d.ts +10 -0
  74. package/dist/hitl/decisionSend.js +57 -17
  75. package/dist/hitl/editedApprovalAcceptance.d.ts +25 -0
  76. package/dist/hitl/editedApprovalAcceptance.js +26 -0
  77. package/dist/hitl/elicitationRefusal.d.ts +4 -0
  78. package/dist/hitl/elicitationRefusal.js +23 -0
  79. package/dist/hitl/frameRouter.d.ts +2 -2
  80. package/dist/hitl/frameRouter.js +12 -33
  81. package/dist/hitl/gateIdentity.d.ts +5 -0
  82. package/dist/hitl/gateIdentity.js +23 -0
  83. package/dist/hitl/gateLedger.d.ts +0 -4
  84. package/dist/hitl/gateLedger.js +0 -19
  85. package/dist/hitl/hitlBridge.d.ts +7 -0
  86. package/dist/hitl/hitlBridge.js +14 -8
  87. package/dist/hitl/hitlHostSurface.d.ts +3 -1
  88. package/dist/hitl/hitlHostSurface.js +14 -4
  89. package/dist/hitl/hostWithdrawal.d.ts +15 -0
  90. package/dist/hitl/hostWithdrawal.js +38 -0
  91. package/dist/hitl/localAllowRedemption.d.ts +67 -0
  92. package/dist/hitl/localAllowRedemption.js +256 -0
  93. package/dist/hitl/parkResolver.js +32 -13
  94. package/dist/hitl/persistedRulesWire.d.ts +16 -0
  95. package/dist/hitl/persistedRulesWire.js +72 -2
  96. package/dist/hitl/planReviewWire.d.ts +3 -0
  97. package/dist/hitl/planReviewWire.js +37 -10
  98. package/dist/hitl/policyDenyCause.d.ts +1 -1
  99. package/dist/hitl/policyDenyCause.js +1 -1
  100. package/dist/hitl/resumeRunningCard.d.ts +1 -0
  101. package/dist/hitl/resumeRunningCard.js +1 -0
  102. package/dist/hitl/screenCardCarriers.d.ts +15 -0
  103. package/dist/hitl/screenCardCarriers.js +41 -0
  104. package/dist/hitl/screenDecisionCards.d.ts +98 -0
  105. package/dist/hitl/screenDecisionCards.js +362 -0
  106. package/dist/hitl/sessionPolicyWire.js +6 -4
  107. package/dist/hitl/standingRows.d.ts +4 -1
  108. package/dist/hitl/standingRows.js +33 -1
  109. package/dist/hitl/toolApprovalWire.d.ts +64 -15
  110. package/dist/hitl/toolApprovalWire.js +470 -125
  111. package/dist/hooksWireCaps.js +31 -1
  112. package/dist/hostSettingNoticeArm.d.ts +3 -0
  113. package/dist/hostSettingNoticeArm.js +12 -0
  114. package/dist/hostTurnSettings.d.ts +13 -4
  115. package/dist/hostTurnSettings.js +150 -10
  116. package/dist/humanTurnRead.js +11 -1
  117. package/dist/i18n/messages.en.d.ts +212 -0
  118. package/dist/i18n/messages.en.js +217 -5
  119. package/dist/i18n/messages.zh.js +235 -5
  120. package/dist/i18n/translate.d.ts +3 -0
  121. package/dist/i18n/translate.js +78 -10
  122. package/dist/i18n/zh.d.ts +1 -0
  123. package/dist/i18n/zh.js +1 -0
  124. package/dist/index.d.ts +56 -16
  125. package/dist/index.js +40 -12
  126. package/dist/inheritEnvCapability.js +2 -0
  127. package/dist/inputAuthor.d.ts +16 -0
  128. package/dist/inputAuthor.js +44 -0
  129. package/dist/interactiveHalt.js +2 -1
  130. package/dist/interactiveInterrupt.js +20 -2
  131. package/dist/interruptRefusalNote.d.ts +2 -0
  132. package/dist/interruptRefusalNote.js +17 -0
  133. package/dist/liveModelCatalog.d.ts +2 -0
  134. package/dist/liveModelCatalog.js +23 -9
  135. package/dist/liveQuestionStore.d.ts +4 -1
  136. package/dist/liveQuestionStore.js +12 -3
  137. package/dist/localEngineSeatReading.d.ts +2 -2
  138. package/dist/localEngineSeatReading.js +5 -3
  139. package/dist/localEngineSpawn.d.ts +0 -7
  140. package/dist/localEngineSpawn.js +0 -92
  141. package/dist/localEngineStep.d.ts +2 -2
  142. package/dist/localEngineStep.js +2 -0
  143. package/dist/mcpEngineLeg.d.ts +3 -0
  144. package/dist/mcpEngineLeg.js +38 -1
  145. package/dist/mcpPanel.js +2 -0
  146. package/dist/mcpReconnect.d.ts +9 -1
  147. package/dist/mcpReconnect.js +124 -19
  148. package/dist/mcpWireCaps.js +1 -1
  149. package/dist/model/engineModelWords.d.ts +3 -0
  150. package/dist/model/engineModelWords.js +13 -0
  151. package/dist/model/subagentModelWord.d.ts +21 -2
  152. package/dist/model/subagentModelWord.js +100 -29
  153. package/dist/modelCapabilityProbe.js +7 -43
  154. package/dist/modsFace.d.ts +8 -1
  155. package/dist/modsFace.js +27 -0
  156. package/dist/notifications.d.ts +36 -6
  157. package/dist/notifications.js +170 -20
  158. package/dist/ownKey.d.ts +6 -5
  159. package/dist/ownKey.js +31 -7
  160. package/dist/peerFrames.d.ts +40 -2
  161. package/dist/peerFrames.js +158 -3
  162. package/dist/pendingUserRow.d.ts +4 -0
  163. package/dist/pendingUserRow.js +16 -0
  164. package/dist/permissionsDeclaration.d.ts +1 -0
  165. package/dist/permissionsDeclaration.js +11 -1
  166. package/dist/planReviewCardFacts.d.ts +3 -0
  167. package/dist/planReviewCardFacts.js +52 -2
  168. package/dist/pluginHooksWire.d.ts +10 -1
  169. package/dist/pluginHooksWire.js +96 -7
  170. package/dist/printToolResultFrame.js +4 -2
  171. package/dist/promptBlockedCopy.js +11 -6
  172. package/dist/promptSuggestionBatch.d.ts +7 -0
  173. package/dist/promptSuggestionBatch.js +9 -0
  174. package/dist/promptSuggestionsTail.d.ts +39 -0
  175. package/dist/promptSuggestionsTail.js +116 -0
  176. package/dist/replayBody.js +10 -2
  177. package/dist/request/taskRequest.d.ts +5 -0
  178. package/dist/request/taskRequest.js +142 -21
  179. package/dist/requestCoordinate.d.ts +1 -0
  180. package/dist/requestCoordinate.js +13 -0
  181. package/dist/resumeRefusalCopy.d.ts +1 -3
  182. package/dist/resumeRefusalCopy.js +2 -1
  183. package/dist/retryStatus.d.ts +2 -2
  184. package/dist/retryStatus.js +2 -0
  185. package/dist/rewindArchiveReading.js +4 -4
  186. package/dist/runCancelContext.d.ts +2 -1
  187. package/dist/runCancelContext.js +1 -0
  188. package/dist/runPermissionModeSwitch.js +2 -2
  189. package/dist/scenarioRefusal.js +11 -13
  190. package/dist/scenarioSkills.js +11 -6
  191. package/dist/seam.d.ts +27 -2
  192. package/dist/seam.js +17 -1
  193. package/dist/seatContract.d.ts +189 -12
  194. package/dist/seatContract.js +401 -9
  195. package/dist/sessionBackground.js +2 -1
  196. package/dist/sessionBackgroundHandoff.js +2 -1
  197. package/dist/sessionCostReading.d.ts +70 -0
  198. package/dist/sessionCostReading.js +150 -0
  199. package/dist/sessionEngine.d.ts +2 -0
  200. package/dist/sessionEngine.js +111 -0
  201. package/dist/sessionHooksRoster.d.ts +4 -0
  202. package/dist/sessionHooksRoster.js +158 -0
  203. package/dist/sessionMemoryStatus.d.ts +2 -1
  204. package/dist/sessionMemoryStatus.js +2 -2
  205. package/dist/sessionReadRedaction.d.ts +7 -0
  206. package/dist/sessionReadRedaction.js +26 -0
  207. package/dist/sessionSyncFileHistory.d.ts +4 -0
  208. package/dist/sessionSyncFileHistory.js +27 -0
  209. package/dist/settingsHooksSalvage.js +2 -1
  210. package/dist/sseIdleTriage.d.ts +13 -1
  211. package/dist/sseIdleTriage.js +25 -6
  212. package/dist/storeDurabilityWord.d.ts +15 -0
  213. package/dist/storeDurabilityWord.js +18 -0
  214. package/dist/storePostureCapability.d.ts +7 -3
  215. package/dist/storePostureCapability.js +69 -39
  216. package/dist/subagent/engineSubagentResume.js +2 -2
  217. package/dist/subagent/engineSubagentTail.js +8 -1
  218. package/dist/subagentContentStore.d.ts +11 -0
  219. package/dist/subagentContentStore.js +28 -2
  220. package/dist/terminalStatuses.d.ts +1 -0
  221. package/dist/terminalStatuses.js +4 -1
  222. package/dist/toolResult.d.ts +1 -0
  223. package/dist/toolResult.js +2 -0
  224. package/dist/turnFailurePresentation.js +9 -2
  225. package/dist/typePins.d.ts +11 -0
  226. package/dist/usageAnalytics.d.ts +17 -0
  227. package/dist/usageAnalytics.js +44 -2
  228. package/dist/userAttachmentEnvelope.d.ts +2 -1
  229. package/dist/userAttachmentEnvelope.js +10 -0
  230. package/dist/wireErrorTriage.js +2 -1
  231. package/dist/wireFailureShape.d.ts +6 -5
  232. package/dist/wireFailureShape.js +150 -38
  233. package/dist/wireRefusalCopy.d.ts +16 -5
  234. package/dist/wireRefusalCopy.js +119 -86
  235. package/docs/INTEGRATION-CLIENTS.md +4228 -21
  236. package/package.json +7 -3
@@ -1099,6 +1099,69 @@ class InnerWordIndex {
1099
1099
  this.spanClose ??= codeSpanClose(this.text, this.plain);
1100
1100
  return this.spanClose[i] ?? -1;
1101
1101
  }
1102
+ eventNext = null;
1103
+ runEnd = null;
1104
+ restFrom = null;
1105
+ tailEnd = null;
1106
+ bareEndFrom(k) {
1107
+ const text = this.text;
1108
+ const n = text.length;
1109
+ if (this.eventNext === null || this.runEnd === null || this.restFrom === null) {
1110
+ const ev = new Int32Array(n + 1).fill(n);
1111
+ const run = new Int32Array(n + 1).fill(n);
1112
+ for (let x = n - 1; x >= 0; x--) {
1113
+ const ch = text.charAt(x);
1114
+ const sep = ch === VIEW_SEPARATOR;
1115
+ ev[x] = sep || isBareValueStop(ch) ? x : (ev[x + 1] ?? n);
1116
+ run[x] = sep ? (run[x + 1] ?? n) : x;
1117
+ }
1118
+ this.eventNext = ev;
1119
+ this.runEnd = run;
1120
+ this.restFrom = new Int32Array(n + 1).fill(-1);
1121
+ }
1122
+ const ev = this.eventNext;
1123
+ const run = this.runEnd;
1124
+ const rest = this.restFrom;
1125
+ const pendingRest = [];
1126
+ let j = k;
1127
+ let end;
1128
+ for (;;) {
1129
+ const x = ev[j] ?? n;
1130
+ if (x >= n || text.charAt(x) !== VIEW_SEPARATOR) {
1131
+ end = x;
1132
+ break;
1133
+ }
1134
+ const p = run[x] ?? n;
1135
+ if (credentialWordStartsNear(text, p, this.tokenInner)) {
1136
+ end = x;
1137
+ break;
1138
+ }
1139
+ const known = rest[p] ?? -1;
1140
+ if (known !== -1) {
1141
+ end = known;
1142
+ break;
1143
+ }
1144
+ pendingRest.push(p);
1145
+ j = p;
1146
+ }
1147
+ for (const p of pendingRest)
1148
+ rest[p] = end;
1149
+ return end;
1150
+ }
1151
+ closingTailEnd(t) {
1152
+ if (this.tailEnd === null) {
1153
+ const text = this.text;
1154
+ const n = text.length;
1155
+ const punct = new Int32Array(n + 1).fill(n);
1156
+ for (let x = n - 1; x >= 0; x--)
1157
+ punct[x] = TRAILING_PUNCTUATION.has(text.charAt(x)) ? (punct[x + 1] ?? n) : x;
1158
+ const tail = new Int32Array(n + 1).fill(n);
1159
+ for (let x = n - 1; x >= 0; x--)
1160
+ tail[x] = text.charCodeAt(x) === 0x60 ? (tail[x + 1] ?? n) : (punct[x] ?? n);
1161
+ this.tailEnd = tail;
1162
+ }
1163
+ return this.tailEnd[t] ?? this.text.length;
1164
+ }
1102
1165
  next(q) {
1103
1166
  let best = null;
1104
1167
  for (const p of this.probes) {
@@ -1231,7 +1294,16 @@ function scanSecretValue(text, from, idx) {
1231
1294
  let cut = false;
1232
1295
  let j = i;
1233
1296
  const closingTick = idx === undefined ? -1 : idx.closingTickFrom(i);
1234
- while (j < text.length) {
1297
+ if (idx !== undefined) {
1298
+ const end0 = idx.bareEndFrom(i);
1299
+ if (pending !== null && pending.start < end0 && innerWordFits(text, pending)) {
1300
+ cut = true;
1301
+ j = pending.start;
1302
+ }
1303
+ else
1304
+ j = end0;
1305
+ }
1306
+ while (idx === undefined && j < text.length) {
1235
1307
  if (pending !== null && j >= pending.start) {
1236
1308
  if (j === pending.start && innerWordFits(text, pending)) {
1237
1309
  cut = true;
@@ -1246,7 +1318,7 @@ function scanSecretValue(text, from, idx) {
1246
1318
  let p = j;
1247
1319
  while (p < text.length && text[p] === VIEW_SEPARATOR)
1248
1320
  p++;
1249
- if (credentialWordStartsNear(text, p, idx?.tokenInner ?? true))
1321
+ if (credentialWordStartsNear(text, p, true))
1250
1322
  break;
1251
1323
  j = p;
1252
1324
  continue;
@@ -1255,13 +1327,8 @@ function scanSecretValue(text, from, idx) {
1255
1327
  }
1256
1328
  while (j > i && text[j - 1] === VIEW_SEPARATOR)
1257
1329
  j--;
1258
- if (closingTick > i && closingTick < j) {
1259
- let t = closingTick;
1260
- while (t < j && text.charCodeAt(t) === 0x60)
1261
- t++;
1262
- while (t < j && TRAILING_PUNCTUATION.has(text.charAt(t)))
1263
- t++;
1264
- if (t === j && text.charCodeAt(closingTick) === 0x60) {
1330
+ if (idx !== undefined && closingTick > i && closingTick < j) {
1331
+ if (idx.closingTailEnd(closingTick) >= j && text.charCodeAt(closingTick) === 0x60) {
1265
1332
  j = closingTick;
1266
1333
  while (j > i && text[j - 1] === VIEW_SEPARATOR)
1267
1334
  j--;
@@ -2473,11 +2540,50 @@ function envSchemeWordReading(text, at) {
2473
2540
  }
2474
2541
  return k > e && ENV_ASSIGNMENT_AHEAD.test(text.slice(k, k + 256)) ? { end: e, beforeAssignment: true } : null;
2475
2542
  }
2476
- function labelCandidates(S, pass, regions, out, blocks, outer = false) {
2543
+ const SCHEME_ADJACENT_SOURCE = String.raw `${SCHEME_LEFT_STRICT}(?<![/\\.@])(bearer|basic)(?=[A-Za-z0-9._~+/-])`;
2544
+ const SCHEME_ADJACENT_STRONG_MIN = 8;
2545
+ const SCHEME_ADJACENT_WEAK_MIN = 20;
2546
+ const SCHEME_ADJACENT_WINDOW = 96;
2547
+ function schemeAdjacentAccepted(scheme, win) {
2548
+ if (ADDRESS_SCHEME_RE.test(win))
2549
+ return true;
2550
+ let w = 0;
2551
+ while (w < win.length && isKeyWordChar(win.charCodeAt(w)))
2552
+ w++;
2553
+ if (w > 0 && isProseKnownLiteral(win.slice(0, w)))
2554
+ return true;
2555
+ const connector = (c) => c === 0x2d || c === 0x5f || c === 0x7e || c === 0x2b;
2556
+ let h = 0;
2557
+ while (h < win.length) {
2558
+ const c = win.charCodeAt(h);
2559
+ if (!(isAlnumCode(c) || connector(c) || c === 0x2e || c === 0x2f))
2560
+ break;
2561
+ h++;
2562
+ }
2563
+ const H = win.slice(0, h);
2564
+ const head = H.charCodeAt(0);
2565
+ if (head === 0x2e || head === 0x2f)
2566
+ return false;
2567
+ const upper = /[A-Z]/.test(H);
2568
+ const digit = /[0-9]/.test(H);
2569
+ if (H.length < (upper || digit ? SCHEME_ADJACENT_STRONG_MIN : SCHEME_ADJACENT_WEAK_MIN))
2570
+ return false;
2571
+ if (upper && digit && /[a-z]/.test(H))
2572
+ return true;
2573
+ const first = /^(?:[A-Z]?[a-z]+|[A-Z]+(?![a-z]))/.exec(connector(head) ? H.slice(1) : H);
2574
+ if (first !== null && schemeFollowerReleased(scheme, first[0], false))
2575
+ return false;
2576
+ if (connector(head) || /^(?:[A-Z][a-z]+)+$/.test(H.split(/[-._~+\/]/, 1)[0] ?? ''))
2577
+ return false;
2578
+ return true;
2579
+ }
2580
+ function labelCandidates(S, pass, regions, out, blocks, mode = 'strict') {
2477
2581
  const text = S.text;
2582
+ const outer = mode === 'outer';
2583
+ const adjacent = mode === 'adjacent' && pass === 'scheme';
2478
2584
  const unitAt = (k) => S.unitAt(k);
2479
2585
  const strictSource = pass === 'label' ? SECRET_LABELLED_WORD.source : SECRET_SCHEME_WORD.source;
2480
- const re = new RegExp(outer ? (pass === 'label' ? LABEL_WORD_OUTER_SOURCE : SCHEME_WORD_OUTER_SOURCE) : strictSource, 'gi');
2586
+ const re = new RegExp(adjacent ? SCHEME_ADJACENT_SOURCE : outer ? (pass === 'label' ? LABEL_WORD_OUTER_SOURCE : SCHEME_WORD_OUTER_SOURCE) : strictSource, 'gi');
2481
2587
  const strictAt = outer ? new RegExp(strictSource, 'iy') : null;
2482
2588
  const schemePass = pass !== 'label';
2483
2589
  const tokenPass = pass === 'token';
@@ -2744,6 +2850,8 @@ function labelCandidates(S, pass, regions, out, blocks, outer = false) {
2744
2850
  continue;
2745
2851
  if (schemePass && labelStartsAt(text, hit.index))
2746
2852
  continue;
2853
+ if (adjacent && !schemeAdjacentAccepted(label, text.slice(hit.index + hit[0].length, hit.index + hit[0].length + SCHEME_ADJACENT_WINDOW)))
2854
+ continue;
2747
2855
  let from = hit.index + hit[0].length;
2748
2856
  if (!schemePass && text.charCodeAt(from) === 0x3e && text.charCodeAt(from - 1) === 0x3d && labelQuotedAt(text, hit.index, hit[0].slice(label.length))) {
2749
2857
  let k = from + 1;
@@ -3102,6 +3210,9 @@ function longestAlnumRun(word) {
3102
3210
  }
3103
3211
  return best;
3104
3212
  }
3213
+ function isProseKnownLiteral(word) {
3214
+ return SECRET_LITERAL_RE.test(word) && (longestAlnumRun(word) >= PROSE_LITERAL_MIN_RUN || shortLiteralTail(word));
3215
+ }
3105
3216
  const JWT_WORD = /^eyJ[A-Za-z0-9_-]{8,}\.[A-Za-z0-9_-]{8,}\.[A-Za-z0-9_-]{4,}$/;
3106
3217
  const PEM_BEGIN_SOURCE = `${PRIVATE_KEY_PEM_HEADER.source}(?: BLOCK)?-----`;
3107
3218
  const PEM_CASE_FLAGS = PRIVATE_KEY_PEM_HEADER.flags.includes('i') ? 'i' : '';
@@ -3569,7 +3680,7 @@ function proseLiteralEdits(text) {
3569
3680
  fileAt = fileUrlPositions(text);
3570
3681
  const localPath = prev === '\\' || prev === '.' || (slashSegment && fileAt != null && fileAt[i] === 1);
3571
3682
  const pathish = slashSegment || localPath;
3572
- if (!localPath && SECRET_LITERAL_RE.test(word) && (longestAlnumRun(word) >= PROSE_LITERAL_MIN_RUN || shortLiteralTail(word))) {
3683
+ if (!localPath && isProseKnownLiteral(word)) {
3573
3684
  pushEdit(edits, text, i + escHead, end, REDACTED_SECRET);
3574
3685
  }
3575
3686
  else if (!localPath) {
@@ -4393,8 +4504,14 @@ function runLabelPasses(S, regions, cands, blocks) {
4393
4504
  labelCandidates(S, 'scheme', regions, cands, blocks);
4394
4505
  labelCandidates(S, 'token', regions, cands, blocks);
4395
4506
  labelCandidates(S, 'label', regions, cands, blocks);
4396
- labelCandidates(S, 'scheme', regions, cands, blocks, true);
4397
- labelCandidates(S, 'label', regions, cands, blocks, true);
4507
+ labelCandidates(S, 'scheme', regions, cands, blocks, 'outer');
4508
+ labelCandidates(S, 'label', regions, cands, blocks, 'outer');
4509
+ emitRow('scheme-adjacent', (phases) => {
4510
+ const adjacent = [];
4511
+ labelCandidates(S, 'scheme', regions, adjacent, blocks, 'adjacent');
4512
+ for (const c of adjacent)
4513
+ cands.push({ ...c, phases });
4514
+ });
4398
4515
  }
4399
4516
  function collectCandidates(text, o, nested) {
4400
4517
  const V = buildScanView(text, o);
@@ -4486,6 +4603,7 @@ const RULES_BY_VERSION = {
4486
4603
  form: { host: 'hooks.slack.com', trailingDot: true, pathKinds: ['services', 'workflows', 'triggers'], tailClass: 'A-Za-z0-9+/_-', minTailLength: 40 },
4487
4604
  },
4488
4605
  ],
4606
+ '0.110.0': [{ id: 'scheme-adjacent', ticket: 'CC-1282', kind: 'generator' }],
4489
4607
  };
4490
4608
  const RULE_ROWS_ARE_GENERATORS = true;
4491
4609
  void RULE_ROWS_ARE_GENERATORS;
@@ -5118,6 +5236,12 @@ export function displayUntrusted(text, opts = {}) {
5118
5236
  const out = renderUntrusted(text, opts, null);
5119
5237
  return typeof out === 'string' ? out : out.tracked.text;
5120
5238
  }
5239
+ export function displayUntrustedCapped(text, max, opts = {}) {
5240
+ const whole = displayUntrusted(text, opts);
5241
+ if (typeof max !== 'number' || !Number.isFinite(max) || whole.length <= max)
5242
+ return whole;
5243
+ return `${displayUntrusted(text, { ...opts, max })}…`;
5244
+ }
5121
5245
  export function cleanUntrustedScalar(v) {
5122
5246
  return displayUntrusted(String(v ?? ''), { credentialUrls: false, credentialWords: false, foldLines: false });
5123
5247
  }
@@ -154,6 +154,9 @@ export declare const APPROVAL_EXPIRED: "approval.expired";
154
154
  export declare function runDeathVerdictNoteOf(code: string | undefined): string | undefined;
155
155
  export declare const CAPABILITY_OPERATOR_PRINCIPALS_REQUIRED = "capability.operator_principals_required";
156
156
  export declare const COMPACT_NOT_RUNNING = "compact.not_running";
157
+ export declare const INTERRUPT_NOTHING_IN_FLIGHT = "interrupt.nothing_in_flight";
158
+ export declare const INTERRUPT_NOT_HELD = "interrupt.not_held";
159
+ export declare const STEERING_NOT_RUNNING = "steering.not_running";
157
160
  export declare function isUnavailableFaceCode(code: string | undefined): boolean;
158
161
  export type OperatorGateRefusal = 'operator_only' | 'operators_unconfigured';
159
162
  export declare function operatorGateRefusalContent(cause: OperatorGateRefusal): string | undefined;
@@ -274,6 +274,9 @@ export function runDeathVerdictNoteOf(code) {
274
274
  }
275
275
  export const CAPABILITY_OPERATOR_PRINCIPALS_REQUIRED = 'capability.operator_principals_required';
276
276
  export const COMPACT_NOT_RUNNING = 'compact.not_running';
277
+ export const INTERRUPT_NOTHING_IN_FLIGHT = 'interrupt.nothing_in_flight';
278
+ export const INTERRUPT_NOT_HELD = 'interrupt.not_held';
279
+ export const STEERING_NOT_RUNNING = 'steering.not_running';
277
280
  export function isUnavailableFaceCode(code) {
278
281
  return typeof code === 'string' && (code.startsWith('capability.') || code.startsWith('feature.'));
279
282
  }
@@ -1,4 +1,5 @@
1
1
  import type { HealthAuthKind } from '@sema-agent/sdk';
2
+ import { type EngineHealthStoreDurability } from './storeDurabilityWord.js';
2
3
  export interface EngineHealthCenterFacts {
3
4
  readonly issuer?: string;
4
5
  readonly webBaseUrl?: string;
@@ -42,4 +43,23 @@ export interface EngineHealthFacts {
42
43
  readonly version?: string;
43
44
  readonly dataRoot?: string;
44
45
  }
46
+ export type ModsDeploymentPackagesReading = {
47
+ readonly kind: 'present';
48
+ readonly count: number;
49
+ } | {
50
+ readonly kind: 'absent';
51
+ } | {
52
+ readonly kind: 'unreadable';
53
+ };
54
+ export declare function readModsDeploymentPackages(health: object | null | undefined): ModsDeploymentPackagesReading;
55
+ export type EngineHealthStoreReading = {
56
+ readonly kind: 'reported';
57
+ readonly durability: EngineHealthStoreDurability;
58
+ } | {
59
+ readonly kind: 'unreadable';
60
+ readonly word?: string;
61
+ } | {
62
+ readonly kind: 'absent';
63
+ };
64
+ export declare function readEngineHealthStore(health: object | null | undefined): EngineHealthStoreReading;
45
65
  export declare function readEngineHealthFacts(health: object | null | undefined): EngineHealthFacts;
@@ -1,4 +1,5 @@
1
- import { readOwnDataValue } from './ownKey.js';
1
+ import { ownDataField, readOwnDataValue } from './ownKey.js';
2
+ import { readStoreDurability } from './storeDurabilityWord.js';
2
3
  const _healthFactsMatchSdk = [true, true, true, true, true, true, true, true, true, true];
3
4
  void _healthFactsMatchSdk;
4
5
  const ENGINE_SIGNAL_KEY = 'engineSignal';
@@ -117,6 +118,46 @@ function guarded(read) {
117
118
  return undefined;
118
119
  }
119
120
  }
121
+ export function readModsDeploymentPackages(health) {
122
+ try {
123
+ if (!isObject(health))
124
+ return Object.freeze({ kind: 'unreadable' });
125
+ const mods = ownDataField(health, 'mods');
126
+ if (mods === undefined)
127
+ return Object.freeze({ kind: 'absent' });
128
+ if (!isObject(mods))
129
+ return Object.freeze({ kind: 'unreadable' });
130
+ const n = ownDataField(mods, 'deploymentPackages');
131
+ if (n === undefined)
132
+ return Object.freeze({ kind: 'absent' });
133
+ if (typeof n === 'number' && Number.isSafeInteger(n) && n >= 1)
134
+ return Object.freeze({ kind: 'present', count: n });
135
+ return Object.freeze({ kind: 'unreadable' });
136
+ }
137
+ catch {
138
+ return Object.freeze({ kind: 'unreadable' });
139
+ }
140
+ }
141
+ export function readEngineHealthStore(health) {
142
+ try {
143
+ if (!isObject(health))
144
+ return Object.freeze({ kind: 'unreadable' });
145
+ const store = ownDataField(health, 'store');
146
+ if (store === undefined)
147
+ return Object.freeze({ kind: 'absent' });
148
+ if (!isObject(store))
149
+ return Object.freeze({ kind: 'unreadable' });
150
+ const read = readStoreDurability(store);
151
+ if (read.kind === 'word')
152
+ return Object.freeze({ kind: 'reported', durability: read.durability });
153
+ if (read.kind === 'unrecognized')
154
+ return Object.freeze({ kind: 'unreadable', word: read.word });
155
+ return Object.freeze({ kind: 'unreadable' });
156
+ }
157
+ catch {
158
+ return Object.freeze({ kind: 'unreadable' });
159
+ }
160
+ }
120
161
  export function readEngineHealthFacts(health) {
121
162
  if (!isObject(health))
122
163
  return Object.freeze({});
@@ -0,0 +1,23 @@
1
+ import type { UiLanguage } from './env/uiLanguage.js';
2
+ import type { ProbeHealthResult } from '@sema-agent/sdk';
3
+ export type HealthProbeUnansweredReason = 'timeout' | 'network';
4
+ export type HealthProbeNotOkReason = 'http' | 'not_ok';
5
+ export interface HealthProbeAnsweredNotOk {
6
+ readonly kind: 'answered_not_ok';
7
+ readonly reason: HealthProbeNotOkReason;
8
+ readonly http: number;
9
+ readonly status?: string;
10
+ }
11
+ export type HealthProbeVerdict = {
12
+ readonly kind: 'unanswered';
13
+ readonly reason: HealthProbeUnansweredReason;
14
+ } | {
15
+ readonly kind: 'answered_ok';
16
+ } | HealthProbeAnsweredNotOk;
17
+ export interface TimedHealthAnswer {
18
+ readonly answer: HealthProbeAnsweredNotOk;
19
+ readonly atMs: number;
20
+ }
21
+ export declare function classifyHealthProbe(reading: ProbeHealthResult): HealthProbeVerdict | undefined;
22
+ export declare function healthAnswerClause(verdict: HealthProbeVerdict, lang?: UiLanguage): string | undefined;
23
+ export declare function latestSegmentHealthAnswer(segmentStartMs: number | undefined, ...seen: ReadonlyArray<TimedHealthAnswer | undefined>): HealthProbeAnsweredNotOk | undefined;
@@ -0,0 +1,115 @@
1
+ import { displayUntrusted } from './displayUntrusted.js';
2
+ import { msg, renderMessage } from './i18n/translate.js';
3
+ import { slotReadOf } from './wireFailureShape.js';
4
+ const UNANSWERED_REASONS = new Set(['timeout', 'network']);
5
+ const NOT_OK_REASONS = new Set(['http', 'not_ok']);
6
+ const REPORTED_STATUS_SHOWN_MAX = 64;
7
+ function ownValue(o, key) {
8
+ const r = slotReadOf(o, key);
9
+ return r.presence === 'present' ? r.value : undefined;
10
+ }
11
+ function isHttpCode(v) {
12
+ return typeof v === 'number' && Number.isInteger(v) && v >= 100 && v <= 599;
13
+ }
14
+ function shownStatusOf(v) {
15
+ if (typeof v !== 'string')
16
+ return undefined;
17
+ const shown = displayUntrusted(v, { max: REPORTED_STATUS_SHOWN_MAX });
18
+ return shown.trim() === '' ? undefined : shown;
19
+ }
20
+ function answeredNotOk(reason, http, status) {
21
+ return Object.freeze({ kind: 'answered_not_ok', reason, http, ...(status !== undefined ? { status } : {}) });
22
+ }
23
+ export function classifyHealthProbe(reading) {
24
+ try {
25
+ if (typeof reading !== 'object' || reading === null)
26
+ return undefined;
27
+ const alive = ownValue(reading, 'alive');
28
+ if (alive === true)
29
+ return Object.freeze({ kind: 'answered_ok' });
30
+ if (alive !== false)
31
+ return undefined;
32
+ const reason = ownValue(reading, 'reason');
33
+ if (typeof reason !== 'string')
34
+ return undefined;
35
+ if (UNANSWERED_REASONS.has(reason))
36
+ return Object.freeze({ kind: 'unanswered', reason: reason });
37
+ if (!NOT_OK_REASONS.has(reason))
38
+ return undefined;
39
+ const http = ownValue(reading, 'status');
40
+ if (!isHttpCode(http))
41
+ return undefined;
42
+ return answeredNotOk(reason, http, reason === 'not_ok' ? shownStatusOf(ownValue(reading, 'reportedStatus')) : undefined);
43
+ }
44
+ catch {
45
+ return undefined;
46
+ }
47
+ }
48
+ function answeredNotOkOf(v) {
49
+ if (typeof v !== 'object' || v === null)
50
+ return undefined;
51
+ if (ownValue(v, 'kind') !== 'answered_not_ok')
52
+ return undefined;
53
+ const reason = ownValue(v, 'reason');
54
+ const http = ownValue(v, 'http');
55
+ if (typeof reason !== 'string' || !NOT_OK_REASONS.has(reason) || !isHttpCode(http))
56
+ return undefined;
57
+ return answeredNotOk(reason, http, shownStatusOf(ownValue(v, 'status')));
58
+ }
59
+ export function healthAnswerClause(verdict, lang) {
60
+ try {
61
+ if (typeof verdict !== 'object' || verdict === null)
62
+ return undefined;
63
+ const kind = ownValue(verdict, 'kind');
64
+ if (kind === 'answered_ok')
65
+ return renderMessage(msg('localEngine.health.answer.ok'), lang);
66
+ if (kind === 'unanswered') {
67
+ const reason = ownValue(verdict, 'reason');
68
+ if (reason === 'timeout')
69
+ return renderMessage(msg('localEngine.health.answer.unansweredTimeout'), lang);
70
+ if (reason === 'network')
71
+ return renderMessage(msg('localEngine.health.answer.unansweredNetwork'), lang);
72
+ return undefined;
73
+ }
74
+ const nok = answeredNotOkOf(verdict);
75
+ if (nok === undefined)
76
+ return undefined;
77
+ return renderMessage(msg(nok.reason === 'not_ok' ? 'localEngine.health.answer.notOkStatus' : 'localEngine.health.answer.notOkHttp', { http: nok.http }), lang);
78
+ }
79
+ catch {
80
+ return undefined;
81
+ }
82
+ }
83
+ function timedNotOkOf(s, start, bestAtMs) {
84
+ try {
85
+ if (typeof s !== 'object' || s === null)
86
+ return { kind: 'not_better' };
87
+ const atMs = ownValue(s, 'atMs');
88
+ if (typeof atMs !== 'number' || !Number.isFinite(atMs))
89
+ return { kind: 'not_better' };
90
+ if (start !== undefined && atMs < start)
91
+ return { kind: 'not_better' };
92
+ if (bestAtMs !== undefined && atMs <= bestAtMs)
93
+ return { kind: 'not_better' };
94
+ const answer = answeredNotOkOf(ownValue(s, 'answer'));
95
+ return answer === undefined ? { kind: 'not_better' } : { kind: 'better', entry: { atMs, answer } };
96
+ }
97
+ catch {
98
+ return { kind: 'unreadable' };
99
+ }
100
+ }
101
+ export function latestSegmentHealthAnswer(segmentStartMs, ...seen) {
102
+ try {
103
+ const start = typeof segmentStartMs === 'number' && Number.isFinite(segmentStartMs) ? segmentStartMs : undefined;
104
+ let best;
105
+ for (const s of seen) {
106
+ const r = timedNotOkOf(s, start, best?.atMs);
107
+ if (r.kind === 'better')
108
+ best = r.entry;
109
+ }
110
+ return best?.answer;
111
+ }
112
+ catch {
113
+ return undefined;
114
+ }
115
+ }
@@ -1,14 +1,15 @@
1
1
  import type { InlineTaskTick } from './seam.js';
2
2
  export interface EngineInlineTaskStats {
3
- toolUses: number;
4
- totalTokens: number;
5
- durationMs: number;
3
+ toolUses?: number;
4
+ totalTokens?: number;
5
+ durationMs?: number;
6
6
  currentAction?: string;
7
7
  model?: string;
8
8
  done: boolean;
9
9
  isError: boolean;
10
10
  }
11
11
  export declare function publishEngineInlineTaskTick(cardId: string, tick: InlineTaskTick): void;
12
+ export declare function publishEngineInlineTaskModel(cardId: string, model: string): void;
12
13
  export declare function settleEngineInlineTaskStats(cardId: string, isError: boolean): void;
13
14
  export declare function settleAllEngineInlineTaskStats(): void;
14
15
  export declare function getEngineInlineTaskStats(cardId: string): EngineInlineTaskStats | undefined;
@@ -13,7 +13,23 @@ export function publishEngineInlineTaskTick(cardId, tick) {
13
13
  const prev = statsByCardId.get(cardId);
14
14
  if (prev?.done)
15
15
  return;
16
- statsByCardId.set(cardId, { ...tick, done: false, isError: false });
16
+ const { model: tickModel, ...counts } = tick;
17
+ const model = typeof tickModel === 'string' && tickModel.length > 0 ? tickModel : prev?.model;
18
+ statsByCardId.set(cardId, { ...counts, ...(model !== undefined ? { model } : {}), done: false, isError: false });
19
+ emit();
20
+ }
21
+ export function publishEngineInlineTaskModel(cardId, model) {
22
+ if (typeof model !== 'string' || model.length === 0)
23
+ return;
24
+ const prev = statsByCardId.get(cardId);
25
+ if (prev === undefined) {
26
+ statsByCardId.set(cardId, { model, done: false, isError: false });
27
+ }
28
+ else {
29
+ if (prev.model === model)
30
+ return;
31
+ statsByCardId.set(cardId, { ...prev, model });
32
+ }
17
33
  emit();
18
34
  }
19
35
  export function settleEngineInlineTaskStats(cardId, isError) {
@@ -40,7 +56,7 @@ export function getEngineInlineTaskStats(cardId) {
40
56
  export function getSoleLiveEngineInlineTaskStats() {
41
57
  let sole;
42
58
  for (const s of statsByCardId.values()) {
43
- if (s.done)
59
+ if (s.done || s.toolUses === undefined)
44
60
  continue;
45
61
  if (sole !== undefined)
46
62
  return undefined;
@@ -394,6 +394,7 @@ export declare function classifierDenialLimitSentence(facts: Pick<ClassifierDeni
394
394
  export declare function taskLateApprovalSentence(facts: Pick<TaskLateApprovalFactsView, 'toolName'>, lang?: UiLanguage): string | undefined;
395
395
  export declare function taskHaltUnconsumedSentence(facts: Pick<TaskHaltUnconsumedFactsView, 'sessionId' | 'runId'>, lang?: UiLanguage): string | undefined;
396
396
  export declare function steeringParkedInputBlockedSentence(facts: Pick<SteeringParkedInputBlockedFactsView, 'sessionId' | 'runId'>, lang?: UiLanguage): string | undefined;
397
+ export declare function modelCapabilityDowngradedSentence(facts: Pick<ModelCapabilityDowngradedFactsView, 'model' | 'capability' | 'status'>, lang?: UiLanguage): string | undefined;
397
398
  export declare function durableGateUnavailableSentence(facts: Pick<DurableGateUnavailableFactsView, 'source' | 'cause' | 'liveApprover' | 'liveQuestionFace'>, lang?: UiLanguage): string | undefined;
398
399
  export type DiscardedDeliveryPathWord = (typeof CORE_DISCARDED_DELIVERY_PATHS)[number];
399
400
  export interface DeliveryDiscardedFactsView {
@@ -403,6 +404,14 @@ export interface DeliveryDiscardedFactsView {
403
404
  path?: DiscardedDeliveryPathWord;
404
405
  }
405
406
  export declare function readDeliveryDiscarded(notice: {} | null | undefined): DeliveryDiscardedFactsView | undefined;
407
+ export interface ModelCapabilityDowngradedFactsView {
408
+ model: string;
409
+ capability: string;
410
+ status: string;
411
+ sessionId: string;
412
+ runId: string;
413
+ }
414
+ export declare function readModelCapabilityDowngraded(notice: {} | null | undefined): ModelCapabilityDowngradedFactsView | undefined;
406
415
  export declare const ENGINE_NOTICE_FACT_READERS: Readonly<{
407
416
  readonly 'mcp.injection_dropped': typeof readMcpInjectionDrop;
408
417
  readonly 'delegation.ask_unresolvable': typeof readAskUnresolvable;
@@ -444,6 +453,7 @@ export declare const ENGINE_NOTICE_FACT_READERS: Readonly<{
444
453
  readonly 'task.halt_unconsumed': typeof readTaskHaltUnconsumed;
445
454
  readonly 'steering.parked_input_blocked': typeof readSteeringParkedInputBlocked;
446
455
  readonly 'delegation.delivery_discarded': typeof readDeliveryDiscarded;
456
+ readonly 'model.capability_downgraded': typeof readModelCapabilityDowngraded;
447
457
  }>;
448
458
  type FactReaderTable = typeof ENGINE_NOTICE_FACT_READERS;
449
459
  export type EngineNoticeFactsCode = keyof FactReaderTable;
@@ -1,8 +1,8 @@
1
1
  import { AUTO_MODE_UNAVAILABLE_CAUSES } from './autoModeUnavailable.js';
2
- import { displayUntrusted } from './displayUntrusted.js';
2
+ import { displayUntrusted, displayUntrustedCapped } from './displayUntrusted.js';
3
3
  import { CORE_ENGINE_NOTICE_CODES, CORE_MCP_INJECTION_DROP_REASONS, CORE_NOTICE_AUDIENCE, CORE_USER_INPUT_UNDRAINED_FAMILIES, } from './generated/engineNoticeTables.js';
4
4
  import { CORE_APPROVAL_REMEDY_KINDS, CORE_ASK_UNRESOLVABLE_CAUSES, CORE_DISCARDED_DELIVERY_PATHS, CORE_DURABLE_MANDATE_SOURCES, CORE_PERMISSION_MODE_FOLD_REASONS, } from './generated/engineFactTables.js';
5
- import { msg, renderMessage } from './i18n/translate.js';
5
+ import { msg, renderLanguageOf, renderMessage } from './i18n/translate.js';
6
6
  import { ownDataField, readOwnDataValue } from './ownKey.js';
7
7
  import { inValueOf, slotReadOf } from './wireFailureShape.js';
8
8
  export const ENGINE_NOTICE_CODES = CORE_ENGINE_NOTICE_CODES;
@@ -196,7 +196,6 @@ function readAskUnresolvableOf(notice) {
196
196
  };
197
197
  }
198
198
  export const DURABLE_MANDATE_SOURCES = CORE_DURABLE_MANDATE_SOURCES;
199
- const DURABLE_MANDATE_SOURCE_SET = new Set(DURABLE_MANDATE_SOURCES);
200
199
  export function readDurableGateUnavailable(notice) {
201
200
  if (typeof notice !== 'object' || notice === null || Array.isArray(notice))
202
201
  return undefined;
@@ -213,7 +212,7 @@ export function readDurableGateUnavailable(notice) {
213
212
  const causeIn = o.cause;
214
213
  const sessionId = typeof sessionIdIn === 'string' && sessionIdIn.length > 0 ? sessionIdIn : undefined;
215
214
  const runId = typeof runIdIn === 'string' && runIdIn.length > 0 ? runIdIn : undefined;
216
- const source = typeof sourceIn === 'string' && DURABLE_MANDATE_SOURCE_SET.has(sourceIn) ? sourceIn : undefined;
215
+ const source = typeof sourceIn === 'string' && sourceIn.length > 0 ? sourceIn : undefined;
217
216
  const cause = typeof causeIn === 'string' && causeIn.length > 0 ? causeIn : undefined;
218
217
  if (sessionId === undefined || runId === undefined || source === undefined || cause === undefined) {
219
218
  return undefined;
@@ -1417,14 +1416,14 @@ function shownName(v) {
1417
1416
  function shownText(v, max) {
1418
1417
  if (v === undefined)
1419
1418
  return undefined;
1420
- const s = displayUntrusted(v, { max });
1419
+ const s = displayUntrustedCapped(v, max);
1421
1420
  return s.length > 0 ? s : undefined;
1422
1421
  }
1423
1422
  function wordLookup(table, word) {
1424
1423
  return Object.hasOwn(table, word) ? table[word] : undefined;
1425
1424
  }
1426
1425
  function joinSentences(parts, lang) {
1427
- return parts.filter((p) => p !== undefined && p.length > 0).join(lang === 'zh' ? '' : ' ');
1426
+ return parts.filter((p) => p !== undefined && p.length > 0).join(renderLanguageOf(lang) === 'zh' ? '' : ' ');
1428
1427
  }
1429
1428
  export function memorySessionPollutedSentence(facts, lang) {
1430
1429
  try {
@@ -1658,6 +1657,21 @@ export function steeringParkedInputBlockedSentence(facts, lang) {
1658
1657
  return undefined;
1659
1658
  }
1660
1659
  }
1660
+ export function modelCapabilityDowngradedSentence(facts, lang) {
1661
+ try {
1662
+ const model = shownName(viewStr(facts, 'model'));
1663
+ const capability = viewStr(facts, 'capability');
1664
+ const status = viewStr(facts, 'status');
1665
+ if (model === undefined || capability === undefined || status === undefined)
1666
+ return undefined;
1667
+ if (capability !== 'image' || status !== 'declared_off')
1668
+ return undefined;
1669
+ return renderMessage(msg('notice.model.capabilityDowngraded.image', { model }), lang);
1670
+ }
1671
+ catch {
1672
+ return undefined;
1673
+ }
1674
+ }
1661
1675
  const DURABLE_MANDATE_CLAUSE = Object.freeze({
1662
1676
  force_durable_gate: 'notice.durableGate.mandate.forceDurableGate',
1663
1677
  durable_approval: 'notice.durableGate.mandate.durableApproval',
@@ -1717,6 +1731,21 @@ function readDeliveryDiscardedOf(notice) {
1717
1731
  const path = typeof pathRaw === 'string' && DISCARDED_DELIVERY_PATH_SET.has(pathRaw) ? pathRaw : undefined;
1718
1732
  return { taskId, taskType, sessionId, ...(path !== undefined ? { path } : {}) };
1719
1733
  }
1734
+ export function readModelCapabilityDowngraded(notice) {
1735
+ return guardedRead(notice, (n) => {
1736
+ const o = userCodeDetail(n, 'model.capability_downgraded');
1737
+ if (o === undefined)
1738
+ return undefined;
1739
+ const model = dataStr(o, 'model');
1740
+ const capability = dataStr(o, 'capability');
1741
+ const status = dataStr(o, 'status');
1742
+ const sessionId = dataStr(o, 'sessionId');
1743
+ const runId = dataStr(o, 'runId');
1744
+ if (model === undefined || capability === undefined || status === undefined || sessionId === undefined || runId === undefined)
1745
+ return undefined;
1746
+ return { model, capability, status, sessionId, runId };
1747
+ });
1748
+ }
1720
1749
  export const ENGINE_NOTICE_FACT_READERS = Object.freeze({
1721
1750
  'mcp.injection_dropped': readMcpInjectionDrop,
1722
1751
  'delegation.ask_unresolvable': readAskUnresolvable,
@@ -1758,6 +1787,7 @@ export const ENGINE_NOTICE_FACT_READERS = Object.freeze({
1758
1787
  'task.halt_unconsumed': readTaskHaltUnconsumed,
1759
1788
  'steering.parked_input_blocked': readSteeringParkedInputBlocked,
1760
1789
  'delegation.delivery_discarded': readDeliveryDiscarded,
1790
+ 'model.capability_downgraded': readModelCapabilityDowngraded,
1761
1791
  });
1762
1792
  const _factReaderTablePin = true;
1763
1793
  void _factReaderTablePin;