@sema-agent/client-core 0.108.0 → 0.110.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 (179) hide show
  1. package/CHANGELOG.md +294 -0
  2. package/README.md +77 -40
  3. package/dist/adapt/arms.js +41 -13
  4. package/dist/adapt/textStream.d.ts +2 -0
  5. package/dist/adapt/textStream.js +37 -16
  6. package/dist/adapter/activeRunSelfHeal.js +1 -1
  7. package/dist/adapter/downstream/eventToSdkMessage.js +11 -5
  8. package/dist/agentSession/engineAgentRegistryRead.js +2 -0
  9. package/dist/bashExitReading.d.ts +12 -0
  10. package/dist/bashExitReading.js +44 -0
  11. package/dist/checkpointRowVerdict.d.ts +1 -1
  12. package/dist/checkpointRowVerdict.js +4 -2
  13. package/dist/compensations.js +1 -1
  14. package/dist/declared/supportFloorDeclared.js +1 -1
  15. package/dist/displayUntrusted.js +132 -14
  16. package/dist/engineAgentAbsence.d.ts +2 -0
  17. package/dist/engineAgentAbsence.js +28 -0
  18. package/dist/engineErrorCodes.d.ts +7 -0
  19. package/dist/engineErrorCodes.js +7 -0
  20. package/dist/engineHealthFacts.d.ts +26 -0
  21. package/dist/engineHealthFacts.js +63 -4
  22. package/dist/engineInlineTaskStats.d.ts +4 -3
  23. package/dist/engineInlineTaskStats.js +18 -2
  24. package/dist/engineNoticeCodes.d.ts +138 -0
  25. package/dist/engineNoticeCodes.js +662 -55
  26. package/dist/engineRepoint.d.ts +140 -0
  27. package/dist/engineRepoint.js +285 -0
  28. package/dist/engineRowRef.js +2 -0
  29. package/dist/engineSessionMessages.d.ts +2 -1
  30. package/dist/engineSessionMessages.js +5 -0
  31. package/dist/errorSupplementRoles.js +5 -1
  32. package/dist/fleet/fleetProjection.js +3 -2
  33. package/dist/fleetTaskDesc.js +3 -3
  34. package/dist/generated/engineFactTables.d.ts +3 -0
  35. package/dist/generated/engineFactTables.js +18 -0
  36. package/dist/generated/engineNoticeTables.js +3 -0
  37. package/dist/generated/sdkFactTables.d.ts +1 -0
  38. package/dist/generated/sdkFactTables.js +4 -0
  39. package/dist/hitl/approvalAskers.d.ts +6 -0
  40. package/dist/hitl/approvalAskers.js +30 -0
  41. package/dist/hitl/approvalCardReasons.js +25 -4
  42. package/dist/hitl/approvalRequestFrameReading.d.ts +21 -0
  43. package/dist/hitl/approvalRequestFrameReading.js +90 -0
  44. package/dist/hitl/approvalResolution.d.ts +8 -1
  45. package/dist/hitl/approvalResolution.js +4 -0
  46. package/dist/hitl/approvalsFeed.js +1 -1
  47. package/dist/hitl/askGateWire.js +0 -2
  48. package/dist/hitl/askParkRowRouting.js +5 -2
  49. package/dist/hitl/automaticAnswerVerdict.d.ts +5 -2
  50. package/dist/hitl/automaticAnswerVerdict.js +18 -4
  51. package/dist/hitl/decisionConflict.d.ts +2 -1
  52. package/dist/hitl/decisionConflict.js +10 -4
  53. package/dist/hitl/decisionRefusal.js +1 -0
  54. package/dist/hitl/decisionSend.d.ts +3 -0
  55. package/dist/hitl/decisionSend.js +29 -11
  56. package/dist/hitl/editedApprovalAcceptance.d.ts +25 -0
  57. package/dist/hitl/editedApprovalAcceptance.js +26 -0
  58. package/dist/hitl/frameRouter.js +13 -19
  59. package/dist/hitl/gateLedger.d.ts +0 -4
  60. package/dist/hitl/gateLedger.js +0 -19
  61. package/dist/hitl/hitlBridge.d.ts +5 -0
  62. package/dist/hitl/hitlBridge.js +13 -9
  63. package/dist/hitl/hitlHostSurface.d.ts +1 -0
  64. package/dist/hitl/hitlHostSurface.js +7 -2
  65. package/dist/hitl/hostWithdrawal.d.ts +15 -0
  66. package/dist/hitl/hostWithdrawal.js +38 -0
  67. package/dist/hitl/livePendingAsk.js +17 -16
  68. package/dist/hitl/localAllowRule.js +2 -1
  69. package/dist/hitl/noAllowCause.d.ts +1 -1
  70. package/dist/hitl/noAllowCause.js +4 -2
  71. package/dist/hitl/parkExpiryJudgements.js +26 -1
  72. package/dist/hitl/parkOwnership.d.ts +2 -0
  73. package/dist/hitl/parkOwnership.js +48 -8
  74. package/dist/hitl/parkResolver.js +32 -16
  75. package/dist/hitl/parkedUnresumable.d.ts +13 -0
  76. package/dist/hitl/parkedUnresumable.js +80 -0
  77. package/dist/hitl/permissionRuleScope.d.ts +4 -0
  78. package/dist/hitl/permissionRuleScope.js +31 -0
  79. package/dist/hitl/persistedRulesWire.d.ts +2 -0
  80. package/dist/hitl/persistedRulesWire.js +13 -12
  81. package/dist/hitl/planReviewWire.js +14 -4
  82. package/dist/hitl/sessionAllowRoute.js +5 -4
  83. package/dist/hitl/sessionPolicyWire.js +6 -4
  84. package/dist/hitl/standingRows.d.ts +2 -5
  85. package/dist/hitl/standingRows.js +30 -15
  86. package/dist/hitl/toolApprovalWire.d.ts +42 -9
  87. package/dist/hitl/toolApprovalWire.js +267 -44
  88. package/dist/hooksWireCaps.js +35 -4
  89. package/dist/hostSettingsSource.js +2 -0
  90. package/dist/hostTurnSettings.d.ts +10 -4
  91. package/dist/hostTurnSettings.js +112 -5
  92. package/dist/i18n/messages.en.d.ts +251 -0
  93. package/dist/i18n/messages.en.js +254 -2
  94. package/dist/i18n/messages.zh.js +264 -2
  95. package/dist/index.d.ts +48 -12
  96. package/dist/index.js +29 -7
  97. package/dist/inheritEnvCapability.js +2 -0
  98. package/dist/inputAuthor.d.ts +16 -0
  99. package/dist/inputAuthor.js +44 -0
  100. package/dist/interruptRefusalNote.d.ts +2 -0
  101. package/dist/interruptRefusalNote.js +17 -0
  102. package/dist/liveModelCatalog.d.ts +2 -0
  103. package/dist/liveModelCatalog.js +21 -7
  104. package/dist/liveQuestionStore.d.ts +4 -1
  105. package/dist/liveQuestionStore.js +12 -3
  106. package/dist/localEngineJudge.d.ts +75 -0
  107. package/dist/localEngineJudge.js +242 -0
  108. package/dist/localEngineOccupancy.d.ts +88 -0
  109. package/dist/localEngineOccupancy.js +269 -0
  110. package/dist/localEngineSeatReading.d.ts +29 -0
  111. package/dist/localEngineSeatReading.js +294 -0
  112. package/dist/localEngineSpawn.d.ts +113 -0
  113. package/dist/localEngineSpawn.js +486 -0
  114. package/dist/localEngineStep.d.ts +286 -0
  115. package/dist/localEngineStep.js +1086 -0
  116. package/dist/localEngineStopLadder.d.ts +29 -0
  117. package/dist/localEngineStopLadder.js +139 -0
  118. package/dist/localEngineSwapCard.d.ts +43 -0
  119. package/dist/localEngineSwapCard.js +205 -0
  120. package/dist/localEngineTiming.d.ts +8 -0
  121. package/dist/localEngineTiming.js +8 -0
  122. package/dist/mcpEngineLeg.d.ts +3 -0
  123. package/dist/mcpEngineLeg.js +38 -1
  124. package/dist/mcpPanel.js +2 -0
  125. package/dist/mcpReconnect.d.ts +9 -1
  126. package/dist/mcpReconnect.js +132 -20
  127. package/dist/mcpWireCaps.js +2 -2
  128. package/dist/memoryEntriesWire.d.ts +1 -1
  129. package/dist/memoryEntriesWire.js +5 -0
  130. package/dist/modelCapabilityProbe.js +4 -3
  131. package/dist/modsFace.d.ts +8 -1
  132. package/dist/modsFace.js +27 -0
  133. package/dist/noticePresentation.d.ts +2 -0
  134. package/dist/noticePresentation.js +79 -1
  135. package/dist/notifications.d.ts +17 -6
  136. package/dist/notifications.js +67 -19
  137. package/dist/ownKey.d.ts +5 -0
  138. package/dist/ownKey.js +8 -1
  139. package/dist/peerFrames.d.ts +40 -2
  140. package/dist/peerFrames.js +158 -3
  141. package/dist/pluginHooksWire.d.ts +2 -1
  142. package/dist/pluginHooksWire.js +56 -1
  143. package/dist/replayBody.js +10 -2
  144. package/dist/request/taskRequest.d.ts +5 -0
  145. package/dist/request/taskRequest.js +138 -21
  146. package/dist/resumeRefusalCopy.d.ts +1 -3
  147. package/dist/resumeRefusalCopy.js +2 -1
  148. package/dist/retryStatus.d.ts +2 -2
  149. package/dist/retryStatus.js +2 -0
  150. package/dist/ruleReadings.js +1 -1
  151. package/dist/seam.d.ts +24 -2
  152. package/dist/seam.js +15 -2
  153. package/dist/seatContract.d.ts +125 -10
  154. package/dist/seatContract.js +373 -7
  155. package/dist/sessionBackground.js +4 -1
  156. package/dist/sessionBackgroundHandoff.js +2 -1
  157. package/dist/sessionEngine.d.ts +2 -0
  158. package/dist/sessionEngine.js +111 -0
  159. package/dist/sessionMemoryStatus.d.ts +2 -1
  160. package/dist/sessionSyncFileHistory.d.ts +4 -0
  161. package/dist/sessionSyncFileHistory.js +28 -0
  162. package/dist/sseIdleTriage.d.ts +13 -1
  163. package/dist/sseIdleTriage.js +24 -6
  164. package/dist/subagent/engineSubagentTail.js +6 -0
  165. package/dist/subagentContentStore.d.ts +12 -0
  166. package/dist/subagentContentStore.js +72 -11
  167. package/dist/terminalStatuses.d.ts +1 -0
  168. package/dist/terminalStatuses.js +4 -1
  169. package/dist/toolResult.js +18 -5
  170. package/dist/turnFailurePresentation.js +9 -2
  171. package/dist/typePins.d.ts +11 -0
  172. package/dist/usageAnalytics.d.ts +17 -0
  173. package/dist/usageAnalytics.js +44 -2
  174. package/dist/wireFailureShape.d.ts +22 -5
  175. package/dist/wireFailureShape.js +47 -26
  176. package/dist/wireRefusalCopy.d.ts +31 -1
  177. package/dist/wireRefusalCopy.js +167 -2
  178. package/docs/INTEGRATION-CLIENTS.md +3269 -21
  179. package/package.json +5 -5
@@ -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,5 +1,6 @@
1
1
  import type { WiringManifestMcpEntryView } from './adapter/downstream/eventToSdkMessage.js';
2
2
  import { type McpAuthorizationView } from './mcpLiveness.js';
3
+ import type { UiLanguage } from './env/uiLanguage.js';
3
4
  export type McpEngineLegLiveness = {
4
5
  kind: 'unobserved';
5
6
  } | {
@@ -43,6 +44,8 @@ export type McpEngineLegConnection = {
43
44
  status: string;
44
45
  };
45
46
  export declare function mcpEngineLegConnectionOf(serverName: string, rows: readonly WiringManifestMcpEntryView[] | null | undefined): McpEngineLegConnection;
47
+ export declare function mcpNeedsReauth(reading: {} | null | undefined): boolean | undefined;
48
+ export declare function mcpFailureStatusSuffix(reading: {} | null | undefined, lang?: UiLanguage): string;
46
49
  export interface McpDetailLegNoteInput {
47
50
  localClientFailed: boolean;
48
51
  engineHostedToolCount: number | undefined;
@@ -1,5 +1,7 @@
1
- import { isMcpLivenessState, readMcpAuthorization } from './mcpLiveness.js';
1
+ import { isMcpLivenessState, MCP_FAILURE_UNAUTHORIZED, readMcpAuthorization } from './mcpLiveness.js';
2
2
  import { mcpSectionDroppedNamedRowsOf } from './ownKey.js';
3
+ import { slotReadOf } from './wireFailureShape.js';
4
+ import { msg, renderMessage } from './i18n/translate.js';
3
5
  void true;
4
6
  void true;
5
7
  void true;
@@ -132,6 +134,41 @@ export function mcpEngineLegConnectionOf(serverName, rows) {
132
134
  ...(authorization.kind === 'record' ? { authorization: authorization.authorization } : authorizationUnreadable ? { authorizationUnreadable: true } : {}),
133
135
  };
134
136
  }
137
+ export function mcpNeedsReauth(reading) {
138
+ try {
139
+ if (reading === null || typeof reading !== 'object' || Array.isArray(reading))
140
+ return undefined;
141
+ const slot = slotReadOf(reading, 'errorCode');
142
+ if (slot.presence === 'absent')
143
+ return false;
144
+ if (slot.presence !== 'present')
145
+ return undefined;
146
+ const code = slot.value;
147
+ if (typeof code !== 'string' || code === '')
148
+ return undefined;
149
+ return code === MCP_FAILURE_UNAUTHORIZED;
150
+ }
151
+ catch {
152
+ return undefined;
153
+ }
154
+ }
155
+ export function mcpFailureStatusSuffix(reading, lang) {
156
+ try {
157
+ if (reading === null || typeof reading !== 'object' || Array.isArray(reading))
158
+ return '';
159
+ const slot = slotReadOf(reading, 'httpStatus');
160
+ const status = slot.presence === 'present' && typeof slot.value === 'number' && Number.isInteger(slot.value) && slot.value > 0 ? slot.value : undefined;
161
+ const number = status === undefined ? '' : ` ${status}`;
162
+ if (mcpNeedsReauth(reading) === true)
163
+ return `${number}${renderMessage(msg('session.mcpFailure.reauthorizeSuffix'), lang)}`;
164
+ if (status !== undefined && status >= 500 && status <= 599)
165
+ return `${number}${renderMessage(msg('session.mcpFailure.serverDownSuffix'), lang)}`;
166
+ return number;
167
+ }
168
+ catch {
169
+ return '';
170
+ }
171
+ }
135
172
  const rosterReadingOf = (v) => {
136
173
  if (v === UNREADABLE_CELL)
137
174
  return 'unreadable';
package/dist/mcpPanel.js CHANGED
@@ -122,6 +122,8 @@ const _mcpPanelShapePin = (p) => p;
122
122
  void _mcpPanelShapePin;
123
123
  const _mcpPanelRefusalPin = (p) => p;
124
124
  void _mcpPanelRefusalPin;
125
+ const _pinMcpPanel = [true, true, true, true, true, true, true, true, true, true];
126
+ void _pinMcpPanel;
125
127
  export function mcpEngineLegPresence(view) {
126
128
  if (view === undefined)
127
129
  return 'unknown';
@@ -1,4 +1,5 @@
1
1
  import { type McpAuthorizationView } from './mcpLiveness.js';
2
+ import type { UiLanguage } from './env/uiLanguage.js';
2
3
  export declare const MCP_RECONNECT_OUTCOMES: readonly string[];
3
4
  export declare const MCP_RECONNECT_TRANSACTION_NOTICE: string;
4
5
  export declare const MCP_RECONNECT_UNSETTLED_NOTICE: string;
@@ -76,4 +77,11 @@ export declare function reconnectMcpServer(client: McpReconnectClientLike, sessi
76
77
  signal?: AbortSignal;
77
78
  }): Promise<McpReconnectVerdict>;
78
79
  export declare function projectMcpReconnectCapability(caps: unknown): 'available' | 'unavailable' | 'not_reported' | undefined;
79
- export declare function mcpReconnectOutcomeDetail(view: McpReconnectResultView): string;
80
+ export declare function mcpReconnectOutcomeDetail(view: McpReconnectResultView, lang?: UiLanguage): string;
81
+ export type McpReconnectNotSentVerdict = {
82
+ readonly kind: 'no_session';
83
+ } | {
84
+ readonly kind: 'unavailable';
85
+ };
86
+ export type McpReconnectDetailVerdict = McpReconnectVerdict | McpReconnectNotSentVerdict;
87
+ export declare function mcpReconnectVerdictDetail(verdict: McpReconnectDetailVerdict, server: string, lang?: UiLanguage): string | undefined;