@sema-agent/client-core 0.110.0 → 0.112.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.
- package/CHANGELOG.md +244 -0
- package/README.md +59 -18
- package/dist/abortableSleep.d.ts +7 -0
- package/dist/abortableSleep.js +37 -0
- package/dist/adapt/arms.js +25 -4
- package/dist/adapt/toolCards.d.ts +3 -1
- package/dist/adapt/toolCards.js +4 -2
- package/dist/adapter/activeRunSelfHeal.d.ts +39 -0
- package/dist/adapter/activeRunSelfHeal.js +171 -3
- package/dist/adapter/downstream/eventToSdkMessage.js +10 -10
- package/dist/adapter/downstream/terminalToSdkResult.d.ts +2 -0
- package/dist/adapter/downstream/terminalToSdkResult.js +11 -0
- package/dist/adapter/runStream.d.ts +5 -0
- package/dist/adapter/runStream.js +15 -3
- package/dist/agentSession/engineSessionBackgroundStop.js +2 -2
- package/dist/attachmentRoute.d.ts +20 -0
- package/dist/attachmentRoute.js +39 -0
- package/dist/attachmentsWireCaps.js +1 -1
- package/dist/builtinOutputStyles.d.ts +12 -0
- package/dist/builtinOutputStyles.js +147 -0
- package/dist/checkpointRowVerdict.d.ts +3 -0
- package/dist/checkpointRowVerdict.js +14 -1
- package/dist/compactionStatus.d.ts +9 -0
- package/dist/compactionStatus.js +29 -5
- package/dist/consoleCaPin.d.ts +136 -0
- package/dist/consoleCaPin.js +827 -0
- package/dist/controlRouter.js +2 -1
- package/dist/coreValuePorts.d.ts +39 -1
- package/dist/coreValuePorts.js +10 -0
- package/dist/decideReceipt.d.ts +2 -1
- package/dist/deviceRebind.js +3 -3
- package/dist/displayUntrusted.d.ts +1 -0
- package/dist/displayUntrusted.js +6 -0
- package/dist/effectiveFacts.d.ts +9 -0
- package/dist/effectiveFacts.js +33 -0
- package/dist/engineAddress.d.ts +1 -0
- package/dist/engineAddress.js +4 -1
- package/dist/engineCredentialRelease.d.ts +54 -0
- package/dist/engineCredentialRelease.js +146 -0
- package/dist/engineErrorCodes.d.ts +1 -0
- package/dist/engineErrorCodes.js +1 -0
- package/dist/engineHealthProbeVerdict.d.ts +24 -0
- package/dist/engineHealthProbeVerdict.js +123 -0
- package/dist/engineNoticeCodes.js +5 -7
- package/dist/engineRepoint.d.ts +12 -5
- package/dist/engineRepoint.js +44 -19
- package/dist/engineRowRef.d.ts +3 -0
- package/dist/engineRowRef.js +11 -1
- package/dist/engineSwapCrossing.d.ts +57 -0
- package/dist/engineSwapCrossing.js +297 -0
- package/dist/engineUnavailable.d.ts +45 -0
- package/dist/engineUnavailable.js +496 -0
- package/dist/engineUrl.js +4 -2
- package/dist/eventLeg.js +3 -3
- package/dist/gateFailureCodes.js +2 -2
- package/dist/generated/sdkFactTables.d.ts +2 -1
- package/dist/generated/sdkFactTables.js +14 -0
- package/dist/generated/settingsSchemaFns.d.ts +1 -0
- package/dist/generated/settingsSchemaFns.js +3 -0
- package/dist/generated/settingsSchemaHooksClassifier.js +38 -9
- package/dist/generated/settingsSchemaTables.d.ts +56 -0
- package/dist/generated/settingsSchemaTables.js +19 -0
- package/dist/generated/settingsSchemaTypes.d.ts +23 -13
- package/dist/generated/settingsSchemaUrlShape.d.ts +1 -0
- package/dist/generated/settingsSchemaUrlShape.js +17 -0
- package/dist/hitl/approvalDelivery.d.ts +1 -0
- package/dist/hitl/approvalDelivery.js +1 -1
- package/dist/hitl/approvalResolution.d.ts +1 -1
- package/dist/hitl/approvalResolution.js +2 -1
- package/dist/hitl/askGateWire.js +5 -6
- package/dist/hitl/decisionRefusal.d.ts +6 -0
- package/dist/hitl/decisionRefusal.js +19 -10
- package/dist/hitl/decisionRefusalCarrier.d.ts +3 -0
- package/dist/hitl/decisionRefusalCarrier.js +348 -0
- package/dist/hitl/decisionSend.d.ts +7 -0
- package/dist/hitl/decisionSend.js +34 -12
- package/dist/hitl/editedApprovalAcceptance.js +1 -1
- package/dist/hitl/elicitationRefusal.d.ts +4 -0
- package/dist/hitl/elicitationRefusal.js +23 -0
- package/dist/hitl/frameRouter.d.ts +2 -2
- package/dist/hitl/frameRouter.js +8 -15
- package/dist/hitl/gateIdentity.d.ts +5 -0
- package/dist/hitl/gateIdentity.js +23 -0
- package/dist/hitl/hitlBridge.d.ts +6 -0
- package/dist/hitl/hitlBridge.js +10 -4
- package/dist/hitl/hitlHostSurface.d.ts +2 -1
- package/dist/hitl/hitlHostSurface.js +7 -2
- package/dist/hitl/localAllowRedemption.d.ts +70 -0
- package/dist/hitl/localAllowRedemption.js +276 -0
- package/dist/hitl/parkOwnership.js +2 -1
- package/dist/hitl/parkResolver.js +14 -4
- package/dist/hitl/persistedRulesWire.d.ts +16 -0
- package/dist/hitl/persistedRulesWire.js +70 -0
- package/dist/hitl/planReviewWire.d.ts +3 -0
- package/dist/hitl/planReviewWire.js +23 -6
- package/dist/hitl/policyDenyCause.d.ts +1 -1
- package/dist/hitl/policyDenyCause.js +1 -1
- package/dist/hitl/resumeRunningCard.d.ts +1 -0
- package/dist/hitl/resumeRunningCard.js +1 -0
- package/dist/hitl/screenCardCarriers.d.ts +15 -0
- package/dist/hitl/screenCardCarriers.js +41 -0
- package/dist/hitl/screenDecisionCards.d.ts +98 -0
- package/dist/hitl/screenDecisionCards.js +363 -0
- package/dist/hitl/sessionPolicyWire.js +2 -2
- package/dist/hitl/standingRows.d.ts +6 -2
- package/dist/hitl/standingRows.js +27 -2
- package/dist/hitl/toolApprovalWire.d.ts +30 -8
- package/dist/hitl/toolApprovalWire.js +264 -121
- package/dist/hooksReaderGenerations.js +1 -1
- package/dist/hooksWireCaps.js +3 -3
- package/dist/hostSettingNoticeArm.d.ts +3 -0
- package/dist/hostSettingNoticeArm.js +12 -0
- package/dist/hostTurnSettings.d.ts +3 -0
- package/dist/hostTurnSettings.js +38 -5
- package/dist/humanTurnRead.js +11 -1
- package/dist/i18n/messages.en.d.ts +292 -0
- package/dist/i18n/messages.en.js +298 -7
- package/dist/i18n/messages.zh.js +316 -6
- package/dist/i18n/translate.d.ts +3 -0
- package/dist/i18n/translate.js +78 -10
- package/dist/i18n/zh.d.ts +1 -0
- package/dist/i18n/zh.js +1 -0
- package/dist/index.d.ts +71 -20
- package/dist/index.js +44 -13
- package/dist/interactiveHalt.js +2 -1
- package/dist/interactiveInterrupt.js +20 -2
- package/dist/liveModelCatalog.d.ts +4 -0
- package/dist/liveModelCatalog.js +12 -3
- package/dist/localConfig/documents.d.ts +61 -0
- package/dist/localConfig/documents.js +51 -0
- package/dist/localConfig/kernel.d.ts +149 -0
- package/dist/localConfig/kernel.js +597 -0
- package/dist/localConfig/mcp/edit.d.ts +161 -0
- package/dist/localConfig/mcp/edit.js +846 -0
- package/dist/localConfig/mcp/servers.d.ts +165 -0
- package/dist/localConfig/mcp/servers.js +776 -0
- package/dist/localConfig/mcp/views.d.ts +170 -0
- package/dist/localConfig/mcp/views.js +429 -0
- package/dist/localConfig/modelPool.d.ts +262 -0
- package/dist/localConfig/modelPool.js +1489 -0
- package/dist/localConfig/modelPoolWords.d.ts +13 -0
- package/dist/localConfig/modelPoolWords.js +20 -0
- package/dist/localConfig/receiptShape.d.ts +7 -0
- package/dist/localConfig/receiptShape.js +135 -0
- package/dist/localConfig/settingsWrite.d.ts +127 -0
- package/dist/localConfig/settingsWrite.js +237 -0
- package/dist/localConfig/skills.d.ts +124 -0
- package/dist/localConfig/skills.js +397 -0
- package/dist/localConfig/skillsWords.d.ts +10 -0
- package/dist/localConfig/skillsWords.js +5 -0
- package/dist/localEngineSeatReading.d.ts +2 -2
- package/dist/localEngineSeatReading.js +5 -3
- package/dist/localEngineSpawn.d.ts +0 -7
- package/dist/localEngineSpawn.js +0 -92
- package/dist/localEngineStep.d.ts +2 -2
- package/dist/localEngineStep.js +2 -0
- package/dist/mcpProbeWire.js +2 -1
- package/dist/mcpReconnect.js +3 -3
- package/dist/mcpWireCaps.js +1 -1
- package/dist/memoryVerbsWire.js +3 -2
- package/dist/model/engineModelWords.d.ts +3 -0
- package/dist/model/engineModelWords.js +13 -0
- package/dist/model/onboardJudgement.d.ts +14 -4
- package/dist/model/onboardJudgement.js +91 -139
- package/dist/model/subagentModelWord.d.ts +21 -2
- package/dist/model/subagentModelWord.js +100 -29
- package/dist/modelCapabilityProbe.js +3 -40
- package/dist/modelConfigGapNotice.d.ts +20 -0
- package/dist/modelConfigGapNotice.js +102 -0
- package/dist/modsKernelIdentity.js +2 -47
- package/dist/notifications.d.ts +19 -0
- package/dist/notifications.js +114 -12
- package/dist/ownKey.d.ts +7 -0
- package/dist/ownKey.js +71 -8
- package/dist/pendingUserRow.d.ts +4 -0
- package/dist/pendingUserRow.js +16 -0
- package/dist/permissionsDeclaration.d.ts +3 -1
- package/dist/permissionsDeclaration.js +33 -9
- package/dist/planReviewCardFacts.d.ts +3 -0
- package/dist/planReviewCardFacts.js +52 -2
- package/dist/pluginHooksWire.d.ts +9 -1
- package/dist/pluginHooksWire.js +40 -6
- package/dist/printToolResultFrame.js +4 -2
- package/dist/promptBlockedCopy.js +12 -7
- package/dist/promptSuggestionBatch.d.ts +7 -0
- package/dist/promptSuggestionBatch.js +9 -0
- package/dist/promptSuggestionsTail.d.ts +39 -0
- package/dist/promptSuggestionsTail.js +116 -0
- package/dist/request/taskRequest.js +10 -6
- package/dist/requestCoordinate.d.ts +1 -0
- package/dist/requestCoordinate.js +13 -0
- package/dist/resumeRefusalCopy.d.ts +3 -1
- package/dist/resumeRefusalCopy.js +12 -4
- package/dist/rewindArchiveReading.js +4 -4
- package/dist/runCancelContext.d.ts +2 -1
- package/dist/runCancelContext.js +1 -0
- package/dist/runLedgerSnapshot.js +3 -3
- package/dist/runPermissionModeSwitch.js +3 -4
- package/dist/scenarioRefusal.js +11 -13
- package/dist/scenarioSkills.js +11 -6
- package/dist/seam.d.ts +16 -2
- package/dist/seam.js +10 -0
- package/dist/seatContract.d.ts +259 -9
- package/dist/seatContract.js +444 -15
- package/dist/sessionCostReading.d.ts +70 -0
- package/dist/sessionCostReading.js +150 -0
- package/dist/sessionHooksRoster.d.ts +4 -0
- package/dist/sessionHooksRoster.js +158 -0
- package/dist/sessionIdSegment.d.ts +1 -0
- package/dist/sessionIdSegment.js +4 -1
- package/dist/sessionMemoryErase.js +2 -1
- package/dist/sessionMemoryStatus.js +2 -2
- package/dist/sessionReadRedaction.d.ts +7 -0
- package/dist/sessionReadRedaction.js +26 -0
- package/dist/sessionSyncFileHistory.js +8 -9
- package/dist/settingsHooksSalvage.js +2 -1
- package/dist/sha256Bytes.d.ts +1 -0
- package/dist/sha256Bytes.js +46 -0
- package/dist/skillOverrideChain.d.ts +83 -0
- package/dist/skillOverrideChain.js +378 -0
- package/dist/skillsWireCaps.d.ts +3 -0
- package/dist/skillsWireCaps.js +16 -1
- package/dist/sseIdleTriage.js +2 -1
- package/dist/storeDurabilityWord.d.ts +15 -0
- package/dist/storeDurabilityWord.js +18 -0
- package/dist/storePostureCapability.d.ts +7 -3
- package/dist/storePostureCapability.js +69 -39
- package/dist/subagent/engineSubagentResume.js +2 -2
- package/dist/subagent/engineSubagentTail.js +2 -1
- package/dist/subagentContentStore.d.ts +11 -0
- package/dist/subagentContentStore.js +28 -2
- package/dist/toolResult.d.ts +1 -0
- package/dist/toolResult.js +2 -0
- package/dist/turnFailurePresentation.js +4 -10
- package/dist/userAttachmentEnvelope.d.ts +2 -1
- package/dist/userAttachmentEnvelope.js +10 -0
- package/dist/wireErrorTriage.js +2 -1
- package/dist/wireFailureShape.d.ts +4 -0
- package/dist/wireFailureShape.js +141 -19
- package/dist/wireRefusalCopy.d.ts +6 -5
- package/dist/wireRefusalCopy.js +49 -92
- package/docs/INTEGRATION-CLIENTS.md +2718 -17
- package/package.json +7 -3
package/dist/engineRepoint.d.ts
CHANGED
|
@@ -15,7 +15,12 @@ export declare function deviceHelloReadingOf(frame: {} | null | undefined): Devi
|
|
|
15
15
|
export interface EngineRepointInput {
|
|
16
16
|
readonly from: string;
|
|
17
17
|
readonly to: string;
|
|
18
|
-
readonly
|
|
18
|
+
readonly continuity?: EngineRepointContinuity;
|
|
19
|
+
}
|
|
20
|
+
export interface EngineRepointContinuity {
|
|
21
|
+
readonly deviceId: string;
|
|
22
|
+
readonly from: string;
|
|
23
|
+
readonly to: string;
|
|
19
24
|
}
|
|
20
25
|
export interface EngineRepointHandshakeTarget {
|
|
21
26
|
readonly address: string;
|
|
@@ -26,8 +31,7 @@ export type EngineRepointHandshakePort = (target: EngineRepointHandshakeTarget,
|
|
|
26
31
|
}) => Promise<{} | null | undefined> | {} | null | undefined;
|
|
27
32
|
export interface EngineRepointRoster {
|
|
28
33
|
readonly credential: 'operator' | 'non-operator';
|
|
29
|
-
readonly address: string;
|
|
30
|
-
readonly devices: DeviceListVerb | null | undefined;
|
|
34
|
+
readonly devices: (address: string) => DeviceListVerb | null | undefined;
|
|
31
35
|
}
|
|
32
36
|
export type EngineRepointRecordReading = {
|
|
33
37
|
readonly kind: 'absent';
|
|
@@ -75,7 +79,7 @@ export type EngineRepointRosterProof = {
|
|
|
75
79
|
readonly why: 'not-listed' | 'lane-absent';
|
|
76
80
|
} | {
|
|
77
81
|
readonly state: 'unreadable';
|
|
78
|
-
readonly why: 'operator-credential' | 'credential-unknown' | '
|
|
82
|
+
readonly why: 'operator-credential' | 'credential-unknown' | 'list-incomplete' | 'refused' | 'transport' | 'unreadable' | 'unarmed';
|
|
79
83
|
};
|
|
80
84
|
export interface EngineRepointProofs {
|
|
81
85
|
readonly handshake: EngineRepointHandshakeProof;
|
|
@@ -94,11 +98,12 @@ export interface EngineRepointSessionTally {
|
|
|
94
98
|
readonly unreadable: number;
|
|
95
99
|
readonly storeFailed: number;
|
|
96
100
|
}
|
|
97
|
-
export type EngineRepointRefusal = 'address-invalid' | 'same-address' | 'record-absent' | 'record-not-active' | 'record-unreadable' | 'target-occupied' | 'unarmed';
|
|
101
|
+
export type EngineRepointRefusal = 'address-invalid' | 'same-address' | 'record-absent' | 'record-not-active' | 'record-unreadable' | 'target-occupied' | 'roster-unbound' | 'unarmed';
|
|
98
102
|
export type EngineRepointResult = EngineRepointDone | EngineRepointPartial | EngineRepointUnverified | EngineRepointUndetermined | EngineRepointStoreFailed | EngineRepointRefused;
|
|
99
103
|
export interface EngineRepointDone {
|
|
100
104
|
readonly kind: 'repointed';
|
|
101
105
|
readonly deviceId: string;
|
|
106
|
+
readonly continuity: EngineRepointContinuity;
|
|
102
107
|
readonly record: 'moved' | 'already-there';
|
|
103
108
|
readonly sessions: EngineRepointSessionTally;
|
|
104
109
|
readonly proofs: EngineRepointProofs;
|
|
@@ -107,6 +112,7 @@ export interface EngineRepointPartial {
|
|
|
107
112
|
readonly kind: 'partial';
|
|
108
113
|
readonly stage: 'sessions' | 'sessions-list';
|
|
109
114
|
readonly deviceId: string;
|
|
115
|
+
readonly continuity: EngineRepointContinuity;
|
|
110
116
|
readonly record: 'moved' | 'already-there';
|
|
111
117
|
readonly sessions: EngineRepointSessionTally;
|
|
112
118
|
readonly proofs: EngineRepointProofs;
|
|
@@ -128,6 +134,7 @@ export interface EngineRepointStoreFailed {
|
|
|
128
134
|
readonly kind: 'store-failed';
|
|
129
135
|
readonly stage: 'record';
|
|
130
136
|
readonly deviceId: string;
|
|
137
|
+
readonly continuity: EngineRepointContinuity;
|
|
131
138
|
}
|
|
132
139
|
export interface EngineRepointRefused {
|
|
133
140
|
readonly kind: 'refused';
|
package/dist/engineRepoint.js
CHANGED
|
@@ -58,18 +58,27 @@ async function handshakeProofOf(port, target, signal) {
|
|
|
58
58
|
return freeze({ state: 'unreadable', why: r.code });
|
|
59
59
|
}
|
|
60
60
|
const RO_PROVEN = freeze({ state: 'proven' });
|
|
61
|
-
|
|
61
|
+
function rosterSliceOf(roster, target) {
|
|
62
62
|
if (!isObject(roster))
|
|
63
|
-
return freeze({ state: 'unreadable', why: 'unarmed' });
|
|
63
|
+
return { kind: 'proof', proof: freeze({ state: 'unreadable', why: 'unarmed' }) };
|
|
64
64
|
const credential = dataOf(roster, 'credential');
|
|
65
65
|
if (credential === 'operator')
|
|
66
|
-
return freeze({ state: 'unreadable', why: 'operator-credential' });
|
|
66
|
+
return { kind: 'proof', proof: freeze({ state: 'unreadable', why: 'operator-credential' }) };
|
|
67
67
|
if (credential !== 'non-operator')
|
|
68
|
-
return freeze({ state: 'unreadable', why: 'credential-unknown' });
|
|
69
|
-
const
|
|
70
|
-
if (
|
|
71
|
-
return
|
|
72
|
-
|
|
68
|
+
return { kind: 'proof', proof: freeze({ state: 'unreadable', why: 'credential-unknown' }) };
|
|
69
|
+
const factory = dataOf(roster, 'devices');
|
|
70
|
+
if (typeof factory !== 'function')
|
|
71
|
+
return { kind: 'unbound' };
|
|
72
|
+
let slice;
|
|
73
|
+
try {
|
|
74
|
+
slice = factory(target);
|
|
75
|
+
}
|
|
76
|
+
catch {
|
|
77
|
+
return { kind: 'proof', proof: freeze({ state: 'unreadable', why: 'unreadable' }) };
|
|
78
|
+
}
|
|
79
|
+
return slice === null || slice === undefined ? { kind: 'unbound' } : { kind: 'slice', devices: slice };
|
|
80
|
+
}
|
|
81
|
+
async function rosterProofOf(devices, deviceId, signal) {
|
|
73
82
|
const out = await listDevices(devices, signal !== undefined ? { signal } : undefined);
|
|
74
83
|
switch (out.kind) {
|
|
75
84
|
case 'ok':
|
|
@@ -123,7 +132,17 @@ async function recordFactOf(read, port, address) {
|
|
|
123
132
|
const deviceId = dataOf(raw, 'deviceId');
|
|
124
133
|
return typeof deviceId === 'string' && deviceId !== '' ? freeze({ k: 'active', deviceId }) : UNREADABLE_RECORD;
|
|
125
134
|
}
|
|
126
|
-
function
|
|
135
|
+
function continuityReadingOf(raw) {
|
|
136
|
+
if (!isObject(raw))
|
|
137
|
+
return undefined;
|
|
138
|
+
const deviceId = dataOf(raw, 'deviceId');
|
|
139
|
+
const f = addressOf(dataOf(raw, 'from'), false);
|
|
140
|
+
const t = addressOf(dataOf(raw, 'to'), true);
|
|
141
|
+
if (typeof deviceId !== 'string' || deviceId === '' || f === undefined || t === undefined)
|
|
142
|
+
return undefined;
|
|
143
|
+
return freeze({ deviceId, fromKey: engineNamespaceKeyFor(f), toKey: engineNamespaceKeyFor(t) });
|
|
144
|
+
}
|
|
145
|
+
function planOf(from, to, evidence, pair) {
|
|
127
146
|
if (from.k === 'unreadable' || to.k === 'unreadable')
|
|
128
147
|
return { kind: 'refused', reason: 'record-unreadable' };
|
|
129
148
|
if (from.k === 'other')
|
|
@@ -135,8 +154,10 @@ function planOf(from, to, expectDeviceId) {
|
|
|
135
154
|
return { kind: 'move', deviceId: from.deviceId };
|
|
136
155
|
return { kind: 'refused', reason: 'target-occupied' };
|
|
137
156
|
}
|
|
138
|
-
if (to.k === 'active')
|
|
139
|
-
|
|
157
|
+
if (to.k === 'active') {
|
|
158
|
+
const bound = evidence !== undefined && to.deviceId === evidence.deviceId && evidence.fromKey === pair.fromKey && evidence.toKey === pair.toKey;
|
|
159
|
+
return bound ? { kind: 'finish', deviceId: to.deviceId } : { kind: 'refused', reason: 'record-absent' };
|
|
160
|
+
}
|
|
140
161
|
if (to.k === 'other')
|
|
141
162
|
return { kind: 'refused', reason: 'record-not-active', recordStatus: to.status };
|
|
142
163
|
return { kind: 'refused', reason: 'record-absent' };
|
|
@@ -188,14 +209,17 @@ export async function repointEngine(input, ports) {
|
|
|
188
209
|
const roster = dataOf(ports, 'roster');
|
|
189
210
|
const signalRaw = dataOf(ports, 'signal');
|
|
190
211
|
const signal = isObject(signalRaw) ? signalRaw : undefined;
|
|
191
|
-
const
|
|
192
|
-
const expectDeviceId = typeof expectRaw === 'string' && expectRaw !== '' ? expectRaw : undefined;
|
|
212
|
+
const evidence = continuityReadingOf(dataOf(input, 'continuity'));
|
|
193
213
|
const [fromFact, toFact] = await Promise.all([recordFactOf(read, recordPort, from), recordFactOf(read, recordPort, to)]);
|
|
194
|
-
const plan = planOf(fromFact, toFact,
|
|
214
|
+
const plan = planOf(fromFact, toFact, evidence, { fromKey: engineNamespaceKeyFor(from), toKey: engineNamespaceKeyFor(to) });
|
|
195
215
|
if (plan.kind === 'refused')
|
|
196
216
|
return refusedOf(plan.reason, plan.recordStatus);
|
|
197
217
|
const deviceId = plan.deviceId;
|
|
198
|
-
const
|
|
218
|
+
const continuity = freeze({ deviceId, from, to });
|
|
219
|
+
const slice = rosterSliceOf(roster, to);
|
|
220
|
+
if (slice.kind === 'unbound')
|
|
221
|
+
return refusedOf('roster-unbound');
|
|
222
|
+
const [hs, ro] = await Promise.all([handshakeProofOf(handshake, freeze({ address: to, deviceId }), signal), slice.kind === 'proof' ? slice.proof : rosterProofOf(slice.devices, deviceId, signal)]);
|
|
199
223
|
const proofs = freeze({ handshake: hs, roster: ro });
|
|
200
224
|
const verdict = engineRepointVerdictOf(proofs);
|
|
201
225
|
if (verdict !== 'apply') {
|
|
@@ -217,7 +241,7 @@ export async function repointEngine(input, ports) {
|
|
|
217
241
|
moved = afterFrom.k === 'absent' && afterTo.k === 'active' && afterTo.deviceId === deviceId;
|
|
218
242
|
}
|
|
219
243
|
if (!moved)
|
|
220
|
-
return freeze({ kind: 'store-failed', stage: 'record', deviceId });
|
|
244
|
+
return freeze({ kind: 'store-failed', stage: 'record', deviceId, continuity });
|
|
221
245
|
}
|
|
222
246
|
const record = plan.kind === 'move' ? 'moved' : 'already-there';
|
|
223
247
|
const counts = { moved: 0, unaffected: 0, conflict: 0, unreadable: 0, storeFailed: 0 };
|
|
@@ -229,7 +253,7 @@ export async function repointEngine(input, ports) {
|
|
|
229
253
|
stores = undefined;
|
|
230
254
|
}
|
|
231
255
|
if (stores === undefined)
|
|
232
|
-
return freeze({ kind: 'partial', stage: 'sessions-list', deviceId, record, sessions: tallyOf(counts), proofs });
|
|
256
|
+
return freeze({ kind: 'partial', stage: 'sessions-list', deviceId, continuity, record, sessions: tallyOf(counts), proofs });
|
|
233
257
|
for (const store of stores) {
|
|
234
258
|
const r = repointSessionEngine(store, from, to);
|
|
235
259
|
if (r === 'moved')
|
|
@@ -245,8 +269,8 @@ export async function repointEngine(input, ports) {
|
|
|
245
269
|
}
|
|
246
270
|
const sessions = tallyOf(counts);
|
|
247
271
|
return counts.conflict + counts.unreadable + counts.storeFailed > 0
|
|
248
|
-
? freeze({ kind: 'partial', stage: 'sessions', deviceId, record, sessions, proofs })
|
|
249
|
-
: freeze({ kind: 'repointed', deviceId, record, sessions, proofs });
|
|
272
|
+
? freeze({ kind: 'partial', stage: 'sessions', deviceId, continuity, record, sessions, proofs })
|
|
273
|
+
: freeze({ kind: 'repointed', deviceId, continuity, record, sessions, proofs });
|
|
250
274
|
}
|
|
251
275
|
catch {
|
|
252
276
|
return refusedOf('unarmed');
|
|
@@ -259,6 +283,7 @@ const REFUSAL_KEYS = {
|
|
|
259
283
|
'record-not-active': 'session.devices.repoint.refused.recordNotActive',
|
|
260
284
|
'record-unreadable': 'session.devices.repoint.refused.recordUnreadable',
|
|
261
285
|
'target-occupied': 'session.devices.repoint.refused.targetOccupied',
|
|
286
|
+
'roster-unbound': 'session.devices.repoint.refused.rosterUnbound',
|
|
262
287
|
unarmed: 'session.devices.repoint.refused.unarmed',
|
|
263
288
|
};
|
|
264
289
|
export function engineRepointMessageOf(result) {
|
package/dist/engineRowRef.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { AgentEvent } from '@sema-agent/sdk';
|
|
2
|
+
import { type GateOutcomeView } from './gateOutcome.js';
|
|
2
3
|
export interface EngineRowRef {
|
|
3
4
|
readonly eventId?: string;
|
|
4
5
|
readonly taskId?: string;
|
|
@@ -22,7 +23,9 @@ export declare function terminalRunIdOf(ev: Extract<AgentEvent, {
|
|
|
22
23
|
} | {
|
|
23
24
|
type: 'failed';
|
|
24
25
|
}>): string | undefined;
|
|
26
|
+
export declare const SEMA_REFUSAL_NOTED_KEY = "_sema_refusal_noted";
|
|
25
27
|
export declare const TRANSCRIPT_ROW_SIDECAR_KEYS: readonly string[];
|
|
28
|
+
export declare function refusalNotedOf(denialKind: string | undefined, gate: GateOutcomeView | undefined): boolean;
|
|
26
29
|
export declare function parkHeldCallIdOf(carrier: {} | null | undefined): string | undefined;
|
|
27
30
|
export declare function parkedToolEndRoleOf(frame: {} | null | undefined): 'held' | 'collateral' | undefined;
|
|
28
31
|
export declare function isUnsettledHeldToolEnd(frame: {} | null | undefined): boolean;
|
package/dist/engineRowRef.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { guardedRead, readFrameStringKey, readOwnDataNonEmptyString, readOwnDataValue } from './ownKey.js';
|
|
2
2
|
import { GATE_PARKED_ERROR_CODE } from './engineErrorCodes.js';
|
|
3
|
-
import { isCcToolDenialKind } from './gateVocabulary.js';
|
|
3
|
+
import { ccToolDenialKindForSettledBy, isCcToolDenialKind } from './gateVocabulary.js';
|
|
4
|
+
import { gateDeniedBy } from './gateOutcome.js';
|
|
4
5
|
import { doneResultView } from './replayBody.js';
|
|
5
6
|
import { TRANSCRIPT_ID_NAMESPACE, uuidV5 } from './uuidV5.js';
|
|
6
7
|
const ENGINE_REF_KEY = '_sema_engine_ref';
|
|
@@ -77,6 +78,7 @@ export function terminalRunIdOf(ev) {
|
|
|
77
78
|
const v = doneResultView(ev.result).body?.runId;
|
|
78
79
|
return typeof v === 'string' && v.length > 0 ? v : undefined;
|
|
79
80
|
}
|
|
81
|
+
export const SEMA_REFUSAL_NOTED_KEY = '_sema_refusal_noted';
|
|
80
82
|
export const TRANSCRIPT_ROW_SIDECAR_KEYS = Object.freeze([
|
|
81
83
|
'_sema_segment_id',
|
|
82
84
|
'_sema_engine_ref',
|
|
@@ -93,6 +95,7 @@ export const TRANSCRIPT_ROW_SIDECAR_KEYS = Object.freeze([
|
|
|
93
95
|
'_sema_interrupted_never_started',
|
|
94
96
|
'_sema_approval_window_expired',
|
|
95
97
|
'_sema_denial_limit_window_expired',
|
|
98
|
+
SEMA_REFUSAL_NOTED_KEY,
|
|
96
99
|
'_sema_api_error_status',
|
|
97
100
|
'_sema_api_error_code',
|
|
98
101
|
'_sema_provider_condition',
|
|
@@ -105,6 +108,13 @@ export const TRANSCRIPT_ROW_SIDECAR_KEYS = Object.freeze([
|
|
|
105
108
|
'_sema_run_origin',
|
|
106
109
|
'_sema_run_origin_unreadable',
|
|
107
110
|
]);
|
|
111
|
+
export function refusalNotedOf(denialKind, gate) {
|
|
112
|
+
if (denialKind !== ccToolDenialKindForSettledBy('human'))
|
|
113
|
+
return false;
|
|
114
|
+
if (gateDeniedBy(gate) !== 'ask_resolution')
|
|
115
|
+
return false;
|
|
116
|
+
return gate?.settlement?.kind === 'human_refused' && gate.settlement.note !== undefined;
|
|
117
|
+
}
|
|
108
118
|
export function parkHeldCallIdOf(carrier) {
|
|
109
119
|
return readFrameStringKey(carrier, 'toolCallId');
|
|
110
120
|
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import type { ApprovalsFeedEmission } from './hitl/approvalsFeed.js';
|
|
2
|
+
import type { LocalEngineUpgradePath, LocalEngineVerdict } from './localEngineJudge.js';
|
|
3
|
+
import type { RequestLane } from './request/taskRequest.js';
|
|
4
|
+
import type { UiLanguage } from './env/uiLanguage.js';
|
|
5
|
+
export declare const ENGINE_DRAIN_CLASSES: readonly ["parked_tool_approvals"];
|
|
6
|
+
export type EngineDrainClass = (typeof ENGINE_DRAIN_CLASSES)[number];
|
|
7
|
+
export interface EngineDrainSession {
|
|
8
|
+
readonly sessionId: string;
|
|
9
|
+
readonly count: number;
|
|
10
|
+
}
|
|
11
|
+
export type EngineDrainReading = {
|
|
12
|
+
readonly class: EngineDrainClass;
|
|
13
|
+
readonly state: 'count';
|
|
14
|
+
readonly count: number;
|
|
15
|
+
readonly sessions: readonly EngineDrainSession[];
|
|
16
|
+
} | {
|
|
17
|
+
readonly class: EngineDrainClass;
|
|
18
|
+
readonly state: 'failed';
|
|
19
|
+
} | {
|
|
20
|
+
readonly class: EngineDrainClass;
|
|
21
|
+
readonly state: 'unsupported';
|
|
22
|
+
};
|
|
23
|
+
export type EngineSwapCrossing = 'newer' | 'same' | 'older' | 'none' | 'unknown';
|
|
24
|
+
export interface EngineSwapCrossingFacts {
|
|
25
|
+
readonly engine: LocalEngineVerdict;
|
|
26
|
+
readonly drain?: readonly EngineDrainReading[];
|
|
27
|
+
readonly informed?: string;
|
|
28
|
+
}
|
|
29
|
+
export type EngineSwapCrossingVerdict = {
|
|
30
|
+
readonly kind: 'clear';
|
|
31
|
+
readonly crossing: 'none' | 'same' | 'older' | 'unknown';
|
|
32
|
+
} | {
|
|
33
|
+
readonly kind: 'hold';
|
|
34
|
+
readonly reason: 'newer_engine';
|
|
35
|
+
readonly crossing: 'newer';
|
|
36
|
+
readonly running: string;
|
|
37
|
+
readonly own: string;
|
|
38
|
+
readonly source: 'running' | 'high-water';
|
|
39
|
+
} | {
|
|
40
|
+
readonly kind: 'hold';
|
|
41
|
+
readonly reason: 'drain_unconfirmed';
|
|
42
|
+
readonly crossing: 'older';
|
|
43
|
+
readonly classes: readonly EngineDrainReading[];
|
|
44
|
+
readonly fingerprint: string;
|
|
45
|
+
} | {
|
|
46
|
+
readonly kind: 'unknown';
|
|
47
|
+
readonly crossing: 'unknown';
|
|
48
|
+
readonly classes: readonly EngineDrainReading[];
|
|
49
|
+
readonly fingerprint: string;
|
|
50
|
+
} | {
|
|
51
|
+
readonly kind: 'swap_and_tell';
|
|
52
|
+
readonly crossing: 'older' | 'unknown';
|
|
53
|
+
readonly classes: readonly EngineDrainReading[];
|
|
54
|
+
};
|
|
55
|
+
export declare function engineSwapCrossingVerdict(facts: EngineSwapCrossingFacts): EngineSwapCrossingVerdict;
|
|
56
|
+
export declare function parkedToolApprovalsBySession(emission: ApprovalsFeedEmission | null | undefined): EngineDrainReading;
|
|
57
|
+
export declare function engineSwapCrossingText(verdict: EngineSwapCrossingVerdict, lane: Exclude<RequestLane, 'utility'>, upgrade: LocalEngineUpgradePath | undefined, lang?: UiLanguage): string | undefined;
|
|
@@ -0,0 +1,297 @@
|
|
|
1
|
+
import { checkpointQueueRowSortOf } from './hitl/approvalQueueRow.js';
|
|
2
|
+
import { durableDecideLegOf } from './adapter/activeRunSelfHeal.js';
|
|
3
|
+
import { checkpointRowVerdictOf } from './checkpointRowVerdict.js';
|
|
4
|
+
import { compareReleaseVersions } from './supportFloor.js';
|
|
5
|
+
import { engineIdentityOf } from './engineIdentity.js';
|
|
6
|
+
import { slotReadOf } from './wireFailureShape.js';
|
|
7
|
+
import { msg, renderMessage } from './i18n/translate.js';
|
|
8
|
+
export const ENGINE_DRAIN_CLASSES = Object.freeze(['parked_tool_approvals']);
|
|
9
|
+
function own(o, key) {
|
|
10
|
+
if (typeof o !== 'object' || o === null)
|
|
11
|
+
return undefined;
|
|
12
|
+
const r = slotReadOf(o, key);
|
|
13
|
+
return r.presence === 'present' ? r.value : undefined;
|
|
14
|
+
}
|
|
15
|
+
function isArray(v) {
|
|
16
|
+
try {
|
|
17
|
+
return Array.isArray(v);
|
|
18
|
+
}
|
|
19
|
+
catch {
|
|
20
|
+
return false;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
function isObject(v) {
|
|
24
|
+
return typeof v === 'object' && v !== null && !isArray(v);
|
|
25
|
+
}
|
|
26
|
+
function isCount(v) {
|
|
27
|
+
return typeof v === 'number' && Number.isSafeInteger(v) && v >= 0;
|
|
28
|
+
}
|
|
29
|
+
function nonEmpty(v) {
|
|
30
|
+
return typeof v === 'string' && v.length > 0 ? v : undefined;
|
|
31
|
+
}
|
|
32
|
+
function elementsOf(v) {
|
|
33
|
+
if (!isArray(v))
|
|
34
|
+
return undefined;
|
|
35
|
+
const len = own(v, 'length');
|
|
36
|
+
if (!isCount(len))
|
|
37
|
+
return undefined;
|
|
38
|
+
const out = [];
|
|
39
|
+
for (let i = 0; i < len; i++) {
|
|
40
|
+
const r = slotReadOf(v, String(i));
|
|
41
|
+
if (r.presence !== 'present')
|
|
42
|
+
return undefined;
|
|
43
|
+
out.push(r.value);
|
|
44
|
+
}
|
|
45
|
+
return out;
|
|
46
|
+
}
|
|
47
|
+
function failedOf(c) {
|
|
48
|
+
return Object.freeze({ class: c, state: 'failed' });
|
|
49
|
+
}
|
|
50
|
+
function crossingOf(v) {
|
|
51
|
+
const kind = own(v, 'kind');
|
|
52
|
+
if (kind === 'none')
|
|
53
|
+
return { crossing: 'none' };
|
|
54
|
+
if (kind === 'attach')
|
|
55
|
+
return isObject(own(v, 'engine')) ? { crossing: 'same' } : { crossing: 'unknown' };
|
|
56
|
+
if (kind === 'ahead' || kind === 'behind') {
|
|
57
|
+
const running = own(v, 'running');
|
|
58
|
+
const mine = own(v, 'own');
|
|
59
|
+
if (typeof running !== 'string' || typeof mine !== 'string')
|
|
60
|
+
return { crossing: 'unknown' };
|
|
61
|
+
const cmp = compareReleaseVersions(running, mine);
|
|
62
|
+
if (kind === 'ahead')
|
|
63
|
+
return cmp === -1 && isObject(own(v, 'engine')) ? { crossing: 'older' } : { crossing: 'unknown' };
|
|
64
|
+
const source = own(v, 'source');
|
|
65
|
+
if (cmp !== 1 || (source !== 'running' && source !== 'high-water'))
|
|
66
|
+
return { crossing: 'unknown' };
|
|
67
|
+
return { crossing: 'newer', running, own: mine, source };
|
|
68
|
+
}
|
|
69
|
+
return { crossing: 'unknown' };
|
|
70
|
+
}
|
|
71
|
+
function targetOf(v) {
|
|
72
|
+
const engine = own(v, 'engine');
|
|
73
|
+
const anchored = own(v, 'anchored');
|
|
74
|
+
const src = isObject(engine) ? own(engine, 'identity') : isObject(anchored) ? anchored : v;
|
|
75
|
+
const id = engineIdentityOf({ pid: own(src, 'pid'), instanceId: own(src, 'instanceId'), startedAt: own(src, 'startedAt') });
|
|
76
|
+
return { ...(id.pid !== undefined ? { pid: id.pid } : {}), ...(id.instanceId !== undefined ? { instanceId: id.instanceId } : {}), ...(id.startedAt !== undefined ? { startedAt: id.startedAt } : {}) };
|
|
77
|
+
}
|
|
78
|
+
function drainEntryOf(e) {
|
|
79
|
+
if (!isObject(e))
|
|
80
|
+
return undefined;
|
|
81
|
+
const c = own(e, 'class');
|
|
82
|
+
if (!ENGINE_DRAIN_CLASSES.includes(c))
|
|
83
|
+
return undefined;
|
|
84
|
+
const cls = c;
|
|
85
|
+
const state = own(e, 'state');
|
|
86
|
+
if (state === 'failed')
|
|
87
|
+
return failedOf(cls);
|
|
88
|
+
if (state === 'unsupported')
|
|
89
|
+
return Object.freeze({ class: cls, state: 'unsupported' });
|
|
90
|
+
if (state !== 'count')
|
|
91
|
+
return undefined;
|
|
92
|
+
const count = own(e, 'count');
|
|
93
|
+
const rows = elementsOf(own(e, 'sessions'));
|
|
94
|
+
if (!isCount(count) || rows === undefined)
|
|
95
|
+
return undefined;
|
|
96
|
+
const sessions = [];
|
|
97
|
+
const seen = new Set();
|
|
98
|
+
let sum = 0;
|
|
99
|
+
for (const s of rows) {
|
|
100
|
+
const sessionId = nonEmpty(own(s, 'sessionId'));
|
|
101
|
+
const n = own(s, 'count');
|
|
102
|
+
if (sessionId === undefined || !isCount(n) || n === 0 || seen.has(sessionId))
|
|
103
|
+
return undefined;
|
|
104
|
+
seen.add(sessionId);
|
|
105
|
+
sum += n;
|
|
106
|
+
sessions.push(Object.freeze({ sessionId, count: n }));
|
|
107
|
+
}
|
|
108
|
+
if (sum !== count)
|
|
109
|
+
return undefined;
|
|
110
|
+
sessions.sort((a, b) => (a.sessionId < b.sessionId ? -1 : a.sessionId > b.sessionId ? 1 : 0));
|
|
111
|
+
return Object.freeze({ class: cls, state: 'count', count, sessions: Object.freeze(sessions) });
|
|
112
|
+
}
|
|
113
|
+
function drainOf(raw) {
|
|
114
|
+
const entries = elementsOf(raw);
|
|
115
|
+
const byClass = new Map();
|
|
116
|
+
let bad = entries === undefined;
|
|
117
|
+
for (const e of entries ?? []) {
|
|
118
|
+
const r = drainEntryOf(e);
|
|
119
|
+
if (r === undefined || byClass.has(r.class)) {
|
|
120
|
+
bad = true;
|
|
121
|
+
break;
|
|
122
|
+
}
|
|
123
|
+
byClass.set(r.class, r);
|
|
124
|
+
}
|
|
125
|
+
return Object.freeze(ENGINE_DRAIN_CLASSES.map(c => (bad ? undefined : byClass.get(c)) ?? failedOf(c)));
|
|
126
|
+
}
|
|
127
|
+
function fingerprintOf(crossing, v, drain) {
|
|
128
|
+
const running = own(v, 'running');
|
|
129
|
+
const mine = own(v, 'own');
|
|
130
|
+
return JSON.stringify([
|
|
131
|
+
'engine-swap-crossing/1',
|
|
132
|
+
crossing,
|
|
133
|
+
targetOf(v),
|
|
134
|
+
typeof running === 'string' ? running : null,
|
|
135
|
+
typeof mine === 'string' ? mine : null,
|
|
136
|
+
drain.map(r => (r.state === 'count' ? [r.class, r.state, r.count, r.sessions.map(s => [s.sessionId, s.count])] : [r.class, r.state])),
|
|
137
|
+
]);
|
|
138
|
+
}
|
|
139
|
+
function judge(facts) {
|
|
140
|
+
const engine = own(facts, 'engine');
|
|
141
|
+
const d = crossingOf(engine);
|
|
142
|
+
if (d.crossing === 'newer') {
|
|
143
|
+
return Object.freeze({ kind: 'hold', reason: 'newer_engine', crossing: 'newer', running: d.running, own: d.own, source: d.source });
|
|
144
|
+
}
|
|
145
|
+
if (d.crossing === 'none' || d.crossing === 'same')
|
|
146
|
+
return Object.freeze({ kind: 'clear', crossing: d.crossing });
|
|
147
|
+
const drain = drainOf(own(facts, 'drain'));
|
|
148
|
+
const classes = Object.freeze(drain.filter(r => !(r.state === 'count' && r.count === 0)));
|
|
149
|
+
const holding = drain.some(r => r.state === 'failed' || (r.state === 'count' && r.count > 0));
|
|
150
|
+
const fingerprint = fingerprintOf(d.crossing, engine, drain);
|
|
151
|
+
const informedRaw = own(facts, 'informed');
|
|
152
|
+
const informed = typeof informedRaw === 'string' && informedRaw === fingerprint;
|
|
153
|
+
if (d.crossing === 'older') {
|
|
154
|
+
if (!holding)
|
|
155
|
+
return Object.freeze({ kind: 'clear', crossing: 'older' });
|
|
156
|
+
if (informed)
|
|
157
|
+
return Object.freeze({ kind: 'swap_and_tell', crossing: 'older', classes });
|
|
158
|
+
return Object.freeze({ kind: 'hold', reason: 'drain_unconfirmed', crossing: 'older', classes, fingerprint });
|
|
159
|
+
}
|
|
160
|
+
if (informed) {
|
|
161
|
+
return holding
|
|
162
|
+
? Object.freeze({ kind: 'swap_and_tell', crossing: 'unknown', classes })
|
|
163
|
+
: Object.freeze({ kind: 'clear', crossing: 'unknown' });
|
|
164
|
+
}
|
|
165
|
+
return Object.freeze({ kind: 'unknown', crossing: 'unknown', classes, fingerprint });
|
|
166
|
+
}
|
|
167
|
+
const UNKNOWN_ALL_FAILED = () => {
|
|
168
|
+
const drain = Object.freeze(ENGINE_DRAIN_CLASSES.map(failedOf));
|
|
169
|
+
return Object.freeze({ kind: 'unknown', crossing: 'unknown', classes: drain, fingerprint: fingerprintOf('unknown', undefined, drain) });
|
|
170
|
+
};
|
|
171
|
+
export function engineSwapCrossingVerdict(facts) {
|
|
172
|
+
try {
|
|
173
|
+
return judge(facts);
|
|
174
|
+
}
|
|
175
|
+
catch {
|
|
176
|
+
return UNKNOWN_ALL_FAILED();
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
const PARKED = 'parked_tool_approvals';
|
|
180
|
+
function parkedOf(emission) {
|
|
181
|
+
if (!isObject(emission) || own(emission, 'kind') !== 'snapshot')
|
|
182
|
+
return failedOf(PARKED);
|
|
183
|
+
const droppedSlot = slotReadOf(emission, 'pendingDropped');
|
|
184
|
+
if (droppedSlot.presence === 'unreadable')
|
|
185
|
+
return failedOf(PARKED);
|
|
186
|
+
if (droppedSlot.presence === 'present' && droppedSlot.value !== undefined && !(isCount(droppedSlot.value) && droppedSlot.value === 0))
|
|
187
|
+
return failedOf(PARKED);
|
|
188
|
+
const rows = elementsOf(own(emission, 'pending'));
|
|
189
|
+
if (rows === undefined)
|
|
190
|
+
return failedOf(PARKED);
|
|
191
|
+
const tally = new Map();
|
|
192
|
+
for (const row of rows) {
|
|
193
|
+
if (!isObject(row))
|
|
194
|
+
return failedOf(PARKED);
|
|
195
|
+
const sort = checkpointQueueRowSortOf(row);
|
|
196
|
+
if (sort === 'excluded')
|
|
197
|
+
continue;
|
|
198
|
+
if (sort === 'unreadable')
|
|
199
|
+
return failedOf(PARKED);
|
|
200
|
+
const gate = slotReadOf(row, 'gateKind');
|
|
201
|
+
const leg = gate.presence === 'unreadable' ? 'unreadable' : durableDecideLegOf({ gateKind: typeof gate.value === 'string' ? gate.value : null });
|
|
202
|
+
if (leg === 'plan_review' || leg === 'other_gate')
|
|
203
|
+
continue;
|
|
204
|
+
const verdict = checkpointRowVerdictOf(row);
|
|
205
|
+
if (verdict !== undefined && verdict.kind !== 'ok')
|
|
206
|
+
continue;
|
|
207
|
+
if (leg !== 'approval')
|
|
208
|
+
return failedOf(PARKED);
|
|
209
|
+
const sessionId = nonEmpty(own(row, 'sessionId'));
|
|
210
|
+
if (sessionId === undefined)
|
|
211
|
+
return failedOf(PARKED);
|
|
212
|
+
tally.set(sessionId, (tally.get(sessionId) ?? 0) + 1);
|
|
213
|
+
}
|
|
214
|
+
const sessions = [...tally.entries()]
|
|
215
|
+
.sort(([a], [b]) => (a < b ? -1 : a > b ? 1 : 0))
|
|
216
|
+
.map(([sessionId, count]) => Object.freeze({ sessionId, count }));
|
|
217
|
+
const count = sessions.reduce((n, s) => n + s.count, 0);
|
|
218
|
+
return Object.freeze({ class: PARKED, state: 'count', count, sessions: Object.freeze(sessions) });
|
|
219
|
+
}
|
|
220
|
+
export function parkedToolApprovalsBySession(emission) {
|
|
221
|
+
try {
|
|
222
|
+
return parkedOf(emission);
|
|
223
|
+
}
|
|
224
|
+
catch {
|
|
225
|
+
return failedOf(PARKED);
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
function say(key, lang, params) {
|
|
229
|
+
return renderMessage(msg(key, params), lang);
|
|
230
|
+
}
|
|
231
|
+
function classLine(r, lang) {
|
|
232
|
+
const state = own(r, 'state');
|
|
233
|
+
if (state === 'failed')
|
|
234
|
+
return say('localEngine.swapGuard.parked.failed', lang);
|
|
235
|
+
if (state === 'unsupported')
|
|
236
|
+
return say('localEngine.swapGuard.parked.unsupported', lang);
|
|
237
|
+
const count = own(r, 'count');
|
|
238
|
+
if (state !== 'count' || !isCount(count) || count === 0)
|
|
239
|
+
return undefined;
|
|
240
|
+
if (count === 1)
|
|
241
|
+
return say('localEngine.swapGuard.parked.one', lang);
|
|
242
|
+
const sessions = elementsOf(own(r, 'sessions'));
|
|
243
|
+
if (sessions !== undefined && sessions.length > 1)
|
|
244
|
+
return say('localEngine.swapGuard.parked.manySessions', lang, { count, sessions: sessions.length });
|
|
245
|
+
return say('localEngine.swapGuard.parked.oneSession', lang, { count });
|
|
246
|
+
}
|
|
247
|
+
function toldLine(r, lang) {
|
|
248
|
+
const state = own(r, 'state');
|
|
249
|
+
if (state === 'failed' || state === 'unsupported')
|
|
250
|
+
return say('localEngine.swapGuard.told.unknown', lang);
|
|
251
|
+
const count = own(r, 'count');
|
|
252
|
+
if (state !== 'count' || !isCount(count) || count === 0)
|
|
253
|
+
return undefined;
|
|
254
|
+
return count === 1 ? say('localEngine.swapGuard.told.one', lang) : say('localEngine.swapGuard.told.other', lang, { count });
|
|
255
|
+
}
|
|
256
|
+
function classesOf(v) {
|
|
257
|
+
return elementsOf(own(v, 'classes')) ?? [];
|
|
258
|
+
}
|
|
259
|
+
function joined(parts, lang) {
|
|
260
|
+
const out = parts.filter((p) => typeof p === 'string' && p.length > 0);
|
|
261
|
+
return out.length > 0 ? out.join(lang === 'zh' ? '' : ' ') : undefined;
|
|
262
|
+
}
|
|
263
|
+
export function engineSwapCrossingText(verdict, lane, upgrade, lang) {
|
|
264
|
+
try {
|
|
265
|
+
const kind = own(verdict, 'kind');
|
|
266
|
+
const reason = own(verdict, 'reason');
|
|
267
|
+
if (kind === 'hold' && reason === 'newer_engine') {
|
|
268
|
+
const running = own(verdict, 'running');
|
|
269
|
+
const mine = own(verdict, 'own');
|
|
270
|
+
const source = own(verdict, 'source');
|
|
271
|
+
if (typeof running !== 'string' || typeof mine !== 'string' || compareReleaseVersions(running, mine) !== 1)
|
|
272
|
+
return undefined;
|
|
273
|
+
if (source !== 'running' && source !== 'high-water')
|
|
274
|
+
return undefined;
|
|
275
|
+
const head = say(source === 'high-water' ? 'localEngine.swapGuard.newer.highWater' : 'localEngine.swapGuard.newer', lang, { running, own: mine });
|
|
276
|
+
const way = upgrade === 'cli-update'
|
|
277
|
+
? say('localEngine.swapGuard.newer.cliUpdate', lang)
|
|
278
|
+
: upgrade === 'app-update'
|
|
279
|
+
? say('localEngine.swapGuard.newer.appUpdate', lang)
|
|
280
|
+
: undefined;
|
|
281
|
+
return joined([head, way], lang);
|
|
282
|
+
}
|
|
283
|
+
const wayOut = () => say(lane === 'interactive' ? 'localEngine.swapGuard.wayOut.interactive' : 'localEngine.swapGuard.wayOut.print', lang);
|
|
284
|
+
if (kind === 'hold' && reason === 'drain_unconfirmed') {
|
|
285
|
+
return joined([say('localEngine.swapGuard.hold', lang), ...classesOf(verdict).map(r => classLine(r, lang)), wayOut()], lang);
|
|
286
|
+
}
|
|
287
|
+
if (kind === 'unknown') {
|
|
288
|
+
return joined([say('localEngine.swapGuard.unknown', lang), ...classesOf(verdict).map(r => classLine(r, lang)), wayOut()], lang);
|
|
289
|
+
}
|
|
290
|
+
if (kind === 'swap_and_tell')
|
|
291
|
+
return joined(classesOf(verdict).map(r => toldLine(r, lang)), lang);
|
|
292
|
+
return undefined;
|
|
293
|
+
}
|
|
294
|
+
catch {
|
|
295
|
+
return undefined;
|
|
296
|
+
}
|
|
297
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import type { RequestLane } from './request/taskRequest.js';
|
|
2
|
+
import type { UiLanguage } from './env/uiLanguage.js';
|
|
3
|
+
import { type HealthProbeVerdict } from './engineHealthProbeVerdict.js';
|
|
4
|
+
export declare const ENGINE_UNAVAILABLE_REASONS: readonly ["not_running", "not_answering", "address_refused", "version_refused", "model_setup", "credential_conflict", "credential_refused", "data_root_refused", "previous_not_stopped"];
|
|
5
|
+
export type EngineUnavailableReason = (typeof ENGINE_UNAVAILABLE_REASONS)[number];
|
|
6
|
+
export type EngineBootRefusalReason = Extract<EngineUnavailableReason, 'model_setup' | 'credential_conflict' | 'credential_refused' | 'data_root_refused'>;
|
|
7
|
+
export declare const ENGINE_INSTALL_SHAPES: readonly ["npm-global", "managed", "npm-local", "dev", "app", "unknown"];
|
|
8
|
+
export type EngineInstallShape = (typeof ENGINE_INSTALL_SHAPES)[number];
|
|
9
|
+
export type EngineBootRefusalForm = {
|
|
10
|
+
readonly kind: 'embedded';
|
|
11
|
+
readonly install: EngineInstallShape;
|
|
12
|
+
readonly dataDir?: string;
|
|
13
|
+
} | {
|
|
14
|
+
readonly kind: 'deployment';
|
|
15
|
+
};
|
|
16
|
+
export type EngineDataRootVariant = 'newer_root' | 'unreadable' | 'unknown';
|
|
17
|
+
export type EngineBootWayOut = 'newer_build' | 'separate_data_root' | 'restore_backup' | 'repair_access';
|
|
18
|
+
export declare const ENGINE_BOOT_REFUSAL_CODES: Readonly<Record<string, EngineBootRefusalReason>>;
|
|
19
|
+
export interface LocalEngineBootRefusal {
|
|
20
|
+
readonly code?: string;
|
|
21
|
+
readonly hint?: string;
|
|
22
|
+
readonly text: string;
|
|
23
|
+
readonly reason?: EngineBootRefusalReason;
|
|
24
|
+
readonly restartWouldHelp?: false;
|
|
25
|
+
readonly variant?: EngineDataRootVariant;
|
|
26
|
+
readonly findings?: readonly string[];
|
|
27
|
+
readonly highWater?: string;
|
|
28
|
+
readonly engineVersion?: string;
|
|
29
|
+
readonly markerPath?: string;
|
|
30
|
+
readonly waysOut?: readonly EngineBootWayOut[];
|
|
31
|
+
}
|
|
32
|
+
export declare function engineBootRefusalOf(lines: readonly string[], scrub: (s: string) => string): LocalEngineBootRefusal | undefined;
|
|
33
|
+
export declare function engineBootRefusalSentence(refusal: LocalEngineBootRefusal, lang?: UiLanguage, form?: EngineBootRefusalForm): string | undefined;
|
|
34
|
+
export interface EngineUnavailableFacts {
|
|
35
|
+
readonly reason?: EngineUnavailableReason;
|
|
36
|
+
readonly code?: string;
|
|
37
|
+
readonly detail?: string;
|
|
38
|
+
readonly refusal?: LocalEngineBootRefusal;
|
|
39
|
+
readonly engineExitCode?: number | null;
|
|
40
|
+
readonly engineSignal?: string | null;
|
|
41
|
+
readonly pid?: number;
|
|
42
|
+
readonly answer?: HealthProbeVerdict;
|
|
43
|
+
readonly form?: EngineBootRefusalForm;
|
|
44
|
+
}
|
|
45
|
+
export declare function engineUnavailableLine(facts: EngineUnavailableFacts, lane: RequestLane, lang?: UiLanguage): string | undefined;
|