@sema-agent/client-core 0.107.0 → 0.109.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 (165) hide show
  1. package/CHANGELOG.md +239 -0
  2. package/README.md +54 -36
  3. package/dist/adapt/arms.js +23 -8
  4. package/dist/adapt/textStream.d.ts +2 -0
  5. package/dist/adapt/textStream.js +37 -16
  6. package/dist/adapter/activeRunSelfHeal.d.ts +2 -0
  7. package/dist/adapter/activeRunSelfHeal.js +21 -4
  8. package/dist/adapter/downstream/eventToSdkMessage.js +2 -1
  9. package/dist/agentSession/engineAgentRegistryRead.js +2 -0
  10. package/dist/bashExitReading.d.ts +12 -0
  11. package/dist/bashExitReading.js +44 -0
  12. package/dist/checkpointRowVerdict.d.ts +6 -1
  13. package/dist/checkpointRowVerdict.js +30 -2
  14. package/dist/cloudConfigWireCaps.d.ts +10 -0
  15. package/dist/cloudConfigWireCaps.js +33 -0
  16. package/dist/compensations.js +1 -1
  17. package/dist/coreValuePorts.d.ts +17 -1
  18. package/dist/coreValuePorts.js +5 -0
  19. package/dist/decideReceipt.js +2 -1
  20. package/dist/engineAgentAbsence.d.ts +2 -0
  21. package/dist/engineAgentAbsence.js +28 -0
  22. package/dist/engineErrorCodes.d.ts +9 -0
  23. package/dist/engineErrorCodes.js +9 -0
  24. package/dist/engineHealthFacts.d.ts +17 -0
  25. package/dist/engineHealthFacts.js +42 -3
  26. package/dist/engineNoticeCodes.d.ts +147 -1
  27. package/dist/engineNoticeCodes.js +694 -57
  28. package/dist/engineTargetSeat.js +1 -0
  29. package/dist/errorSupplementRoles.js +6 -1
  30. package/dist/eventLeg.js +1 -1
  31. package/dist/executionLaneWords.js +2 -1
  32. package/dist/fleetTaskDesc.js +3 -3
  33. package/dist/gateOutcome.d.ts +10 -1
  34. package/dist/gateOutcome.js +48 -1
  35. package/dist/generated/engineFactTables.d.ts +2 -0
  36. package/dist/generated/engineFactTables.js +11 -0
  37. package/dist/generated/engineNoticeTables.js +6 -0
  38. package/dist/generated/settingsSchemaFns.d.ts +4 -2
  39. package/dist/generated/settingsSchemaFns.js +9 -3
  40. package/dist/generated/settingsSchemaMcpRequestEntry.d.ts +1 -1
  41. package/dist/generated/settingsSchemaMcpRequestEntry.js +9 -18
  42. package/dist/generated/settingsSchemaReservedMemberName.d.ts +1 -0
  43. package/dist/generated/settingsSchemaReservedMemberName.js +7 -0
  44. package/dist/generated/settingsSchemaTables.d.ts +2 -0
  45. package/dist/generated/settingsSchemaTables.js +10 -0
  46. package/dist/generated/settingsSchemaWireName.d.ts +1 -0
  47. package/dist/generated/settingsSchemaWireName.js +8 -0
  48. package/dist/headlessReconnectWire.js +12 -7
  49. package/dist/hitl/approvalAskers.d.ts +13 -0
  50. package/dist/hitl/approvalAskers.js +79 -0
  51. package/dist/hitl/approvalCardReasons.js +22 -4
  52. package/dist/hitl/approvalRequestFrameReading.d.ts +14 -0
  53. package/dist/hitl/approvalRequestFrameReading.js +79 -0
  54. package/dist/hitl/approvalResolution.d.ts +3 -0
  55. package/dist/hitl/approvalResolution.js +22 -4
  56. package/dist/hitl/approvalsFeed.js +4 -13
  57. package/dist/hitl/askParkRowRouting.js +10 -3
  58. package/dist/hitl/automaticAnswerVerdict.d.ts +5 -2
  59. package/dist/hitl/automaticAnswerVerdict.js +16 -2
  60. package/dist/hitl/decisionConflict.d.ts +2 -1
  61. package/dist/hitl/decisionConflict.js +4 -1
  62. package/dist/hitl/decisionRefusal.d.ts +1 -0
  63. package/dist/hitl/decisionRefusal.js +5 -2
  64. package/dist/hitl/decisionSend.js +2 -6
  65. package/dist/hitl/frameRouter.d.ts +3 -2
  66. package/dist/hitl/frameRouter.js +37 -7
  67. package/dist/hitl/gateLedger.d.ts +2 -0
  68. package/dist/hitl/gateLedger.js +3 -1
  69. package/dist/hitl/hitlBridge.d.ts +4 -0
  70. package/dist/hitl/hitlBridge.js +11 -8
  71. package/dist/hitl/livePendingAsk.js +17 -16
  72. package/dist/hitl/localAllowRule.js +2 -1
  73. package/dist/hitl/noAllowCause.d.ts +1 -1
  74. package/dist/hitl/noAllowCause.js +4 -2
  75. package/dist/hitl/parkExpiryJudgements.js +26 -1
  76. package/dist/hitl/parkOwnership.d.ts +2 -0
  77. package/dist/hitl/parkOwnership.js +48 -8
  78. package/dist/hitl/parkResolver.js +39 -30
  79. package/dist/hitl/parkRowBirthWait.d.ts +2 -0
  80. package/dist/hitl/parkRowBirthWait.js +8 -1
  81. package/dist/hitl/parkedUnresumable.d.ts +13 -0
  82. package/dist/hitl/parkedUnresumable.js +80 -0
  83. package/dist/hitl/permissionRuleScope.d.ts +4 -0
  84. package/dist/hitl/permissionRuleScope.js +31 -0
  85. package/dist/hitl/persistedRulesWire.d.ts +7 -1
  86. package/dist/hitl/persistedRulesWire.js +25 -8
  87. package/dist/hitl/planReviewWire.js +12 -16
  88. package/dist/hitl/policyDenyCause.d.ts +3 -0
  89. package/dist/hitl/policyDenyCause.js +16 -0
  90. package/dist/hitl/sessionAllowRoute.js +5 -4
  91. package/dist/hitl/sessionPolicyDeliverable.js +1 -1
  92. package/dist/hitl/standingRows.d.ts +1 -5
  93. package/dist/hitl/standingRows.js +15 -14
  94. package/dist/hitl/toolApprovalWire.d.ts +16 -4
  95. package/dist/hitl/toolApprovalWire.js +57 -17
  96. package/dist/hooksReaderGenerations.d.ts +1 -0
  97. package/dist/hooksReaderGenerations.js +12 -0
  98. package/dist/hooksWireCaps.js +12 -7
  99. package/dist/hostSettingsSource.js +2 -0
  100. package/dist/i18n/messages.en.d.ts +206 -1
  101. package/dist/i18n/messages.en.js +209 -4
  102. package/dist/i18n/messages.zh.js +214 -4
  103. package/dist/index.d.ts +35 -8
  104. package/dist/index.js +20 -5
  105. package/dist/liveModelCatalog.d.ts +4 -2
  106. package/dist/liveModelCatalog.js +164 -26
  107. package/dist/localEngineJudge.d.ts +75 -0
  108. package/dist/localEngineJudge.js +242 -0
  109. package/dist/localEngineOccupancy.d.ts +88 -0
  110. package/dist/localEngineOccupancy.js +269 -0
  111. package/dist/localEngineSeatReading.d.ts +29 -0
  112. package/dist/localEngineSeatReading.js +294 -0
  113. package/dist/localEngineSpawn.d.ts +113 -0
  114. package/dist/localEngineSpawn.js +486 -0
  115. package/dist/localEngineStep.d.ts +286 -0
  116. package/dist/localEngineStep.js +1086 -0
  117. package/dist/localEngineStopLadder.d.ts +29 -0
  118. package/dist/localEngineStopLadder.js +139 -0
  119. package/dist/localEngineSwapCard.d.ts +43 -0
  120. package/dist/localEngineSwapCard.js +205 -0
  121. package/dist/localEngineTiming.d.ts +8 -0
  122. package/dist/localEngineTiming.js +8 -0
  123. package/dist/mcpReconnect.js +12 -5
  124. package/dist/mcpWireCaps.js +2 -2
  125. package/dist/memoryEntriesWire.d.ts +1 -1
  126. package/dist/memoryEntriesWire.js +5 -0
  127. package/dist/model/catalogDefault.d.ts +25 -0
  128. package/dist/model/catalogDefault.js +44 -0
  129. package/dist/noticePresentation.d.ts +2 -0
  130. package/dist/noticePresentation.js +79 -1
  131. package/dist/ownKey.d.ts +10 -0
  132. package/dist/ownKey.js +15 -1
  133. package/dist/permissionWireCaps.d.ts +1 -0
  134. package/dist/permissionWireCaps.js +11 -0
  135. package/dist/pluginHooksWire.d.ts +5 -3
  136. package/dist/pluginHooksWire.js +116 -7
  137. package/dist/queuedDelivery.d.ts +1 -0
  138. package/dist/queuedDelivery.js +12 -0
  139. package/dist/resultFrameKeys.js +4 -2
  140. package/dist/resumeRefusalCopy.js +15 -8
  141. package/dist/ruleReadings.js +1 -1
  142. package/dist/runPermissionModeSwitch.d.ts +2 -1
  143. package/dist/runPermissionModeSwitch.js +16 -6
  144. package/dist/seam.d.ts +13 -2
  145. package/dist/seam.js +8 -1
  146. package/dist/seatContract.d.ts +103 -12
  147. package/dist/seatContract.js +344 -14
  148. package/dist/sessionBackground.js +2 -0
  149. package/dist/sessionEngine.d.ts +2 -1
  150. package/dist/sessionEngine.js +5 -0
  151. package/dist/settingsHooksSalvage.d.ts +5 -0
  152. package/dist/settingsHooksSalvage.js +54 -0
  153. package/dist/subagentContentStore.d.ts +12 -0
  154. package/dist/subagentContentStore.js +73 -12
  155. package/dist/supportFloor.js +2 -0
  156. package/dist/taskNotificationAdmission.d.ts +19 -0
  157. package/dist/taskNotificationAdmission.js +84 -0
  158. package/dist/toolResult.js +20 -6
  159. package/dist/webSearchWireCaps.js +9 -4
  160. package/dist/wireFailureShape.d.ts +20 -0
  161. package/dist/wireFailureShape.js +37 -6
  162. package/dist/wireRefusalCopy.d.ts +23 -2
  163. package/dist/wireRefusalCopy.js +93 -4
  164. package/docs/INTEGRATION-CLIENTS.md +1959 -15
  165. package/package.json +4 -4
@@ -58,6 +58,7 @@ const REFUSAL_KEYS = {
58
58
  not_configured: 'config.engineTarget.notConfigured',
59
59
  not_signed_in: 'config.engineTarget.notSignedIn',
60
60
  probe_failed: 'config.engineTarget.probeFailed',
61
+ cloud_unreachable: 'config.engineTarget.cloudUnreachable',
61
62
  org_policy: 'config.engineTarget.orgPolicy',
62
63
  url_refused: 'config.engineTarget.urlRefused',
63
64
  login_failed: 'config.engineTarget.loginFailed',
@@ -5,7 +5,8 @@ import { resumeReopenContent } from './hitl/suspendedReopen.js';
5
5
  import { idempotencyPayloadMismatchContent } from './engineErrorCodes.js';
6
6
  import { inheritEnvRefusalContent } from './inheritEnvWire.js';
7
7
  import { projectSeedRefusalContent } from './projectSeed.js';
8
- import { usageWindowExhaustedContent, fleetLeaseUnavailableContent, settingsPermissionBucketRefusalContent, fieldLimitRefusalContent, autonomyLaneRefusalContent, sessionArchiveStampedContent, unsupportedRuleRefusalContent, admissionWallRefusalContent, hostPostureRefusalContent, toolDeclarationRefusalContent, } from './wireRefusalCopy.js';
8
+ import { usageWindowExhaustedContent, fleetLeaseUnavailableContent, settingsPermissionBucketRefusalContent, fieldLimitRefusalContent, autonomyLaneRefusalContent, sessionArchiveStampedContent, unsupportedRuleRefusalContent, admissionWallRefusalContent, hostPostureRefusalContent, toolDeclarationRefusalContent, envCredentialRefusalContent, sessionIdRetiredContent, runConcurrencyCapContent, } from './wireRefusalCopy.js';
9
+ import { catalogDefaultRefusalContent } from './model/catalogDefault.js';
9
10
  const ROLE_BY_READER = new Map([
10
11
  [corruptSessionContent, 'replacement'],
11
12
  [corruptStoredRowContent, 'replacement'],
@@ -23,6 +24,10 @@ const ROLE_BY_READER = new Map([
23
24
  [idempotencyPayloadMismatchContent, 'replacement'],
24
25
  [unsupportedRuleRefusalContent, 'replacement'],
25
26
  [projectSeedRefusalContent, 'replacement'],
27
+ [catalogDefaultRefusalContent, 'replacement'],
28
+ [envCredentialRefusalContent, 'replacement'],
29
+ [sessionIdRetiredContent, 'replacement'],
30
+ [runConcurrencyCapContent, 'replacement'],
26
31
  [admissionWallRefusalContent, 'supplement'],
27
32
  [hostPostureRefusalContent, 'supplement'],
28
33
  [toolDeclarationRefusalContent, 'supplement'],
package/dist/eventLeg.js CHANGED
@@ -21,7 +21,7 @@ function makeFrameStageDomains(domains) {
21
21
  }
22
22
  const FRAME_STAGE_DOMAINS = makeFrameStageDomains({
23
23
  bindRun: Object.freeze(['meta', 'done', 'failed']),
24
- stampOwner: Object.freeze(['task_progress']),
24
+ stampOwner: Object.freeze(['task_progress', 'task_started']),
25
25
  hitlFrames: Object.freeze(['question', 'question_complete', 'elicitation', 'elicitation_complete', 'tool_approval', 'tool_approval_complete', 'approval_request', 'approval_complete', 'approval_revoke']),
26
26
  });
27
27
  const HITL_FRAMES_PROJECTED = Object.freeze(['human_input']);
@@ -1,3 +1,4 @@
1
+ import { SETTINGS_NO_EXECUTION_TARGET_LANES } from './generated/settingsSchemaTables.js';
1
2
  export function executionLaneWordIsNone(provider) {
2
- return provider === 'none' || provider === 'in-process';
3
+ return SETTINGS_NO_EXECUTION_TARGET_LANES.some((w) => w === provider) || provider === 'in-process';
3
4
  }
@@ -1,12 +1,12 @@
1
- import { applyDisplayFace, ESCAPE_FACE, LABEL_FACE, paintAndCap } from './displayUntrusted.js';
1
+ import { applyDisplayFace, displayUntrusted, ESCAPE_FACE } from './displayUntrusted.js';
2
2
  export function escapeDisplayControlChars(s) {
3
3
  return applyDisplayFace(s, ESCAPE_FACE);
4
4
  }
5
5
  export function capForDisplay(raw, max) {
6
- return paintAndCap(raw, ESCAPE_FACE, typeof max === 'number' && max > 0 ? max : 0);
6
+ return displayUntrusted(raw, { foldLines: false, escapeBackslashes: 'auto', max: typeof max === 'number' && max > 0 ? max : 0 });
7
7
  }
8
8
  export function collapseLabel(s) {
9
- return applyDisplayFace(s, LABEL_FACE);
9
+ return displayUntrusted(s, { escapeBackslashes: 'auto' });
10
10
  }
11
11
  export function taskDescFromName(name, agentType, agentName) {
12
12
  if (!name || !agentType)
@@ -1,6 +1,6 @@
1
1
  import type { DeniedBy, Settlement } from '@sema-agent/sdk';
2
2
  import { type CcToolDenialKind } from './gateVocabulary.js';
3
- import { CORE_MODE_RELEASE_REASONS } from './generated/engineFactTables.js';
3
+ import { CORE_MODE_RELEASE_REASONS, CORE_REFUSAL_ECHO_KINDS } from './generated/engineFactTables.js';
4
4
  export type GateDispositionView = {
5
5
  kind: 'allowed';
6
6
  classifier?: GateClassifierRoundView;
@@ -14,7 +14,16 @@ export type GateDispositionView = {
14
14
  deniedBy: DeniedBy | (string & {});
15
15
  cause?: string;
16
16
  extension?: string;
17
+ echoed?: readonly GateRefusalEchoView[];
17
18
  };
19
+ export interface GateRefusalEchoView {
20
+ readonly kind: string;
21
+ readonly value: string;
22
+ readonly canonical?: string;
23
+ }
24
+ export declare const GATE_REFUSAL_ECHO_KIND_WORDS: readonly ["path", "command", "pattern"];
25
+ export type GateRefusalEchoKindWord = (typeof CORE_REFUSAL_ECHO_KINDS)[number];
26
+ export declare function isGateRefusalEchoKindWord(v: string): v is GateRefusalEchoKindWord;
18
27
  export interface GateClassifierRoundView {
19
28
  modelRequested: string;
20
29
  modelUsed: string;
@@ -1,10 +1,14 @@
1
1
  import { ccToolDenialKindForSettledBy, isCcToolDenialKind, isGateDeniedByWord } from './gateVocabulary.js';
2
2
  import { GATE_PARKED_ERROR_CODE } from './engineErrorCodes.js';
3
- import { CORE_MODE_RELEASE_REASONS, CORE_SETTLEMENT_KINDS } from './generated/engineFactTables.js';
3
+ import { CORE_MODE_RELEASE_REASONS, CORE_REFUSAL_ECHO_KINDS, CORE_SETTLEMENT_KINDS } from './generated/engineFactTables.js';
4
4
  import { readAskOrigin, readOwnDataNonEmptyString, readOwnDataValue } from './ownKey.js';
5
5
  function str(v) {
6
6
  return typeof v === 'string' && v.length > 0 ? v : undefined;
7
7
  }
8
+ export const GATE_REFUSAL_ECHO_KIND_WORDS = CORE_REFUSAL_ECHO_KINDS;
9
+ export function isGateRefusalEchoKindWord(v) {
10
+ return typeof v === 'string' && CORE_REFUSAL_ECHO_KINDS.includes(v);
11
+ }
8
12
  export const GATE_MODE_RELEASE_REASON_WORDS = CORE_MODE_RELEASE_REASONS;
9
13
  export function isGateModeReleaseReasonWord(v) {
10
14
  return typeof v === 'string' && CORE_MODE_RELEASE_REASONS.includes(v);
@@ -112,6 +116,46 @@ function nonEmptyStringList(v) {
112
116
  }
113
117
  return Object.freeze(out);
114
118
  }
119
+ function ownDataOf(o, key) {
120
+ try {
121
+ const d = Object.getOwnPropertyDescriptor(o, key);
122
+ return d === undefined || !Object.hasOwn(d, 'value') ? { ok: false } : { ok: true, value: d.value };
123
+ }
124
+ catch {
125
+ return { ok: false };
126
+ }
127
+ }
128
+ function readRefusalEchoes(raw) {
129
+ try {
130
+ if (!Array.isArray(raw))
131
+ return undefined;
132
+ const len = ownDataOf(raw, 'length');
133
+ if (!len.ok || typeof len.value !== 'number' || !Number.isInteger(len.value) || len.value <= 0)
134
+ return undefined;
135
+ const out = [];
136
+ for (let i = 0; i < len.value; i += 1) {
137
+ const slot = ownDataOf(raw, String(i));
138
+ if (!slot.ok)
139
+ return undefined;
140
+ const e = slot.value;
141
+ if (typeof e !== 'object' || e === null || Array.isArray(e))
142
+ return undefined;
143
+ const kind = ownDataOf(e, 'kind');
144
+ const value = ownDataOf(e, 'value');
145
+ if (!kind.ok || typeof kind.value !== 'string' || kind.value.length === 0)
146
+ return undefined;
147
+ if (!value.ok || typeof value.value !== 'string' || value.value.length === 0)
148
+ return undefined;
149
+ const canonical = ownDataOf(e, 'canonical');
150
+ const canon = canonical.ok && typeof canonical.value === 'string' && canonical.value.length > 0 ? canonical.value : undefined;
151
+ out.push(Object.freeze({ kind: kind.value, value: value.value, ...(canon !== undefined ? { canonical: canon } : {}) }));
152
+ }
153
+ return Object.freeze(out);
154
+ }
155
+ catch {
156
+ return undefined;
157
+ }
158
+ }
115
159
  function readModeRelease(raw) {
116
160
  if (typeof raw !== 'object' || raw === null || Array.isArray(raw))
117
161
  return undefined;
@@ -198,6 +242,8 @@ function readGateRecord(frame) {
198
242
  const askClass = str(dr.askClass);
199
243
  const classes = nonEmptyStringList(dr.classes);
200
244
  const extension = str(dr.extension);
245
+ const echoedSeat = ownDataOf(dr, 'echoed');
246
+ const echoed = echoedSeat.ok ? readRefusalEchoes(echoedSeat.value) : undefined;
201
247
  disposition = {
202
248
  kind: 'denied',
203
249
  deniedBy,
@@ -207,6 +253,7 @@ function readGateRecord(frame) {
207
253
  ...(askClass !== undefined ? { askClass } : {}),
208
254
  ...(classes !== undefined ? { classes } : {}),
209
255
  ...(extension !== undefined ? { extension } : {}),
256
+ ...(echoed !== undefined ? { echoed } : {}),
210
257
  };
211
258
  }
212
259
  else {
@@ -73,3 +73,5 @@ export declare const CORE_USER_ATTACHMENTS_MAX: number;
73
73
  export declare const CORE_USER_ATTACHMENT_LABEL_MAX: number;
74
74
  export declare const CORE_PRESENT_PLAN_TOOL_NAME: "ExitPlanMode";
75
75
  export declare const CORE_WORKFLOW_AGENT_PARKED_ERROR_CODE: "workflow.agent_parked";
76
+ export declare const CORE_REFUSAL_ECHO_KINDS: readonly ["path", "command", "pattern"];
77
+ export declare const CORE_DISCARDED_DELIVERY_PATHS: readonly ["live", "box", "drain", "notice"];
@@ -466,3 +466,14 @@ export const CORE_USER_ATTACHMENTS_MAX = 20;
466
466
  export const CORE_USER_ATTACHMENT_LABEL_MAX = 4096;
467
467
  export const CORE_PRESENT_PLAN_TOOL_NAME = "ExitPlanMode";
468
468
  export const CORE_WORKFLOW_AGENT_PARKED_ERROR_CODE = "workflow.agent_parked";
469
+ export const CORE_REFUSAL_ECHO_KINDS = Object.freeze([
470
+ "path",
471
+ "command",
472
+ "pattern",
473
+ ]);
474
+ export const CORE_DISCARDED_DELIVERY_PATHS = Object.freeze([
475
+ "live",
476
+ "box",
477
+ "drain",
478
+ "notice",
479
+ ]);
@@ -37,6 +37,7 @@ export const CORE_ENGINE_NOTICE_CODES = Object.freeze([
37
37
  "permission.rule_store_unavailable",
38
38
  "permission.rule_row_dropped",
39
39
  "config.session_rules_earlier_grammar",
40
+ "config.legacy_tool_name",
40
41
  "permission.allowed_tool_not_granted",
41
42
  "mods.registration_refused",
42
43
  "peer.inbound_disposition",
@@ -52,6 +53,7 @@ export const CORE_ENGINE_NOTICE_CODES = Object.freeze([
52
53
  "delegation.transcript_integrity",
53
54
  "delegation.ask_unresolvable",
54
55
  "delegation.resume_lane_missing",
56
+ "delegation.delivery_discarded",
55
57
  "mcp.injection_dropped",
56
58
  "mcp.revocation_probe_failed",
57
59
  "mcp.server_redialed",
@@ -156,6 +158,7 @@ export const CORE_NOTICE_AUDIENCE = Object.freeze({
156
158
  "permission.rule_store_unavailable": "user",
157
159
  "permission.rule_row_dropped": "user",
158
160
  "config.session_rules_earlier_grammar": "user",
161
+ "config.legacy_tool_name": "user",
159
162
  "permission.allowed_tool_not_granted": "user",
160
163
  "mods.registration_refused": "user",
161
164
  "peer.inbound_disposition": "user",
@@ -171,6 +174,7 @@ export const CORE_NOTICE_AUDIENCE = Object.freeze({
171
174
  "delegation.transcript_integrity": "operator",
172
175
  "delegation.ask_unresolvable": "user",
173
176
  "delegation.resume_lane_missing": "operator",
177
+ "delegation.delivery_discarded": "operator",
174
178
  "mcp.injection_dropped": "user",
175
179
  "mcp.revocation_probe_failed": "operator",
176
180
  "mcp.server_redialed": "operator",
@@ -281,6 +285,7 @@ export const CORE_NOTICE_MINTER = Object.freeze({
281
285
  "permission.rule_store_unavailable": "engine",
282
286
  "permission.rule_row_dropped": "engine",
283
287
  "config.session_rules_earlier_grammar": "engine",
288
+ "config.legacy_tool_name": "engine",
284
289
  "permission.allowed_tool_not_granted": "engine",
285
290
  "mods.registration_refused": "engine",
286
291
  "peer.inbound_disposition": "engine",
@@ -296,6 +301,7 @@ export const CORE_NOTICE_MINTER = Object.freeze({
296
301
  "delegation.transcript_integrity": "engine",
297
302
  "delegation.ask_unresolvable": "engine",
298
303
  "delegation.resume_lane_missing": "engine",
304
+ "delegation.delivery_discarded": "engine",
299
305
  "mcp.injection_dropped": "engine",
300
306
  "mcp.revocation_probe_failed": "engine",
301
307
  "mcp.server_redialed": "engine",
@@ -34,18 +34,20 @@ export declare const SETTINGS_READ_KEY: (record: object, key: PropertyKey) => ob
34
34
  export declare const SETTINGS_IS_RESERVED_MCP_SERVER_NAME: (name: string) => boolean;
35
35
  export declare const SETTINGS_REMOTE_MCP_SERVER_NAME_PREFIX: "remote-";
36
36
  export declare const SETTINGS_RESERVED_MCP_SERVER_NAME_REASON: "the \"remote-\" prefix is reserved for the remote MCP servers a device executor offers";
37
+ export declare const SETTINGS_IS_USABLE_WIRE_NAME: (v: unknown) => v is string;
38
+ export declare const SETTINGS_TOOL_WIRE_NAME_MAX_CHARS: 128;
39
+ export declare const SETTINGS_HAS_EDGE_WHITESPACE: (v: string) => boolean;
40
+ export declare const SETTINGS_IS_RESERVED_MEMBER_NAME: (name: string) => boolean;
37
41
  export declare const SETTINGS_READ_REQUEST_MCP_TRANSPORT: (t: unknown) => RequestMcpTransportRead;
38
42
  export declare const SETTINGS_READ_MCP_IDENTITY_HEADERS: (transport: Record<string, unknown>) => {
39
43
  principalHeader?: string;
40
44
  assertionHeader?: string;
41
45
  };
42
- export declare const SETTINGS_IS_USABLE_WIRE_NAME: (v: unknown) => v is string;
43
46
  export declare const SETTINGS_DESCRIBE_BAD_WIRE_NAME: (v: unknown) => string;
44
47
  export declare const SETTINGS_IS_USABLE_MCP_SERVER_NAME: (v: unknown) => v is string;
45
48
  export declare const SETTINGS_DESCRIBE_BAD_MCP_SERVER_NAME: (v: unknown) => string;
46
49
  export declare const SETTINGS_IS_CONTENT_ORIGIN_WORD: (v: unknown) => v is McpContentOrigin;
47
50
  export declare const SETTINGS_DESCRIBE_BAD_CONTENT_ORIGIN: (v: unknown) => string;
48
- export declare const SETTINGS_TOOL_WIRE_NAME_MAX_CHARS: 128;
49
51
  export declare const SETTINGS_URL_ALLOW_PATTERN_MATCHES: (url: string, pattern: string) => boolean;
50
52
  export declare const SETTINGS_IS_AT_LEAST: (layer: string, minTrust: string) => boolean;
51
53
  export declare const SETTINGS_MEMBER_ADMISSION: (category: string, member: string) => object;
@@ -4,6 +4,8 @@ import { SETTINGS_CALLER_TEXT_ECHO_CLOSURE } from './settingsSchemaCallerTextEch
4
4
  import { SETTINGS_PLAIN_JSON_OBJECT_CLOSURE } from './settingsSchemaPlainJsonObject.js';
5
5
  import { SETTINGS_OWN_KEY_READ_CLOSURE } from './settingsSchemaOwnKeyRead.js';
6
6
  import { SETTINGS_MCP_SERVER_NAME_CLOSURE } from './settingsSchemaMcpServerName.js';
7
+ import { SETTINGS_WIRE_NAME_CLOSURE } from './settingsSchemaWireName.js';
8
+ import { SETTINGS_RESERVED_MEMBER_NAME_CLOSURE } from './settingsSchemaReservedMemberName.js';
7
9
  import { SETTINGS_MCP_REQUEST_ENTRY_CLOSURE } from './settingsSchemaMcpRequestEntry.js';
8
10
  import { SETTINGS_MCP_CONTENT_ORIGINS } from './settingsSchemaTables.js';
9
11
  import { SETTINGS_URL_ALLOW_PATTERN_MATCHES_CLOSURE } from './settingsSchemaUrlPattern.js';
@@ -167,16 +169,20 @@ const SETTINGS_MCP_SERVER_NAME = SETTINGS_MCP_SERVER_NAME_CLOSURE();
167
169
  export const SETTINGS_IS_RESERVED_MCP_SERVER_NAME = SETTINGS_MCP_SERVER_NAME.isReservedMcpServerName;
168
170
  export const SETTINGS_REMOTE_MCP_SERVER_NAME_PREFIX = SETTINGS_MCP_SERVER_NAME.REMOTE_MCP_SERVER_NAME_PREFIX;
169
171
  export const SETTINGS_RESERVED_MCP_SERVER_NAME_REASON = SETTINGS_MCP_SERVER_NAME.RESERVED_MCP_SERVER_NAME_REASON;
170
- const SETTINGS_MCP_REQUEST_ENTRY = SETTINGS_MCP_REQUEST_ENTRY_CLOSURE(SETTINGS_MCP_CONTENT_ORIGINS, SETTINGS_STARTS_WITH_HTTP_SCHEME, SETTINGS_ECHO_CALLER_TEXT, SETTINGS_UNINSPECTABLE, SETTINGS_CAPTURE_STRING_ARRAY, SETTINGS_DATA_DESCRIPTOR, SETTINGS_INSPECT, SETTINGS_OWN_FIELDS_OF, SETTINGS_OWN_VALUE_OF, SETTINGS_READ_KEY, SETTINGS_IS_JSON_ARRAY, SETTINGS_JSON_SHAPE_OF, SETTINGS_IS_RESERVED_MCP_SERVER_NAME, SETTINGS_RESERVED_MCP_SERVER_NAME_REASON);
172
+ const SETTINGS_WIRE_NAME = SETTINGS_WIRE_NAME_CLOSURE();
173
+ export const SETTINGS_IS_USABLE_WIRE_NAME = SETTINGS_WIRE_NAME.isUsableWireName;
174
+ export const SETTINGS_TOOL_WIRE_NAME_MAX_CHARS = SETTINGS_WIRE_NAME.TOOL_WIRE_NAME_MAX_CHARS;
175
+ export const SETTINGS_HAS_EDGE_WHITESPACE = SETTINGS_WIRE_NAME.hasEdgeWhitespace;
176
+ const SETTINGS_RESERVED_MEMBER_NAME = SETTINGS_RESERVED_MEMBER_NAME_CLOSURE();
177
+ export const SETTINGS_IS_RESERVED_MEMBER_NAME = SETTINGS_RESERVED_MEMBER_NAME.isReservedMemberName;
178
+ const SETTINGS_MCP_REQUEST_ENTRY = SETTINGS_MCP_REQUEST_ENTRY_CLOSURE(SETTINGS_MCP_CONTENT_ORIGINS, SETTINGS_STARTS_WITH_HTTP_SCHEME, SETTINGS_ECHO_CALLER_TEXT, SETTINGS_UNINSPECTABLE, SETTINGS_CAPTURE_STRING_ARRAY, SETTINGS_DATA_DESCRIPTOR, SETTINGS_INSPECT, SETTINGS_OWN_FIELDS_OF, SETTINGS_OWN_VALUE_OF, SETTINGS_READ_KEY, SETTINGS_IS_JSON_ARRAY, SETTINGS_JSON_SHAPE_OF, SETTINGS_IS_RESERVED_MCP_SERVER_NAME, SETTINGS_RESERVED_MCP_SERVER_NAME_REASON, SETTINGS_TOOL_WIRE_NAME_MAX_CHARS, SETTINGS_HAS_EDGE_WHITESPACE, SETTINGS_IS_USABLE_WIRE_NAME, SETTINGS_IS_RESERVED_MEMBER_NAME);
171
179
  export const SETTINGS_READ_REQUEST_MCP_TRANSPORT = SETTINGS_MCP_REQUEST_ENTRY.readRequestMcpTransport;
172
180
  export const SETTINGS_READ_MCP_IDENTITY_HEADERS = SETTINGS_MCP_REQUEST_ENTRY.readMcpIdentityHeaders;
173
- export const SETTINGS_IS_USABLE_WIRE_NAME = SETTINGS_MCP_REQUEST_ENTRY.isUsableWireName;
174
181
  export const SETTINGS_DESCRIBE_BAD_WIRE_NAME = SETTINGS_MCP_REQUEST_ENTRY.describeBadWireName;
175
182
  export const SETTINGS_IS_USABLE_MCP_SERVER_NAME = SETTINGS_MCP_REQUEST_ENTRY.isUsableMcpServerName;
176
183
  export const SETTINGS_DESCRIBE_BAD_MCP_SERVER_NAME = SETTINGS_MCP_REQUEST_ENTRY.describeBadMcpServerName;
177
184
  export const SETTINGS_IS_CONTENT_ORIGIN_WORD = SETTINGS_MCP_REQUEST_ENTRY.isContentOriginWord;
178
185
  export const SETTINGS_DESCRIBE_BAD_CONTENT_ORIGIN = SETTINGS_MCP_REQUEST_ENTRY.describeBadContentOrigin;
179
- export const SETTINGS_TOOL_WIRE_NAME_MAX_CHARS = SETTINGS_MCP_REQUEST_ENTRY.TOOL_WIRE_NAME_MAX_CHARS;
180
186
  export const SETTINGS_URL_ALLOW_PATTERN_MATCHES = SETTINGS_URL_ALLOW_PATTERN_MATCHES_CLOSURE();
181
187
  const SETTINGS_SAFETY_MERGE = SETTINGS_SAFETY_MERGE_CLOSURE(SETTINGS_MIN_TRUST_WORDS);
182
188
  export const SETTINGS_IS_AT_LEAST = SETTINGS_SAFETY_MERGE.isAtLeast;
@@ -1 +1 @@
1
- export declare const SETTINGS_MCP_REQUEST_ENTRY_CLOSURE: (MCP_CONTENT_ORIGINS: readonly ["local", "execution", "external"], startsWithHttpScheme: (raw: string) => boolean, echoCallerText: (text: string) => string, UNINSPECTABLE: "an object that could not be inspected (a proxy trap threw)", captureStringArray: (v: unknown, classification: "strict" | "wide") => string[] | undefined, dataDescriptor: (value: unknown) => PropertyDescriptor, inspect: (read: () => unknown) => object, ownFieldsOf: (record: object, keys: readonly string[]) => object, ownValueOf: (record: object, key: string) => object, readKey: (record: object, key: PropertyKey) => object, isJsonArray: (v: unknown) => v is unknown[], jsonShapeOf: (v: unknown) => "plain" | "non_plain_object" | "array" | "null" | "primitive" | "uninspectable", isReservedMcpServerName: (name: string) => boolean, RESERVED_MCP_SERVER_NAME_REASON: "the \"remote-\" prefix is reserved for the remote MCP servers a device executor offers") => any;
1
+ export declare const SETTINGS_MCP_REQUEST_ENTRY_CLOSURE: (MCP_CONTENT_ORIGINS: readonly ["local", "execution", "external"], startsWithHttpScheme: (raw: string) => boolean, echoCallerText: (text: string) => string, UNINSPECTABLE: "an object that could not be inspected (a proxy trap threw)", captureStringArray: (v: unknown, classification: "strict" | "wide") => string[] | undefined, dataDescriptor: (value: unknown) => PropertyDescriptor, inspect: (read: () => unknown) => object, ownFieldsOf: (record: object, keys: readonly string[]) => object, ownValueOf: (record: object, key: string) => object, readKey: (record: object, key: PropertyKey) => object, isJsonArray: (v: unknown) => v is unknown[], jsonShapeOf: (v: unknown) => "plain" | "non_plain_object" | "array" | "null" | "primitive" | "uninspectable", isReservedMcpServerName: (name: string) => boolean, RESERVED_MCP_SERVER_NAME_REASON: "the \"remote-\" prefix is reserved for the remote MCP servers a device executor offers", TOOL_WIRE_NAME_MAX_CHARS: 128, hasEdgeWhitespace: (v: string) => boolean, isUsableWireName: (v: unknown) => v is string, isReservedMemberName: (name: string) => boolean) => any;
@@ -1,4 +1,4 @@
1
- export const SETTINGS_MCP_REQUEST_ENTRY_CLOSURE = (MCP_CONTENT_ORIGINS, startsWithHttpScheme, echoCallerText, UNINSPECTABLE, captureStringArray, dataDescriptor, inspect, ownFieldsOf, ownValueOf, readKey, isJsonArray, jsonShapeOf, isReservedMcpServerName, RESERVED_MCP_SERVER_NAME_REASON) => {
1
+ export const SETTINGS_MCP_REQUEST_ENTRY_CLOSURE = (MCP_CONTENT_ORIGINS, startsWithHttpScheme, echoCallerText, UNINSPECTABLE, captureStringArray, dataDescriptor, inspect, ownFieldsOf, ownValueOf, readKey, isJsonArray, jsonShapeOf, isReservedMcpServerName, RESERVED_MCP_SERVER_NAME_REASON, TOOL_WIRE_NAME_MAX_CHARS, hasEdgeWhitespace, isUsableWireName, isReservedMemberName) => {
2
2
  function describeKindWord(v) {
3
3
  const shape = jsonShapeOf(v);
4
4
  switch (shape) {
@@ -46,11 +46,6 @@ export const SETTINGS_MCP_REQUEST_ENTRY_CLOSURE = (MCP_CONTENT_ORIGINS, startsWi
46
46
  function quotedCallerText(text) {
47
47
  return `"${echoCallerText(text)}"`;
48
48
  }
49
- const TOOL_WIRE_NAME_MAX_CHARS = 128;
50
- const hasEdgeWhitespace = (v) => v.trim() !== v;
51
- function isUsableWireName(v) {
52
- return typeof v === "string" && v.length > 0 && v.length <= TOOL_WIRE_NAME_MAX_CHARS && !hasEdgeWhitespace(v);
53
- }
54
49
  function describeBadWireName(v) {
55
50
  if (typeof v !== "string")
56
51
  return describeKindWord(v);
@@ -202,8 +197,7 @@ export const SETTINGS_MCP_REQUEST_ENTRY_CLOSURE = (MCP_CONTENT_ORIGINS, startsWi
202
197
  }
203
198
  return { ok: true, value: { kind: "other", value: kind.value } };
204
199
  }
205
- const PLAIN_STRING_RECORD_RESERVED_MEMBER = "__proto__";
206
- const RESERVED_MEMBER_FAULT = `no member of a declaration may be named "${PLAIN_STRING_RECORD_RESERVED_MEMBER}"`;
200
+ const reservedMemberFault = (name) => `no member of a declaration may be named "${name}"`;
207
201
  function notPlainDetail(shape, v) {
208
202
  switch (shape) {
209
203
  case "null":
@@ -233,28 +227,25 @@ export const SETTINGS_MCP_REQUEST_ENTRY_CLOSURE = (MCP_CONTENT_ORIGINS, startsWi
233
227
  return { ok: false, fault: "not_plain_record", detail: `got ${namesRead.sentence}` };
234
228
  const names = namesRead.value;
235
229
  const members = Object.create(null);
236
- let reservedMember = false;
230
+ const reservedMembers = names.filter(isReservedMemberName);
237
231
  for (const name of names) {
238
232
  const read = readKey(v, name);
239
233
  const unreadable = read.presence === "unreadable";
240
234
  const value = read.presence === "own" ? read.value : undefined;
241
235
  if (unreadable || typeof value !== "string") {
242
236
  const valueFault = unreadable ? "could not be read (its getter threw)" : `must be a string — got ${describeValueShape(value)}`;
243
- const reserved = name === PLAIN_STRING_RECORD_RESERVED_MEMBER;
244
- const fault = reserved ? "member_name_reserved" : "member_not_string";
237
+ const fault = isReservedMemberName(name) ? "member_name_reserved" : "member_not_string";
245
238
  return {
246
239
  ok: false,
247
240
  fault,
248
241
  member: echoCallerText(name),
249
- detail: `its member "${echoCallerText(name)}" ${reserved ? `is not allowed (${RESERVED_MEMBER_FAULT}) and its value ${valueFault}` : valueFault}`,
242
+ detail: `its member "${echoCallerText(name)}" ${isReservedMemberName(name) ? `is not allowed (${reservedMemberFault(name)}) and its value ${valueFault}` : valueFault}`,
250
243
  };
251
244
  }
252
- if (name === PLAIN_STRING_RECORD_RESERVED_MEMBER)
253
- reservedMember = true;
254
- else
245
+ if (!isReservedMemberName(name))
255
246
  Object.defineProperty(members, name, dataDescriptor(value));
256
247
  }
257
- return { ok: true, record: { ...members }, reservedMember };
248
+ return { ok: true, record: { ...members }, reservedMembers };
258
249
  }
259
250
  const issuesOf = (...candidates) => candidates.filter((c) => c !== undefined);
260
251
  function readTransportRecord(path, raw) {
@@ -269,8 +260,8 @@ export const SETTINGS_MCP_REQUEST_ENTRY_CLOSURE = (MCP_CONTENT_ORIGINS, startsWi
269
260
  }
270
261
  return {
271
262
  record: read.record,
272
- issues: read.reservedMember ? [{ path: `${path}.${PLAIN_STRING_RECORD_RESERVED_MEMBER}`, reason: RESERVED_MEMBER_FAULT, member: PLAIN_STRING_RECORD_RESERVED_MEMBER, fault: "member_name_reserved" }] : [],
263
+ issues: read.reservedMembers.map((name) => ({ path: `${path}.${name}`, reason: reservedMemberFault(name), member: name, fault: "member_name_reserved" })),
273
264
  };
274
265
  }
275
- return { readRequestMcpTransport, readMcpIdentityHeaders, isUsableWireName, describeBadWireName, isUsableMcpServerName, describeBadMcpServerName, isContentOriginWord, describeBadContentOrigin, TOOL_WIRE_NAME_MAX_CHARS };
266
+ return { readRequestMcpTransport, readMcpIdentityHeaders, describeBadWireName, isUsableMcpServerName, describeBadMcpServerName, isContentOriginWord, describeBadContentOrigin };
276
267
  };
@@ -0,0 +1 @@
1
+ export declare const SETTINGS_RESERVED_MEMBER_NAME_CLOSURE: () => any;
@@ -0,0 +1,7 @@
1
+ export const SETTINGS_RESERVED_MEMBER_NAME_CLOSURE = () => {
2
+ const RESERVED_MEMBER_NAMES = ["__proto__", "constructor", "prototype"];
3
+ function isReservedMemberName(name) {
4
+ return RESERVED_MEMBER_NAMES.includes(name);
5
+ }
6
+ return { isReservedMemberName };
7
+ };
@@ -13,3 +13,5 @@ export declare const SETTINGS_UI_LANGUAGE_VALUES: readonly ["en", "zh"];
13
13
  export declare const SETTINGS_MCP_CONTENT_ORIGINS: readonly ["local", "execution", "external"];
14
14
  export declare const SETTINGS_MIN_TRUST_WORDS: readonly ["local", "session", "project", "global", "managed", "task"];
15
15
  export declare const SETTINGS_WORKSPACE_TRUST_STATES: readonly ["accepted", "declined", "no_trust_step"];
16
+ export declare const SETTINGS_MODEL_PLANE_REFUSAL_CODES: readonly ["config.default_model_missing", "config.model_refused_name_minted", "config.model_route_endpoint_missing", "config.gateway_fallback_without_primary", "config.catalog_replaces_env_models"];
17
+ export declare const SETTINGS_NO_EXECUTION_TARGET_LANES: readonly ["none"];
@@ -63,3 +63,13 @@ export const SETTINGS_WORKSPACE_TRUST_STATES = Object.freeze([
63
63
  "declined",
64
64
  "no_trust_step",
65
65
  ]);
66
+ export const SETTINGS_MODEL_PLANE_REFUSAL_CODES = Object.freeze([
67
+ "config.default_model_missing",
68
+ "config.model_refused_name_minted",
69
+ "config.model_route_endpoint_missing",
70
+ "config.gateway_fallback_without_primary",
71
+ "config.catalog_replaces_env_models",
72
+ ]);
73
+ export const SETTINGS_NO_EXECUTION_TARGET_LANES = Object.freeze([
74
+ "none",
75
+ ]);
@@ -0,0 +1 @@
1
+ export declare const SETTINGS_WIRE_NAME_CLOSURE: () => any;
@@ -0,0 +1,8 @@
1
+ export const SETTINGS_WIRE_NAME_CLOSURE = () => {
2
+ const TOOL_WIRE_NAME_MAX_CHARS = 128;
3
+ const hasEdgeWhitespace = (v) => v.trim() !== v;
4
+ function isUsableWireName(v) {
5
+ return typeof v === "string" && v.length > 0 && v.length <= TOOL_WIRE_NAME_MAX_CHARS && !hasEdgeWhitespace(v);
6
+ }
7
+ return { isUsableWireName, TOOL_WIRE_NAME_MAX_CHARS, hasEdgeWhitespace };
8
+ };
@@ -53,7 +53,7 @@ export async function* withHeadlessR1Reconnect(live, deps) {
53
53
  let attempts = 0;
54
54
  let lastSeenSeq;
55
55
  const probe = deps.probeAlive ?? probeEngineAlive;
56
- let isRecoverableTear;
56
+ let tearShape;
57
57
  const drains = createStreamDrainingLegs();
58
58
  let drainReopenAfterMs;
59
59
  let lastBreak;
@@ -62,6 +62,11 @@ export async function* withHeadlessR1Reconnect(live, deps) {
62
62
  registerRunNotFollowed(originalTearErr, fact);
63
63
  throw originalTearErr;
64
64
  };
65
+ const unboundHandle = (cause) => {
66
+ if (tearShape === 'transport')
67
+ throw originalTearErr;
68
+ return giveUp(mintRunNotFollowed(cause));
69
+ };
65
70
  const terminalFromRunRow = async (taskId) => {
66
71
  const row = await deps.getRun(taskId).catch(() => null);
67
72
  const terminal = terminalEventFromRunRow(row);
@@ -72,21 +77,21 @@ export async function* withHeadlessR1Reconnect(live, deps) {
72
77
  for (;;) {
73
78
  if (deps.signal?.aborted)
74
79
  throw originalTearErr;
75
- if (isRecoverableTear === undefined)
76
- isRecoverableTear = isSseIdleError(originalTearErr);
77
- if (!isRecoverableTear)
80
+ if (tearShape === undefined)
81
+ tearShape = isSseIdleError(originalTearErr) ? 'idle' : guardedTransport(originalTearErr) ? 'transport' : 'other';
82
+ if (tearShape === 'other')
78
83
  throw originalTearErr;
79
84
  let handle;
80
85
  try {
81
86
  handle = deps.getTaskId();
82
87
  }
83
88
  catch {
84
- return giveUp(mintRunNotFollowed('bad_input'));
89
+ return unboundHandle('bad_input');
85
90
  }
86
91
  if (handle === null || handle === undefined)
87
- return giveUp(mintRunNotFollowed('no_run_id'));
92
+ return unboundHandle('no_run_id');
88
93
  if (typeof handle !== 'string' || handle === '')
89
- return giveUp(mintRunNotFollowed('bad_input'));
94
+ return unboundHandle('bad_input');
90
95
  const taskId = handle;
91
96
  if (drainReopenAfterMs !== undefined) {
92
97
  const waitMs = drainReopenAfterMs;
@@ -0,0 +1,13 @@
1
+ export interface ApprovalAskReasonByHook {
2
+ readonly by: 'hook';
3
+ readonly cause: string;
4
+ readonly registration?: string;
5
+ readonly words?: string;
6
+ }
7
+ export interface ApprovalAskReasonByPolicy {
8
+ readonly by: string;
9
+ readonly words: string;
10
+ }
11
+ export type ApprovalAskReason = ApprovalAskReasonByHook | ApprovalAskReasonByPolicy;
12
+ export declare function approvalAskReasonsOf(carrier: object | null | undefined): readonly ApprovalAskReason[] | undefined;
13
+ export declare function approvalAgentIdOf(carrier: object | null | undefined): string | undefined;
@@ -0,0 +1,79 @@
1
+ import { appendOwnElement } from '../ownKey.js';
2
+ import { slotReadOf } from '../wireFailureShape.js';
3
+ function ownNonEmptyText(o, key) {
4
+ const r = slotReadOf(o, key);
5
+ return r.presence === 'present' && typeof r.value === 'string' && r.value !== '' ? r.value : undefined;
6
+ }
7
+ function optionalText(o, key) {
8
+ const r = slotReadOf(o, key);
9
+ if (r.presence === 'absent')
10
+ return { state: 'absent' };
11
+ if (r.presence === 'present' && typeof r.value === 'string')
12
+ return { state: 'text', value: r.value };
13
+ return { state: 'bad' };
14
+ }
15
+ function askReasonOf(item) {
16
+ if (typeof item !== 'object' || item === null)
17
+ return undefined;
18
+ const by = ownNonEmptyText(item, 'by');
19
+ if (by === undefined)
20
+ return undefined;
21
+ const words = optionalText(item, 'words');
22
+ if (words.state === 'bad')
23
+ return undefined;
24
+ if (by === 'hook') {
25
+ const cause = ownNonEmptyText(item, 'cause');
26
+ if (cause === undefined)
27
+ return undefined;
28
+ const registration = optionalText(item, 'registration');
29
+ if (registration.state === 'bad')
30
+ return undefined;
31
+ return Object.freeze({
32
+ by: 'hook',
33
+ cause,
34
+ ...(registration.state === 'text' ? { registration: registration.value } : {}),
35
+ ...(words.state === 'text' ? { words: words.value } : {}),
36
+ });
37
+ }
38
+ if (words.state !== 'text')
39
+ return undefined;
40
+ return Object.freeze({ by, words: words.value });
41
+ }
42
+ export function approvalAskReasonsOf(carrier) {
43
+ try {
44
+ if (typeof carrier !== 'object' || carrier === null)
45
+ return undefined;
46
+ const slot = slotReadOf(carrier, 'askReasons');
47
+ if (slot.presence !== 'present')
48
+ return undefined;
49
+ const raw = slot.value;
50
+ if (typeof raw !== 'object' || raw === null || !Array.isArray(raw))
51
+ return undefined;
52
+ const len = slotReadOf(raw, 'length');
53
+ if (len.presence !== 'present' || typeof len.value !== 'number' || !Number.isSafeInteger(len.value) || len.value < 0)
54
+ return undefined;
55
+ const out = [];
56
+ for (let i = 0; i < len.value; i++) {
57
+ const el = slotReadOf(raw, String(i));
58
+ if (el.presence !== 'present')
59
+ return undefined;
60
+ const reason = askReasonOf(el.value);
61
+ if (reason !== undefined)
62
+ appendOwnElement(out, reason);
63
+ }
64
+ return out.length === 0 ? undefined : Object.freeze(out);
65
+ }
66
+ catch {
67
+ return undefined;
68
+ }
69
+ }
70
+ export function approvalAgentIdOf(carrier) {
71
+ try {
72
+ if (typeof carrier !== 'object' || carrier === null)
73
+ return undefined;
74
+ return ownNonEmptyText(carrier, 'agentId');
75
+ }
76
+ catch {
77
+ return undefined;
78
+ }
79
+ }
@@ -2,7 +2,9 @@ import { displayUntrusted } from '../displayUntrusted.js';
2
2
  import { msg, renderMessage } from '../i18n/translate.js';
3
3
  import { approvalMandateDetail, askOriginNoteOf } from '../gateVocabulary.js';
4
4
  import { readAskOrigin, readOwnDataValue, guardedRead } from '../ownKey.js';
5
+ import { elideMiddleForDisplay } from '../noticePresentation.js';
5
6
  import { allowRuleShadowSentence } from './allowRuleShadow.js';
7
+ import { approvalUnreadableWhyWordOf } from './approvalRequestFrameReading.js';
6
8
  import { mandatedApprovalDetailOf } from './automaticAnswerVerdict.js';
7
9
  import { approvalBoundGrantsDetail, approvalIsMandated, approvalPriorCardsDetail, askProbeReasonDetail, classifierNoRulingDetail, readApprovalBoundGrants, readApprovalClassifierNoRuling, readApprovalMandate, readDenialLimitFallback, } from './toolApprovalWire.js';
8
10
  export const APPROVAL_CARD_REASON_SOURCES = Object.freeze([
@@ -21,8 +23,24 @@ export const APPROVAL_CARD_REASON_SOURCES = Object.freeze([
21
23
  ]);
22
24
  export const APPROVAL_CARD_REASONS_DEFAULT_MAX_LINES = 4;
23
25
  const MESSAGE_DISPLAY_MAX = 300;
24
- function payloadUnreadableDetail(lang) {
25
- return renderMessage(msg('approval.card.payloadUnreadable'), lang);
26
+ function engineMessageLine(engineMessage) {
27
+ const shown = displayUntrusted(engineMessage);
28
+ if (shown.length <= MESSAGE_DISPLAY_MAX)
29
+ return shown;
30
+ const settled = displayUntrusted(elideMiddleForDisplay(shown, MESSAGE_DISPLAY_MAX));
31
+ return settled.length <= MESSAGE_DISPLAY_MAX ? settled : displayUntrusted(engineMessage, { max: MESSAGE_DISPLAY_MAX });
32
+ }
33
+ function payloadUnreadableDetail(why, lang) {
34
+ switch (typeof why === 'string' ? approvalUnreadableWhyWordOf(why) : undefined) {
35
+ case 'version_unknown':
36
+ return renderMessage(msg('approval.card.payloadUnreadable.versionUnknown'), lang);
37
+ case 'kind_unknown':
38
+ return renderMessage(msg('approval.card.payloadUnreadable.partUnknown'), lang);
39
+ case 'unreadable_fields':
40
+ return renderMessage(msg('approval.card.payloadUnreadable.fieldsMalformed'), lang);
41
+ default:
42
+ return renderMessage(msg('approval.card.payloadUnreadable'), lang);
43
+ }
26
44
  }
27
45
  function moreDetail(n, lang) {
28
46
  return renderMessage(n === 1 ? msg('approval.card.more.one') : msg('approval.card.more.other', { count: n }), lang);
@@ -64,7 +82,7 @@ export function approvalCardReasons(card, opts, lang) {
64
82
  catch {
65
83
  denialLimitReadable = false;
66
84
  }
67
- add('payload_unreadable', () => (ownData(card, 'cardPayloadUnreadable') === true ? payloadUnreadableDetail(lang) : undefined));
85
+ add('payload_unreadable', () => (ownData(card, 'cardPayloadUnreadable') === true ? payloadUnreadableDetail(ownData(card, 'cardPayloadUnreadableWhy'), lang) : undefined));
68
86
  add('prior_cards', () => approvalPriorCardsDetail(card, lang));
69
87
  add('message', () => {
70
88
  const engineMessage = ownData(card, 'message');
@@ -73,7 +91,7 @@ export function approvalCardReasons(card, opts, lang) {
73
91
  const tool = ownData(card, 'toolName');
74
92
  if (typeof tool === 'string' && engineMessage.trim() === `approval required for "${tool}"`)
75
93
  return undefined;
76
- return displayUntrusted(engineMessage, { max: MESSAGE_DISPLAY_MAX });
94
+ return engineMessageLine(engineMessage);
77
95
  });
78
96
  add('mandated', () => (approvalIsMandated(card) ? mandatedApprovalDetailOf(card, lang) : undefined));
79
97
  add('mandate', () => {