@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
@@ -0,0 +1,29 @@
1
+ export declare const LOCAL_ENGINE_STOP_LADDER: Readonly<{
2
+ g: 1000;
3
+ P: 5000;
4
+ H: 20000;
5
+ }>;
6
+ export type StopLadderSignal = 'term' | 'term-2' | 'kill';
7
+ export interface StopLadderState {
8
+ readonly mode: 'idle' | 'forced';
9
+ readonly target: {
10
+ readonly pid: number;
11
+ readonly startedAt?: number;
12
+ };
13
+ readonly t0: number;
14
+ readonly sent: readonly StopLadderSignal[];
15
+ readonly processedAt?: number;
16
+ readonly deadlineAt?: number;
17
+ readonly killedAt?: number;
18
+ }
19
+ export interface StopLadderObservation {
20
+ readonly nowMs: number;
21
+ readonly alive: 'alive' | 'gone' | 'unknown';
22
+ readonly health: object | null;
23
+ }
24
+ export interface StopLadderStepResult {
25
+ readonly state: StopLadderState;
26
+ readonly action: StopLadderSignal | 'wait' | 'done' | 'gave-up';
27
+ readonly waitMs?: number;
28
+ }
29
+ export declare function stopLadderStep(s: StopLadderState, obs: StopLadderObservation): StopLadderStepResult;
@@ -0,0 +1,139 @@
1
+ import { readEngineHealthFacts } from './engineHealthFacts.js';
2
+ import { readOwnDataValue } from './ownKey.js';
3
+ export const LOCAL_ENGINE_STOP_LADDER = Object.freeze({ g: 1000, P: 5000, H: 20000 });
4
+ const SIGTERM_ACTION_ID = 'signal:SIGTERM';
5
+ function own(v, key) {
6
+ if (typeof v !== 'object' || v === null)
7
+ return undefined;
8
+ try {
9
+ return readOwnDataValue(v, key);
10
+ }
11
+ catch {
12
+ return undefined;
13
+ }
14
+ }
15
+ function isTime(v) {
16
+ return typeof v === 'number' && Number.isSafeInteger(v) && v >= 0;
17
+ }
18
+ function isPid(v) {
19
+ return typeof v === 'number' && Number.isSafeInteger(v) && v > 0;
20
+ }
21
+ const SIGNALS = Object.freeze(['term', 'term-2', 'kill']);
22
+ function stateOf(s) {
23
+ const mode = own(s, 'mode');
24
+ if (mode !== 'idle' && mode !== 'forced')
25
+ return undefined;
26
+ const target = own(s, 'target');
27
+ const pid = own(target, 'pid');
28
+ if (!isPid(pid))
29
+ return undefined;
30
+ const startedAt = own(target, 'startedAt');
31
+ const t0 = own(s, 't0');
32
+ if (!isTime(t0))
33
+ return undefined;
34
+ const sentRaw = own(s, 'sent');
35
+ let sent = [];
36
+ try {
37
+ if (!Array.isArray(sentRaw))
38
+ return undefined;
39
+ for (let i = 0; i < sentRaw.length; i++) {
40
+ const x = own(sentRaw, String(i));
41
+ if (!SIGNALS.includes(x))
42
+ return undefined;
43
+ if (!sent.includes(x))
44
+ sent.push(x);
45
+ }
46
+ }
47
+ catch {
48
+ return undefined;
49
+ }
50
+ sent = SIGNALS.filter((x) => sent.includes(x));
51
+ const processedAt = own(s, 'processedAt');
52
+ const deadlineAt = own(s, 'deadlineAt');
53
+ const killedAt = own(s, 'killedAt');
54
+ if (processedAt !== undefined && !isTime(processedAt))
55
+ return undefined;
56
+ if (deadlineAt !== undefined && !isTime(deadlineAt))
57
+ return undefined;
58
+ if (killedAt !== undefined && !isTime(killedAt))
59
+ return undefined;
60
+ return {
61
+ mode,
62
+ target: isTime(startedAt) && startedAt > 0 ? { pid, startedAt } : { pid },
63
+ t0,
64
+ sent,
65
+ ...(processedAt !== undefined ? { processedAt } : {}),
66
+ ...(deadlineAt !== undefined ? { deadlineAt } : {}),
67
+ ...(killedAt !== undefined ? { killedAt } : {}),
68
+ };
69
+ }
70
+ function frozen(s) {
71
+ return Object.freeze({ ...s, target: Object.freeze({ ...s.target }), sent: Object.freeze([...s.sent]) });
72
+ }
73
+ function result(s, action, waitMs) {
74
+ return Object.freeze({ state: frozen(s), action, ...(waitMs !== undefined ? { waitMs: Math.max(0, waitMs) } : {}) });
75
+ }
76
+ export function stopLadderStep(s, obs) {
77
+ const st = stateOf(s);
78
+ if (st === undefined) {
79
+ return Object.freeze({ state: s, action: 'gave-up' });
80
+ }
81
+ const nowMs = own(obs, 'nowMs');
82
+ const alive = own(obs, 'alive');
83
+ if (alive === 'gone')
84
+ return result(st, 'done');
85
+ if (!isTime(nowMs))
86
+ return result(st, 'wait');
87
+ const { g, P, H } = LOCAL_ENGINE_STOP_LADDER;
88
+ const health = own(obs, 'health');
89
+ let facts;
90
+ try {
91
+ facts = typeof health === 'object' && health !== null ? readEngineHealthFacts(health) : undefined;
92
+ }
93
+ catch {
94
+ facts = undefined;
95
+ }
96
+ const draining = facts?.draining;
97
+ let next = st;
98
+ if (draining !== undefined) {
99
+ if (st.mode === 'idle') {
100
+ next = { ...next, deadlineAt: Math.max(st.deadlineAt ?? draining.deadlineAt, draining.deadlineAt) };
101
+ }
102
+ else if (st.processedAt === undefined && st.sent.includes('term') && draining.actionId === SIGTERM_ACTION_ID && draining.since >= st.t0) {
103
+ next = { ...next, processedAt: nowMs };
104
+ }
105
+ }
106
+ const isAlive = alive === 'alive';
107
+ if (next.sent.length === 0) {
108
+ if (isAlive)
109
+ return result({ ...next, sent: ['term'] }, 'term');
110
+ return result(next, nowMs >= next.t0 + H ? 'gave-up' : 'wait', next.t0 + H - nowMs);
111
+ }
112
+ const killAt = next.mode === 'idle'
113
+ ? Math.max(next.t0, next.deadlineAt ?? next.t0) + H
114
+ : next.processedAt !== undefined && next.processedAt <= next.t0 + P
115
+ ? next.processedAt + g + H
116
+ : next.t0 + H;
117
+ if (next.killedAt !== undefined || next.sent.includes('kill')) {
118
+ const giveUpAt = (next.killedAt ?? killAt) + H;
119
+ if (nowMs >= giveUpAt)
120
+ return result(next, 'gave-up');
121
+ return result(next, 'wait', giveUpAt - nowMs);
122
+ }
123
+ if (!isAlive) {
124
+ if (nowMs >= killAt)
125
+ return result(next, 'gave-up');
126
+ return result(next, 'wait', killAt - nowMs);
127
+ }
128
+ if (nowMs >= killAt)
129
+ return result({ ...next, sent: [...next.sent, 'kill'], killedAt: nowMs }, 'kill');
130
+ if (next.mode === 'forced' &&
131
+ next.processedAt !== undefined &&
132
+ nowMs >= next.processedAt + g &&
133
+ draining !== undefined &&
134
+ !next.sent.includes('term-2')) {
135
+ return result({ ...next, sent: [...next.sent.filter((x) => x !== 'kill'), 'term-2'] }, 'term-2');
136
+ }
137
+ const term2At = next.mode === 'forced' && next.processedAt !== undefined && !next.sent.includes('term-2') ? next.processedAt + g : Infinity;
138
+ return result(next, 'wait', Math.min(killAt, term2At) - nowMs);
139
+ }
@@ -0,0 +1,43 @@
1
+ import type { LocalEngineAnchoredProcess, LocalEngineRef } from './localEngineJudge.js';
2
+ import type { LocalEngineOccupancy } from './localEngineOccupancy.js';
3
+ import type { UiLanguage } from './env/uiLanguage.js';
4
+ export declare const LOCAL_ENGINE_SWAP_CAUSES: readonly ["version", "config", "credential", "model-default", "user", "unresponsive"];
5
+ export type LocalEngineSwapCause = (typeof LOCAL_ENGINE_SWAP_CAUSES)[number];
6
+ export interface LocalEngineSwapPolicy {
7
+ readonly credentialAuto?: boolean;
8
+ }
9
+ export declare function localEngineSwapAutoable(cause: LocalEngineSwapCause, serving: boolean, policy?: LocalEngineSwapPolicy): boolean;
10
+ export type EngineSwapCardTarget = LocalEngineRef | LocalEngineAnchoredProcess;
11
+ export type EngineSwapCardUnknown = 'others' | 'inflight' | 'bg' | 'self';
12
+ export interface EngineSwapCardInput {
13
+ readonly cause: LocalEngineSwapCause;
14
+ readonly target: EngineSwapCardTarget;
15
+ readonly running?: string;
16
+ readonly own?: string;
17
+ readonly occupancy: LocalEngineOccupancy;
18
+ readonly bgIds: readonly string[] | null;
19
+ }
20
+ export interface EngineSwapCardOthers {
21
+ readonly total: number;
22
+ readonly midTurn: number;
23
+ }
24
+ export interface EngineSwapCard {
25
+ readonly cause: LocalEngineSwapCause;
26
+ readonly target: EngineSwapCardTarget;
27
+ readonly running?: string;
28
+ readonly own?: string;
29
+ readonly others: EngineSwapCardOthers | null;
30
+ readonly inflight: number | null;
31
+ readonly bgLive: number | null;
32
+ readonly unknown: readonly EngineSwapCardUnknown[];
33
+ readonly forcedWithinMs: number;
34
+ readonly fingerprint: string;
35
+ }
36
+ export declare function engineSwapCardOf(input: EngineSwapCardInput): EngineSwapCard | undefined;
37
+ export interface EngineSwapCardText {
38
+ readonly title: string;
39
+ readonly lines: readonly string[];
40
+ readonly force: string;
41
+ readonly wait: string;
42
+ }
43
+ export declare function engineSwapCardText(card: EngineSwapCard, lang?: UiLanguage): EngineSwapCardText | undefined;
@@ -0,0 +1,205 @@
1
+ import { engineIdentityOf } from './engineIdentity.js';
2
+ import { readOwnDataValue } from './ownKey.js';
3
+ import { displayUntrusted } from './displayUntrusted.js';
4
+ import { LOCAL_ENGINE_STOP_LADDER } from './localEngineStopLadder.js';
5
+ import { msg, renderMessage } from './i18n/translate.js';
6
+ export const LOCAL_ENGINE_SWAP_CAUSES = Object.freeze(['version', 'config', 'credential', 'model-default', 'user', 'unresponsive']);
7
+ function isCause(v) {
8
+ return typeof v === 'string' && LOCAL_ENGINE_SWAP_CAUSES.includes(v);
9
+ }
10
+ function isRecord(v) {
11
+ if (typeof v !== 'object' || v === null)
12
+ return false;
13
+ try {
14
+ return !Array.isArray(v);
15
+ }
16
+ catch {
17
+ return false;
18
+ }
19
+ }
20
+ function isArray(v) {
21
+ try {
22
+ return Array.isArray(v);
23
+ }
24
+ catch {
25
+ return false;
26
+ }
27
+ }
28
+ function own(v, key) {
29
+ if (!isRecord(v) && !isArray(v))
30
+ return undefined;
31
+ try {
32
+ return readOwnDataValue(v, key);
33
+ }
34
+ catch {
35
+ return undefined;
36
+ }
37
+ }
38
+ function isCount(v) {
39
+ return typeof v === 'number' && Number.isSafeInteger(v) && v >= 0;
40
+ }
41
+ function isPid(v) {
42
+ return typeof v === 'number' && Number.isSafeInteger(v) && v > 0;
43
+ }
44
+ export function localEngineSwapAutoable(cause, serving, policy) {
45
+ if (!isCause(cause))
46
+ return false;
47
+ if (serving === false)
48
+ return true;
49
+ if (cause === 'version' || cause === 'user')
50
+ return true;
51
+ return cause === 'credential' && own(policy, 'credentialAuto') === true;
52
+ }
53
+ const FORCED_WITHIN_MS = LOCAL_ENGINE_STOP_LADDER.P + LOCAL_ENGINE_STOP_LADDER.g + LOCAL_ENGINE_STOP_LADDER.H;
54
+ function targetOf(t) {
55
+ const pid = own(t, 'pid');
56
+ if (!isPid(pid))
57
+ return undefined;
58
+ const identity = own(t, 'identity');
59
+ if (isRecord(identity)) {
60
+ const port = own(t, 'port');
61
+ if (typeof port !== 'number' || !Number.isInteger(port) || port < 1 || port > 65535)
62
+ return undefined;
63
+ const id = Object.freeze({ ...engineIdentityOf(identity) });
64
+ const version = own(t, 'version');
65
+ const target = Object.freeze({ pid, port, identity: id, ...(typeof version === 'string' && version.length > 0 ? { version } : {}) });
66
+ return { target, key: id };
67
+ }
68
+ const startedAt = own(t, 'startedAt');
69
+ const target = Object.freeze({ pid, ...(typeof startedAt === 'number' && Number.isFinite(startedAt) && startedAt > 0 ? { startedAt } : {}) });
70
+ return { target, key: engineIdentityOf(target) };
71
+ }
72
+ export function engineSwapCardOf(input) {
73
+ try {
74
+ const cause = own(input, 'cause');
75
+ if (!isCause(cause))
76
+ return undefined;
77
+ const t = targetOf(own(input, 'target'));
78
+ if (t === undefined)
79
+ return undefined;
80
+ const occ = own(input, 'occupancy');
81
+ const unknown = [];
82
+ const o = own(occ, 'others');
83
+ const total = own(o, 'total');
84
+ const midTurn = own(o, 'midTurn');
85
+ const others = own(o, 'known') === true && isCount(total) && isCount(midTurn) ? Object.freeze({ total, midTurn }) : null;
86
+ if (others === null)
87
+ unknown.push('others');
88
+ const inflightRaw = own(occ, 'inflight');
89
+ const inflight = isCount(inflightRaw) ? inflightRaw : null;
90
+ if (inflight === null)
91
+ unknown.push('inflight');
92
+ const bgRaw = own(occ, 'bgLive');
93
+ const idsRaw = own(input, 'bgIds');
94
+ let bgIds = null;
95
+ if (Array.isArray(idsRaw)) {
96
+ const list = [];
97
+ let readable = true;
98
+ for (let i = 0; i < idsRaw.length && readable; i++) {
99
+ const id = own(idsRaw, String(i));
100
+ if (typeof id === 'string')
101
+ list.push(id);
102
+ else
103
+ readable = false;
104
+ }
105
+ bgIds = readable ? list : null;
106
+ }
107
+ const bgLive = isCount(bgRaw) && bgIds !== null && bgIds.length === bgRaw ? bgRaw : null;
108
+ if (bgLive === null) {
109
+ unknown.push('bg');
110
+ bgIds = null;
111
+ }
112
+ const self = own(occ, 'self');
113
+ if (self !== 'idle' && self !== 'busy')
114
+ unknown.push('self');
115
+ const runningRaw = own(input, 'running');
116
+ const ownRaw = own(input, 'own');
117
+ const running = typeof runningRaw === 'string' && runningRaw.length > 0 ? runningRaw : undefined;
118
+ const mine = typeof ownRaw === 'string' && ownRaw.length > 0 ? ownRaw : undefined;
119
+ const k = t.key;
120
+ const fingerprint = JSON.stringify([
121
+ 'local-engine-swap-card/1',
122
+ cause,
123
+ [t.target.pid, k.pid ?? null, k.instanceId ?? null, k.startedAt ?? null],
124
+ running ?? null,
125
+ mine ?? null,
126
+ others === null ? null : [others.total, others.midTurn],
127
+ inflight,
128
+ bgLive,
129
+ bgIds === null ? null : [...bgIds].sort(),
130
+ unknown,
131
+ self === 'idle' || self === 'busy' ? self : null,
132
+ ]);
133
+ return Object.freeze({
134
+ cause,
135
+ target: t.target,
136
+ ...(running !== undefined ? { running } : {}),
137
+ ...(mine !== undefined ? { own: mine } : {}),
138
+ others,
139
+ inflight,
140
+ bgLive,
141
+ unknown: Object.freeze(unknown),
142
+ forcedWithinMs: FORCED_WITHIN_MS,
143
+ fingerprint,
144
+ });
145
+ }
146
+ catch {
147
+ return undefined;
148
+ }
149
+ }
150
+ const TITLE_KEYS = Object.freeze({
151
+ version: 'localEngine.card.title.version',
152
+ config: 'localEngine.card.title.config',
153
+ credential: 'localEngine.card.title.credential',
154
+ 'model-default': 'localEngine.card.title.modelDefault',
155
+ user: 'localEngine.card.title.user',
156
+ unresponsive: 'localEngine.card.title.unresponsive',
157
+ });
158
+ const VERSION_DISPLAY_MAX = 64;
159
+ export function engineSwapCardText(card, lang) {
160
+ try {
161
+ const cause = own(card, 'cause');
162
+ const forcedWithinMs = own(card, 'forcedWithinMs');
163
+ if (!isCause(cause) || !isCount(forcedWithinMs))
164
+ return undefined;
165
+ const say = (key, params) => renderMessage(msg(key, params), lang);
166
+ const lines = [];
167
+ const running = own(card, 'running');
168
+ const mine = own(card, 'own');
169
+ if (typeof running === 'string' && running.length > 0 && typeof mine === 'string' && mine.length > 0) {
170
+ lines.push(say('localEngine.card.versions', { running: displayUntrusted(running, { max: VERSION_DISPLAY_MAX }), own: displayUntrusted(mine, { max: VERSION_DISPLAY_MAX }) }));
171
+ }
172
+ const others = own(card, 'others');
173
+ const total = own(others, 'total');
174
+ const midTurn = own(others, 'midTurn');
175
+ if (isCount(total) && isCount(midTurn))
176
+ lines.push(say(total === 1 ? 'localEngine.card.others.one' : 'localEngine.card.others.other', { total, midTurn }));
177
+ else
178
+ lines.push(say('localEngine.card.others.unknown'));
179
+ const inflight = own(card, 'inflight');
180
+ if (isCount(inflight))
181
+ lines.push(say(inflight === 1 ? 'localEngine.card.inflight.one' : 'localEngine.card.inflight.other', { count: inflight }));
182
+ else
183
+ lines.push(say('localEngine.card.inflight.unknown'));
184
+ const bgLive = own(card, 'bgLive');
185
+ if (isCount(bgLive))
186
+ lines.push(say(bgLive === 1 ? 'localEngine.card.background.one' : 'localEngine.card.background.other', { count: bgLive }));
187
+ else
188
+ lines.push(say('localEngine.card.background.unknown'));
189
+ if (isCount(inflight) && inflight > 0 && isCount(bgLive) && bgLive > 0)
190
+ lines.push(say('localEngine.card.overlap'));
191
+ const unknown = own(card, 'unknown');
192
+ if (Array.isArray(unknown) && unknown.includes('self'))
193
+ lines.push(say('localEngine.card.selfUnknown'));
194
+ lines.push(say('localEngine.card.parked'));
195
+ return Object.freeze({
196
+ title: say(TITLE_KEYS[cause]),
197
+ lines: Object.freeze(lines),
198
+ force: say('localEngine.card.force', { seconds: Math.ceil(forcedWithinMs / 1000) }),
199
+ wait: say('localEngine.card.wait'),
200
+ });
201
+ }
202
+ catch {
203
+ return undefined;
204
+ }
205
+ }
@@ -0,0 +1,8 @@
1
+ export declare const LOCAL_ENGINE_TIMING: Readonly<{
2
+ unansweredWaitMs: 60000;
3
+ prepareTimeoutMs: 10000;
4
+ stopProbeTimeoutMs: 4000;
5
+ crashWindowMs: 300000;
6
+ crashMaxDeaths: 3;
7
+ cooldownMs: readonly [60000, 120000, 240000, 480000, 600000, 600000];
8
+ }>;
@@ -0,0 +1,8 @@
1
+ export const LOCAL_ENGINE_TIMING = Object.freeze({
2
+ unansweredWaitMs: 60000,
3
+ prepareTimeoutMs: 10000,
4
+ stopProbeTimeoutMs: 4000,
5
+ crashWindowMs: 300000,
6
+ crashMaxDeaths: 3,
7
+ cooldownMs: Object.freeze([60000, 120000, 240000, 480000, 600000, 600000]),
8
+ });
@@ -1,6 +1,7 @@
1
1
  import { capForDisplay } from './fleetTaskDesc.js';
2
2
  import { ownDataField } from './ownKey.js';
3
3
  import { isSessionIdPathSegment } from './sessionIdSegment.js';
4
+ import { inSlotReadOf, inValueOf } from './wireFailureShape.js';
4
5
  import { readMcpAuthorization } from './mcpLiveness.js';
5
6
  export const MCP_RECONNECT_OUTCOMES = Object.freeze(['accepted', 'refused', 'unsupported']);
6
7
  export const MCP_RECONNECT_TRANSACTION_NOTICE = 'Reconnecting closes the current connection before dialing again. On a healthy server this is a transaction, ' +
@@ -82,8 +83,11 @@ export function projectMcpReconnectResult(body) {
82
83
  added,
83
84
  removed,
84
85
  };
85
- if ('toolNames' in body && body.toolNames !== undefined) {
86
- const toolNames = stringList(body.toolNames);
86
+ const names = inValueOf(body, 'toolNames');
87
+ if (names.state === 'unproven')
88
+ return undefined;
89
+ if (names.state === 'present' && names.value !== undefined) {
90
+ const toolNames = stringList(names.value);
87
91
  if (toolNames === undefined)
88
92
  return undefined;
89
93
  view.toolNames = toolNames;
@@ -93,8 +97,11 @@ export function projectMcpReconnectResult(body) {
93
97
  const status = projectStatus(body.status);
94
98
  if (status !== undefined)
95
99
  view.status = status;
96
- if ('listingIncomplete' in body && body.listingIncomplete !== undefined) {
97
- const li = projectListingIncomplete(body.listingIncomplete);
100
+ const incomplete = inValueOf(body, 'listingIncomplete');
101
+ if (incomplete.state === 'unproven')
102
+ return undefined;
103
+ if (incomplete.state === 'present' && incomplete.value !== undefined) {
104
+ const li = projectListingIncomplete(incomplete.value);
98
105
  if (li === undefined)
99
106
  return undefined;
100
107
  view.listingIncomplete = li;
@@ -116,7 +123,7 @@ function unsettledVerdict(carrier) {
116
123
  }
117
124
  function isUnsettledBody(raw) {
118
125
  try {
119
- return isRecord(raw) && !('outcome' in raw) && raw.errorCode === UNSETTLED_CODE;
126
+ return isRecord(raw) && inSlotReadOf(raw, 'outcome').state === 'absent' && raw.errorCode === UNSETTLED_CODE;
120
127
  }
121
128
  catch {
122
129
  return false;
@@ -329,7 +329,7 @@ function dropNotice(name, reason, problem, opts, path, transportKind) {
329
329
  : reason === 'elicitation_invalid'
330
330
  ? msg('config.mcp.elicitationInvalid', { name: quoted, where })
331
331
  : reason === 'allow_tools_invalid'
332
- ? msg('config.mcp.allowToolsInvalid', { name: quoted, where, problem: capForDisplay(problem ?? '', DROP_PROBLEM_SHOWN) })
332
+ ? msg('config.mcp.allowToolsInvalid', { name: quoted, where, problem: problem ?? '' })
333
333
  : reason === 'identity_headers_both_set'
334
334
  ? msg('config.mcp.identityHeadersBothSet', { name: quoted, where })
335
335
  : reason === 'transport_invalid'
@@ -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.144.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.147.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
  }
@@ -61,7 +61,7 @@ export interface MemoryEraseConflictRow {
61
61
  id: string;
62
62
  reason: string;
63
63
  }
64
- declare const MEMORY_ERASE_CARRIER_CLASSES: readonly ["projection", "shadow", "indexLine", "quarantineCopy", "planArchive", "planWorkbook", "evidenceBinding", "backendDerived"];
64
+ declare const MEMORY_ERASE_CARRIER_CLASSES: readonly ["projection", "shadow", "indexLine", "quarantineCopy", "clearanceCustody", "planArchive", "planWorkbook", "evidenceBinding", "backendDerived"];
65
65
  export type MemoryEraseCarrierClass = (typeof MEMORY_ERASE_CARRIER_CLASSES)[number];
66
66
  export type MemoryEraseCarrierReading = {
67
67
  removed: number;
@@ -174,6 +174,7 @@ const MEMORY_ERASE_CARRIER_CLASSES = Object.freeze([
174
174
  'shadow',
175
175
  'indexLine',
176
176
  'quarantineCopy',
177
+ 'clearanceCustody',
177
178
  'planArchive',
178
179
  'planWorkbook',
179
180
  'evidenceBinding',
@@ -237,6 +238,10 @@ function eraseResidualsOf(o, lane) {
237
238
  return null;
238
239
  const carriers = {};
239
240
  for (const cls of MEMORY_ERASE_CARRIER_CLASSES) {
241
+ if (!Object.hasOwn(rawCarriers, cls)) {
242
+ carriers[cls] = { unverified: true };
243
+ continue;
244
+ }
240
245
  const answer = carrierAnswerOf(readThrownSlot(rawCarriers, cls, 'data'));
241
246
  if (answer === null)
242
247
  return null;
@@ -1,4 +1,6 @@
1
1
  import { SETTINGS_RESOLVE_CATALOG_DEFAULT_MODEL, type SETTINGS_DEFAULT_ROLE_TIER_LADDER } from '../generated/settingsSchemaFns.js';
2
+ import { SETTINGS_MODEL_PLANE_REFUSAL_CODES } from '../generated/settingsSchemaTables.js';
3
+ import type { UiLanguage } from '../env/uiLanguage.js';
2
4
  export type CatalogDefaultModelsInput = Parameters<typeof SETTINGS_RESOLVE_CATALOG_DEFAULT_MODEL>[0];
3
5
  export type CatalogDefaultSource = 'roles.default' | 'fallback' | `tierGroup.${(typeof SETTINGS_DEFAULT_ROLE_TIER_LADDER)[number]}`;
4
6
  export interface CatalogDefaultDangling {
@@ -22,3 +24,26 @@ export interface CatalogDefaultSelect {
22
24
  }
23
25
  export type CatalogDefaultModel = CatalogDefaultNamed | CatalogDefaultSelect;
24
26
  export declare function resolveCatalogDefaultModel(models: CatalogDefaultModelsInput, has: (name: string) => boolean, fallback: string): CatalogDefaultModel;
27
+ export type CatalogDefaultRefusalCode = Extract<(typeof SETTINGS_MODEL_PLANE_REFUSAL_CODES)[number], 'config.default_model_missing'>;
28
+ export interface CatalogDefaultModelVerdictInput {
29
+ readonly models: CatalogDefaultModelsInput;
30
+ readonly has: (name: string) => boolean;
31
+ readonly fallback: string;
32
+ readonly face: object;
33
+ }
34
+ export interface CatalogDefaultResolvable {
35
+ readonly ok: true;
36
+ readonly default: CatalogDefaultModel;
37
+ }
38
+ export interface CatalogDefaultRefused {
39
+ readonly ok: false;
40
+ readonly code: CatalogDefaultRefusalCode;
41
+ readonly default: CatalogDefaultModel;
42
+ readonly detail: {
43
+ readonly cause: string;
44
+ readonly role: string;
45
+ };
46
+ }
47
+ export type CatalogDefaultModelVerdict = CatalogDefaultResolvable | CatalogDefaultRefused;
48
+ export declare function catalogDefaultModelVerdict(input: CatalogDefaultModelVerdictInput): CatalogDefaultModelVerdict | undefined;
49
+ export declare function catalogDefaultRefusalContent(verdict: CatalogDefaultModelVerdict, lang?: UiLanguage): string | undefined;
@@ -1,4 +1,48 @@
1
1
  import { SETTINGS_RESOLVE_CATALOG_DEFAULT_MODEL } from '../generated/settingsSchemaFns.js';
2
+ import { modelFaceResolvable } from '../coreValuePorts.js';
3
+ import { slotReadOf } from '../wireFailureShape.js';
4
+ import { displayUntrusted } from '../displayUntrusted.js';
5
+ import { msg, renderMessage } from '../i18n/translate.js';
2
6
  export function resolveCatalogDefaultModel(models, has, fallback) {
3
7
  return SETTINGS_RESOLVE_CATALOG_DEFAULT_MODEL(models, has, fallback);
4
8
  }
9
+ const CATALOG_DEFAULT_REFUSAL_CODE = 'config.default_model_missing';
10
+ export function catalogDefaultModelVerdict(input) {
11
+ const { models, has, fallback, face } = input;
12
+ const chain = resolveCatalogDefaultModel(models, has, fallback);
13
+ const verdict = modelFaceResolvable(face, { spec: { modelRole: 'default' } });
14
+ if (verdict === undefined || typeof verdict !== 'object' || verdict === null)
15
+ return undefined;
16
+ const okSlot = slotReadOf(verdict, 'ok');
17
+ if (okSlot.presence !== 'present')
18
+ return undefined;
19
+ if (okSlot.value === true)
20
+ return Object.freeze({ ok: true, default: chain });
21
+ if (okSlot.value !== false)
22
+ return undefined;
23
+ const codeSlot = slotReadOf(verdict, 'code');
24
+ const roleSlot = slotReadOf(verdict, 'role');
25
+ const code = codeSlot.presence === 'present' ? codeSlot.value : undefined;
26
+ const role = roleSlot.presence === 'present' ? roleSlot.value : undefined;
27
+ if (typeof code !== 'string' || code.length === 0 || typeof role !== 'string' || role.length === 0)
28
+ return undefined;
29
+ return Object.freeze({
30
+ ok: false,
31
+ code: CATALOG_DEFAULT_REFUSAL_CODE,
32
+ default: chain,
33
+ detail: Object.freeze({ cause: code, role }),
34
+ });
35
+ }
36
+ export function catalogDefaultRefusalContent(verdict, lang) {
37
+ if (typeof verdict !== 'object' || verdict === null || verdict.ok !== false)
38
+ return undefined;
39
+ const d = verdict.default;
40
+ if (typeof d !== 'object' || d === null)
41
+ return undefined;
42
+ if (d.kind === 'named' && typeof d.name === 'string') {
43
+ return renderMessage(msg('model.catalogDefault.refused.named', { name: displayUntrusted(d.name, { max: 64 }) }), lang);
44
+ }
45
+ if (d.kind === 'select')
46
+ return renderMessage(msg('model.catalogDefault.refused.select'), lang);
47
+ return undefined;
48
+ }
@@ -6,7 +6,9 @@ export interface CutForDisplayResult {
6
6
  readonly shown: string;
7
7
  readonly truncated: boolean;
8
8
  }
9
+ export declare function pairSafeCut(text: string, cut: number): number;
9
10
  export declare function cutForDisplay(text: string, budget: number, opts?: CutForDisplayOptions): CutForDisplayResult;
11
+ export declare function elideMiddleForDisplay(text: string, budget: number): string;
10
12
  export type NoticePresentationAudience = 'user' | 'operator' | 'unknown';
11
13
  export type NoticeOutlet = 'present' | 'absent' | 'unknown';
12
14
  export type NoticeOccurrence = {