@sema-agent/client-core 0.110.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 (176) hide show
  1. package/CHANGELOG.md +169 -0
  2. package/README.md +50 -18
  3. package/dist/abortableSleep.d.ts +7 -0
  4. package/dist/abortableSleep.js +37 -0
  5. package/dist/adapt/arms.js +25 -4
  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 +10 -10
  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/displayUntrusted.d.ts +1 -0
  26. package/dist/displayUntrusted.js +6 -0
  27. package/dist/engineHealthFacts.d.ts +11 -0
  28. package/dist/engineHealthFacts.js +21 -0
  29. package/dist/engineHealthProbeVerdict.d.ts +23 -0
  30. package/dist/engineHealthProbeVerdict.js +115 -0
  31. package/dist/engineNoticeCodes.js +5 -7
  32. package/dist/engineRepoint.d.ts +12 -5
  33. package/dist/engineRepoint.js +44 -19
  34. package/dist/engineRowRef.d.ts +3 -0
  35. package/dist/engineRowRef.js +11 -1
  36. package/dist/engineSwapCrossing.d.ts +57 -0
  37. package/dist/engineSwapCrossing.js +297 -0
  38. package/dist/engineUnavailable.d.ts +44 -0
  39. package/dist/engineUnavailable.js +492 -0
  40. package/dist/eventLeg.js +3 -3
  41. package/dist/generated/sdkFactTables.d.ts +1 -1
  42. package/dist/generated/sdkFactTables.js +1 -0
  43. package/dist/generated/settingsSchemaTables.d.ts +4 -0
  44. package/dist/generated/settingsSchemaTables.js +1 -0
  45. package/dist/hitl/approvalDelivery.d.ts +1 -0
  46. package/dist/hitl/approvalDelivery.js +1 -1
  47. package/dist/hitl/approvalResolution.d.ts +1 -1
  48. package/dist/hitl/approvalResolution.js +2 -1
  49. package/dist/hitl/askGateWire.js +5 -6
  50. package/dist/hitl/decisionRefusal.d.ts +2 -0
  51. package/dist/hitl/decisionRefusal.js +7 -8
  52. package/dist/hitl/decisionRefusalCarrier.d.ts +3 -0
  53. package/dist/hitl/decisionRefusalCarrier.js +348 -0
  54. package/dist/hitl/decisionSend.d.ts +7 -0
  55. package/dist/hitl/decisionSend.js +34 -12
  56. package/dist/hitl/editedApprovalAcceptance.js +1 -1
  57. package/dist/hitl/elicitationRefusal.d.ts +4 -0
  58. package/dist/hitl/elicitationRefusal.js +23 -0
  59. package/dist/hitl/frameRouter.d.ts +2 -2
  60. package/dist/hitl/frameRouter.js +8 -15
  61. package/dist/hitl/gateIdentity.d.ts +5 -0
  62. package/dist/hitl/gateIdentity.js +23 -0
  63. package/dist/hitl/hitlBridge.d.ts +6 -0
  64. package/dist/hitl/hitlBridge.js +10 -4
  65. package/dist/hitl/hitlHostSurface.d.ts +2 -1
  66. package/dist/hitl/hitlHostSurface.js +7 -2
  67. package/dist/hitl/localAllowRedemption.d.ts +67 -0
  68. package/dist/hitl/localAllowRedemption.js +256 -0
  69. package/dist/hitl/parkResolver.js +7 -4
  70. package/dist/hitl/persistedRulesWire.d.ts +16 -0
  71. package/dist/hitl/persistedRulesWire.js +70 -0
  72. package/dist/hitl/planReviewWire.d.ts +3 -0
  73. package/dist/hitl/planReviewWire.js +23 -6
  74. package/dist/hitl/policyDenyCause.d.ts +1 -1
  75. package/dist/hitl/policyDenyCause.js +1 -1
  76. package/dist/hitl/resumeRunningCard.d.ts +1 -0
  77. package/dist/hitl/resumeRunningCard.js +1 -0
  78. package/dist/hitl/screenCardCarriers.d.ts +15 -0
  79. package/dist/hitl/screenCardCarriers.js +41 -0
  80. package/dist/hitl/screenDecisionCards.d.ts +98 -0
  81. package/dist/hitl/screenDecisionCards.js +362 -0
  82. package/dist/hitl/standingRows.d.ts +3 -1
  83. package/dist/hitl/standingRows.js +18 -0
  84. package/dist/hitl/toolApprovalWire.d.ts +30 -8
  85. package/dist/hitl/toolApprovalWire.js +264 -121
  86. package/dist/hooksWireCaps.js +3 -3
  87. package/dist/hostSettingNoticeArm.d.ts +3 -0
  88. package/dist/hostSettingNoticeArm.js +12 -0
  89. package/dist/hostTurnSettings.d.ts +3 -0
  90. package/dist/hostTurnSettings.js +38 -5
  91. package/dist/humanTurnRead.js +11 -1
  92. package/dist/i18n/messages.en.d.ts +129 -0
  93. package/dist/i18n/messages.en.js +135 -7
  94. package/dist/i18n/messages.zh.js +142 -6
  95. package/dist/i18n/translate.d.ts +3 -0
  96. package/dist/i18n/translate.js +78 -10
  97. package/dist/i18n/zh.d.ts +1 -0
  98. package/dist/i18n/zh.js +1 -0
  99. package/dist/index.d.ts +43 -17
  100. package/dist/index.js +30 -12
  101. package/dist/interactiveHalt.js +2 -1
  102. package/dist/interactiveInterrupt.js +20 -2
  103. package/dist/liveModelCatalog.js +2 -2
  104. package/dist/localEngineSeatReading.d.ts +2 -2
  105. package/dist/localEngineSeatReading.js +5 -3
  106. package/dist/localEngineSpawn.d.ts +0 -7
  107. package/dist/localEngineSpawn.js +0 -92
  108. package/dist/localEngineStep.d.ts +2 -2
  109. package/dist/localEngineStep.js +2 -0
  110. package/dist/mcpReconnect.js +3 -3
  111. package/dist/mcpWireCaps.js +1 -1
  112. package/dist/model/engineModelWords.d.ts +3 -0
  113. package/dist/model/engineModelWords.js +13 -0
  114. package/dist/model/subagentModelWord.d.ts +21 -2
  115. package/dist/model/subagentModelWord.js +100 -29
  116. package/dist/modelCapabilityProbe.js +3 -40
  117. package/dist/notifications.d.ts +19 -0
  118. package/dist/notifications.js +114 -12
  119. package/dist/ownKey.d.ts +6 -0
  120. package/dist/ownKey.js +31 -0
  121. package/dist/pendingUserRow.d.ts +4 -0
  122. package/dist/pendingUserRow.js +16 -0
  123. package/dist/permissionsDeclaration.d.ts +1 -0
  124. package/dist/permissionsDeclaration.js +11 -1
  125. package/dist/planReviewCardFacts.d.ts +3 -0
  126. package/dist/planReviewCardFacts.js +52 -2
  127. package/dist/pluginHooksWire.d.ts +9 -1
  128. package/dist/pluginHooksWire.js +40 -6
  129. package/dist/printToolResultFrame.js +4 -2
  130. package/dist/promptBlockedCopy.js +11 -6
  131. package/dist/promptSuggestionBatch.d.ts +7 -0
  132. package/dist/promptSuggestionBatch.js +9 -0
  133. package/dist/promptSuggestionsTail.d.ts +39 -0
  134. package/dist/promptSuggestionsTail.js +116 -0
  135. package/dist/request/taskRequest.js +10 -6
  136. package/dist/requestCoordinate.d.ts +1 -0
  137. package/dist/requestCoordinate.js +13 -0
  138. package/dist/rewindArchiveReading.js +4 -4
  139. package/dist/runCancelContext.d.ts +2 -1
  140. package/dist/runCancelContext.js +1 -0
  141. package/dist/runPermissionModeSwitch.js +2 -2
  142. package/dist/scenarioRefusal.js +11 -13
  143. package/dist/scenarioSkills.js +11 -6
  144. package/dist/seam.d.ts +16 -2
  145. package/dist/seam.js +10 -0
  146. package/dist/seatContract.d.ts +109 -9
  147. package/dist/seatContract.js +218 -15
  148. package/dist/sessionCostReading.d.ts +70 -0
  149. package/dist/sessionCostReading.js +150 -0
  150. package/dist/sessionHooksRoster.d.ts +4 -0
  151. package/dist/sessionHooksRoster.js +158 -0
  152. package/dist/sessionMemoryStatus.js +2 -2
  153. package/dist/sessionReadRedaction.d.ts +7 -0
  154. package/dist/sessionReadRedaction.js +26 -0
  155. package/dist/sessionSyncFileHistory.js +8 -9
  156. package/dist/settingsHooksSalvage.js +2 -1
  157. package/dist/sseIdleTriage.js +2 -1
  158. package/dist/storeDurabilityWord.d.ts +15 -0
  159. package/dist/storeDurabilityWord.js +18 -0
  160. package/dist/storePostureCapability.d.ts +7 -3
  161. package/dist/storePostureCapability.js +69 -39
  162. package/dist/subagent/engineSubagentResume.js +2 -2
  163. package/dist/subagent/engineSubagentTail.js +2 -1
  164. package/dist/subagentContentStore.d.ts +11 -0
  165. package/dist/subagentContentStore.js +28 -2
  166. package/dist/toolResult.d.ts +1 -0
  167. package/dist/toolResult.js +2 -0
  168. package/dist/userAttachmentEnvelope.d.ts +2 -1
  169. package/dist/userAttachmentEnvelope.js +10 -0
  170. package/dist/wireErrorTriage.js +2 -1
  171. package/dist/wireFailureShape.d.ts +4 -0
  172. package/dist/wireFailureShape.js +141 -19
  173. package/dist/wireRefusalCopy.d.ts +6 -5
  174. package/dist/wireRefusalCopy.js +49 -92
  175. package/docs/INTEGRATION-CLIENTS.md +2118 -17
  176. package/package.json +6 -2
@@ -61,14 +61,6 @@ function stringOf(x) {
61
61
  return undefined;
62
62
  }
63
63
  }
64
- function parseJsonLine(t) {
65
- try {
66
- return JSON.parse(t);
67
- }
68
- catch {
69
- return undefined;
70
- }
71
- }
72
64
  function freezeRecord(rows) {
73
65
  const out = {};
74
66
  for (const [k, v] of rows)
@@ -397,90 +389,6 @@ export function localEnginePrincipalSentence(p, lang) {
397
389
  return undefined;
398
390
  }
399
391
  }
400
- const BOOT_REFUSAL_MAX_CHARS = 800;
401
- const BOOT_REFUSAL_MAX_HINTS = 2;
402
- const CONFIG_CODE = /^config\.[A-Za-z0-9_.-]+$/;
403
- function capSentence(s) {
404
- const t = s.trim();
405
- return t.length > BOOT_REFUSAL_MAX_CHARS ? `${t.slice(0, BOOT_REFUSAL_MAX_CHARS)}…` : t;
406
- }
407
- export function engineBootRefusalOf(lines, scrub) {
408
- try {
409
- const clean = (s) => {
410
- try {
411
- const out = scrub(s);
412
- return typeof out === 'string' ? out : undefined;
413
- }
414
- catch {
415
- return undefined;
416
- }
417
- };
418
- const hints = [];
419
- let code;
420
- let hint;
421
- let fatal;
422
- const list = Array.isArray(lines) ? [...lines] : [];
423
- for (const raw of list) {
424
- if (typeof raw !== 'string')
425
- continue;
426
- const line = clean(raw);
427
- if (line === undefined)
428
- continue;
429
- const t = line.trim();
430
- if (!t.startsWith('{'))
431
- continue;
432
- const o = parseJsonLine(t);
433
- if (!isRecord(o))
434
- continue;
435
- const m = own(o, 'msg');
436
- const err = own(o, 'err');
437
- if (m === 'fatal' && typeof err === 'string' && err.trim() !== '') {
438
- const full = clean(err);
439
- const s = full === undefined ? undefined : full.replace(/^\s*Error:\s*/, '');
440
- if (s !== undefined && s.trim() !== '')
441
- fatal = capSentence(s);
442
- continue;
443
- }
444
- const c = own(o, 'code');
445
- const h = own(o, 'hint');
446
- if (typeof c === 'string' && CONFIG_CODE.test(c) && typeof h === 'string' && h.trim() !== '') {
447
- const model = own(o, 'model');
448
- const who = typeof model === 'string' && model !== '' ? `"${model}": ` : '';
449
- const s = clean(`${who}${h}`);
450
- const cc = clean(c);
451
- if (s === undefined || cc === undefined || !CONFIG_CODE.test(cc))
452
- continue;
453
- const sentence = capSentence(s);
454
- code = cc;
455
- const ch = clean(h);
456
- hint = ch === undefined ? undefined : capSentence(ch);
457
- if (hints.includes(sentence))
458
- continue;
459
- hints.push(sentence);
460
- if (hints.length > BOOT_REFUSAL_MAX_HINTS)
461
- hints.shift();
462
- }
463
- }
464
- const parts = [...hints, ...(fatal !== undefined ? [fatal] : [])];
465
- if (parts.length === 0)
466
- return undefined;
467
- return Object.freeze({ ...(code !== undefined ? { code } : {}), ...(hint !== undefined ? { hint } : {}), text: parts.join('\n') });
468
- }
469
- catch {
470
- return undefined;
471
- }
472
- }
473
- export function engineBootRefusalSentence(refusal, lang) {
474
- try {
475
- const text = own(refusal, 'text');
476
- if (typeof text !== 'string' || text.trim() === '')
477
- return undefined;
478
- return renderMessage(msg('localEngine.bootRefusal', { reason: text }), lang);
479
- }
480
- catch {
481
- return undefined;
482
- }
483
- }
484
392
  export function localEngineFirstShareSentence(lang) {
485
393
  return renderMessage(msg('localEngine.firstShare'), lang);
486
394
  }
@@ -14,7 +14,7 @@ export interface LocalEngineStepOccupancy extends LocalEngineOccupancy {
14
14
  readonly bgIds: readonly string[] | null;
15
15
  }
16
16
  export type LocalEngineTarget = EngineSwapCardTarget;
17
- export type LocalEngineStateDownReason = 'lock-unavailable' | 'spawn-failed' | 'spawn-refused' | 'stop-failed' | 'crash-loop' | 'high-water-unreadable';
17
+ export type LocalEngineStateDownReason = 'lock-unavailable' | 'spawn-failed' | 'spawn-refused' | 'stop-failed' | 'crash-loop' | 'high-water-unreadable' | 'exited-once';
18
18
  export interface LocalEngineCauseEntry {
19
19
  readonly cause: LocalEngineSwapCause;
20
20
  readonly fingerprint: string;
@@ -189,7 +189,7 @@ export type LocalEngineEvent = {
189
189
  readonly clean: boolean | 'unknown';
190
190
  readonly nowMs: number;
191
191
  };
192
- export declare const LOCAL_ENGINE_FAIL_CODES: readonly ["local_engine.behind", "local_engine.legacy_below_floor", "local_engine.unresponsive", "local_engine.swap_pending", "local_engine.drain_overdue", "local_engine.unanswered_unverifiable", "local_engine.lock_unavailable", "local_engine.spawn_failed", "local_engine.spawn_refused", "local_engine.stop_failed", "local_engine.crash_loop", "local_engine.high_water_unreadable", "local_engine.principal_unknown"];
192
+ export declare const LOCAL_ENGINE_FAIL_CODES: readonly ["local_engine.behind", "local_engine.legacy_below_floor", "local_engine.unresponsive", "local_engine.swap_pending", "local_engine.drain_overdue", "local_engine.unanswered_unverifiable", "local_engine.lock_unavailable", "local_engine.spawn_failed", "local_engine.spawn_refused", "local_engine.stop_failed", "local_engine.crash_loop", "local_engine.high_water_unreadable", "local_engine.exited_once", "local_engine.principal_unknown"];
193
193
  export type LocalEngineFailCode = (typeof LOCAL_ENGINE_FAIL_CODES)[number];
194
194
  export type LocalEngineNotice = {
195
195
  readonly key: 'versionUnknown';
@@ -18,6 +18,7 @@ export const LOCAL_ENGINE_FAIL_CODES = Object.freeze([
18
18
  'local_engine.stop_failed',
19
19
  'local_engine.crash_loop',
20
20
  'local_engine.high_water_unreadable',
21
+ 'local_engine.exited_once',
21
22
  'local_engine.principal_unknown',
22
23
  ]);
23
24
  function isRecord(v) {
@@ -210,6 +211,7 @@ const DOWN_FAIL = Object.freeze({
210
211
  'stop-failed': 'local_engine.stop_failed',
211
212
  'crash-loop': 'local_engine.crash_loop',
212
213
  'high-water-unreadable': 'local_engine.high_water_unreadable',
214
+ 'exited-once': 'local_engine.exited_once',
213
215
  });
214
216
  function showCard(p, hold, occ, fx, policy) {
215
217
  if (headless(policy)) {
@@ -1,12 +1,12 @@
1
1
  import { capForDisplay } from './fleetTaskDesc.js';
2
+ import { STEERING_NOT_RUNNING } from './engineErrorCodes.js';
2
3
  import { ownDataField } from './ownKey.js';
3
4
  import { isSessionIdPathSegment } from './sessionIdSegment.js';
4
5
  import { inSlotReadOf, inValueOf, slotReadOf } from './wireFailureShape.js';
5
6
  import { readMcpAuthorization } from './mcpLiveness.js';
6
7
  import { msg, renderMessage } from './i18n/translate.js';
7
8
  export const MCP_RECONNECT_OUTCOMES = Object.freeze(['accepted', 'refused', 'unsupported']);
8
- export const MCP_RECONNECT_TRANSACTION_NOTICE = 'Reconnecting closes the current connection before dialing again. On a healthy server this is a transaction, ' +
9
- 'not a refresh: a failed re-dial leaves the server down and withdraws its tools from the model until a later re-dial succeeds.';
9
+ export const MCP_RECONNECT_TRANSACTION_NOTICE = renderMessage(msg('session.mcpReconnect.transaction'));
10
10
  export const MCP_RECONNECT_UNSETTLED_NOTICE = renderMessage(msg('session.mcpReconnect.unsettled'));
11
11
  const UNSETTLED_CODE = 'state.mcp_reconnect_unsettled';
12
12
  const _sdkClientIsAnInjection = [true];
@@ -141,7 +141,7 @@ export function classifyMcpReconnectFailure(e) {
141
141
  return unsettledVerdict(e);
142
142
  if (code === 'steering.invalid_content')
143
143
  return { kind: 'invalid' };
144
- if (code === 'steering.not_running')
144
+ if (code === STEERING_NOT_RUNNING)
145
145
  return { kind: 'not_running' };
146
146
  if (typeof code === 'string' && code.startsWith('capability.'))
147
147
  return { kind: 'unsupported', reason: 'capability' };
@@ -448,6 +448,6 @@ export function mcpAssertionHeaderNotSentNotice(specs) {
448
448
  const parts = distinct.slice(0, ASSERTION_NOTICE_NAMES_SHOWN).map((x) => `"${x}"`);
449
449
  if (distinct.length > ASSERTION_NOTICE_NAMES_SHOWN)
450
450
  parts.push(`+${distinct.length - ASSERTION_NOTICE_NAMES_SHOWN} more`);
451
- return (`MCP servers that declare an assertion header (assertionHeader): ${parts.join(', ')} — server versions up to 7.147.0 accept this setting but do not send the header, ` +
451
+ return (`MCP servers that declare an assertion header (assertionHeader): ${parts.join(', ')} — server versions up to 7.148.0 accept this setting but do not send the header, ` +
452
452
  'and this client cannot tell whether the engine it uses sends it; a connector that requires the header will refuse requests from these servers');
453
453
  }
@@ -0,0 +1,3 @@
1
+ export type EngineModelWordKind = 'tier' | 'cc-alias' | 'best' | 'default';
2
+ export declare const ENGINE_MODEL_WORDS: readonly string[];
3
+ export declare function engineModelWordKindOf(word: string): EngineModelWordKind | undefined;
@@ -0,0 +1,13 @@
1
+ import { CC_TIER_ALIASES, TIER_ORDER } from './tierVocabulary.js';
2
+ export const ENGINE_MODEL_WORDS = Object.freeze([...TIER_ORDER, ...Object.keys(CC_TIER_ALIASES), 'best', 'default']);
3
+ export function engineModelWordKindOf(word) {
4
+ if (typeof word !== 'string')
5
+ return undefined;
6
+ if (TIER_ORDER.includes(word))
7
+ return 'tier';
8
+ if (Object.hasOwn(CC_TIER_ALIASES, word))
9
+ return 'cc-alias';
10
+ if (word === 'best')
11
+ return 'best';
12
+ return word === 'default' ? 'default' : undefined;
13
+ }
@@ -1,9 +1,9 @@
1
1
  import { type LiveModelCatalog } from '../liveModelCatalog.js';
2
2
  import type { UiLanguage } from '../env/uiLanguage.js';
3
- export type SubagentModelWordKind = 'inherit' | 'catalog' | 'tier' | 'cc-alias' | 'best' | 'model-id' | 'passthrough' | 'catalog-unknown' | 'ambiguous' | 'unbound';
3
+ export type SubagentModelWordKind = 'inherit' | 'catalog' | 'tier' | 'cc-alias' | 'best' | 'default' | 'model-id' | 'passthrough' | 'catalog-unknown' | 'ambiguous' | 'unbound';
4
4
  export type SubagentModelWordProblem = 'tiers-inert' | 'chain-unbound' | 'binding-not-in-catalog';
5
5
  export interface SubagentModelLocalEngine {
6
- readonly engine: 'started-by-this-process';
6
+ readonly engine: 'reads-this-config' | 'started-by-this-process';
7
7
  readonly tiers: Readonly<Record<string, string>> | undefined;
8
8
  readonly pool?: readonly {
9
9
  readonly name: string;
@@ -29,3 +29,22 @@ export interface SubagentModelWordReading {
29
29
  }
30
30
  export declare function resolveSubagentModelWord(input: SubagentModelWordInput | null | undefined): SubagentModelWordReading;
31
31
  export declare function subagentModelWordProblemLine(word: string, reading: SubagentModelWordReading, lang?: UiLanguage): string | undefined;
32
+ export declare function subagentModelCallRefusalReason(word: string, reading: SubagentModelWordReading, lang?: UiLanguage): string | undefined;
33
+ export type SubagentModelAdmission = {
34
+ readonly verdict: 'accepted';
35
+ readonly why: 'not_sent';
36
+ } | {
37
+ readonly verdict: 'accepted';
38
+ readonly why: 'served';
39
+ readonly model: string;
40
+ } | {
41
+ readonly verdict: 'refused';
42
+ readonly why: 'not_listed' | 'not_served' | 'disabled';
43
+ readonly model: string;
44
+ } | {
45
+ readonly verdict: 'unknown';
46
+ readonly why: 'catalog_absent' | 'catalog_unreadable' | 'catalog_incomplete' | 'reserved_word';
47
+ readonly model: string;
48
+ };
49
+ export declare function subagentModelAdmissionOf(input: SubagentModelWordInput | null | undefined): SubagentModelAdmission;
50
+ export declare function subagentModelAdmissionLine(word: string, admission: SubagentModelAdmission, lang?: UiLanguage): string | undefined;
@@ -1,8 +1,10 @@
1
1
  import { CC_TIER_ALIASES, TIER_ORDER } from './tierVocabulary.js';
2
- import { liveModelRowsOf } from '../liveModelCatalog.js';
2
+ import { ENGINE_MODEL_WORDS, engineModelWordKindOf } from './engineModelWords.js';
3
+ import { liveModelRowsOf, modelAcceptanceOf } from '../liveModelCatalog.js';
3
4
  import { quoteUntrustedForSentence } from '../displayUntrusted.js';
4
5
  import { msg, renderMessage } from '../i18n/translate.js';
5
- const STARTED_BY_THIS_PROCESS = 'started-by-this-process';
6
+ const READS_THIS_CONFIG = 'reads-this-config';
7
+ const LEGACY_LOCAL_ENGINE_WORD = 'started-by-this-process';
6
8
  function ownData(v, key) {
7
9
  if (v === null || typeof v !== 'object')
8
10
  return undefined;
@@ -46,7 +48,8 @@ function localOf(input) {
46
48
  const local = ownData(input, 'local');
47
49
  if (local === null || typeof local !== 'object')
48
50
  return undefined;
49
- return ownData(local, 'engine') === STARTED_BY_THIS_PROCESS ? local : undefined;
51
+ const engine = ownData(local, 'engine');
52
+ return engine === READS_THIS_CONFIG || engine === LEGACY_LOCAL_ENGINE_WORD ? local : undefined;
50
53
  }
51
54
  function catalogOf(input, local) {
52
55
  const live = ownData(input, 'liveCatalog');
@@ -115,14 +118,7 @@ function tiersOf(local) {
115
118
  }
116
119
  return out;
117
120
  }
118
- const BUILTIN_VOCAB = [...TIER_ORDER, ...Object.keys(CC_TIER_ALIASES), 'best'];
119
- function builtinKindOf(w) {
120
- if (TIER_ORDER.includes(w))
121
- return 'tier';
122
- if (Object.hasOwn(CC_TIER_ALIASES, w))
123
- return 'cc-alias';
124
- return w === 'best' ? 'best' : undefined;
125
- }
121
+ const builtinKindOf = engineModelWordKindOf;
126
122
  class BrokenBinding {
127
123
  }
128
124
  function landingOf(word, kind, tiers, cat) {
@@ -203,21 +199,22 @@ function resolveIn(input) {
203
199
  return { kind, model: w, landing: { name: l.name, via: l.via, source: 'local-config' }, label: `${l.name} (${label})` };
204
200
  };
205
201
  const asCatalog = (name) => ({ kind: 'catalog', model: name, label: name });
202
+ const asDefault = (w) => ({ kind: 'default', model: w, label: w });
203
+ const vocab = (w, b) => (b === 'default' ? asDefault(w) : tierClass(w, b));
206
204
  const classify = (k) => {
207
205
  if (cat?.nameSet.has(k))
208
206
  return asCatalog(k);
209
- const b = builtinKindOf(k);
210
- return tierClass(k, b ?? 'tier');
207
+ return vocab(k, builtinKindOf(k) ?? 'tier');
211
208
  };
212
209
  if (cat?.nameSet.has(word))
213
210
  return freezeReading(asCatalog(word));
214
211
  const exact = builtinKindOf(word);
215
212
  if (exact !== undefined)
216
- return freezeReading(tierClass(word, exact));
213
+ return freezeReading(vocab(word, exact));
217
214
  if (tiers?.has(word))
218
215
  return freezeReading(tierClass(word, 'tier'));
219
216
  const lower = word.toLowerCase();
220
- const space = new Set([...(cat?.names ?? []), ...BUILTIN_VOCAB, ...customTierKeys]);
217
+ const space = new Set([...(cat?.names ?? []), ...ENGINE_MODEL_WORDS, ...customTierKeys]);
221
218
  const ciMatches = [...space].filter((k) => k.toLowerCase() === lower);
222
219
  if (builtinKindOf(lower) !== undefined) {
223
220
  return freezeReading(ciMatches.length === 1 ? classify(ciMatches[0]) : { kind: 'ambiguous' });
@@ -241,21 +238,95 @@ export function resolveSubagentModelWord(input) {
241
238
  return freezeReading(word === '' ? { kind: 'inherit' } : { kind: 'catalog-unknown', model: word, label: word });
242
239
  }
243
240
  }
244
- export function subagentModelWordProblemLine(word, reading, lang) {
245
- const ref = problemRefOf(word, reading);
246
- return ref === undefined ? undefined : renderMessage(ref, lang);
247
- }
248
- function problemRefOf(word, reading) {
241
+ function wordCauseOf(reading) {
249
242
  const kind = ownData(reading, 'kind');
250
- if (kind !== 'unbound' && kind !== 'ambiguous')
251
- return undefined;
252
- const quoted = quoteUntrustedForSentence(typeof word === 'string' ? word.trim() : '', 80) ?? '""';
253
243
  if (kind === 'ambiguous')
254
- return msg('model.subagent.ambiguous', { word: quoted });
244
+ return 'ambiguous';
245
+ if (kind !== 'unbound')
246
+ return undefined;
255
247
  const problem = ownData(reading, 'problem');
256
- if (problem === 'tiers-inert')
257
- return msg('model.subagent.tiersInert', { word: quoted });
258
- if (problem === 'binding-not-in-catalog')
259
- return msg('model.subagent.bindingNotInCatalog', { word: quoted });
260
- return msg('model.subagent.chainUnbound', { word: quoted });
248
+ return problem === 'tiers-inert' || problem === 'binding-not-in-catalog' ? problem : 'chain-unbound';
249
+ }
250
+ const PROBLEM_LINE_KEYS = Object.freeze({
251
+ ambiguous: 'model.subagent.ambiguous',
252
+ 'tiers-inert': 'model.subagent.tiersInert',
253
+ 'chain-unbound': 'model.subagent.chainUnbound',
254
+ 'binding-not-in-catalog': 'model.subagent.bindingNotInCatalog',
255
+ });
256
+ const CALL_REFUSAL_KEYS = Object.freeze({
257
+ ambiguous: 'model.subagent.call.ambiguous',
258
+ 'tiers-inert': 'model.subagent.call.tiersInert',
259
+ 'chain-unbound': 'model.subagent.call.chainUnbound',
260
+ 'binding-not-in-catalog': 'model.subagent.call.bindingNotInCatalog',
261
+ });
262
+ const WORD_SHOWN_MAX = 80;
263
+ function quotedWord(word) {
264
+ return quoteUntrustedForSentence(typeof word === 'string' ? word.trim() : '', WORD_SHOWN_MAX) ?? '""';
265
+ }
266
+ export function subagentModelWordProblemLine(word, reading, lang) {
267
+ const cause = wordCauseOf(reading);
268
+ return cause === undefined ? undefined : renderMessage(msg(PROBLEM_LINE_KEYS[cause], { word: quotedWord(word) }), lang);
269
+ }
270
+ export function subagentModelCallRefusalReason(word, reading, lang) {
271
+ try {
272
+ const cause = wordCauseOf(reading);
273
+ if (cause === undefined)
274
+ return undefined;
275
+ const label = ownData(reading, 'label');
276
+ const tier = typeof label === 'string' && label.trim() !== '' ? label : word;
277
+ return renderMessage(msg(CALL_REFUSAL_KEYS[cause], { word: quotedWord(word), tier: quotedWord(tier) }), lang);
278
+ }
279
+ catch {
280
+ return undefined;
281
+ }
282
+ }
283
+ const notSent = () => Object.freeze({ verdict: 'accepted', why: 'not_sent' });
284
+ const isVocabKind = (k) => k === 'tier' || k === 'cc-alias' || k === 'best' || k === 'default';
285
+ function admissionIn(input) {
286
+ const reading = resolveIn(input);
287
+ const model = reading.model;
288
+ if (model === undefined)
289
+ return notSent();
290
+ const live = ownData(input, 'liveCatalog');
291
+ if (live === undefined || live === null)
292
+ return Object.freeze({ verdict: 'unknown', why: 'catalog_absent', model });
293
+ const a = modelAcceptanceOf(model, live);
294
+ if (a.verdict === 'accepted')
295
+ return Object.freeze({ verdict: 'accepted', why: 'served', model });
296
+ if (a.verdict === 'refused') {
297
+ if (a.why === 'not_at_mentionable')
298
+ return Object.freeze({ verdict: 'accepted', why: 'served', model });
299
+ if (a.why === 'disabled')
300
+ return Object.freeze({ verdict: 'refused', why: 'disabled', model });
301
+ return Object.freeze({ verdict: 'refused', why: isVocabKind(reading.kind) ? 'not_served' : 'not_listed', model });
302
+ }
303
+ return Object.freeze({ verdict: 'unknown', why: a.why === 'model_absent' ? 'catalog_unreadable' : a.why, model });
304
+ }
305
+ export function subagentModelAdmissionOf(input) {
306
+ try {
307
+ return admissionIn(input);
308
+ }
309
+ catch {
310
+ const w = ownData(input, 'word');
311
+ const word = typeof w === 'string' ? w.trim() : '';
312
+ return word === '' ? notSent() : Object.freeze({ verdict: 'unknown', why: 'catalog_unreadable', model: word });
313
+ }
314
+ }
315
+ const ADMISSION_LINE_KEYS = Object.freeze({
316
+ not_listed: 'model.subagent.refused.notListed',
317
+ not_served: 'model.subagent.refused.notServed',
318
+ disabled: 'model.subagent.refused.disabled',
319
+ });
320
+ export function subagentModelAdmissionLine(word, admission, lang) {
321
+ try {
322
+ if (ownData(admission, 'verdict') !== 'refused')
323
+ return undefined;
324
+ const why = ownData(admission, 'why');
325
+ if (why !== 'not_listed' && why !== 'not_served' && why !== 'disabled')
326
+ return undefined;
327
+ return renderMessage(msg(ADMISSION_LINE_KEYS[why], { word: quotedWord(word) }), lang);
328
+ }
329
+ catch {
330
+ return undefined;
331
+ }
261
332
  }
@@ -1,5 +1,5 @@
1
1
  import { displayUntrusted } from './displayUntrusted.js';
2
- import { abortableSleep } from './abortableSleep.js';
2
+ import { requestDeadline } from './abortableSleep.js';
3
3
  import { causeSlotProtected, walkCauseChain } from './engineWireFor.js';
4
4
  import { readThrownSlot } from './wireFailureShape.js';
5
5
  import { guardedRead, readOwnDataValue } from './ownKey.js';
@@ -522,45 +522,8 @@ function shownCause(e, redact) {
522
522
  const shown = displayUntrusted(masked, { max: 160 });
523
523
  return shown.trim() === '' ? undefined : shown;
524
524
  }
525
- const MAX_TIMER_MS = 2_147_483_647;
526
- function probeDeadline(ms, cancel) {
527
- const ctl = new AbortController();
528
- const stop = new AbortController();
529
- let expired = false;
530
- const gone = new Promise((_resolve, reject) => {
531
- const fire = () => reject(Object.assign(new Error('aborted'), { name: 'AbortError' }));
532
- if (ctl.signal.aborted)
533
- fire();
534
- else
535
- ctl.signal.addEventListener('abort', fire, { once: true });
536
- });
537
- gone.catch(() => undefined);
538
- void abortableSleep(Math.min(ms, MAX_TIMER_MS), stop.signal).then(() => {
539
- if (stop.signal.aborted)
540
- return;
541
- expired = true;
542
- ctl.abort();
543
- });
544
- const onCancel = () => ctl.abort();
545
- if (cancel !== undefined) {
546
- if (cancel.aborted)
547
- ctl.abort();
548
- else
549
- cancel.addEventListener('abort', onCancel, { once: true });
550
- }
551
- return {
552
- signal: ctl.signal,
553
- expired: () => expired,
554
- abort: () => {
555
- stop.abort();
556
- cancel?.removeEventListener('abort', onCancel);
557
- ctl.abort();
558
- },
559
- race: (p) => Promise.race([p, gone]),
560
- };
561
- }
562
525
  async function getCatalogText(fetchIt, url, headers, timeoutMs, cancel) {
563
- const d = probeDeadline(timeoutMs, cancel);
526
+ const d = requestDeadline(timeoutMs, cancel);
564
527
  try {
565
528
  const res = await d.race(fetchIt(url, { method: 'GET', headers, signal: d.signal }));
566
529
  let text = '';
@@ -577,7 +540,7 @@ async function getCatalogText(fetchIt, url, headers, timeoutMs, cancel) {
577
540
  }
578
541
  }
579
542
  async function postForFirstToken(fetchIt, api, url, path, headers, body, deadlineMs, cancel, now, redact) {
580
- const d = probeDeadline(deadlineMs, cancel);
543
+ const d = requestDeadline(deadlineMs, cancel);
581
544
  const startedAt = now();
582
545
  try {
583
546
  const res = await d.race(fetchIt(url, { method: 'POST', headers, body, signal: d.signal }));
@@ -1,4 +1,5 @@
1
1
  import type { PlanReviewOutcomeMeta } from './hitl/planReviewWire.js';
2
+ import type { UiLanguage } from './env/uiLanguage.js';
2
3
  import type { SubmissionKind } from './request/submissionIdentity.js';
3
4
  export interface TaskNotificationFields {
4
5
  taskId: string;
@@ -87,6 +88,19 @@ export declare function installNotificationQueuePort(port: NotificationQueuePort
87
88
  export declare function notificationQueuePortMisses(): number;
88
89
  export declare function _resetNotificationQueuePortForTest(): void;
89
90
  export declare function enqueuePlanReviewOutcome(value: string, meta?: PlanReviewOutcomeMeta): boolean;
91
+ export type ResupplyTruncatedSource = 'task_notification' | 'workflow_complete';
92
+ export declare function resupplyTruncatedSentence(facts: {
93
+ readonly bytes: number;
94
+ readonly droppedKeys: readonly string[];
95
+ } | null | undefined, lang?: UiLanguage): string | undefined;
96
+ export interface ResupplyTruncatedArmBody {
97
+ readonly source: ResupplyTruncatedSource;
98
+ readonly taskId: string;
99
+ readonly bytes: number;
100
+ readonly droppedKeys: readonly string[];
101
+ readonly text: string;
102
+ }
103
+ export declare function resupplyTruncatedArmBody(carrier: object | null | undefined, source: ResupplyTruncatedSource, taskId: string): ResupplyTruncatedArmBody | undefined;
90
104
  export declare function dropQueuedNotificationsForRun(taskId: string): number;
91
105
  export declare function markEngineWorkflowNotified(runId: string): void;
92
106
  export declare function isEngineWorkflowNotified(runId: string): boolean;
@@ -104,6 +118,7 @@ export type WorkflowRunTerminalReading = {
104
118
  readonly result?: string;
105
119
  readonly error?: string;
106
120
  readonly pointer: 'absent';
121
+ readonly truncated?: true;
107
122
  } | {
108
123
  readonly state: 'unknown';
109
124
  readonly why: 'body_unreadable' | 'status_unreadable' | 'status_unrecognized';
@@ -140,6 +155,7 @@ export interface EngineWorkflowCompletion {
140
155
  status: 'completed' | 'failed';
141
156
  summary: string;
142
157
  completionId?: string;
158
+ diagnostics?: string;
143
159
  }
144
160
  export declare function enqueueBgChildNotification(raw: {
145
161
  taskId: string;
@@ -149,6 +165,9 @@ export declare function enqueueBgChildNotification(raw: {
149
165
  completionId?: string;
150
166
  }): void;
151
167
  export declare function enqueueEngineWorkflowNotification(raw: EngineWorkflowCompletion): void;
168
+ export declare function workflowRecordRefOf(diagnostics: string | undefined): string | undefined;
169
+ export declare function takeWorkflowPointerSupplement(runId: string, status: string, diagnostics: string | undefined, completionId?: string): Readonly<TaskNotificationFields> | undefined;
170
+ export declare function settleWorkflowPointerOwed(runId: string): void;
152
171
  export declare function _resetEngineTaskNotificationForTest(): void;
153
172
  export declare function _tickWatchOnceForTest(nowMs?: number): Promise<void>;
154
173
  export declare function _setWatcherTimingForTest(o: {