@sema-agent/client-core 0.109.0 → 0.111.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +342 -0
- package/README.md +88 -32
- package/dist/abortableSleep.d.ts +7 -0
- package/dist/abortableSleep.js +37 -0
- package/dist/adapt/arms.js +45 -11
- 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 +20 -15
- 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/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/compactionStatus.d.ts +9 -0
- package/dist/compactionStatus.js +29 -5
- package/dist/controlRouter.js +2 -1
- package/dist/coreValuePorts.d.ts +39 -1
- package/dist/coreValuePorts.js +10 -0
- package/dist/declared/supportFloorDeclared.js +1 -1
- package/dist/displayUntrusted.d.ts +1 -0
- package/dist/displayUntrusted.js +138 -14
- package/dist/engineErrorCodes.d.ts +3 -0
- package/dist/engineErrorCodes.js +3 -0
- package/dist/engineHealthFacts.d.ts +20 -0
- package/dist/engineHealthFacts.js +42 -1
- package/dist/engineHealthProbeVerdict.d.ts +23 -0
- package/dist/engineHealthProbeVerdict.js +115 -0
- package/dist/engineInlineTaskStats.d.ts +4 -3
- package/dist/engineInlineTaskStats.js +18 -2
- package/dist/engineNoticeCodes.d.ts +10 -0
- package/dist/engineNoticeCodes.js +36 -6
- package/dist/engineRepoint.d.ts +147 -0
- package/dist/engineRepoint.js +310 -0
- package/dist/engineRowRef.d.ts +3 -0
- package/dist/engineRowRef.js +13 -1
- package/dist/engineSessionMessages.d.ts +2 -1
- package/dist/engineSessionMessages.js +5 -0
- package/dist/engineSwapCrossing.d.ts +57 -0
- package/dist/engineSwapCrossing.js +297 -0
- package/dist/engineUnavailable.d.ts +44 -0
- package/dist/engineUnavailable.js +492 -0
- package/dist/errorSupplementRoles.js +2 -1
- package/dist/eventLeg.js +3 -3
- package/dist/fleet/fleetProjection.js +3 -2
- package/dist/generated/engineFactTables.d.ts +2 -0
- package/dist/generated/engineFactTables.js +12 -0
- package/dist/generated/sdkFactTables.d.ts +2 -1
- package/dist/generated/sdkFactTables.js +5 -0
- package/dist/generated/settingsSchemaTables.d.ts +4 -0
- package/dist/generated/settingsSchemaTables.js +1 -0
- package/dist/hitl/approvalAskers.d.ts +6 -0
- package/dist/hitl/approvalAskers.js +30 -0
- package/dist/hitl/approvalCardReasons.js +6 -3
- package/dist/hitl/approvalDelivery.d.ts +1 -0
- package/dist/hitl/approvalDelivery.js +1 -1
- package/dist/hitl/approvalRequestFrameReading.d.ts +7 -0
- package/dist/hitl/approvalRequestFrameReading.js +11 -0
- package/dist/hitl/approvalResolution.d.ts +9 -2
- package/dist/hitl/approvalResolution.js +6 -1
- package/dist/hitl/askGateWire.js +5 -8
- package/dist/hitl/automaticAnswerVerdict.js +2 -2
- package/dist/hitl/decisionConflict.js +6 -3
- package/dist/hitl/decisionRefusal.d.ts +2 -0
- package/dist/hitl/decisionRefusal.js +8 -8
- package/dist/hitl/decisionRefusalCarrier.d.ts +3 -0
- package/dist/hitl/decisionRefusalCarrier.js +348 -0
- package/dist/hitl/decisionSend.d.ts +10 -0
- package/dist/hitl/decisionSend.js +57 -17
- package/dist/hitl/editedApprovalAcceptance.d.ts +25 -0
- package/dist/hitl/editedApprovalAcceptance.js +26 -0
- 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 +12 -33
- package/dist/hitl/gateIdentity.d.ts +5 -0
- package/dist/hitl/gateIdentity.js +23 -0
- package/dist/hitl/gateLedger.d.ts +0 -4
- package/dist/hitl/gateLedger.js +0 -19
- package/dist/hitl/hitlBridge.d.ts +7 -0
- package/dist/hitl/hitlBridge.js +14 -8
- package/dist/hitl/hitlHostSurface.d.ts +3 -1
- package/dist/hitl/hitlHostSurface.js +14 -4
- package/dist/hitl/hostWithdrawal.d.ts +15 -0
- package/dist/hitl/hostWithdrawal.js +38 -0
- package/dist/hitl/localAllowRedemption.d.ts +67 -0
- package/dist/hitl/localAllowRedemption.js +256 -0
- package/dist/hitl/parkResolver.js +32 -13
- package/dist/hitl/persistedRulesWire.d.ts +16 -0
- package/dist/hitl/persistedRulesWire.js +72 -2
- package/dist/hitl/planReviewWire.d.ts +3 -0
- package/dist/hitl/planReviewWire.js +37 -10
- 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 +362 -0
- package/dist/hitl/sessionPolicyWire.js +6 -4
- package/dist/hitl/standingRows.d.ts +4 -1
- package/dist/hitl/standingRows.js +33 -1
- package/dist/hitl/toolApprovalWire.d.ts +64 -15
- package/dist/hitl/toolApprovalWire.js +470 -125
- package/dist/hooksWireCaps.js +31 -1
- package/dist/hostSettingNoticeArm.d.ts +3 -0
- package/dist/hostSettingNoticeArm.js +12 -0
- package/dist/hostTurnSettings.d.ts +13 -4
- package/dist/hostTurnSettings.js +150 -10
- package/dist/humanTurnRead.js +11 -1
- package/dist/i18n/messages.en.d.ts +212 -0
- package/dist/i18n/messages.en.js +217 -5
- package/dist/i18n/messages.zh.js +235 -5
- 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 +56 -16
- package/dist/index.js +40 -12
- package/dist/inheritEnvCapability.js +2 -0
- package/dist/inputAuthor.d.ts +16 -0
- package/dist/inputAuthor.js +44 -0
- package/dist/interactiveHalt.js +2 -1
- package/dist/interactiveInterrupt.js +20 -2
- package/dist/interruptRefusalNote.d.ts +2 -0
- package/dist/interruptRefusalNote.js +17 -0
- package/dist/liveModelCatalog.d.ts +2 -0
- package/dist/liveModelCatalog.js +23 -9
- package/dist/liveQuestionStore.d.ts +4 -1
- package/dist/liveQuestionStore.js +12 -3
- 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/mcpEngineLeg.d.ts +3 -0
- package/dist/mcpEngineLeg.js +38 -1
- package/dist/mcpPanel.js +2 -0
- package/dist/mcpReconnect.d.ts +9 -1
- package/dist/mcpReconnect.js +124 -19
- package/dist/mcpWireCaps.js +1 -1
- package/dist/model/engineModelWords.d.ts +3 -0
- package/dist/model/engineModelWords.js +13 -0
- package/dist/model/subagentModelWord.d.ts +21 -2
- package/dist/model/subagentModelWord.js +100 -29
- package/dist/modelCapabilityProbe.js +7 -43
- package/dist/modsFace.d.ts +8 -1
- package/dist/modsFace.js +27 -0
- package/dist/notifications.d.ts +36 -6
- package/dist/notifications.js +170 -20
- package/dist/ownKey.d.ts +6 -5
- package/dist/ownKey.js +31 -7
- package/dist/peerFrames.d.ts +40 -2
- package/dist/peerFrames.js +158 -3
- package/dist/pendingUserRow.d.ts +4 -0
- package/dist/pendingUserRow.js +16 -0
- package/dist/permissionsDeclaration.d.ts +1 -0
- package/dist/permissionsDeclaration.js +11 -1
- package/dist/planReviewCardFacts.d.ts +3 -0
- package/dist/planReviewCardFacts.js +52 -2
- package/dist/pluginHooksWire.d.ts +10 -1
- package/dist/pluginHooksWire.js +96 -7
- package/dist/printToolResultFrame.js +4 -2
- package/dist/promptBlockedCopy.js +11 -6
- 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/replayBody.js +10 -2
- package/dist/request/taskRequest.d.ts +5 -0
- package/dist/request/taskRequest.js +142 -21
- package/dist/requestCoordinate.d.ts +1 -0
- package/dist/requestCoordinate.js +13 -0
- package/dist/resumeRefusalCopy.d.ts +1 -3
- package/dist/resumeRefusalCopy.js +2 -1
- package/dist/retryStatus.d.ts +2 -2
- package/dist/retryStatus.js +2 -0
- package/dist/rewindArchiveReading.js +4 -4
- package/dist/runCancelContext.d.ts +2 -1
- package/dist/runCancelContext.js +1 -0
- package/dist/runPermissionModeSwitch.js +2 -2
- package/dist/scenarioRefusal.js +11 -13
- package/dist/scenarioSkills.js +11 -6
- package/dist/seam.d.ts +27 -2
- package/dist/seam.js +17 -1
- package/dist/seatContract.d.ts +189 -12
- package/dist/seatContract.js +401 -9
- package/dist/sessionBackground.js +2 -1
- package/dist/sessionBackgroundHandoff.js +2 -1
- package/dist/sessionCostReading.d.ts +70 -0
- package/dist/sessionCostReading.js +150 -0
- package/dist/sessionEngine.d.ts +2 -0
- package/dist/sessionEngine.js +111 -0
- package/dist/sessionHooksRoster.d.ts +4 -0
- package/dist/sessionHooksRoster.js +158 -0
- package/dist/sessionMemoryStatus.d.ts +2 -1
- package/dist/sessionMemoryStatus.js +2 -2
- package/dist/sessionReadRedaction.d.ts +7 -0
- package/dist/sessionReadRedaction.js +26 -0
- package/dist/sessionSyncFileHistory.d.ts +4 -0
- package/dist/sessionSyncFileHistory.js +27 -0
- package/dist/settingsHooksSalvage.js +2 -1
- package/dist/sseIdleTriage.d.ts +13 -1
- package/dist/sseIdleTriage.js +25 -6
- 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 +8 -1
- package/dist/subagentContentStore.d.ts +11 -0
- package/dist/subagentContentStore.js +28 -2
- package/dist/terminalStatuses.d.ts +1 -0
- package/dist/terminalStatuses.js +4 -1
- package/dist/toolResult.d.ts +1 -0
- package/dist/toolResult.js +2 -0
- package/dist/turnFailurePresentation.js +9 -2
- package/dist/typePins.d.ts +11 -0
- package/dist/usageAnalytics.d.ts +17 -0
- package/dist/usageAnalytics.js +44 -2
- package/dist/userAttachmentEnvelope.d.ts +2 -1
- package/dist/userAttachmentEnvelope.js +10 -0
- package/dist/wireErrorTriage.js +2 -1
- package/dist/wireFailureShape.d.ts +6 -5
- package/dist/wireFailureShape.js +150 -38
- package/dist/wireRefusalCopy.d.ts +16 -5
- package/dist/wireRefusalCopy.js +119 -86
- package/docs/INTEGRATION-CLIENTS.md +4228 -21
- package/package.json +7 -3
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import { type DeviceListVerb } from './deviceRebind.js';
|
|
2
|
+
import { type SessionMapStorePort } from './sessionMap.js';
|
|
3
|
+
import { type MessageRef } from './i18n/translate.js';
|
|
4
|
+
declare const HELLO_REJECT_WORDS: readonly ["auth_failed", "revoked", "protocol_version_unsupported", "draining", "already_connected"];
|
|
5
|
+
export type DeviceHelloRejectWord = (typeof HELLO_REJECT_WORDS)[number];
|
|
6
|
+
export type DeviceHelloReading = {
|
|
7
|
+
readonly kind: 'ack';
|
|
8
|
+
} | {
|
|
9
|
+
readonly kind: 'reject';
|
|
10
|
+
readonly code: DeviceHelloRejectWord;
|
|
11
|
+
} | {
|
|
12
|
+
readonly kind: 'unreadable';
|
|
13
|
+
};
|
|
14
|
+
export declare function deviceHelloReadingOf(frame: {} | null | undefined): DeviceHelloReading;
|
|
15
|
+
export interface EngineRepointInput {
|
|
16
|
+
readonly from: string;
|
|
17
|
+
readonly to: string;
|
|
18
|
+
readonly continuity?: EngineRepointContinuity;
|
|
19
|
+
}
|
|
20
|
+
export interface EngineRepointContinuity {
|
|
21
|
+
readonly deviceId: string;
|
|
22
|
+
readonly from: string;
|
|
23
|
+
readonly to: string;
|
|
24
|
+
}
|
|
25
|
+
export interface EngineRepointHandshakeTarget {
|
|
26
|
+
readonly address: string;
|
|
27
|
+
readonly deviceId: string;
|
|
28
|
+
}
|
|
29
|
+
export type EngineRepointHandshakePort = (target: EngineRepointHandshakeTarget, opts?: {
|
|
30
|
+
readonly signal?: AbortSignal;
|
|
31
|
+
}) => Promise<{} | null | undefined> | {} | null | undefined;
|
|
32
|
+
export interface EngineRepointRoster {
|
|
33
|
+
readonly credential: 'operator' | 'non-operator';
|
|
34
|
+
readonly devices: (address: string) => DeviceListVerb | null | undefined;
|
|
35
|
+
}
|
|
36
|
+
export type EngineRepointRecordReading = {
|
|
37
|
+
readonly kind: 'absent';
|
|
38
|
+
} | EngineRepointRecordPresent | {
|
|
39
|
+
readonly kind: 'unreadable';
|
|
40
|
+
};
|
|
41
|
+
export interface EngineRepointRecordPresent {
|
|
42
|
+
readonly kind: 'present';
|
|
43
|
+
readonly status: 'active' | 'enrolling' | 'revoked';
|
|
44
|
+
readonly deviceId?: string;
|
|
45
|
+
}
|
|
46
|
+
export type EngineRepointMoveResult = {
|
|
47
|
+
readonly kind: 'moved';
|
|
48
|
+
} | {
|
|
49
|
+
readonly kind: 'failed';
|
|
50
|
+
};
|
|
51
|
+
export interface EngineRepointRecordPort {
|
|
52
|
+
read(address: string): EngineRepointRecordReading | Promise<EngineRepointRecordReading>;
|
|
53
|
+
move(from: string, to: string): EngineRepointMoveResult | Promise<EngineRepointMoveResult>;
|
|
54
|
+
}
|
|
55
|
+
export interface EngineRepointSessionsPort {
|
|
56
|
+
stores(): readonly SessionMapStorePort[] | Promise<readonly SessionMapStorePort[]>;
|
|
57
|
+
}
|
|
58
|
+
export interface EngineRepointPorts {
|
|
59
|
+
readonly handshake?: EngineRepointHandshakePort;
|
|
60
|
+
readonly roster?: EngineRepointRoster;
|
|
61
|
+
readonly record: EngineRepointRecordPort;
|
|
62
|
+
readonly sessions: EngineRepointSessionsPort;
|
|
63
|
+
readonly signal?: AbortSignal;
|
|
64
|
+
}
|
|
65
|
+
export type EngineRepointProofState = 'proven' | 'unproven' | 'unreadable';
|
|
66
|
+
export type EngineRepointHandshakeProof = {
|
|
67
|
+
readonly state: 'proven';
|
|
68
|
+
} | {
|
|
69
|
+
readonly state: 'unproven';
|
|
70
|
+
readonly why: 'auth_failed' | 'revoked';
|
|
71
|
+
} | {
|
|
72
|
+
readonly state: 'unreadable';
|
|
73
|
+
readonly why: 'draining' | 'already_connected' | 'protocol_version_unsupported' | 'unreadable_frame' | 'transport' | 'unarmed';
|
|
74
|
+
};
|
|
75
|
+
export type EngineRepointRosterProof = {
|
|
76
|
+
readonly state: 'proven';
|
|
77
|
+
} | {
|
|
78
|
+
readonly state: 'unproven';
|
|
79
|
+
readonly why: 'not-listed' | 'lane-absent';
|
|
80
|
+
} | {
|
|
81
|
+
readonly state: 'unreadable';
|
|
82
|
+
readonly why: 'operator-credential' | 'credential-unknown' | 'list-incomplete' | 'refused' | 'transport' | 'unreadable' | 'unarmed';
|
|
83
|
+
};
|
|
84
|
+
export interface EngineRepointProofs {
|
|
85
|
+
readonly handshake: EngineRepointHandshakeProof;
|
|
86
|
+
readonly roster: EngineRepointRosterProof;
|
|
87
|
+
}
|
|
88
|
+
export type EngineRepointVerdict = 'apply' | 'unverified' | 'undetermined';
|
|
89
|
+
export interface EngineRepointExit {
|
|
90
|
+
readonly path: 'reenroll-at-engine-address';
|
|
91
|
+
readonly address: string;
|
|
92
|
+
readonly removeDeviceId: string;
|
|
93
|
+
}
|
|
94
|
+
export interface EngineRepointSessionTally {
|
|
95
|
+
readonly moved: number;
|
|
96
|
+
readonly unaffected: number;
|
|
97
|
+
readonly conflict: number;
|
|
98
|
+
readonly unreadable: number;
|
|
99
|
+
readonly storeFailed: number;
|
|
100
|
+
}
|
|
101
|
+
export type EngineRepointRefusal = 'address-invalid' | 'same-address' | 'record-absent' | 'record-not-active' | 'record-unreadable' | 'target-occupied' | 'roster-unbound' | 'unarmed';
|
|
102
|
+
export type EngineRepointResult = EngineRepointDone | EngineRepointPartial | EngineRepointUnverified | EngineRepointUndetermined | EngineRepointStoreFailed | EngineRepointRefused;
|
|
103
|
+
export interface EngineRepointDone {
|
|
104
|
+
readonly kind: 'repointed';
|
|
105
|
+
readonly deviceId: string;
|
|
106
|
+
readonly continuity: EngineRepointContinuity;
|
|
107
|
+
readonly record: 'moved' | 'already-there';
|
|
108
|
+
readonly sessions: EngineRepointSessionTally;
|
|
109
|
+
readonly proofs: EngineRepointProofs;
|
|
110
|
+
}
|
|
111
|
+
export interface EngineRepointPartial {
|
|
112
|
+
readonly kind: 'partial';
|
|
113
|
+
readonly stage: 'sessions' | 'sessions-list';
|
|
114
|
+
readonly deviceId: string;
|
|
115
|
+
readonly continuity: EngineRepointContinuity;
|
|
116
|
+
readonly record: 'moved' | 'already-there';
|
|
117
|
+
readonly sessions: EngineRepointSessionTally;
|
|
118
|
+
readonly proofs: EngineRepointProofs;
|
|
119
|
+
}
|
|
120
|
+
export interface EngineRepointUnverified {
|
|
121
|
+
readonly kind: 'unverified';
|
|
122
|
+
readonly deviceId: string;
|
|
123
|
+
readonly proofs: EngineRepointProofs;
|
|
124
|
+
readonly exit: EngineRepointExit;
|
|
125
|
+
}
|
|
126
|
+
export interface EngineRepointUndetermined {
|
|
127
|
+
readonly kind: 'undetermined';
|
|
128
|
+
readonly deviceId: string;
|
|
129
|
+
readonly proofs: EngineRepointProofs;
|
|
130
|
+
readonly exit: EngineRepointExit;
|
|
131
|
+
readonly retryable: true;
|
|
132
|
+
}
|
|
133
|
+
export interface EngineRepointStoreFailed {
|
|
134
|
+
readonly kind: 'store-failed';
|
|
135
|
+
readonly stage: 'record';
|
|
136
|
+
readonly deviceId: string;
|
|
137
|
+
readonly continuity: EngineRepointContinuity;
|
|
138
|
+
}
|
|
139
|
+
export interface EngineRepointRefused {
|
|
140
|
+
readonly kind: 'refused';
|
|
141
|
+
readonly reason: EngineRepointRefusal;
|
|
142
|
+
readonly recordStatus?: 'enrolling' | 'revoked';
|
|
143
|
+
}
|
|
144
|
+
export declare function engineRepointVerdictOf(proofs: {} | null | undefined): EngineRepointVerdict;
|
|
145
|
+
export declare function repointEngine(input: EngineRepointInput, ports: EngineRepointPorts): Promise<EngineRepointResult>;
|
|
146
|
+
export declare function engineRepointMessageOf(result: {} | null | undefined): MessageRef | undefined;
|
|
147
|
+
export {};
|
|
@@ -0,0 +1,310 @@
|
|
|
1
|
+
import { listDevices } from './deviceRebind.js';
|
|
2
|
+
import { engineUrlTransportVerdict, normalizeEngineBaseUrl } from './engineUrl.js';
|
|
3
|
+
import { engineNamespaceKeyFor } from './sessionMap.js';
|
|
4
|
+
import { repointSessionEngine } from './sessionEngine.js';
|
|
5
|
+
import { slotReadOf } from './wireFailureShape.js';
|
|
6
|
+
import { msg } from './i18n/translate.js';
|
|
7
|
+
const HELLO_REJECT_WORDS = Object.freeze(['auth_failed', 'revoked', 'protocol_version_unsupported', 'draining', 'already_connected']);
|
|
8
|
+
const HELLO_ACK = Object.freeze({ kind: 'ack' });
|
|
9
|
+
const HELLO_UNREADABLE = Object.freeze({ kind: 'unreadable' });
|
|
10
|
+
function dataOf(o, key) {
|
|
11
|
+
if (o === null || typeof o !== 'object')
|
|
12
|
+
return undefined;
|
|
13
|
+
const s = slotReadOf(o, key);
|
|
14
|
+
return s.presence === 'present' ? s.value : undefined;
|
|
15
|
+
}
|
|
16
|
+
const isObject = (v) => v !== null && typeof v === 'object';
|
|
17
|
+
export function deviceHelloReadingOf(frame) {
|
|
18
|
+
const t = dataOf(frame, 't');
|
|
19
|
+
if (t === 'helloAck')
|
|
20
|
+
return dataOf(frame, 'ok') === true ? HELLO_ACK : HELLO_UNREADABLE;
|
|
21
|
+
if (t === 'helloReject') {
|
|
22
|
+
const code = dataOf(frame, 'code');
|
|
23
|
+
const word = HELLO_REJECT_WORDS.find((w) => w === code);
|
|
24
|
+
return word === undefined ? HELLO_UNREADABLE : Object.freeze({ kind: 'reject', code: word });
|
|
25
|
+
}
|
|
26
|
+
return HELLO_UNREADABLE;
|
|
27
|
+
}
|
|
28
|
+
const freeze = (v) => Object.freeze(v);
|
|
29
|
+
function methodOf(o, key) {
|
|
30
|
+
if (!isObject(o))
|
|
31
|
+
return undefined;
|
|
32
|
+
try {
|
|
33
|
+
const v = o[key];
|
|
34
|
+
return typeof v === 'function' ? v : undefined;
|
|
35
|
+
}
|
|
36
|
+
catch {
|
|
37
|
+
return undefined;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
const HS_PROVEN = freeze({ state: 'proven' });
|
|
41
|
+
async function handshakeProofOf(port, target, signal) {
|
|
42
|
+
if (typeof port !== 'function')
|
|
43
|
+
return freeze({ state: 'unreadable', why: 'unarmed' });
|
|
44
|
+
let frame;
|
|
45
|
+
try {
|
|
46
|
+
frame = await port(target, signal !== undefined ? { signal } : undefined);
|
|
47
|
+
}
|
|
48
|
+
catch {
|
|
49
|
+
return freeze({ state: 'unreadable', why: 'transport' });
|
|
50
|
+
}
|
|
51
|
+
const r = deviceHelloReadingOf(frame);
|
|
52
|
+
if (r.kind === 'ack')
|
|
53
|
+
return HS_PROVEN;
|
|
54
|
+
if (r.kind === 'unreadable')
|
|
55
|
+
return freeze({ state: 'unreadable', why: 'unreadable_frame' });
|
|
56
|
+
if (r.code === 'auth_failed' || r.code === 'revoked')
|
|
57
|
+
return freeze({ state: 'unproven', why: r.code });
|
|
58
|
+
return freeze({ state: 'unreadable', why: r.code });
|
|
59
|
+
}
|
|
60
|
+
const RO_PROVEN = freeze({ state: 'proven' });
|
|
61
|
+
function rosterSliceOf(roster, target) {
|
|
62
|
+
if (!isObject(roster))
|
|
63
|
+
return { kind: 'proof', proof: freeze({ state: 'unreadable', why: 'unarmed' }) };
|
|
64
|
+
const credential = dataOf(roster, 'credential');
|
|
65
|
+
if (credential === 'operator')
|
|
66
|
+
return { kind: 'proof', proof: freeze({ state: 'unreadable', why: 'operator-credential' }) };
|
|
67
|
+
if (credential !== 'non-operator')
|
|
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) {
|
|
82
|
+
const out = await listDevices(devices, signal !== undefined ? { signal } : undefined);
|
|
83
|
+
switch (out.kind) {
|
|
84
|
+
case 'ok':
|
|
85
|
+
if (out.devices.some((d) => d.deviceId === deviceId))
|
|
86
|
+
return RO_PROVEN;
|
|
87
|
+
return out.dropped > 0
|
|
88
|
+
? freeze({ state: 'unreadable', why: 'list-incomplete' })
|
|
89
|
+
: freeze({ state: 'unproven', why: 'not-listed' });
|
|
90
|
+
case 'lane-absent':
|
|
91
|
+
return freeze({ state: 'unproven', why: 'lane-absent' });
|
|
92
|
+
case 'refused':
|
|
93
|
+
return freeze({ state: 'unreadable', why: 'refused' });
|
|
94
|
+
case 'transport':
|
|
95
|
+
return freeze({ state: 'unreadable', why: 'transport' });
|
|
96
|
+
case 'unarmed':
|
|
97
|
+
return freeze({ state: 'unreadable', why: 'unarmed' });
|
|
98
|
+
default:
|
|
99
|
+
return freeze({ state: 'unreadable', why: 'unreadable' });
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
function proofStateOf(proofs, key) {
|
|
103
|
+
const state = dataOf(dataOf(proofs, key), 'state');
|
|
104
|
+
return state === 'proven' || state === 'unproven' ? state : 'unreadable';
|
|
105
|
+
}
|
|
106
|
+
export function engineRepointVerdictOf(proofs) {
|
|
107
|
+
const a = proofStateOf(proofs, 'handshake');
|
|
108
|
+
const b = proofStateOf(proofs, 'roster');
|
|
109
|
+
if (a === 'unreadable' || b === 'unreadable')
|
|
110
|
+
return 'undetermined';
|
|
111
|
+
return a === 'unproven' || b === 'unproven' ? 'unverified' : 'apply';
|
|
112
|
+
}
|
|
113
|
+
const UNREADABLE_RECORD = freeze({ k: 'unreadable' });
|
|
114
|
+
async function recordFactOf(read, port, address) {
|
|
115
|
+
let raw;
|
|
116
|
+
try {
|
|
117
|
+
raw = await read.call(port, address);
|
|
118
|
+
}
|
|
119
|
+
catch {
|
|
120
|
+
return UNREADABLE_RECORD;
|
|
121
|
+
}
|
|
122
|
+
const kind = dataOf(raw, 'kind');
|
|
123
|
+
if (kind === 'absent')
|
|
124
|
+
return freeze({ k: 'absent' });
|
|
125
|
+
if (kind !== 'present')
|
|
126
|
+
return UNREADABLE_RECORD;
|
|
127
|
+
const status = dataOf(raw, 'status');
|
|
128
|
+
if (status === 'enrolling' || status === 'revoked')
|
|
129
|
+
return freeze({ k: 'other', status });
|
|
130
|
+
if (status !== 'active')
|
|
131
|
+
return UNREADABLE_RECORD;
|
|
132
|
+
const deviceId = dataOf(raw, 'deviceId');
|
|
133
|
+
return typeof deviceId === 'string' && deviceId !== '' ? freeze({ k: 'active', deviceId }) : UNREADABLE_RECORD;
|
|
134
|
+
}
|
|
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) {
|
|
146
|
+
if (from.k === 'unreadable' || to.k === 'unreadable')
|
|
147
|
+
return { kind: 'refused', reason: 'record-unreadable' };
|
|
148
|
+
if (from.k === 'other')
|
|
149
|
+
return { kind: 'refused', reason: 'record-not-active', recordStatus: from.status };
|
|
150
|
+
if (from.k === 'active') {
|
|
151
|
+
if (to.k === 'absent')
|
|
152
|
+
return { kind: 'move', deviceId: from.deviceId };
|
|
153
|
+
if (to.k === 'active' && to.deviceId === from.deviceId)
|
|
154
|
+
return { kind: 'move', deviceId: from.deviceId };
|
|
155
|
+
return { kind: 'refused', reason: 'target-occupied' };
|
|
156
|
+
}
|
|
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
|
+
}
|
|
161
|
+
if (to.k === 'other')
|
|
162
|
+
return { kind: 'refused', reason: 'record-not-active', recordStatus: to.status };
|
|
163
|
+
return { kind: 'refused', reason: 'record-absent' };
|
|
164
|
+
}
|
|
165
|
+
const refusedOf = (reason, recordStatus) => freeze(recordStatus === undefined ? { kind: 'refused', reason } : { kind: 'refused', reason, recordStatus });
|
|
166
|
+
function addressOf(raw, forTarget) {
|
|
167
|
+
const n = normalizeEngineBaseUrl(typeof raw === 'string' ? raw : undefined);
|
|
168
|
+
if (!n.ok)
|
|
169
|
+
return undefined;
|
|
170
|
+
if (forTarget && !engineUrlTransportVerdict(n.url).ok)
|
|
171
|
+
return undefined;
|
|
172
|
+
return n.url;
|
|
173
|
+
}
|
|
174
|
+
function tallyOf(c) {
|
|
175
|
+
return freeze({ moved: c.moved, unaffected: c.unaffected, conflict: c.conflict, unreadable: c.unreadable, storeFailed: c.storeFailed });
|
|
176
|
+
}
|
|
177
|
+
function storeListOf(list) {
|
|
178
|
+
try {
|
|
179
|
+
if (!Array.isArray(list))
|
|
180
|
+
return undefined;
|
|
181
|
+
}
|
|
182
|
+
catch {
|
|
183
|
+
return undefined;
|
|
184
|
+
}
|
|
185
|
+
const len = dataOf(list, 'length');
|
|
186
|
+
if (typeof len !== 'number' || !Number.isSafeInteger(len) || len < 0)
|
|
187
|
+
return undefined;
|
|
188
|
+
const out = [];
|
|
189
|
+
for (let i = 0; i < len; i += 1)
|
|
190
|
+
out.push(dataOf(list, String(i)));
|
|
191
|
+
return out;
|
|
192
|
+
}
|
|
193
|
+
export async function repointEngine(input, ports) {
|
|
194
|
+
try {
|
|
195
|
+
const from = addressOf(dataOf(input, 'from'), false);
|
|
196
|
+
const to = addressOf(dataOf(input, 'to'), true);
|
|
197
|
+
if (from === undefined || to === undefined)
|
|
198
|
+
return refusedOf('address-invalid');
|
|
199
|
+
if (engineNamespaceKeyFor(from) === engineNamespaceKeyFor(to))
|
|
200
|
+
return refusedOf('same-address');
|
|
201
|
+
const recordPort = dataOf(ports, 'record');
|
|
202
|
+
const sessionsPort = dataOf(ports, 'sessions');
|
|
203
|
+
const read = methodOf(recordPort, 'read');
|
|
204
|
+
const move = methodOf(recordPort, 'move');
|
|
205
|
+
const listStores = methodOf(sessionsPort, 'stores');
|
|
206
|
+
if (read === undefined || move === undefined || listStores === undefined)
|
|
207
|
+
return refusedOf('unarmed');
|
|
208
|
+
const handshake = dataOf(ports, 'handshake');
|
|
209
|
+
const roster = dataOf(ports, 'roster');
|
|
210
|
+
const signalRaw = dataOf(ports, 'signal');
|
|
211
|
+
const signal = isObject(signalRaw) ? signalRaw : undefined;
|
|
212
|
+
const evidence = continuityReadingOf(dataOf(input, 'continuity'));
|
|
213
|
+
const [fromFact, toFact] = await Promise.all([recordFactOf(read, recordPort, from), recordFactOf(read, recordPort, to)]);
|
|
214
|
+
const plan = planOf(fromFact, toFact, evidence, { fromKey: engineNamespaceKeyFor(from), toKey: engineNamespaceKeyFor(to) });
|
|
215
|
+
if (plan.kind === 'refused')
|
|
216
|
+
return refusedOf(plan.reason, plan.recordStatus);
|
|
217
|
+
const deviceId = plan.deviceId;
|
|
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)]);
|
|
223
|
+
const proofs = freeze({ handshake: hs, roster: ro });
|
|
224
|
+
const verdict = engineRepointVerdictOf(proofs);
|
|
225
|
+
if (verdict !== 'apply') {
|
|
226
|
+
const exit = freeze({ path: 'reenroll-at-engine-address', address: to, removeDeviceId: deviceId });
|
|
227
|
+
return verdict === 'unverified'
|
|
228
|
+
? freeze({ kind: 'unverified', deviceId, proofs, exit })
|
|
229
|
+
: freeze({ kind: 'undetermined', deviceId, proofs, exit, retryable: true });
|
|
230
|
+
}
|
|
231
|
+
if (plan.kind === 'move') {
|
|
232
|
+
let moved = false;
|
|
233
|
+
try {
|
|
234
|
+
moved = dataOf(await move.call(recordPort, from, to), 'kind') === 'moved';
|
|
235
|
+
}
|
|
236
|
+
catch {
|
|
237
|
+
moved = false;
|
|
238
|
+
}
|
|
239
|
+
if (moved) {
|
|
240
|
+
const [afterFrom, afterTo] = await Promise.all([recordFactOf(read, recordPort, from), recordFactOf(read, recordPort, to)]);
|
|
241
|
+
moved = afterFrom.k === 'absent' && afterTo.k === 'active' && afterTo.deviceId === deviceId;
|
|
242
|
+
}
|
|
243
|
+
if (!moved)
|
|
244
|
+
return freeze({ kind: 'store-failed', stage: 'record', deviceId, continuity });
|
|
245
|
+
}
|
|
246
|
+
const record = plan.kind === 'move' ? 'moved' : 'already-there';
|
|
247
|
+
const counts = { moved: 0, unaffected: 0, conflict: 0, unreadable: 0, storeFailed: 0 };
|
|
248
|
+
let stores;
|
|
249
|
+
try {
|
|
250
|
+
stores = storeListOf(await listStores.call(sessionsPort));
|
|
251
|
+
}
|
|
252
|
+
catch {
|
|
253
|
+
stores = undefined;
|
|
254
|
+
}
|
|
255
|
+
if (stores === undefined)
|
|
256
|
+
return freeze({ kind: 'partial', stage: 'sessions-list', deviceId, continuity, record, sessions: tallyOf(counts), proofs });
|
|
257
|
+
for (const store of stores) {
|
|
258
|
+
const r = repointSessionEngine(store, from, to);
|
|
259
|
+
if (r === 'moved')
|
|
260
|
+
counts.moved += 1;
|
|
261
|
+
else if (r === 'unaffected')
|
|
262
|
+
counts.unaffected += 1;
|
|
263
|
+
else if (r === 'conflict')
|
|
264
|
+
counts.conflict += 1;
|
|
265
|
+
else if (r === 'store-failed')
|
|
266
|
+
counts.storeFailed += 1;
|
|
267
|
+
else
|
|
268
|
+
counts.unreadable += 1;
|
|
269
|
+
}
|
|
270
|
+
const sessions = tallyOf(counts);
|
|
271
|
+
return counts.conflict + counts.unreadable + counts.storeFailed > 0
|
|
272
|
+
? freeze({ kind: 'partial', stage: 'sessions', deviceId, continuity, record, sessions, proofs })
|
|
273
|
+
: freeze({ kind: 'repointed', deviceId, continuity, record, sessions, proofs });
|
|
274
|
+
}
|
|
275
|
+
catch {
|
|
276
|
+
return refusedOf('unarmed');
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
const REFUSAL_KEYS = {
|
|
280
|
+
'address-invalid': 'session.devices.repoint.refused.addressInvalid',
|
|
281
|
+
'same-address': 'session.devices.repoint.refused.sameAddress',
|
|
282
|
+
'record-absent': 'session.devices.repoint.refused.recordAbsent',
|
|
283
|
+
'record-not-active': 'session.devices.repoint.refused.recordNotActive',
|
|
284
|
+
'record-unreadable': 'session.devices.repoint.refused.recordUnreadable',
|
|
285
|
+
'target-occupied': 'session.devices.repoint.refused.targetOccupied',
|
|
286
|
+
'roster-unbound': 'session.devices.repoint.refused.rosterUnbound',
|
|
287
|
+
unarmed: 'session.devices.repoint.refused.unarmed',
|
|
288
|
+
};
|
|
289
|
+
export function engineRepointMessageOf(result) {
|
|
290
|
+
const kind = dataOf(result, 'kind');
|
|
291
|
+
switch (kind) {
|
|
292
|
+
case 'repointed':
|
|
293
|
+
return msg('session.devices.repoint.done');
|
|
294
|
+
case 'partial':
|
|
295
|
+
return msg('session.devices.repoint.partial');
|
|
296
|
+
case 'unverified':
|
|
297
|
+
return msg('session.devices.repoint.unverified');
|
|
298
|
+
case 'undetermined':
|
|
299
|
+
return msg('session.devices.repoint.undetermined');
|
|
300
|
+
case 'store-failed':
|
|
301
|
+
return msg('session.devices.repoint.storeFailed');
|
|
302
|
+
case 'refused': {
|
|
303
|
+
const reason = dataOf(result, 'reason');
|
|
304
|
+
const word = Object.keys(REFUSAL_KEYS).find((w) => w === reason);
|
|
305
|
+
return word === undefined ? undefined : msg(REFUSAL_KEYS[word]);
|
|
306
|
+
}
|
|
307
|
+
default:
|
|
308
|
+
return undefined;
|
|
309
|
+
}
|
|
310
|
+
}
|
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',
|
|
@@ -102,7 +105,16 @@ export const TRANSCRIPT_ROW_SIDECAR_KEYS = Object.freeze([
|
|
|
102
105
|
'_sema_task_notification',
|
|
103
106
|
'_sema_answered_by',
|
|
104
107
|
'_sema_rewrite',
|
|
108
|
+
'_sema_run_origin',
|
|
109
|
+
'_sema_run_origin_unreadable',
|
|
105
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
|
+
}
|
|
106
118
|
export function parkHeldCallIdOf(carrier) {
|
|
107
119
|
return readFrameStringKey(carrier, 'toolCallId');
|
|
108
120
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type RunOriginRowKeys } from './inputAuthor.js';
|
|
1
2
|
export type EngineHistoryJson = string | number | boolean | null | readonly EngineHistoryJson[] | {
|
|
2
3
|
readonly [key: string]: EngineHistoryJson;
|
|
3
4
|
};
|
|
@@ -44,7 +45,7 @@ export interface EngineHistoryMessageBody {
|
|
|
44
45
|
readonly content: string | readonly EngineHistoryBlock[];
|
|
45
46
|
readonly model?: string;
|
|
46
47
|
}
|
|
47
|
-
export interface EngineHistoryMessage {
|
|
48
|
+
export interface EngineHistoryMessage extends RunOriginRowKeys {
|
|
48
49
|
readonly type: 'user' | 'assistant';
|
|
49
50
|
readonly uuid: string;
|
|
50
51
|
readonly session_id: string;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { isGateParkedToolEnd } from './gateOutcome.js';
|
|
2
|
+
import { runOriginRowKeys } from './inputAuthor.js';
|
|
2
3
|
import { appendOwnElement, ownDataField, ownSendableField } from './ownKey.js';
|
|
3
4
|
const isObjectLike = (v) => typeof v === 'object' && v !== null && !Array.isArray(v);
|
|
4
5
|
function optionalOwn(o, key) {
|
|
@@ -344,14 +345,17 @@ export function projectEngineSessionMessages(rows, opts) {
|
|
|
344
345
|
for (let i = 0; i < count; i += 1) {
|
|
345
346
|
let outcome;
|
|
346
347
|
let timestamp;
|
|
348
|
+
let originRow;
|
|
347
349
|
try {
|
|
348
350
|
const row = ownDataField(rows, String(i));
|
|
349
351
|
outcome = projectRow(row, tally);
|
|
350
352
|
timestamp = outcome.kind === 'message' && isObjectLike(row) ? timestampOf(row) : undefined;
|
|
353
|
+
originRow = outcome.kind === 'message' && isObjectLike(row) && ownDataField(row, 'role') === 'user' ? row : undefined;
|
|
351
354
|
}
|
|
352
355
|
catch {
|
|
353
356
|
outcome = unreadable();
|
|
354
357
|
timestamp = undefined;
|
|
358
|
+
originRow = undefined;
|
|
355
359
|
}
|
|
356
360
|
if (outcome.kind === 'skip') {
|
|
357
361
|
tally[outcome.why] += 1;
|
|
@@ -362,6 +366,7 @@ export function projectEngineSessionMessages(rows, opts) {
|
|
|
362
366
|
uuid: `restored-${sessionId}-${messages.length + 1}`,
|
|
363
367
|
session_id: sessionId,
|
|
364
368
|
...(timestamp !== undefined ? { timestamp } : {}),
|
|
369
|
+
...(originRow !== undefined ? runOriginRowKeys(originRow) : {}),
|
|
365
370
|
message: outcome.body,
|
|
366
371
|
parent_tool_use_id: null,
|
|
367
372
|
});
|
|
@@ -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;
|