@sema-agent/client-core 0.112.1 → 0.113.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 (178) hide show
  1. package/CHANGELOG.md +130 -0
  2. package/README.md +36 -23
  3. package/dist/adapt/arms.js +7 -1
  4. package/dist/adapt/textStream.d.ts +2 -0
  5. package/dist/adapt/textStream.js +27 -1
  6. package/dist/adapter/activeRunSelfHeal.d.ts +7 -5
  7. package/dist/adapter/activeRunSelfHeal.js +38 -66
  8. package/dist/adapter/downstream/eventToSdkMessage.js +4 -0
  9. package/dist/adapter/downstream/terminalToSdkResult.d.ts +8 -0
  10. package/dist/adapter/downstream/terminalToSdkResult.js +36 -1
  11. package/dist/adapter/runStream.d.ts +2 -12
  12. package/dist/adapter/runStream.js +46 -19
  13. package/dist/agentSession/engineAgentRegistryRead.js +2 -1
  14. package/dist/agentSession/engineSessionBackgroundStop.js +2 -2
  15. package/dist/attachmentOutcome.d.ts +35 -0
  16. package/dist/attachmentOutcome.js +192 -0
  17. package/dist/attachmentPathPlan.d.ts +67 -0
  18. package/dist/attachmentPathPlan.js +203 -0
  19. package/dist/attachmentRoute.d.ts +9 -1
  20. package/dist/attachmentRoute.js +23 -2
  21. package/dist/declared/supportFloorDeclared.d.ts +1 -1
  22. package/dist/declared/supportFloorDeclared.js +1 -0
  23. package/dist/deviceRebind.js +2 -3
  24. package/dist/displayUntrusted.js +126 -19
  25. package/dist/engineAddress.d.ts +1 -1
  26. package/dist/engineAddress.js +9 -6
  27. package/dist/engineErrorCodes.d.ts +3 -0
  28. package/dist/engineErrorCodes.js +4 -0
  29. package/dist/engineNoticeCodes.d.ts +34 -4
  30. package/dist/engineNoticeCodes.js +133 -6
  31. package/dist/engineUnavailable.d.ts +4 -2
  32. package/dist/engineUnavailable.js +99 -17
  33. package/dist/fleet/fleetLedger.d.ts +9 -3
  34. package/dist/fleet/fleetLedger.js +112 -16
  35. package/dist/fleet/fleetProjection.d.ts +5 -0
  36. package/dist/fleet/fleetProjection.js +9 -1
  37. package/dist/gateVocabulary.d.ts +7 -0
  38. package/dist/gateVocabulary.js +40 -14
  39. package/dist/generated/engineFactTables.d.ts +4 -2
  40. package/dist/generated/engineFactTables.js +198 -2
  41. package/dist/generated/engineNoticeTables.js +56 -8
  42. package/dist/generated/settingsSchemaFns.d.ts +7 -0
  43. package/dist/generated/settingsSchemaFns.js +11 -0
  44. package/dist/generated/settingsSchemaHash.d.ts +1 -0
  45. package/dist/generated/settingsSchemaHash.js +58 -0
  46. package/dist/generated/settingsSchemaOwnKeyRead.js +6 -1
  47. package/dist/generated/settingsSchemaTables.d.ts +3 -2
  48. package/dist/generated/settingsSchemaTables.js +14 -0
  49. package/dist/generated/settingsSchemaTightenVerdict.d.ts +1 -0
  50. package/dist/generated/settingsSchemaTightenVerdict.js +125 -0
  51. package/dist/headlessPermissionModeWire.d.ts +7 -2
  52. package/dist/headlessPermissionModeWire.js +77 -8
  53. package/dist/hitl/approvalDecisionDoor.d.ts +24 -0
  54. package/dist/hitl/approvalDecisionDoor.js +77 -0
  55. package/dist/hitl/approvalDelivery.d.ts +6 -0
  56. package/dist/hitl/approvalDelivery.js +57 -7
  57. package/dist/hitl/approvalResolution.d.ts +6 -3
  58. package/dist/hitl/approvalResolution.js +24 -2
  59. package/dist/hitl/approvalsFeed.js +1 -1
  60. package/dist/hitl/automaticAnswerVerdict.d.ts +1 -1
  61. package/dist/hitl/decisionSend.d.ts +7 -4
  62. package/dist/hitl/decisionSend.js +90 -41
  63. package/dist/hitl/frameRouter.d.ts +3 -3
  64. package/dist/hitl/frameRouter.js +5 -0
  65. package/dist/hitl/hitlHostSurface.d.ts +3 -2
  66. package/dist/hitl/hitlHostSurface.js +5 -3
  67. package/dist/hitl/legacyApprovalShapes.d.ts +142 -0
  68. package/dist/hitl/legacyApprovalShapes.js +1 -0
  69. package/dist/hitl/livePendingAsk.d.ts +4 -4
  70. package/dist/hitl/livePendingAsk.js +5 -3
  71. package/dist/hitl/parkResolver.js +1 -1
  72. package/dist/hitl/persistedRulesWire.js +2 -2
  73. package/dist/hitl/planReviewCard.d.ts +2 -1
  74. package/dist/hitl/planReviewCard.js +64 -1
  75. package/dist/hitl/planReviewWire.d.ts +30 -0
  76. package/dist/hitl/planReviewWire.js +204 -65
  77. package/dist/hitl/sessionPolicyWire.js +16 -7
  78. package/dist/hitl/subagentSource.d.ts +1 -0
  79. package/dist/hitl/subagentSource.js +11 -0
  80. package/dist/hitl/toolApprovalWire.d.ts +34 -10
  81. package/dist/hitl/toolApprovalWire.js +182 -33
  82. package/dist/hookMatcherVerdict.d.ts +2 -1
  83. package/dist/hookMatcherVerdict.js +3 -2
  84. package/dist/hooksReaderGenerations.d.ts +8 -0
  85. package/dist/hooksReaderGenerations.js +49 -0
  86. package/dist/hooksWireCaps.js +43 -18
  87. package/dist/hostSettingsSource.d.ts +1 -1
  88. package/dist/hostSettingsSource.js +2 -2
  89. package/dist/hostTurnSettings.d.ts +2 -2
  90. package/dist/hostTurnSettings.js +87 -47
  91. package/dist/humanTurn.d.ts +2 -1
  92. package/dist/humanTurn.js +44 -13
  93. package/dist/humanTurnRead.d.ts +7 -0
  94. package/dist/humanTurnRead.js +23 -14
  95. package/dist/humanTurnSentences.js +3 -0
  96. package/dist/i18n/messages.en.d.ts +91 -5
  97. package/dist/i18n/messages.en.js +98 -12
  98. package/dist/i18n/messages.zh.js +108 -15
  99. package/dist/index.d.ts +29 -15
  100. package/dist/index.js +17 -9
  101. package/dist/liveModelCatalog.js +1 -0
  102. package/dist/liveQuestionStore.d.ts +2 -0
  103. package/dist/liveQuestionStore.js +7 -2
  104. package/dist/localConfig/kernel.d.ts +2 -1
  105. package/dist/localConfig/kernel.js +12 -18
  106. package/dist/localConfig/mcp/edit.js +25 -27
  107. package/dist/localConfig/mcp/servers.js +5 -8
  108. package/dist/localConfig/modelPool.d.ts +6 -1
  109. package/dist/localConfig/modelPool.js +104 -27
  110. package/dist/localConfig/modelPoolWords.d.ts +2 -0
  111. package/dist/localConfig/modelPoolWords.js +1 -0
  112. package/dist/localConfig/settingsWrite.js +1 -14
  113. package/dist/localConfig/skills.js +9 -16
  114. package/dist/localEngineSpawn.d.ts +29 -1
  115. package/dist/localEngineSpawn.js +62 -1
  116. package/dist/mcpLiveness.d.ts +1 -1
  117. package/dist/mcpProbeWire.js +2 -2
  118. package/dist/mcpReconnect.js +2 -2
  119. package/dist/model/catalogLoader.js +3 -17
  120. package/dist/model/onboardJudgement.d.ts +8 -0
  121. package/dist/model/onboardJudgement.js +8 -3
  122. package/dist/model/onboardSteps.d.ts +19 -0
  123. package/dist/model/onboardSteps.js +76 -0
  124. package/dist/notifications.js +6 -0
  125. package/dist/ownKey.d.ts +4 -0
  126. package/dist/ownKey.js +61 -0
  127. package/dist/pathShape.d.ts +14 -0
  128. package/dist/pathShape.js +44 -0
  129. package/dist/planReviewCardFacts.d.ts +3 -0
  130. package/dist/planReviewCardFacts.js +20 -3
  131. package/dist/pluginHooksWire.d.ts +20 -8
  132. package/dist/pluginHooksWire.js +204 -86
  133. package/dist/prepareRefusal.d.ts +2 -0
  134. package/dist/prepareRefusal.js +11 -1
  135. package/dist/request/taskRequest.js +3 -1
  136. package/dist/resultFrameKeys.d.ts +1 -0
  137. package/dist/resultFrameKeys.js +3 -0
  138. package/dist/resumeRefusalCopy.js +3 -1
  139. package/dist/retryStatus.d.ts +11 -1
  140. package/dist/retryStatus.js +15 -4
  141. package/dist/runTerminal.d.ts +1 -0
  142. package/dist/runTerminal.js +15 -1
  143. package/dist/sdkWireTransit.d.ts +1 -1
  144. package/dist/seatContract.d.ts +12 -3
  145. package/dist/seatContract.js +24 -13
  146. package/dist/sessionEngine.js +1 -1
  147. package/dist/sessionHooksRoster.js +8 -6
  148. package/dist/sessionIdSegment.d.ts +0 -1
  149. package/dist/sessionIdSegment.js +1 -3
  150. package/dist/sessionMemoryErase.js +2 -2
  151. package/dist/sessionMemoryStatus.js +2 -1
  152. package/dist/sessionOccupant.d.ts +29 -0
  153. package/dist/sessionOccupant.js +78 -0
  154. package/dist/settingsHooksSalvage.d.ts +4 -1
  155. package/dist/settingsHooksSalvage.js +22 -9
  156. package/dist/skillOverrideChain.d.ts +3 -0
  157. package/dist/skillOverrideChain.js +31 -4
  158. package/dist/skillsWireCaps.d.ts +16 -2
  159. package/dist/skillsWireCaps.js +47 -20
  160. package/dist/subagent/agentStateDetail.js +32 -8
  161. package/dist/subagent/engineCompactWire.js +48 -36
  162. package/dist/subagent/engineDelegatedPrompt.d.ts +3 -2
  163. package/dist/subagent/engineDelegatedPrompt.js +65 -28
  164. package/dist/subagentEditOutcomes.d.ts +9 -0
  165. package/dist/subagentEditOutcomes.js +43 -0
  166. package/dist/supportFloor.d.ts +2 -1
  167. package/dist/supportFloor.js +1 -1
  168. package/dist/toolResult.js +4 -2
  169. package/dist/toolRoster.d.ts +1 -0
  170. package/dist/toolRoster.js +1 -0
  171. package/dist/usageAnalytics.js +2 -1
  172. package/dist/userAttachmentEnvelope.d.ts +11 -0
  173. package/dist/userAttachmentEnvelope.js +7 -2
  174. package/dist/userAttachmentSeat.d.ts +7 -1
  175. package/dist/userAttachmentSeat.js +44 -7
  176. package/dist/wiringInstructionsAttribution.js +8 -2
  177. package/docs/INTEGRATION-CLIENTS.md +1588 -16
  178. package/package.json +5 -5
@@ -2,10 +2,59 @@ import { displayUntrusted } from './displayUntrusted.js';
2
2
  import { appendOwnElement, readOwnDataValue } from './ownKey.js';
3
3
  import { inSlotReadOf } from './wireFailureShape.js';
4
4
  import { msg, renderMessage } from './i18n/translate.js';
5
- import { SETTINGS_ENGINE_OWNED_HOOK_EVENTS } from './generated/settingsSchemaTables.js';
5
+ import { SETTINGS_ENGINE_OWNED_HOOK_EVENTS, SETTINGS_ENGINE_OWNED_HOOK_EVENT_SINCE } from './generated/settingsSchemaTables.js';
6
6
  import { SETTINGS_HOOK_EVENTS } from './generated/settingsSchemaFns.js';
7
- import { HOOK_SETTINGS_SOURCE_TEXT, hooksEntryUnreadKeys, hooksGroupAuthoredSource, hooksGroupUnreadKeys, hooksKeyCoordinateText, hooksSalvageMaskOf, salvageSettingsHooksEntries, } from './settingsHooksSalvage.js';
8
- export const ENGINE_FIRED_HOOK_EVENTS = SETTINGS_ENGINE_OWNED_HOOK_EVENTS;
7
+ import { hostLog } from './host.js';
8
+ import { SUPPORT_FLOOR, compareReleaseVersions } from './supportFloor.js';
9
+ import { HOOK_SETTINGS_SOURCE_TEXT, hooksEntryContractView, hooksEntryUnreadKeys, hooksGroupAuthoredSource, hooksGroupUnreadKeys, hooksKeyCoordinateText, hooksSalvageMaskOf, isGuardHookEvent, salvageSettingsHooksEntries, } from './settingsHooksSalvage.js';
10
+ export const SUPPORT_FLOOR_SETTINGS_CONTRACT = Object.freeze({ version: SUPPORT_FLOOR.settingsContract, basis: 'absent' });
11
+ const CONTRACT_BASES = new Set(['reported', 'absent', 'unreadable']);
12
+ function isCompleteVersion(v) {
13
+ return typeof v === 'string' && compareReleaseVersions(v, v) !== undefined;
14
+ }
15
+ export function contractOwnsHookEventAt(event, contractVersion) {
16
+ if (!isCompleteVersion(contractVersion))
17
+ return undefined;
18
+ if (typeof event !== 'string' || !SETTINGS_ENGINE_OWNED_HOOK_EVENTS.includes(event))
19
+ return false;
20
+ const order = compareReleaseVersions(contractVersion, SETTINGS_ENGINE_OWNED_HOOK_EVENT_SINCE[event]);
21
+ return order !== undefined && order >= 0;
22
+ }
23
+ function contractReadingOf(reading) {
24
+ if (reading === SUPPORT_FLOOR_SETTINGS_CONTRACT)
25
+ return SUPPORT_FLOOR_SETTINGS_CONTRACT;
26
+ let version;
27
+ let basis;
28
+ try {
29
+ if (isRecord(reading)) {
30
+ version = readOwnDataValue(reading, 'version');
31
+ basis = readOwnDataValue(reading, 'basis');
32
+ }
33
+ }
34
+ catch {
35
+ version = undefined;
36
+ }
37
+ if (isCompleteVersion(version) && typeof basis === 'string' && CONTRACT_BASES.has(basis) && (basis === 'reported' || version === SUPPORT_FLOOR.settingsContract)) {
38
+ return Object.freeze({ version, basis: basis });
39
+ }
40
+ hostLog('debug', `hooks-settings-contract-unreadable floor=${SUPPORT_FLOOR.settingsContract}`);
41
+ return Object.freeze({ version: SUPPORT_FLOOR.settingsContract, basis: 'unreadable' });
42
+ }
43
+ export function engineLaneOf(reading) {
44
+ const contract = contractReadingOf(reading);
45
+ return (event) => contractOwnsHookEventAt(event, contract.version) === true;
46
+ }
47
+ export function planSettingsContractOf(plan) {
48
+ let reading;
49
+ try {
50
+ const engine = isRecord(plan) ? readOwnDataValue(plan, 'engine') : undefined;
51
+ reading = isRecord(engine) ? readOwnDataValue(engine, 'settingsContract') : undefined;
52
+ }
53
+ catch {
54
+ reading = undefined;
55
+ }
56
+ return reading === undefined ? undefined : contractReadingOf(reading);
57
+ }
9
58
  export const PLUGIN_HOOK_DISPOSITIONS = ['engine', 'shell', 'not_run'];
10
59
  export const PLUGIN_HOOK_REASONS = [
11
60
  'projected',
@@ -51,6 +100,7 @@ export const SETTINGS_HOOK_DROP_REASONS = [
51
100
  'governance_unreadable',
52
101
  'policy_disable_all',
53
102
  'no_executor',
103
+ 'layer_degraded',
54
104
  ];
55
105
  export const HOOK_ENTRY_TYPE_WORDS = Object.freeze(['command', 'prompt', 'agent', 'http', 'mcp_tool']);
56
106
  const _hookEntryTypePins = [true, true, true, true];
@@ -148,8 +198,7 @@ function hookExecutorOf(x) {
148
198
  return judged('engine', 'projected');
149
199
  return judged(x.shellRuns ? 'shell' : 'not_run', why);
150
200
  }
151
- const ENGINE_EVENTS = new Set(ENGINE_FIRED_HOOK_EVENTS);
152
- const SHELL_OWNED_EVENTS = new Set(SETTINGS_HOOK_EVENTS.filter((e) => !ENGINE_EVENTS.has(e)));
201
+ const CONTRACT_HOOK_EVENTS = new Set(SETTINGS_HOOK_EVENTS);
153
202
  const USER_CONFIG_REF_ONE = /\$\{user_config\.[^}]+\}/;
154
203
  const USER_CONFIG_REF_ALL = /\$\{user_config\.([^}]+)\}/g;
155
204
  function isRecord(v) {
@@ -164,8 +213,8 @@ function ownView(v) {
164
213
  function nonEmptyString(v) {
165
214
  return typeof v === 'string' && v.length > 0;
166
215
  }
167
- export function isEngineFiredHookEvent(event) {
168
- return ENGINE_EVENTS.has(event);
216
+ export function isEngineFiredHookEvent(event, contract) {
217
+ return engineLaneOf(contract)(event);
169
218
  }
170
219
  function declaresSensitive(options) {
171
220
  if (options === undefined)
@@ -239,6 +288,7 @@ export function occupancyOf(wire) {
239
288
  return out;
240
289
  }
241
290
  export function decidePluginHooks(input) {
291
+ const engineEvent = engineLaneOf(input.engine?.settingsContract);
242
292
  const verdicts = [];
243
293
  const excluded = [];
244
294
  const modules = [];
@@ -309,7 +359,7 @@ export function decidePluginHooks(input) {
309
359
  appendOwnElement(verdicts, { ...key, disposition: 'not_run', reason: 'user_config_unset' });
310
360
  return;
311
361
  }
312
- if (!ENGINE_EVENTS.has(event)) {
362
+ if (!engineEvent(event)) {
313
363
  appendOwnElement(verdicts, {
314
364
  ...key,
315
365
  ...(input.shellRuns(event, entryType)
@@ -336,7 +386,7 @@ export function decidePluginHooks(input) {
336
386
  appendOwnElement(verdicts, { ...key, disposition: ex.disposition, reason: ex.reason });
337
387
  return;
338
388
  }
339
- const entryUnread = isRecord(entry) ? hooksEntryUnreadKeys(event, entry, input.readerNotRead) : undefined;
389
+ const entryUnread = isRecord(entry) ? hooksEntryUnreadKeys(event, entry, input.reader) : undefined;
340
390
  if (groupSourceAuthored && (authored === 'unreadable' || entryUnread !== undefined)) {
341
391
  appendOwnElement(verdicts, { ...key, ...fallback(event, entryType, 'source_not_authored') });
342
392
  return;
@@ -403,7 +453,7 @@ export function decidePluginHooks(input) {
403
453
  if (v.disposition !== 'shell' || !suppressed.has(v.pluginId))
404
454
  continue;
405
455
  v.disposition = 'not_run';
406
- if (!ENGINE_EVENTS.has(v.event))
456
+ if (!engineEvent(v.event))
407
457
  v.reason = 'no_executor';
408
458
  }
409
459
  }
@@ -425,6 +475,7 @@ function sessionHooksForJudge(hooks) {
425
475
  return out;
426
476
  }
427
477
  export function decideSessionHooks(input) {
478
+ const engineEvent = engineLaneOf(input.engine?.settingsContract);
428
479
  const out = [];
429
480
  let unreadable = 0;
430
481
  for (const src of input.sources) {
@@ -457,7 +508,7 @@ export function decideSessionHooks(input) {
457
508
  return;
458
509
  }
459
510
  const shellRuns = input.shellRuns(event, type);
460
- if (!ENGINE_EVENTS.has(event)) {
511
+ if (!engineEvent(event)) {
461
512
  appendOwnElement(out, { ...key, ...(shellRuns ? { disposition: 'shell', reason: 'shell_event' } : { disposition: 'not_run', reason: 'no_executor' }) });
462
513
  return;
463
514
  }
@@ -493,14 +544,14 @@ function unreadKeyPathsOf(event, groupIndex, hookIndex, groupUnread, entryUnread
493
544
  appendOwnElement(out, Object.freeze(['hooks', event, groupIndex, 'hooks', hookIndex, k]));
494
545
  return Object.freeze(out);
495
546
  }
496
- export function filterSettingsHookGroups(source, event, groups, execFormCapable, shellRunsType, judge, readerNotRead, mask) {
547
+ export function filterSettingsHookGroups(source, event, groups, execFormCapable, shellRunsType, judge, reader, contract, mask) {
497
548
  const drops = [];
498
549
  const verdicts = [];
499
550
  const excluded = [];
500
551
  const out = [];
501
552
  let stripped = 0;
502
- const engineEvent = isEngineFiredHookEvent(event);
503
- const shellOwned = !engineEvent && SHELL_OWNED_EVENTS.has(event);
553
+ const engineEvent = isEngineFiredHookEvent(event, contract);
554
+ const shellOwned = !engineEvent && CONTRACT_HOOK_EVENTS.has(event);
504
555
  groups.forEach((group, groupIndex) => {
505
556
  if (mask !== undefined && mask.groupDropped(event, groupIndex))
506
557
  return;
@@ -512,7 +563,7 @@ export function filterSettingsHookGroups(source, event, groups, execFormCapable,
512
563
  return;
513
564
  if (shellRunsType(isRecord(entry) && typeof entry.type === 'string' ? entry.type : undefined))
514
565
  return;
515
- appendOwnElement(drops, { source, event, groupIndex, hookIndex, reason: 'no_executor', notRun: true });
566
+ appendOwnElement(drops, { source, event, groupIndex, hookIndex, reason: 'no_executor', notRun: true, guard: isGuardHookEvent(event) });
516
567
  });
517
568
  return;
518
569
  }
@@ -537,7 +588,7 @@ export function filterSettingsHookGroups(source, event, groups, execFormCapable,
537
588
  : entry.type === 'command' && carriesArgs(entry) && !execFormCapable
538
589
  ? 'exec_form_unsupported'
539
590
  : undefined;
540
- const entryUnread = earlier === undefined && isRecord(entry) ? hooksEntryUnreadKeys(event, entry, readerNotRead) : undefined;
591
+ const entryUnread = earlier === undefined && isRecord(entry) ? hooksEntryUnreadKeys(event, entry, reader) : undefined;
541
592
  const sourceNotAuthored = earlier === undefined && groupSourceAuthored && (authored === 'unreadable' || entryUnread !== undefined);
542
593
  const unreadKeys = earlier === undefined && !sourceNotAuthored ? unreadKeyPathsOf(event, groupIndex, hookIndex, groupUnread ?? [], entryUnread) : [];
543
594
  const reason = earlier ?? (sourceNotAuthored ? 'source_not_authored' : unreadKeys.length > 0 ? 'key_not_read' : undefined);
@@ -551,6 +602,7 @@ export function filterSettingsHookGroups(source, event, groups, execFormCapable,
551
602
  ...typed,
552
603
  reason,
553
604
  notRun: !shellRunsType(isRecord(entry) && typeof entry.type === 'string' ? entry.type : undefined),
605
+ guard: isGuardHookEvent(event),
554
606
  ...(reason === 'key_not_read' ? { unreadKeys } : {}),
555
607
  });
556
608
  changed = true;
@@ -611,7 +663,7 @@ export function createSettingsHookJudge(engine, shellRuns, promptAuthoredByUser,
611
663
  const seen = new Map();
612
664
  return (event, group, entry) => {
613
665
  let dk;
614
- const entryKey = settingsHookEntryKey(entry);
666
+ const entryKey = settingsHookIdentityKey(entry);
615
667
  if (entryKey !== undefined && isRecord(group)) {
616
668
  try {
617
669
  const { hooks: _hooks, ...rest } = group;
@@ -683,26 +735,44 @@ function settingsHookEntryKey(entry) {
683
735
  return undefined;
684
736
  }
685
737
  }
686
- function ccMergeRank(source) {
687
- switch (source) {
688
- case 'userSettings':
689
- return 0;
690
- case 'projectSettings':
691
- return 1;
692
- case 'localSettings':
693
- return 2;
694
- case 'flagSettings':
695
- return 3;
696
- case 'policySettings':
697
- return 4;
738
+ function settingsHookIdentityKey(entry) {
739
+ if (settingsHookEntryKey(entry) === undefined)
740
+ return undefined;
741
+ try {
742
+ return JSON.stringify(canonicalHookValue(entry, new Set()));
743
+ }
744
+ catch {
745
+ return undefined;
746
+ }
747
+ }
748
+ function canonicalHookValue(v, ancestors) {
749
+ if (typeof v !== 'object' || v === null)
750
+ return v;
751
+ if (ancestors.has(v))
752
+ throw new TypeError('cycle');
753
+ ancestors.add(v);
754
+ try {
755
+ if (Array.isArray(v))
756
+ return v.map((x) => canonicalHookValue(x, ancestors));
757
+ const out = Object.create(null);
758
+ for (const k of Object.keys(v).sort()) {
759
+ const x = v[k];
760
+ if (x !== undefined)
761
+ out[k] = canonicalHookValue(x, ancestors);
762
+ }
763
+ return out;
764
+ }
765
+ finally {
766
+ ancestors.delete(v);
698
767
  }
699
768
  }
700
769
  export function dedupeSettingsHookGroups(groups) {
701
- const keysOf = [];
702
- const winner = new Map();
703
- for (const { source, group } of groups) {
770
+ const placed = new Set();
771
+ const out = [];
772
+ let removed = 0;
773
+ for (const { group } of groups) {
704
774
  if (!isRecord(group) || !Array.isArray(group.hooks)) {
705
- appendOwnElement(keysOf, []);
775
+ appendOwnElement(out, group);
706
776
  continue;
707
777
  }
708
778
  let groupKey;
@@ -714,53 +784,25 @@ export function dedupeSettingsHookGroups(groups) {
714
784
  catch {
715
785
  groupKey = undefined;
716
786
  }
717
- const rank = ccMergeRank(source);
718
- const keys = [];
719
- for (const entry of group.hooks) {
720
- const entryKey = groupKey === undefined ? undefined : settingsHookEntryKey(entry);
721
- const key = entryKey === undefined ? undefined : `${groupKey}\u0000${entryKey}`;
722
- appendOwnElement(keys, key);
723
- if (key === undefined)
724
- continue;
725
- const prev = winner.get(key);
726
- if (prev === undefined || rank >= prev.rank)
727
- winner.set(key, { entry, rank });
728
- }
729
- appendOwnElement(keysOf, keys);
730
- }
731
- const placed = new Set();
732
- const out = [];
733
- let removed = 0;
734
- groups.forEach(({ group }, gi) => {
735
- if (!isRecord(group) || !Array.isArray(group.hooks)) {
736
- appendOwnElement(out, group);
737
- return;
738
- }
739
- const keys = keysOf[gi] ?? [];
740
787
  const kept = [];
741
788
  let changed = false;
742
- group.hooks.forEach((entry, hi) => {
743
- const key = keys[hi];
744
- if (key === undefined) {
745
- appendOwnElement(kept, entry);
746
- return;
747
- }
748
- if (placed.has(key)) {
789
+ for (const entry of group.hooks) {
790
+ const entryKey = groupKey === undefined ? undefined : settingsHookIdentityKey(entry);
791
+ const key = entryKey === undefined ? undefined : `${groupKey}\u0000${entryKey}`;
792
+ if (key !== undefined && placed.has(key)) {
749
793
  removed++;
750
794
  changed = true;
751
- return;
795
+ continue;
752
796
  }
753
- placed.add(key);
754
- const win = winner.get(key)?.entry ?? entry;
755
- if (win !== entry)
756
- changed = true;
757
- appendOwnElement(kept, win);
758
- });
797
+ if (key !== undefined)
798
+ placed.add(key);
799
+ appendOwnElement(kept, entry);
800
+ }
759
801
  if (!changed)
760
802
  appendOwnElement(out, group);
761
803
  else if (kept.length > 0)
762
804
  appendOwnElement(out, { ...group, hooks: kept });
763
- });
805
+ }
764
806
  return { groups: out, removed };
765
807
  }
766
808
  export function pluginHookVerdictOf(plan, pluginId, event, groupIndex, hookIndex) {
@@ -769,6 +811,50 @@ export function pluginHookVerdictOf(plan, pluginId, event, groupIndex, hookIndex
769
811
  function skipMatcherKey(matcher) {
770
812
  return matcher === undefined || matcher === null || matcher === '' || matcher === '*' ? 'null' : JSON.stringify(matcher);
771
813
  }
814
+ function skipPairOf(entry) {
815
+ const names = entry.type === 'http' && Object.hasOwn(entry, 'allowedEnvVars') ? entry.allowedEnvVars : undefined;
816
+ const env = Array.isArray(names) && Array.from(names).every((n) => typeof n === 'string') ? names : undefined;
817
+ let body = entry;
818
+ if (env !== undefined) {
819
+ body = Object.create(null);
820
+ for (const k of Object.keys(entry))
821
+ if (k !== 'allowedEnvVars')
822
+ body[k] = entry[k];
823
+ }
824
+ const key = settingsHookIdentityKey(body);
825
+ return key === undefined ? undefined : env === undefined ? { key } : { key: `${key}\u0000allowedEnvVars`, env };
826
+ }
827
+ function localPairViewOf(event, entry, wireKeys) {
828
+ try {
829
+ if (!isRecord(entry))
830
+ return undefined;
831
+ const proto = Object.getPrototypeOf(entry);
832
+ const flat = Object.create(null);
833
+ if (proto === null || Object.getPrototypeOf(proto) === null) {
834
+ for (const k of Object.keys(entry)) {
835
+ if (k === 'plugin')
836
+ continue;
837
+ const v = entry[k];
838
+ if (v !== undefined)
839
+ flat[k] = v;
840
+ }
841
+ return flat;
842
+ }
843
+ const keys = new Set(wireKeys);
844
+ for (const k in entry)
845
+ keys.add(k);
846
+ for (const k of keys) {
847
+ const v = entry[k];
848
+ if (v !== undefined)
849
+ flat[k] = v;
850
+ }
851
+ const view = hooksEntryContractView(event, flat);
852
+ return isRecord(view) ? view : undefined;
853
+ }
854
+ catch {
855
+ return undefined;
856
+ }
857
+ }
772
858
  export function settingsHooksKeptLocally(plan, event, group, opts) {
773
859
  if (planClosedLocally(plan))
774
860
  return [];
@@ -794,7 +880,10 @@ export function settingsHooksKeptLocally(plan, event, group, opts) {
794
880
  if (layerSkipped)
795
881
  return [];
796
882
  }
797
- if (!Array.isArray(hooks) || hooks.length === 0 || !ENGINE_EVENTS.has(event))
883
+ if (!Array.isArray(hooks) || hooks.length === 0)
884
+ return hooks;
885
+ const engineEvent = engineLaneOf(planSettingsContractOf(plan));
886
+ if (!engineEvent(event))
798
887
  return hooks;
799
888
  try {
800
889
  if (COMPACTION_EVENTS.has(event) && opts?.engineCompaction === 'not_performed')
@@ -806,9 +895,10 @@ export function settingsHooksKeptLocally(plan, event, group, opts) {
806
895
  const wire = ownField(planRec, 'wire');
807
896
  if (!Array.isArray(excludedList) || (wire !== undefined && !isRecord(wire)))
808
897
  return hooks;
809
- if (excludedList.some((e) => settingsExclusionRowOf(e)?.event === event))
898
+ if (excludedList.some((e) => settingsExclusionRowOf(e, engineEvent)?.event === event))
810
899
  return [];
811
- const sent = new Set();
900
+ const sent = new Map();
901
+ const wireKeys = new Set();
812
902
  const groups = isRecord(wire) ? ownField(wire, event) : undefined;
813
903
  if (Array.isArray(groups)) {
814
904
  for (const g of groups) {
@@ -821,9 +911,18 @@ export function settingsHooksKeptLocally(plan, event, group, opts) {
821
911
  for (const h of gh) {
822
912
  if (isRecord(h) && Object.hasOwn(h, 'plugin'))
823
913
  continue;
824
- const k = settingsHookEntryKey(ownView(h));
825
- if (k !== undefined)
826
- sent.add(`${mk}\u0000${k}`);
914
+ const v = ownView(h);
915
+ const pair = isRecord(v) ? skipPairOf(v) : undefined;
916
+ if (pair === undefined || !isRecord(v))
917
+ continue;
918
+ for (const k of Object.keys(v))
919
+ wireKeys.add(k);
920
+ const slot = `${mk}\u0000${pair.key}`;
921
+ const list = sent.get(slot);
922
+ if (list === undefined)
923
+ sent.set(slot, [pair.env]);
924
+ else
925
+ appendOwnElement(list, pair.env);
827
926
  }
828
927
  }
829
928
  }
@@ -832,8 +931,11 @@ export function settingsHooksKeptLocally(plan, event, group, opts) {
832
931
  const mk = skipMatcherKey(isRecord(group) ? group.matcher : undefined);
833
932
  let kept = null;
834
933
  hooks.forEach((h, i) => {
835
- const k = settingsHookEntryKey(h);
836
- const skip = k !== undefined && sent.has(`${mk}\u0000${k}`);
934
+ const view = localPairViewOf(event, h, wireKeys);
935
+ const pair = view === undefined ? undefined : skipPairOf(view);
936
+ const list = pair === undefined ? undefined : sent.get(`${mk}\u0000${pair.key}`);
937
+ const env = pair?.env;
938
+ const skip = list !== undefined && (env === undefined || list.some((w) => w !== undefined && w.every((n) => env.includes(n))));
837
939
  if (skip)
838
940
  kept ??= hooks.slice(0, i);
839
941
  else if (kept !== null)
@@ -881,7 +983,7 @@ export function pluginHooksKeptLocally(plan, pluginId, event, groupIndex, hooks)
881
983
  return hooks;
882
984
  }
883
985
  }
884
- function settingsRowBaseOf(v) {
986
+ function settingsRowBaseOf(v, engineEvent) {
885
987
  if (!isRecord(v))
886
988
  return undefined;
887
989
  const source = ownField(v, 'source');
@@ -890,7 +992,7 @@ function settingsRowBaseOf(v) {
890
992
  const hookIndex = ownField(v, 'hookIndex');
891
993
  if (typeof source !== 'string' || !Object.hasOwn(SOURCE_TEXT, source))
892
994
  return undefined;
893
- if (typeof event !== 'string' || !ENGINE_EVENTS.has(event))
995
+ if (typeof event !== 'string' || !engineEvent(event))
894
996
  return undefined;
895
997
  if (!Number.isInteger(groupIndex) || groupIndex < 0 || !Number.isInteger(hookIndex) || hookIndex < 0)
896
998
  return undefined;
@@ -899,9 +1001,9 @@ function settingsRowBaseOf(v) {
899
1001
  const DISPOSITION_SET = new Set(PLUGIN_HOOK_DISPOSITIONS);
900
1002
  const REASON_SET = new Set(PLUGIN_HOOK_REASONS);
901
1003
  const EXCLUSION_REASON_SET = new Set(PLUGIN_HOOK_EXCLUSION_REASONS);
902
- function settingsVerdictRowOf(v) {
1004
+ function settingsVerdictRowOf(v, engineEvent) {
903
1005
  try {
904
- const b = settingsRowBaseOf(v);
1006
+ const b = settingsRowBaseOf(v, engineEvent);
905
1007
  if (b === undefined)
906
1008
  return undefined;
907
1009
  const disposition = ownField(b.o, 'disposition');
@@ -914,9 +1016,9 @@ function settingsVerdictRowOf(v) {
914
1016
  return undefined;
915
1017
  }
916
1018
  }
917
- function settingsExclusionRowOf(v) {
1019
+ function settingsExclusionRowOf(v, engineEvent) {
918
1020
  try {
919
- const b = settingsRowBaseOf(v);
1021
+ const b = settingsRowBaseOf(v, engineEvent);
920
1022
  if (b === undefined)
921
1023
  return undefined;
922
1024
  const reason = ownField(b.o, 'reason');
@@ -964,6 +1066,7 @@ const DROP_TEXT = {
964
1066
  governance_unreadable: renderMessage(msg('config.hooks.plan.reason.closedGovernanceUnreadable')),
965
1067
  policy_disable_all: renderMessage(msg('config.hooks.plan.reason.closedDisableAll')),
966
1068
  no_executor: REASON_TEXT.no_executor,
1069
+ layer_degraded: renderMessage(msg('config.hooks.plan.reason.layerDegraded')),
967
1070
  };
968
1071
  const SOURCE_TEXT = HOOK_SETTINGS_SOURCE_TEXT;
969
1072
  export function pluginHookReasonText(reason) {
@@ -1045,6 +1148,7 @@ function namedPathsOfRow(d) {
1045
1148
  case 'governance_unreadable':
1046
1149
  case 'policy_disable_all':
1047
1150
  case 'no_executor':
1151
+ case 'layer_degraded':
1048
1152
  return [];
1049
1153
  }
1050
1154
  }
@@ -1065,6 +1169,15 @@ function sourceNotAuthoredLine(source, row) {
1065
1169
  const coordinates = namedCoordinatesText(row.coordinates);
1066
1170
  return renderMessage(msg(row.coordinates.length === 1 ? 'config.hooks.plan.sourceNotAuthored.oneKey' : 'config.hooks.plan.sourceNotAuthored.manyKeys', { layer: SOURCE_TEXT[source], hooks, coordinates }));
1067
1171
  }
1172
+ function hookEntryFieldsUnreadableIn(plan) {
1173
+ try {
1174
+ const engine = isRecord(plan) ? readOwnDataValue(plan, 'engine') : undefined;
1175
+ return isRecord(engine) && readOwnDataValue(engine, 'hookEntryFields') === 'unreadable';
1176
+ }
1177
+ catch {
1178
+ return false;
1179
+ }
1180
+ }
1068
1181
  export function hooksNotRunNotice(plan) {
1069
1182
  const lines = [];
1070
1183
  let closedBy;
@@ -1128,10 +1241,15 @@ export function hooksNotRunNotice(plan) {
1128
1241
  }
1129
1242
  for (const row of namedBySource.values())
1130
1243
  appendOwnElement(lines, row.reason === 'key_not_read' ? keyNotReadLine(row.source, row) : sourceNotAuthoredLine(row.source, row));
1244
+ if (hookEntryFieldsUnreadableIn(plan) &&
1245
+ (plan.settingsDropped.some((d) => d.notRun && d.reason === 'key_not_read') || plan.verdicts.some((v) => v.disposition === 'not_run' && v.reason === 'key_not_read'))) {
1246
+ appendOwnElement(lines, renderMessage(msg('config.hooks.plan.keyNotRead.readerFieldsUnreadable')));
1247
+ }
1131
1248
  const settingsVerdicts = plan.settingsVerdicts;
1132
1249
  const byVerdict = new Map();
1250
+ const engineEvent = engineLaneOf(planSettingsContractOf(plan));
1133
1251
  for (const raw of Array.isArray(settingsVerdicts) ? settingsVerdicts : []) {
1134
- const v = settingsVerdictRowOf(raw);
1252
+ const v = settingsVerdictRowOf(raw, engineEvent);
1135
1253
  if (v === undefined || v.disposition !== 'not_run')
1136
1254
  continue;
1137
1255
  const k = `${v.source}\u0000${v.reason}`;
@@ -1,8 +1,10 @@
1
1
  import { CONFIG_AGENT_UNKNOWN_TOOL, CONFIG_IMAGE_INVALID, CONFIG_LEGACY_TOOL_NAME, CONFIG_MCP_SERVER_NAME_COLLISION, CONFIG_TOOL_FACE_CONTROL, PROMPT_ASSEMBLED_ROLE_REFUSED, USER_ATTACHMENT_INVALID_ERROR_CODE, USER_INVOKED_SKILL_UNKNOWN_ERROR_CODE } from './engineErrorCodes.js';
2
+ import type { AttachmentSupply } from './attachmentOutcome.js';
2
3
  export type PrepareRefusalCode = typeof CONFIG_LEGACY_TOOL_NAME | typeof CONFIG_IMAGE_INVALID | typeof CONFIG_AGENT_UNKNOWN_TOOL | typeof PROMPT_ASSEMBLED_ROLE_REFUSED | typeof USER_ATTACHMENT_INVALID_ERROR_CODE | typeof USER_INVOKED_SKILL_UNKNOWN_ERROR_CODE | typeof CONFIG_TOOL_FACE_CONTROL | typeof CONFIG_MCP_SERVER_NAME_COLLISION;
3
4
  export interface PrepareRefusalNoteFacts {
4
5
  readonly index?: number;
5
6
  readonly draftKept?: boolean;
7
+ readonly namedSupply?: AttachmentSupply;
6
8
  }
7
9
  export declare function prepareRefusalNoteOf(code: string | undefined, facts?: PrepareRefusalNoteFacts): string | undefined;
8
10
  export declare function prepareRefusalCodeOf(failure: {} | null | undefined): PrepareRefusalCode | undefined;
@@ -6,6 +6,7 @@ import { effectiveWireErrorCode } from './wireErrorTriage.js';
6
6
  const nonNegInt = (v) => (typeof v === 'number' && Number.isSafeInteger(v) && v >= 0 ? v : undefined);
7
7
  const draftKeptSegment = (facts) => Object.hasOwn(facts, 'draftKept') && facts.draftKept === true ? ` · ${renderMessage(msg('notice.prepareRefusal.draftKept'))}` : '';
8
8
  const indexOf = (facts) => nonNegInt(Object.hasOwn(facts, 'index') ? facts.index : undefined);
9
+ const pathNamed = (facts) => Object.hasOwn(facts, 'namedSupply') && facts.namedSupply === 'path';
9
10
  const PREPARE_REFUSAL_NOTES = Object.freeze({
10
11
  [CONFIG_LEGACY_TOOL_NAME]: () => `The engine refused this run at setup: a tool rule applied to it names a tool the engine refuses — ${REFUSED_NAME_CLASSES} (the engine's own error text names the entry). ` +
11
12
  'Every later run fails the same way until that entry is removed from wherever it is set: this session’s rule record, the settings sent with the run, a parent session’s rule record, or the deployment’s own tool rules.',
@@ -17,6 +18,8 @@ const PREPARE_REFUSAL_NOTES = Object.freeze({
17
18
  'Send only your own role text (the engine assembles the rest), then send it again',
18
19
  [USER_ATTACHMENT_INVALID_ERROR_CODE]: (facts) => {
19
20
  const index = indexOf(facts);
21
+ if (index !== undefined && pathNamed(facts))
22
+ return renderMessage(msg('notice.prepareRefusal.userAttachmentPath', { n: index + 1, draft: draftKeptSegment(facts) }));
20
23
  return index !== undefined
21
24
  ? `The engine refused attachment ${index + 1} of this message: it is in a form the engine does not accept, or larger than it takes${draftKeptSegment(facts)} · Remove or replace that attachment, then send it again`
22
25
  : 'The engine refused the files attached to this message: together with the message they are more than it can take in one request on this model, or one of them is in a form it does not accept' +
@@ -57,8 +60,15 @@ export function prepareRefusalNoteOf(code, facts) {
57
60
  catch {
58
61
  draftKept = undefined;
59
62
  }
63
+ let namedSupply;
64
+ try {
65
+ namedSupply = readOwnDataValue(bag, 'namedSupply');
66
+ }
67
+ catch {
68
+ namedSupply = undefined;
69
+ }
60
70
  const i = nonNegInt(index);
61
- return PREPARE_REFUSAL_NOTES[code]({ ...(i !== undefined ? { index: i } : {}), ...(draftKept === true ? { draftKept: true } : {}) });
71
+ return PREPARE_REFUSAL_NOTES[code]({ ...(i !== undefined ? { index: i } : {}), ...(draftKept === true ? { draftKept: true } : {}), ...(namedSupply === 'path' ? { namedSupply: 'path' } : {}) });
62
72
  }
63
73
  catch {
64
74
  return undefined;
@@ -1,4 +1,5 @@
1
1
  import { appendOwnElement, readOwnDataValue } from '../ownKey.js';
2
+ import { planSettingsContractOf } from '../pluginHooksWire.js';
2
3
  import { refuseBadDisableSkills, refuseDisableSkillsConflict } from '../disableSkillsWire.js';
3
4
  import { ATTACHMENTS_SPEC_KEYS, AttachmentsSpecRefused } from '../attachmentsWireCaps.js';
4
5
  import { REASONING_EFFORT_WORDS, retiredAttachmentsKeyOf } from '../taskRequestWords.js';
@@ -558,7 +559,8 @@ export function refilterHostSettings(request, fresh, lane) {
558
559
  return unjudged();
559
560
  let names;
560
561
  try {
561
- names = hookEnvNamesOf(finalHooks);
562
+ const plan = readOwnDataValue(host, 'hooks');
563
+ names = hookEnvNamesOf(finalHooks, planSettingsContractOf(typeof plan === 'object' && plan !== null ? plan : undefined));
562
564
  }
563
565
  catch {
564
566
  return unjudged();
@@ -2,4 +2,5 @@ export declare function resultErrorCodeOf(frame: unknown): string | undefined;
2
2
  export declare function resultSelectedModelOf(frame: unknown): string | undefined;
3
3
  export declare function resultSalvagedResultOf(frame: unknown): string | undefined;
4
4
  export declare function resultParkFailedReasonOf(frame: unknown): string | undefined;
5
+ export declare function resultTurnAbortedByOf(frame: object | null | undefined): string | undefined;
5
6
  export declare function resultErrorCodeInTextOf(frame: object | null | undefined): true | undefined;
@@ -11,6 +11,9 @@ export function resultSalvagedResultOf(frame) {
11
11
  export function resultParkFailedReasonOf(frame) {
12
12
  return readFrameStringKey(frame, '_sema_park_failed_reason');
13
13
  }
14
+ export function resultTurnAbortedByOf(frame) {
15
+ return readFrameStringKey(frame, '_sema_turn_aborted_by');
16
+ }
14
17
  export function resultErrorCodeInTextOf(frame) {
15
18
  if (!readFrameTrueMark(frame, '_sema_error_code_in_text'))
16
19
  return undefined;
@@ -2,7 +2,7 @@ import { msg, renderMessage } from './i18n/translate.js';
2
2
  import { readBlockedBy, readErrorNumber, readErrorString, readThrownSlot } from './wireFailureShape.js';
3
3
  import { guardedRead, ownDataField, readOwnDataNonEmptyString, readOwnDataValue } from './ownKey.js';
4
4
  import { CORE_RESUME_STARTUP_CAUSES } from './generated/engineFactTables.js';
5
- import { RESUME_CONTEXT_UNAVAILABLE, RESUME_PLACEMENT_MISMATCH, RESUME_PREFLIGHT_REJECTED, RESUME_PRINCIPAL_MISMATCH, RESUME_COMPOSITION_MISMATCH, RESUME_PARENT_CONSTRAINT_MISSING, RESUME_PARENT_CONSTRAINT_MISMATCH, RESUME_CONSTRAINT_UNPROJECTABLE, RESUME_POLICY_FOLD_CODE, PARKED_RESUME_STARTUP_FAILED, isStatusDerivedCoarseCode, RESUME_SESSION_NOT_FOUND, REQUEST_FIELD_CONFLICT, CHECKPOINT_UNSUPPORTED_VERSION, CHECKPOINT_WALLTIME_AXIS_RETIRED, CHECKPOINT_CONFIG_REFUSED, isRefusedParkCode, refusalSaysStillPending, refusalRetriableReading, } from './engineErrorCodes.js';
5
+ import { RESUME_CONTEXT_UNAVAILABLE, RESUME_PLACEMENT_MISMATCH, RESUME_PREFLIGHT_REJECTED, RESUME_PRINCIPAL_MISMATCH, RESUME_COMPOSITION_MISMATCH, RESUME_PARENT_CONSTRAINT_MISSING, RESUME_PARENT_CONSTRAINT_MISMATCH, RESUME_CONSTRAINT_UNPROJECTABLE, RESUME_ISOLATION_SCOPE_MISMATCH, RESUME_AGENT_DEFINITION_MISMATCH, RESUME_POLICY_FOLD_CODE, PARKED_RESUME_STARTUP_FAILED, isStatusDerivedCoarseCode, RESUME_SESSION_NOT_FOUND, REQUEST_FIELD_CONFLICT, CHECKPOINT_UNSUPPORTED_VERSION, CHECKPOINT_WALLTIME_AXIS_RETIRED, CHECKPOINT_CONFIG_REFUSED, isRefusedParkCode, refusalSaysStillPending, refusalRetriableReading, } from './engineErrorCodes.js';
6
6
  import { capForDisplay } from './fleetTaskDesc.js';
7
7
  import { decisionRefusalWayOutContent } from './checkpointRowVerdict.js';
8
8
  import { engineVersionTier } from './supportFloor.js';
@@ -15,6 +15,8 @@ const REFUSAL_COPY_KEYS = Object.freeze({
15
15
  [RESUME_PARENT_CONSTRAINT_MISSING]: 'resume.refusal.parentConstraintMissing',
16
16
  [RESUME_PARENT_CONSTRAINT_MISMATCH]: 'resume.refusal.parentConstraintMismatch',
17
17
  [RESUME_CONSTRAINT_UNPROJECTABLE]: 'resume.refusal.constraintUnprojectable',
18
+ [RESUME_ISOLATION_SCOPE_MISMATCH]: 'resume.refusal.isolationScopeMismatch',
19
+ [RESUME_AGENT_DEFINITION_MISMATCH]: 'resume.refusal.agentDefinitionMismatch',
18
20
  });
19
21
  export const RESUME_REFUSAL_CODES = Object.freeze(Object.keys(REFUSAL_COPY_KEYS));
20
22
  export function resumeRefusalFromError(err) {