@sema-agent/client-core 0.97.0 → 0.98.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 +429 -0
- package/README.md +74 -36
- package/dist/adapt/arms.d.ts +1 -0
- package/dist/adapt/arms.js +128 -34
- package/dist/adapt/ids.d.ts +12 -1
- package/dist/adapt/ids.js +59 -8
- package/dist/adapt/instanceLedger.d.ts +50 -0
- package/dist/adapt/instanceLedger.js +147 -0
- package/dist/adapt/textStream.d.ts +1 -0
- package/dist/adapt/textStream.js +24 -7
- package/dist/adapt/toolCards.d.ts +27 -5
- package/dist/adapt/toolCards.js +39 -6
- package/dist/adapt/wireShapes.js +6 -2
- package/dist/adapt.d.ts +2 -0
- package/dist/adapt.js +8 -3
- package/dist/adapter/activeRunSelfHeal.d.ts +5 -0
- package/dist/adapter/activeRunSelfHeal.js +51 -28
- package/dist/adapter/downstream/eventToSdkMessage.d.ts +2 -5
- package/dist/adapter/downstream/eventToSdkMessage.js +27 -34
- package/dist/adapter/downstream/terminalToSdkResult.js +11 -4
- package/dist/adapter/downstream/turnUsageToModelUsage.d.ts +5 -2
- package/dist/adapter/downstream/turnUsageToModelUsage.js +2 -0
- package/dist/adapter/runStream.js +29 -13
- package/dist/adapter/types.d.ts +4 -4
- package/dist/agentSession/backgroundView.js +2 -1
- package/dist/agentSession/engineAgentRegistryRead.d.ts +2 -2
- package/dist/agentSession/engineAgentRegistryRead.js +12 -13
- package/dist/agentsWireCaps.d.ts +8 -6
- package/dist/agentsWireCaps.js +177 -162
- package/dist/approvalDecidedByCapability.d.ts +0 -4
- package/dist/approvalDecidedByCapability.js +0 -6
- package/dist/approvalsStreamLiveCapability.d.ts +0 -4
- package/dist/approvalsStreamLiveCapability.js +0 -6
- package/dist/assistantInbox.d.ts +34 -0
- package/dist/assistantInbox.js +118 -0
- package/dist/centerWiringCapability.js +9 -1
- package/dist/clientSlice.d.ts +0 -9
- package/dist/clientSlice.js +0 -3
- package/dist/cloudConfigWireCaps.d.ts +4 -2
- package/dist/cloudConfigWireCaps.js +81 -61
- package/dist/compensations.js +1 -1
- package/dist/connectorStatus.d.ts +21 -0
- package/dist/connectorStatus.js +112 -0
- package/dist/controlRouter.d.ts +14 -1
- package/dist/controlRouter.js +68 -17
- package/dist/coreValuePorts.d.ts +3 -3
- package/dist/decideReceipt.d.ts +2 -2
- package/dist/decideReceipt.js +5 -2
- package/dist/declared/supportFloorDeclared.js +3 -3
- package/dist/deviceExecutorManagementCapability.d.ts +0 -4
- package/dist/deviceExecutorManagementCapability.js +0 -6
- package/dist/deviceRebind.d.ts +49 -1
- package/dist/deviceRebind.js +221 -3
- package/dist/displayUntrusted.d.ts +1 -0
- package/dist/displayUntrusted.js +250 -76
- package/dist/engineAgentAbsence.d.ts +1 -1
- package/dist/engineAgentPanelStore.d.ts +5 -4
- package/dist/engineAgentPanelStore.js +3 -12
- package/dist/engineCapReader.d.ts +0 -4
- package/dist/engineCapReader.js +1 -5
- package/dist/engineCapsCache.d.ts +4 -0
- package/dist/engineCapsCache.js +17 -12
- package/dist/engineClosedSets.d.ts +1 -0
- package/dist/engineClosedSets.js +4 -1
- package/dist/engineErrorCodes.d.ts +9 -2
- package/dist/engineErrorCodes.js +9 -1
- package/dist/engineIdentity.d.ts +1 -0
- package/dist/engineIdentity.js +8 -0
- package/dist/engineRowRef.d.ts +28 -0
- package/dist/engineRowRef.js +111 -0
- package/dist/engineSessionMessages.d.ts +67 -0
- package/dist/engineSessionMessages.js +364 -0
- package/dist/engineToolDirectory.d.ts +18 -0
- package/dist/engineToolDirectory.js +85 -0
- package/dist/engineUrl.d.ts +18 -0
- package/dist/engineUrl.js +52 -0
- package/dist/env/uiLanguage.d.ts +9 -0
- package/dist/env/uiLanguage.js +35 -0
- package/dist/eventLeg.d.ts +92 -0
- package/dist/eventLeg.js +285 -0
- package/dist/executionLaneCapability.d.ts +0 -4
- package/dist/executionLaneCapability.js +3 -16
- package/dist/fileHistoryCaptureCapability.d.ts +0 -4
- package/dist/fileHistoryCaptureCapability.js +5 -7
- package/dist/fleet/fleetLedger.d.ts +0 -3
- package/dist/fleet/fleetLedger.js +21 -36
- package/dist/fleet/fleetProjection.d.ts +2 -2
- package/dist/fleet/fleetProjection.js +10 -8
- package/dist/frameBinding.d.ts +5 -0
- package/dist/frameBinding.js +23 -0
- package/dist/gateFailureCodes.d.ts +2 -0
- package/dist/gateFailureCodes.js +15 -0
- package/dist/gateOutcome.d.ts +3 -1
- package/dist/gateOutcome.js +25 -6
- package/dist/gateVocabulary.d.ts +5 -0
- package/dist/gateVocabulary.js +64 -2
- package/dist/generated/engineAskFaceTables.js +2 -2
- package/dist/generated/engineFactTables.d.ts +6 -3
- package/dist/generated/engineFactTables.js +22 -4
- package/dist/generated/engineNoticeTables.js +9 -0
- package/dist/generated/toolNameTables.d.ts +1 -0
- package/dist/generated/toolNameTables.js +1 -0
- package/dist/hitl/allowRuleShadow.d.ts +6 -1
- package/dist/hitl/allowRuleShadow.js +21 -17
- package/dist/hitl/approvalCardReading.d.ts +15 -0
- package/dist/hitl/approvalCardReading.js +154 -0
- package/dist/hitl/approvalCardReasons.d.ts +13 -0
- package/dist/hitl/approvalCardReasons.js +120 -0
- package/dist/hitl/approvalHolds.d.ts +47 -15
- package/dist/hitl/approvalHolds.js +134 -28
- package/dist/hitl/approvalResolution.d.ts +51 -26
- package/dist/hitl/approvalResolution.js +86 -122
- package/dist/hitl/approvalsFeed.js +6 -18
- package/dist/hitl/askClassPair.d.ts +2 -0
- package/dist/hitl/askClassPair.js +1 -0
- package/dist/hitl/askGateWire.d.ts +20 -2
- package/dist/hitl/askGateWire.js +49 -1
- package/dist/hitl/askParkRowRouting.d.ts +5 -0
- package/dist/hitl/askParkRowRouting.js +32 -1
- package/dist/hitl/askSettlementLine.d.ts +18 -0
- package/dist/hitl/askSettlementLine.js +79 -0
- package/dist/hitl/automaticAnswerVerdict.d.ts +1 -1
- package/dist/hitl/automaticAnswerVerdict.js +21 -5
- package/dist/hitl/crashConverged.d.ts +11 -20
- package/dist/hitl/crashConverged.js +56 -0
- package/dist/hitl/crashConvergedNotice.d.ts +3 -1
- package/dist/hitl/crashConvergedNotice.js +48 -11
- package/dist/hitl/decisionConflict.js +3 -10
- package/dist/hitl/decisionRefusal.d.ts +40 -1
- package/dist/hitl/decisionRefusal.js +199 -42
- package/dist/hitl/frameRouter.d.ts +5 -2
- package/dist/hitl/frameRouter.js +20 -16
- package/dist/hitl/gateLedger.d.ts +2 -0
- package/dist/hitl/gateLedger.js +50 -13
- package/dist/hitl/hitlBridge.d.ts +1 -2
- package/dist/hitl/hitlBridge.js +10 -7
- package/dist/hitl/livePendingAsk.d.ts +3 -3
- package/dist/hitl/livePendingAsk.js +7 -18
- package/dist/hitl/parkResolver.d.ts +2 -24
- package/dist/hitl/parkResolver.js +61 -97
- package/dist/hitl/persistedRulesWire.d.ts +24 -0
- package/dist/hitl/persistedRulesWire.js +122 -2
- package/dist/hitl/planReviewWire.d.ts +26 -13
- package/dist/hitl/planReviewWire.js +112 -78
- package/dist/hitl/refusedToolNameProse.d.ts +0 -1
- package/dist/hitl/refusedToolNameProse.js +0 -3
- package/dist/hitl/replayedApproval.d.ts +4 -3
- package/dist/hitl/replayedApproval.js +7 -4
- package/dist/hitl/sessionPolicyDeliverable.js +2 -4
- package/dist/hitl/sessionPolicyWire.d.ts +32 -20
- package/dist/hitl/sessionPolicyWire.js +162 -52
- package/dist/hitl/standingRows.d.ts +20 -2
- package/dist/hitl/standingRows.js +69 -8
- package/dist/hitl/toolApprovalWire.d.ts +87 -152
- package/dist/hitl/toolApprovalWire.js +591 -380
- package/dist/hookMatcherVerdict.d.ts +6 -1
- package/dist/hookMatcherVerdict.js +14 -7
- package/dist/hooksWireCaps.d.ts +2 -2
- package/dist/hooksWireCaps.js +59 -55
- package/dist/i18n/messages.en.d.ts +121 -0
- package/dist/i18n/messages.en.js +119 -0
- package/dist/i18n/messages.zh.d.ts +3 -0
- package/dist/i18n/messages.zh.js +120 -0
- package/dist/i18n/translate.d.ts +25 -0
- package/dist/i18n/translate.js +127 -0
- package/dist/index.d.ts +53 -18
- package/dist/index.js +38 -10
- package/dist/inheritEnvCapability.d.ts +31 -0
- package/dist/inheritEnvCapability.js +104 -0
- package/dist/liveModelCatalog.d.ts +1 -2
- package/dist/liveModelCatalog.js +2 -6
- package/dist/liveQuestionStore.d.ts +2 -21
- package/dist/mcpLiveness.d.ts +2 -1
- package/dist/mcpProbeWire.d.ts +6 -1
- package/dist/mcpProbeWire.js +1 -1
- package/dist/mcpWireCaps.d.ts +13 -2
- package/dist/mcpWireCaps.js +48 -0
- package/dist/memoryEntriesWire.d.ts +4 -9
- package/dist/model/modelSupplyRules.d.ts +0 -2
- package/dist/model/modelSupplyRules.js +3 -12
- package/dist/model/modelsPolicy.d.ts +0 -5
- package/dist/model/modelsPolicy.js +6 -36
- package/dist/model/subagentModelWord.d.ts +31 -0
- package/dist/model/subagentModelWord.js +261 -0
- package/dist/notifications.d.ts +6 -0
- package/dist/notifications.js +71 -23
- package/dist/outputStyleSeatCapability.d.ts +0 -3
- package/dist/outputStyleSeatCapability.js +0 -3
- package/dist/ownKey.d.ts +15 -0
- package/dist/ownKey.js +60 -3
- package/dist/panelReduce.d.ts +15 -9
- package/dist/panelReduce.js +680 -549
- package/dist/panelStateHolder.d.ts +3 -7
- package/dist/panelStateHolder.js +14 -130
- package/dist/peerLaneCapability.d.ts +0 -4
- package/dist/peerLaneCapability.js +0 -6
- package/dist/permissionRulesWriteCapability.d.ts +0 -4
- package/dist/permissionRulesWriteCapability.js +0 -6
- package/dist/permissionWireCaps.d.ts +2 -2
- package/dist/permissionWireCaps.js +2 -0
- package/dist/permissionsAllowGrantCapability.d.ts +0 -4
- package/dist/permissionsAllowGrantCapability.js +0 -6
- package/dist/permissionsDeclaration.d.ts +0 -11
- package/dist/permissionsDeclaration.js +60 -53
- package/dist/pluginHooksWire.d.ts +1 -1
- package/dist/pluginHooksWire.js +3 -6
- package/dist/preemptWire.d.ts +44 -0
- package/dist/preemptWire.js +83 -0
- package/dist/printToolResultFrame.js +15 -4
- package/dist/replayBody.d.ts +3 -0
- package/dist/replayBody.js +14 -0
- package/dist/request/taskRequest.d.ts +0 -1
- package/dist/request/taskRequest.js +0 -3
- package/dist/resumeRefusalCopy.d.ts +2 -1
- package/dist/resumeRefusalCopy.js +38 -2
- package/dist/retryStatus.d.ts +8 -0
- package/dist/retryStatus.js +106 -1
- package/dist/rewindArchiveCapability.d.ts +0 -4
- package/dist/rewindArchiveCapability.js +2 -10
- package/dist/rewindArchiveReading.d.ts +0 -1
- package/dist/rewindArchiveReading.js +0 -3
- package/dist/runCancelContext.d.ts +2 -1
- package/dist/runCancelContext.js +4 -2
- package/dist/runReattachPolicy.d.ts +31 -0
- package/dist/runReattachPolicy.js +46 -0
- package/dist/runTerminal.d.ts +3 -6
- package/dist/runTerminal.js +8 -9
- package/dist/sandboxWire.d.ts +3 -1
- package/dist/sandboxWire.js +76 -27
- package/dist/scenarioWire.js +1 -1
- package/dist/seam.d.ts +24 -2
- package/dist/seam.js +15 -3
- package/dist/seatContract.d.ts +53 -10
- package/dist/seatContract.js +132 -81
- package/dist/sessionPolicyCapability.d.ts +0 -4
- package/dist/sessionPolicyCapability.js +0 -6
- package/dist/sessionSyncFileHistoryCapability.d.ts +0 -3
- package/dist/sessionSyncFileHistoryCapability.js +0 -3
- package/dist/skillToolListsCapability.d.ts +0 -3
- package/dist/skillToolListsCapability.js +0 -3
- package/dist/sqlEngineCapability.d.ts +0 -4
- package/dist/sqlEngineCapability.js +0 -6
- package/dist/steerPriorityCapability.d.ts +0 -3
- package/dist/steerPriorityCapability.js +0 -3
- package/dist/streamDrainingLegs.d.ts +4 -0
- package/dist/streamDrainingLegs.js +6 -1
- package/dist/subagent/engineCompactWire.d.ts +0 -1
- package/dist/subagent/engineCompactWire.js +7 -5
- package/dist/subagent/engineTaskHandleWire.js +4 -7
- package/dist/subagentContentStore.js +1 -11
- package/dist/submitReopen.d.ts +24 -0
- package/dist/submitReopen.js +75 -0
- package/dist/terminalStatuses.d.ts +3 -0
- package/dist/terminalStatuses.js +10 -2
- package/dist/toolResult.d.ts +10 -1
- package/dist/toolResult.js +34 -6
- package/dist/toolRoster.d.ts +0 -2
- package/dist/toolRoster.js +0 -2
- package/dist/turnFailurePresentation.d.ts +28 -0
- package/dist/turnFailurePresentation.js +205 -0
- package/dist/userInvokedSkillsCapability.d.ts +0 -3
- package/dist/userInvokedSkillsCapability.js +0 -3
- package/dist/webSearchBackendCapability.d.ts +0 -4
- package/dist/webSearchBackendCapability.js +0 -6
- package/dist/wireErrorTriage.js +5 -24
- package/dist/wireFailureShape.d.ts +62 -5
- package/dist/wireFailureShape.js +105 -5
- package/dist/wireRefusalCopy.d.ts +12 -2
- package/dist/wireRefusalCopy.js +50 -52
- package/dist/workflowsJournalCapability.d.ts +0 -4
- package/dist/workflowsJournalCapability.js +0 -6
- package/dist/writeProtectionCapability.d.ts +0 -4
- package/dist/writeProtectionCapability.js +0 -6
- package/docs/INTEGRATION-CLIENTS.md +1305 -46
- package/package.json +5 -4
- package/dist/attachmentSeatCapability.d.ts +0 -12
- package/dist/attachmentSeatCapability.js +0 -23
- package/dist/hitl/approvalOutcomeNote.d.ts +0 -10
- package/dist/hitl/approvalOutcomeNote.js +0 -29
- package/dist/sessionReadRedactionCapability.d.ts +0 -13
- package/dist/sessionReadRedactionCapability.js +0 -35
package/dist/eventLeg.js
ADDED
|
@@ -0,0 +1,285 @@
|
|
|
1
|
+
import { frameBindingOf, registerFrameBinding } from './frameBinding.js';
|
|
2
|
+
import { bridgeAskUserQuestionGates } from './hitl/askGateWire.js';
|
|
3
|
+
import { diagnoseSseIdleTear } from './sseIdleTriage.js';
|
|
4
|
+
import { recordSubagentOwnerFromProgress } from './subagentContentStore.js';
|
|
5
|
+
import { activeRunBusySignal } from './adapter/runStream.js';
|
|
6
|
+
import { invokeHostCallbackIsolated } from './hostCallbackGuard.js';
|
|
7
|
+
import { hostLog } from './host.js';
|
|
8
|
+
import { guardedRead, readOwnDataNonEmptyString, readOwnDataValue } from './ownKey.js';
|
|
9
|
+
export const EVENT_LEG_KINDS = Object.freeze(['live', 'durable', 'continuation']);
|
|
10
|
+
export const EVENT_LEG_TABLE = Object.freeze({
|
|
11
|
+
live: Object.freeze({ stages: Object.freeze(['bindRun', 'stampOwner', 'hitlFrames', 'askBridge', 'idleTriage']), windowIsCurrent: true }),
|
|
12
|
+
durable: Object.freeze({ stages: Object.freeze(['bindRun', 'stampOwner', 'hitlFrames', 'askBridge']), windowIsCurrent: false }),
|
|
13
|
+
continuation: Object.freeze({ stages: Object.freeze(['bindRun', 'stampOwner', 'hitlFrames']), windowIsCurrent: false }),
|
|
14
|
+
});
|
|
15
|
+
function makeFrameStageDomains(domains) {
|
|
16
|
+
return Object.freeze(domains);
|
|
17
|
+
}
|
|
18
|
+
const FRAME_STAGE_DOMAINS = makeFrameStageDomains({
|
|
19
|
+
bindRun: Object.freeze(['meta', 'done', 'failed']),
|
|
20
|
+
stampOwner: Object.freeze(['task_progress']),
|
|
21
|
+
hitlFrames: Object.freeze(['question', 'question_complete', 'elicitation', 'elicitation_complete', 'tool_approval', 'tool_approval_complete']),
|
|
22
|
+
});
|
|
23
|
+
const HITL_PORT_OF = Object.freeze({
|
|
24
|
+
question: 'question',
|
|
25
|
+
question_complete: 'question',
|
|
26
|
+
elicitation: 'elicitation',
|
|
27
|
+
elicitation_complete: 'elicitation',
|
|
28
|
+
tool_approval: 'toolApproval',
|
|
29
|
+
tool_approval_complete: 'toolApproval',
|
|
30
|
+
});
|
|
31
|
+
const inDomain = (stage, frameType) => FRAME_STAGE_DOMAINS[stage].includes(frameType);
|
|
32
|
+
const HOST_PORT_MISSING = 'host_port_missing';
|
|
33
|
+
export function composeEventLeg(source, leg, ports) {
|
|
34
|
+
const kind = leg.kind;
|
|
35
|
+
if (!EVENT_LEG_KINDS.includes(kind))
|
|
36
|
+
throw new TypeError(`composeEventLeg: unknown leg kind ${JSON.stringify(kind)}`);
|
|
37
|
+
const legRunId = kind === 'live' ? undefined : leg.runId;
|
|
38
|
+
if (kind !== 'live' && (typeof legRunId !== 'string' || legRunId === ''))
|
|
39
|
+
throw new TypeError(`composeEventLeg: a ${kind} leg needs a non-empty runId`);
|
|
40
|
+
const row = EVENT_LEG_TABLE[kind];
|
|
41
|
+
const stageOn = (s) => row.stages.includes(s);
|
|
42
|
+
const hostBridge = stageOn('askBridge') && typeof ports.askBridge === 'object' && ports.askBridge !== null ? ports.askBridge : undefined;
|
|
43
|
+
const hitl = ports.hitl;
|
|
44
|
+
const required = [];
|
|
45
|
+
if (typeof hitl?.question !== 'function')
|
|
46
|
+
required.push('hitl.question');
|
|
47
|
+
if (typeof hitl?.elicitation !== 'function')
|
|
48
|
+
required.push('hitl.elicitation');
|
|
49
|
+
if (hostBridge === undefined && typeof hitl?.toolApproval !== 'function')
|
|
50
|
+
required.push('hitl.toolApproval');
|
|
51
|
+
if (hostBridge !== undefined && typeof hostBridge.respondToolApproval !== 'function')
|
|
52
|
+
required.push('askBridge.respondToolApproval');
|
|
53
|
+
if (required.length > 0) {
|
|
54
|
+
throw Object.assign(new Error(`composeEventLeg: host port missing — ${required.join(', ')}`), { code: HOST_PORT_MISSING, ports: Object.freeze([...required]) });
|
|
55
|
+
}
|
|
56
|
+
const runPorts = ports.run;
|
|
57
|
+
const missingPorts = [];
|
|
58
|
+
if (typeof runPorts?.onBound !== 'function')
|
|
59
|
+
missingPorts.push('run.onBound');
|
|
60
|
+
if (typeof runPorts?.onTerminal !== 'function')
|
|
61
|
+
missingPorts.push('run.onTerminal');
|
|
62
|
+
const portFaults = {};
|
|
63
|
+
let hitlUndelivered = 0;
|
|
64
|
+
const fault = (name, why) => {
|
|
65
|
+
portFaults[name] = (portFaults[name] ?? 0) + 1;
|
|
66
|
+
hostLog('debug', `eventLeg: host port ${name} faulted — ${why.slice(0, 160)}`);
|
|
67
|
+
};
|
|
68
|
+
const callPort = (name, call) => {
|
|
69
|
+
let threw = false;
|
|
70
|
+
invokeHostCallbackIsolated(`eventLeg: ${name}`, () => {
|
|
71
|
+
try {
|
|
72
|
+
return call();
|
|
73
|
+
}
|
|
74
|
+
catch (e) {
|
|
75
|
+
threw = true;
|
|
76
|
+
portFaults[name] = (portFaults[name] ?? 0) + 1;
|
|
77
|
+
throw e;
|
|
78
|
+
}
|
|
79
|
+
});
|
|
80
|
+
return threw;
|
|
81
|
+
};
|
|
82
|
+
const isCurrentNow = () => {
|
|
83
|
+
if (runPorts === undefined)
|
|
84
|
+
return true;
|
|
85
|
+
try {
|
|
86
|
+
const port = runPorts.isCurrent;
|
|
87
|
+
if (port === undefined)
|
|
88
|
+
return true;
|
|
89
|
+
if (typeof port !== 'function') {
|
|
90
|
+
fault('run.isCurrent', `not a function (${typeof port})`);
|
|
91
|
+
return false;
|
|
92
|
+
}
|
|
93
|
+
return port.call(runPorts) === true;
|
|
94
|
+
}
|
|
95
|
+
catch (e) {
|
|
96
|
+
fault('run.isCurrent', String(e));
|
|
97
|
+
return false;
|
|
98
|
+
}
|
|
99
|
+
};
|
|
100
|
+
const readHeaderRunId = () => {
|
|
101
|
+
if (runPorts === undefined)
|
|
102
|
+
return undefined;
|
|
103
|
+
try {
|
|
104
|
+
const port = runPorts.headerRunId;
|
|
105
|
+
if (port === undefined)
|
|
106
|
+
return undefined;
|
|
107
|
+
if (typeof port !== 'function') {
|
|
108
|
+
fault('run.headerRunId', `not a function (${typeof port})`);
|
|
109
|
+
return undefined;
|
|
110
|
+
}
|
|
111
|
+
const v = port.call(runPorts);
|
|
112
|
+
if (typeof v === 'string' && v !== '')
|
|
113
|
+
return v;
|
|
114
|
+
if (v !== undefined && v !== '')
|
|
115
|
+
fault('run.headerRunId', `returned ${typeof v}`);
|
|
116
|
+
return undefined;
|
|
117
|
+
}
|
|
118
|
+
catch (e) {
|
|
119
|
+
fault('run.headerRunId', String(e));
|
|
120
|
+
return undefined;
|
|
121
|
+
}
|
|
122
|
+
};
|
|
123
|
+
const sessionKey = typeof ports.owner?.sessionKey === 'string' && ports.owner.sessionKey !== '' ? ports.owner.sessionKey : undefined;
|
|
124
|
+
const taps = (ports.taps ?? []).filter((t) => typeof t === 'function');
|
|
125
|
+
const decorators = (ports.perStream ?? []).filter((d) => typeof d === 'function');
|
|
126
|
+
const info = Object.freeze({ leg: kind });
|
|
127
|
+
const runSessions = new Map();
|
|
128
|
+
let lastBound;
|
|
129
|
+
const noteBound = (binding) => {
|
|
130
|
+
if (lastBound !== undefined && lastBound.taskId === binding.taskId && lastBound.sessionId === binding.sessionId)
|
|
131
|
+
return;
|
|
132
|
+
const cause = lastBound === undefined ? 'open' : lastBound.taskId !== binding.taskId ? 'handoff' : 'frame';
|
|
133
|
+
lastBound = binding;
|
|
134
|
+
if (runPorts === undefined || typeof runPorts.onBound !== 'function' || !isCurrentNow())
|
|
135
|
+
return;
|
|
136
|
+
const boundInfo = Object.freeze({ cause, leg: kind });
|
|
137
|
+
callPort('run.onBound', () => runPorts.onBound?.(binding, boundInfo));
|
|
138
|
+
};
|
|
139
|
+
const deliverHitl = (ev, env) => {
|
|
140
|
+
if (!inDomain('hitlFrames', ev.type))
|
|
141
|
+
return false;
|
|
142
|
+
const port = HITL_PORT_OF[ev.type];
|
|
143
|
+
if (port === 'toolApproval' && hostBridge !== undefined)
|
|
144
|
+
return false;
|
|
145
|
+
const threw = callPort(`hitl.${port}`, () => hitl?.[port]?.call(hitl, ev, env));
|
|
146
|
+
if (threw)
|
|
147
|
+
hitlUndelivered++;
|
|
148
|
+
return true;
|
|
149
|
+
};
|
|
150
|
+
async function* frameLevel(stream, streamKind, streamRunId) {
|
|
151
|
+
let taskId = streamRunId;
|
|
152
|
+
let sessionId = streamRunId !== undefined ? runSessions.get(streamRunId) : undefined;
|
|
153
|
+
let binding;
|
|
154
|
+
let runEvidence = false;
|
|
155
|
+
const env = Object.freeze({ windowIsCurrent: EVENT_LEG_TABLE[streamKind].windowIsCurrent, leg: streamKind });
|
|
156
|
+
for await (const ev of stream) {
|
|
157
|
+
if (taskId === undefined && streamKind === 'live')
|
|
158
|
+
taskId = readHeaderRunId();
|
|
159
|
+
const refusal = streamKind === 'live' && !runEvidence && inDomain('bindRun', ev.type) ? refusalOf(ev, taskId) : undefined;
|
|
160
|
+
if (!inDomain('bindRun', ev.type))
|
|
161
|
+
runEvidence = true;
|
|
162
|
+
if (refusal !== undefined) {
|
|
163
|
+
if (runPorts !== undefined && typeof runPorts.onRefused === 'function' && isCurrentNow())
|
|
164
|
+
callPort('run.onRefused', () => runPorts.onRefused?.(refusal, info));
|
|
165
|
+
}
|
|
166
|
+
else {
|
|
167
|
+
if (ev.type === 'meta' || ev.type === 'done') {
|
|
168
|
+
const carrier = ev.type === 'meta' ? ev : ev.result;
|
|
169
|
+
const tid = typeof carrier === 'object' && carrier !== null ? guardedRead(() => readOwnDataNonEmptyString(carrier, 'taskId')) : undefined;
|
|
170
|
+
const sid = typeof carrier === 'object' && carrier !== null ? guardedRead(() => readOwnDataNonEmptyString(carrier, 'sessionId')) : undefined;
|
|
171
|
+
const runId = ev.type === 'done' && tid !== undefined && tid === sid ? undefined : tid;
|
|
172
|
+
if (streamKind === 'live' && runId !== undefined && runId !== taskId) {
|
|
173
|
+
taskId = runId;
|
|
174
|
+
sessionId = sid;
|
|
175
|
+
}
|
|
176
|
+
else if (sid !== undefined && taskId !== undefined && (runId === undefined || runId === taskId)) {
|
|
177
|
+
sessionId = sid;
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
if (taskId !== undefined) {
|
|
181
|
+
if (binding === undefined || binding.taskId !== taskId || binding.sessionId !== sessionId) {
|
|
182
|
+
binding = Object.freeze({ taskId, ...(sessionId !== undefined ? { sessionId } : {}) });
|
|
183
|
+
}
|
|
184
|
+
if (sessionId !== undefined)
|
|
185
|
+
runSessions.set(taskId, sessionId);
|
|
186
|
+
registerFrameBinding(ev, binding);
|
|
187
|
+
noteBound(binding);
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
if (inDomain('stampOwner', ev.type)) {
|
|
191
|
+
const b = frameBindingOf(ev);
|
|
192
|
+
recordSubagentOwnerFromProgress(ev, b?.taskId, b?.sessionId, sessionKey);
|
|
193
|
+
}
|
|
194
|
+
if (deliverHitl(ev, env))
|
|
195
|
+
continue;
|
|
196
|
+
for (const tap of taps)
|
|
197
|
+
callPort('taps', () => tap(ev));
|
|
198
|
+
yield ev;
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
const streamOf = (raw, streamKind, streamRunId) => {
|
|
202
|
+
let s = generatorOf(raw);
|
|
203
|
+
const ctx = Object.freeze({ leg: streamKind, runId: streamRunId });
|
|
204
|
+
for (const d of decorators)
|
|
205
|
+
s = d(s, ctx);
|
|
206
|
+
return frameLevel(s, streamKind, streamRunId);
|
|
207
|
+
};
|
|
208
|
+
let inner = streamOf(source, kind, legRunId);
|
|
209
|
+
if (hostBridge !== undefined) {
|
|
210
|
+
let windowOpen = row.windowIsCurrent;
|
|
211
|
+
const runsEvents = (taskId, opts) => {
|
|
212
|
+
windowOpen = false;
|
|
213
|
+
return streamOf(hostBridge.runsEvents(taskId, opts), 'continuation', taskId);
|
|
214
|
+
};
|
|
215
|
+
const deps = hostView(hostBridge, {
|
|
216
|
+
runsEvents: () => runsEvents,
|
|
217
|
+
approvalLane: () => {
|
|
218
|
+
const lane = hostBridge.approvalLane;
|
|
219
|
+
return typeof lane === 'object' && lane !== null ? hostView(lane, { windowIsCurrent: () => windowOpen }) : Object.freeze({ windowIsCurrent: windowOpen });
|
|
220
|
+
},
|
|
221
|
+
});
|
|
222
|
+
inner = bridgeAskUserQuestionGates(inner, deps, { ...(ports.signal !== undefined ? { signal: ports.signal } : {}), ...(legRunId !== undefined ? { taskId: legRunId } : {}) });
|
|
223
|
+
}
|
|
224
|
+
const baseUrl = ports.idleTriage?.baseUrl;
|
|
225
|
+
if (stageOn('idleTriage') && typeof baseUrl === 'string' && baseUrl !== '')
|
|
226
|
+
inner = diagnoseSseIdleTear(inner, baseUrl, ports.signal);
|
|
227
|
+
async function* exit(stream) {
|
|
228
|
+
for await (const ev of stream) {
|
|
229
|
+
if ((ev.type === 'done' || ev.type === 'failed') && runPorts !== undefined && typeof runPorts.onTerminal === 'function' && isCurrentNow()) {
|
|
230
|
+
const binding = frameBindingOf(ev);
|
|
231
|
+
callPort('run.onTerminal', () => runPorts.onTerminal?.(ev, binding, info));
|
|
232
|
+
}
|
|
233
|
+
yield ev;
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
return Object.freeze({
|
|
237
|
+
events: exit(inner),
|
|
238
|
+
report: () => Object.freeze({ missingPorts: Object.freeze([...missingPorts]), portFaults: Object.freeze({ ...portFaults }), hitlUndelivered }),
|
|
239
|
+
});
|
|
240
|
+
}
|
|
241
|
+
function refusalOf(ev, candidateRunId) {
|
|
242
|
+
if (ev.type !== 'done' && ev.type !== 'failed')
|
|
243
|
+
return undefined;
|
|
244
|
+
const candidate = candidateRunId !== undefined ? { candidateRunId } : {};
|
|
245
|
+
const busy = activeRunBusySignal(ev);
|
|
246
|
+
if (busy !== null)
|
|
247
|
+
return Object.freeze({ kind: 'busy', ...candidate, busy });
|
|
248
|
+
if (ev.type !== 'done')
|
|
249
|
+
return undefined;
|
|
250
|
+
const r = guardedRead(() => readOwnDataValue(ev, 'result'));
|
|
251
|
+
if (typeof r !== 'object' || r === null || Array.isArray(r))
|
|
252
|
+
return undefined;
|
|
253
|
+
if (guardedRead(() => readOwnDataNonEmptyString(r, 'status')) !== 'failed')
|
|
254
|
+
return undefined;
|
|
255
|
+
for (const k of ['taskId', 'stats', 'terminal', 'activeTaskId'])
|
|
256
|
+
if (guardedRead(() => Object.hasOwn(r, k)) !== false)
|
|
257
|
+
return undefined;
|
|
258
|
+
const errorCode = guardedRead(() => readOwnDataNonEmptyString(r, 'errorCode'));
|
|
259
|
+
if (errorCode === undefined || guardedRead(() => readOwnDataNonEmptyString(r, 'errorMessage')) === undefined)
|
|
260
|
+
return undefined;
|
|
261
|
+
return Object.freeze({ kind: 'not_created', ...candidate, errorCode });
|
|
262
|
+
}
|
|
263
|
+
function hostView(host, overrides) {
|
|
264
|
+
const replaced = (k) => typeof k === 'string' && Object.hasOwn(overrides, k);
|
|
265
|
+
const valueOf = (k) => overrides[k]?.();
|
|
266
|
+
return new Proxy(Object.create(null), {
|
|
267
|
+
get(_t, k) {
|
|
268
|
+
if (replaced(k))
|
|
269
|
+
return valueOf(k);
|
|
270
|
+
const v = Reflect.get(host, k, host);
|
|
271
|
+
return typeof v === 'function' ? v.bind(host) : v;
|
|
272
|
+
},
|
|
273
|
+
has: (_t, k) => replaced(k) || Reflect.has(host, k),
|
|
274
|
+
getOwnPropertyDescriptor(_t, k) {
|
|
275
|
+
if (replaced(k))
|
|
276
|
+
return { value: valueOf(k), writable: false, enumerable: true, configurable: true };
|
|
277
|
+
const d = Reflect.getOwnPropertyDescriptor(host, k);
|
|
278
|
+
return d === undefined ? undefined : { ...d, configurable: true };
|
|
279
|
+
},
|
|
280
|
+
ownKeys: () => [...new Set([...Reflect.ownKeys(host), ...Object.keys(overrides)])],
|
|
281
|
+
});
|
|
282
|
+
}
|
|
283
|
+
async function* generatorOf(raw) {
|
|
284
|
+
yield* raw;
|
|
285
|
+
}
|
|
@@ -17,12 +17,8 @@ export type ExecutionLaneReading = {
|
|
|
17
17
|
};
|
|
18
18
|
export declare function projectExecutionLaneCapability(caps: unknown): ExecutionLaneReading | undefined;
|
|
19
19
|
export declare function projectExecutionLaneWiring(wiring: unknown): ExecutionLaneReading | undefined;
|
|
20
|
-
export declare function noteEngineCapsForExecutionLane(baseUrl: string, caps: unknown, opts?: {
|
|
21
|
-
generation?: number;
|
|
22
|
-
}): void;
|
|
23
20
|
export declare function observedExecutionLane(baseUrl?: string | undefined): ExecutionLaneReading;
|
|
24
21
|
export declare function toolsRunHereFromExecutionLane(reading: ExecutionLaneReading): boolean;
|
|
25
22
|
export declare function noOsSandboxOnThisHost(reading: ExecutionLaneReading): 'yes' | 'no' | 'unknown';
|
|
26
23
|
export declare function noOsSandboxContent(): string;
|
|
27
24
|
export declare function executionLaneDoctorDetail(reading: ExecutionLaneReading): string;
|
|
28
|
-
export declare function __resetExecutionLaneReadingsForTests(): void;
|
|
@@ -26,17 +26,10 @@ function projectExecutionLaneObject(lane) {
|
|
|
26
26
|
return undefined;
|
|
27
27
|
if (typeof toolsOnThisHost !== 'boolean')
|
|
28
28
|
return undefined;
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
try {
|
|
32
|
-
isolated = ownDataField(lane, 'isolated');
|
|
33
|
-
}
|
|
34
|
-
catch {
|
|
35
|
-
isolatedThrew = true;
|
|
36
|
-
}
|
|
37
|
-
if (!isolatedThrew && typeof isolated === 'boolean')
|
|
29
|
+
const isolated = ownDataField(lane, 'isolated');
|
|
30
|
+
if (typeof isolated === 'boolean')
|
|
38
31
|
return { kind: 'present', view: { provider, toolsOnThisHost, isolated } };
|
|
39
|
-
const isolatedAbsent =
|
|
32
|
+
const isolatedAbsent = isolated !== undefined ? 'unreadable' : toolsOnThisHost ? 'unreadable' : 'no_hands';
|
|
40
33
|
return { kind: 'present', view: { provider, toolsOnThisHost, isolatedAbsent } };
|
|
41
34
|
}
|
|
42
35
|
export function projectExecutionLaneWiring(wiring) {
|
|
@@ -56,9 +49,6 @@ const reader = createEngineCapReader({
|
|
|
56
49
|
name: 'executionLane',
|
|
57
50
|
project: projectExecutionLaneCapability,
|
|
58
51
|
});
|
|
59
|
-
export function noteEngineCapsForExecutionLane(baseUrl, caps, opts) {
|
|
60
|
-
reader.note(baseUrl, caps, opts);
|
|
61
|
-
}
|
|
62
52
|
export function observedExecutionLane(baseUrl = engineWireTarget()?.baseUrl) {
|
|
63
53
|
return reader.observed(baseUrl);
|
|
64
54
|
}
|
|
@@ -117,6 +107,3 @@ export function executionLaneDoctorDetail(reading) {
|
|
|
117
107
|
}
|
|
118
108
|
}
|
|
119
109
|
}
|
|
120
|
-
export function __resetExecutionLaneReadingsForTests() {
|
|
121
|
-
reader.__resetForTests();
|
|
122
|
-
}
|
|
@@ -10,9 +10,6 @@ export type FileHistoryCaptureReading = {
|
|
|
10
10
|
};
|
|
11
11
|
export type FileHistoryCaptureMode = 'off' | 'on-optional' | 'unknown';
|
|
12
12
|
export declare function projectFileHistoryCaptureCapability(caps: unknown): FileHistoryCaptureReading | undefined;
|
|
13
|
-
export declare function noteEngineCapsForFileHistoryCapture(baseUrl: string, caps: unknown, opts?: {
|
|
14
|
-
generation?: number;
|
|
15
|
-
}): void;
|
|
16
13
|
export declare function observedFileHistoryCapture(baseUrl?: string | undefined): FileHistoryCaptureReading;
|
|
17
14
|
export declare function fileHistoryCaptureMode(reading: FileHistoryCaptureReading): FileHistoryCaptureMode;
|
|
18
15
|
export declare function fileHistoryDeclarationField(reading: FileHistoryCaptureReading, captureOff: boolean): {
|
|
@@ -33,4 +30,3 @@ export declare function judgeFileHistoryTighten(captureOffByUser: boolean, opts?
|
|
|
33
30
|
withinMs?: number;
|
|
34
31
|
}): Promise<FileHistoryTightenJudgement>;
|
|
35
32
|
export declare function fileHistoryCaptureDoctorDetail(reading: FileHistoryCaptureReading): string;
|
|
36
|
-
export declare function __resetFileHistoryCaptureReadingsForTests(): void;
|
|
@@ -23,9 +23,6 @@ const reader = createEngineCapReader({
|
|
|
23
23
|
name: 'fileHistoryCapture',
|
|
24
24
|
project: projectFileHistoryCaptureCapability,
|
|
25
25
|
});
|
|
26
|
-
export function noteEngineCapsForFileHistoryCapture(baseUrl, caps, opts) {
|
|
27
|
-
reader.note(baseUrl, caps, opts);
|
|
28
|
-
}
|
|
29
26
|
export function observedFileHistoryCapture(baseUrl = engineWireTarget()?.baseUrl) {
|
|
30
27
|
return reader.observed(baseUrl);
|
|
31
28
|
}
|
|
@@ -69,6 +66,10 @@ const FILE_HISTORY_REFUSAL_NOT_YET = "Nothing was sent: file checkpointing is tu
|
|
|
69
66
|
const FILE_HISTORY_REFUSAL_NOT_SAID = 'Nothing was sent: file checkpointing is turned off in your settings, but this engine did not report whether it can ' +
|
|
70
67
|
'stop recording file history for a session, so sending now could record it anyway. Trying again will not change that ' +
|
|
71
68
|
'while this engine reports the same; to send and let file history be recorded this time, turn file checkpointing back on in your settings.';
|
|
69
|
+
const FILE_HISTORY_REFUSAL_UNRECOGNIZED = 'Nothing was sent: file checkpointing is turned off in your settings, but this engine reported a file-history capture mode ' +
|
|
70
|
+
'this client does not recognize, so whether it can stop recording file history for a session is unknown and sending now could ' +
|
|
71
|
+
'record it anyway. Trying again will not change that while this engine reports the same; to send and let file history be ' +
|
|
72
|
+
'recorded this time, turn file checkpointing back on in your settings.';
|
|
72
73
|
const FILE_HISTORY_REFUSAL_UNREADABLE = "Nothing was sent: file checkpointing is turned off in your settings, but this engine's report on whether it can stop " +
|
|
73
74
|
'recording file history for a session could not be read by this client, so sending now could record it anyway. Trying ' +
|
|
74
75
|
'again will not change that while this engine reports the same; to send and let file history be recorded this time, ' +
|
|
@@ -88,7 +89,7 @@ function unjudgedRefusalOf(reading) {
|
|
|
88
89
|
if (kind === 'not_reported')
|
|
89
90
|
return FILE_HISTORY_REFUSAL_NOT_SAID;
|
|
90
91
|
if (kind === 'present' && typeof word === 'string' && word.length > 0)
|
|
91
|
-
return
|
|
92
|
+
return FILE_HISTORY_REFUSAL_UNRECOGNIZED;
|
|
92
93
|
return FILE_HISTORY_REFUSAL_NOT_YET;
|
|
93
94
|
}
|
|
94
95
|
export function fileHistoryUnjudgedRefusal(reading, captureOffByUser) {
|
|
@@ -179,6 +180,3 @@ export function fileHistoryCaptureDoctorDetail(reading) {
|
|
|
179
180
|
return unobserved;
|
|
180
181
|
}
|
|
181
182
|
}
|
|
182
|
-
export function __resetFileHistoryCaptureReadingsForTests() {
|
|
183
|
-
reader.__resetForTests();
|
|
184
|
-
}
|
|
@@ -74,7 +74,6 @@ export interface CreateFleetLedgerOptions {
|
|
|
74
74
|
nowFn?: () => number;
|
|
75
75
|
}
|
|
76
76
|
export interface FleetLedgerStatus {
|
|
77
|
-
connected: boolean;
|
|
78
77
|
version: number | null;
|
|
79
78
|
scoped: boolean | null;
|
|
80
79
|
sessionScoped: boolean | undefined;
|
|
@@ -89,12 +88,10 @@ export interface FleetLedgerStatus {
|
|
|
89
88
|
droppedStaleIngress: number;
|
|
90
89
|
}
|
|
91
90
|
export interface FleetLedger {
|
|
92
|
-
applyFrame(frame: FleetFrame): void;
|
|
93
91
|
issueStream(): FleetIngress;
|
|
94
92
|
issueSnapshot(opts?: {
|
|
95
93
|
timeoutMs?: number;
|
|
96
94
|
}): FleetSnapshotIngress;
|
|
97
|
-
setConnected(v: boolean): void;
|
|
98
95
|
project(nowMs: number, opts: ProjectTasksOptions & {
|
|
99
96
|
viewingTaskId?: string | undefined;
|
|
100
97
|
}): {
|
|
@@ -44,7 +44,7 @@ export function readEngineActiveBgTasksFor(sessionKey) {
|
|
|
44
44
|
for (const view of viewsFor(sessionKey)) {
|
|
45
45
|
try {
|
|
46
46
|
const r = view.read();
|
|
47
|
-
if (r.
|
|
47
|
+
if (r.fresh)
|
|
48
48
|
fresh = true;
|
|
49
49
|
for (const row of r.rows)
|
|
50
50
|
byId.set(row.id, row);
|
|
@@ -146,7 +146,6 @@ export function createFleetLedger(hooks = {}, opts = {}) {
|
|
|
146
146
|
let droppedUnknownFrame = 0;
|
|
147
147
|
let droppedForeignBgNotification = 0;
|
|
148
148
|
let droppedStaleIngress = 0;
|
|
149
|
-
let connected = false;
|
|
150
149
|
let version = null;
|
|
151
150
|
let scoped = null;
|
|
152
151
|
let sessionScopedMeta;
|
|
@@ -154,12 +153,12 @@ export function createFleetLedger(hooks = {}, opts = {}) {
|
|
|
154
153
|
let disposed = false;
|
|
155
154
|
let epochSeq = 0;
|
|
156
155
|
let liveStreamEpoch = 0;
|
|
156
|
+
let deliveredStreamEpoch = 0;
|
|
157
157
|
let liveSnapshotEpoch = 0;
|
|
158
158
|
let streamAnchor;
|
|
159
|
-
let everIssuedStream = false;
|
|
160
159
|
let contentAnchor;
|
|
161
160
|
let contentAnchorSet = false;
|
|
162
|
-
|
|
161
|
+
const streamDelivering = () => !disposed && liveStreamEpoch !== 0 && deliveredStreamEpoch === liveStreamEpoch;
|
|
163
162
|
const debug = (line) => {
|
|
164
163
|
if (engineWireDebugEnabled())
|
|
165
164
|
hostLog('debug', line);
|
|
@@ -242,7 +241,7 @@ export function createFleetLedger(hooks = {}, opts = {}) {
|
|
|
242
241
|
continue;
|
|
243
242
|
rows.push(toBgTask(r.row, true));
|
|
244
243
|
}
|
|
245
|
-
return {
|
|
244
|
+
return { fresh: streamDelivering(), rows };
|
|
246
245
|
},
|
|
247
246
|
sessionScoped: () => sessionScopedMeta,
|
|
248
247
|
clearRetained: () => {
|
|
@@ -259,7 +258,6 @@ export function createFleetLedger(hooks = {}, opts = {}) {
|
|
|
259
258
|
views.add(bgView);
|
|
260
259
|
}
|
|
261
260
|
function applyFrame(frame, ing) {
|
|
262
|
-
ledgerWrites++;
|
|
263
261
|
switch (frame.type) {
|
|
264
262
|
case 'meta': {
|
|
265
263
|
version = frame.version;
|
|
@@ -324,7 +322,7 @@ export function createFleetLedger(hooks = {}, opts = {}) {
|
|
|
324
322
|
if (parentOwned)
|
|
325
323
|
recordOwnEngineRun(childTid);
|
|
326
324
|
if (parentOwned || sessionScopedMeta === true) {
|
|
327
|
-
recordBgParentRun(childTid, parentTid, ing
|
|
325
|
+
recordBgParentRun(childTid, parentTid, ing.session, ing.sessionKey);
|
|
328
326
|
}
|
|
329
327
|
else {
|
|
330
328
|
debug(`[fleet-frame] task row parent-map SKIPPED foreign/unowned(row=${row.id} parent=${parentTid})`);
|
|
@@ -409,7 +407,7 @@ export function createFleetLedger(hooks = {}, opts = {}) {
|
|
|
409
407
|
return;
|
|
410
408
|
}
|
|
411
409
|
const serverFailClosed = bgNotifyFailClosedMeta && sessionScopedMeta === true;
|
|
412
|
-
const anchor = ing
|
|
410
|
+
const anchor = ing.session;
|
|
413
411
|
const ownByRoot = typeof n.rootSessionId === 'string' &&
|
|
414
412
|
n.rootSessionId.length > 0 &&
|
|
415
413
|
n.rootSessionId === anchor;
|
|
@@ -423,16 +421,14 @@ export function createFleetLedger(hooks = {}, opts = {}) {
|
|
|
423
421
|
return;
|
|
424
422
|
}
|
|
425
423
|
const defaultSlot = sessionKey === DEFAULT_SESSION_KEY;
|
|
426
|
-
const viaIngress = ing !== null;
|
|
427
|
-
const ownRootTrusted = defaultSlot || viaIngress;
|
|
428
424
|
const serverFailClosedTrusted = defaultSlot;
|
|
429
425
|
const trustedSessionArm = serverFailClosed && serverFailClosedTrusted
|
|
430
426
|
? 'server_fail_closed'
|
|
431
|
-
: ownByRoot
|
|
427
|
+
: ownByRoot
|
|
432
428
|
? 'own_root'
|
|
433
429
|
: undefined;
|
|
434
430
|
const evidence = trustedSessionArm ??
|
|
435
|
-
(serverFailClosed
|
|
431
|
+
(serverFailClosed
|
|
436
432
|
? 'session_anchor_untrusted'
|
|
437
433
|
: typeof n.parentTaskId === 'string' && n.parentTaskId.length > 0
|
|
438
434
|
? 'own_parent'
|
|
@@ -446,7 +442,7 @@ export function createFleetLedger(hooks = {}, opts = {}) {
|
|
|
446
442
|
}
|
|
447
443
|
if (isSdkFleetTaskTerminal(n.status)) {
|
|
448
444
|
if (typeof n.parentTaskId === 'string' && n.parentTaskId) {
|
|
449
|
-
recordBgParentRun(n.taskId, n.parentTaskId, ing
|
|
445
|
+
recordBgParentRun(n.taskId, n.parentTaskId, ing.session, ing.sessionKey);
|
|
450
446
|
}
|
|
451
447
|
if (typeof n.transcriptId === 'string' && n.transcriptId.length > 0) {
|
|
452
448
|
recordEngineTranscriptId(n.taskId, n.transcriptId);
|
|
@@ -629,9 +625,13 @@ export function createFleetLedger(hooks = {}, opts = {}) {
|
|
|
629
625
|
` type=${String(frame.type)})`);
|
|
630
626
|
return;
|
|
631
627
|
}
|
|
632
|
-
|
|
628
|
+
if (kind === 'stream')
|
|
629
|
+
deliveredStreamEpoch = epoch;
|
|
630
|
+
else
|
|
631
|
+
closed = true;
|
|
633
632
|
contentAnchor = session;
|
|
634
633
|
contentAnchorSet = true;
|
|
634
|
+
applyFrame(frame, { session, sessionKey });
|
|
635
635
|
},
|
|
636
636
|
close() {
|
|
637
637
|
closed = true;
|
|
@@ -649,8 +649,7 @@ export function createFleetLedger(hooks = {}, opts = {}) {
|
|
|
649
649
|
bgNotifyFailClosedMeta = false;
|
|
650
650
|
debug(`[fleet-frame] 连接级 meta 复位(${why})—— 新连接自报之前不许沿用上一条连接的让位/信任位`);
|
|
651
651
|
};
|
|
652
|
-
const
|
|
653
|
-
const shouldResetContentFor = (session) => contentAnchorSet ? contentAnchor !== session : hasLedgerContent();
|
|
652
|
+
const shouldResetContentFor = (session) => contentAnchorSet && contentAnchor !== session;
|
|
654
653
|
const resetLedgerContentOnSessionChange = (from, to) => {
|
|
655
654
|
taskMap.clear();
|
|
656
655
|
wfMap.clear();
|
|
@@ -664,21 +663,14 @@ export function createFleetLedger(hooks = {}, opts = {}) {
|
|
|
664
663
|
'(换会话不是重连:再渲上一会话的行就是跨会话残影)');
|
|
665
664
|
};
|
|
666
665
|
return {
|
|
667
|
-
applyFrame(frame) {
|
|
668
|
-
if (disposed)
|
|
669
|
-
return;
|
|
670
|
-
applyFrame(frame, null);
|
|
671
|
-
},
|
|
672
666
|
issueStream() {
|
|
673
667
|
const session = engineSessionParamFor(sessionKey);
|
|
674
|
-
if (shouldResetContentFor(session))
|
|
675
|
-
resetLedgerContentOnSessionChange(
|
|
676
|
-
}
|
|
668
|
+
if (shouldResetContentFor(session))
|
|
669
|
+
resetLedgerContentOnSessionChange(contentAnchor, session);
|
|
677
670
|
resetConnectionMeta('新 stream ingress');
|
|
678
671
|
const epoch = ++epochSeq;
|
|
679
672
|
liveStreamEpoch = epoch;
|
|
680
673
|
streamAnchor = session;
|
|
681
|
-
everIssuedStream = true;
|
|
682
674
|
liveSnapshotEpoch = 0;
|
|
683
675
|
debug(`[fleet-frame] ingress issued(kind=stream key=${sessionKey} epoch=${epoch} session=${session ?? '-'})`);
|
|
684
676
|
return {
|
|
@@ -688,13 +680,11 @@ export function createFleetLedger(hooks = {}, opts = {}) {
|
|
|
688
680
|
},
|
|
689
681
|
issueSnapshot(snapOpts) {
|
|
690
682
|
const inStreamMode = liveStreamEpoch !== 0;
|
|
691
|
-
const
|
|
692
|
-
const duringLiveStream = inStreamMode || compatStreamLive;
|
|
683
|
+
const duringLiveStream = inStreamMode;
|
|
693
684
|
const session = inStreamMode ? streamAnchor : engineSessionParamFor(sessionKey);
|
|
694
685
|
if (!duringLiveStream) {
|
|
695
|
-
if (shouldResetContentFor(session))
|
|
696
|
-
resetLedgerContentOnSessionChange(
|
|
697
|
-
}
|
|
686
|
+
if (shouldResetContentFor(session))
|
|
687
|
+
resetLedgerContentOnSessionChange(contentAnchor, session);
|
|
698
688
|
resetConnectionMeta('快照连接:SDK 封装吞掉了它自己的 meta,不许沿用别条连接的信任位');
|
|
699
689
|
}
|
|
700
690
|
if (inStreamMode) {
|
|
@@ -704,9 +694,8 @@ export function createFleetLedger(hooks = {}, opts = {}) {
|
|
|
704
694
|
const epoch = ++epochSeq;
|
|
705
695
|
liveSnapshotEpoch = epoch;
|
|
706
696
|
debug(`[fleet-frame] ingress issued(kind=snapshot key=${sessionKey} epoch=${epoch} session=${session ?? '-'})`);
|
|
707
|
-
const writesAtIssue = ledgerWrites;
|
|
708
697
|
const issuedDuringStream = duringLiveStream;
|
|
709
|
-
const base = makeIngress('snapshot', epoch, session, () => liveSnapshotEpoch === epoch && !issuedDuringStream
|
|
698
|
+
const base = makeIngress('snapshot', epoch, session, () => liveSnapshotEpoch === epoch && !issuedDuringStream);
|
|
710
699
|
return {
|
|
711
700
|
...base,
|
|
712
701
|
applySnapshot(snapshot) {
|
|
@@ -723,12 +712,8 @@ export function createFleetLedger(hooks = {}, opts = {}) {
|
|
|
723
712
|
},
|
|
724
713
|
};
|
|
725
714
|
},
|
|
726
|
-
setConnected(v) {
|
|
727
|
-
connected = v;
|
|
728
|
-
},
|
|
729
715
|
project,
|
|
730
716
|
status: () => ({
|
|
731
|
-
connected,
|
|
732
717
|
version,
|
|
733
718
|
scoped,
|
|
734
719
|
sessionScoped: sessionScopedMeta,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { FleetTaskRow, FleetWorkflowRow } from '@sema-agent/sdk';
|
|
2
|
-
export type FleetTaskStatus
|
|
1
|
+
import type { FleetTaskRow, FleetWorkflowRow, FleetTaskStatus } from '@sema-agent/sdk';
|
|
2
|
+
export type { FleetTaskStatus };
|
|
3
3
|
export interface FleetTaskView {
|
|
4
4
|
id: string;
|
|
5
5
|
name: string;
|
|
@@ -4,7 +4,10 @@ import { cycleSeqValue } from '../cycleOrder.js';
|
|
|
4
4
|
import { frozenSet } from '../frozenSet.js';
|
|
5
5
|
import { CORE_RESERVED_AGENT_NAMES } from '../generated/engineFactTables.js';
|
|
6
6
|
export function coerceTaskStatus(s) {
|
|
7
|
-
|
|
7
|
+
if (s === 'parked')
|
|
8
|
+
return 'awaiting approval';
|
|
9
|
+
const word = s;
|
|
10
|
+
switch (word) {
|
|
8
11
|
case 'queued':
|
|
9
12
|
case 'running':
|
|
10
13
|
case 'waiting':
|
|
@@ -14,11 +17,12 @@ export function coerceTaskStatus(s) {
|
|
|
14
17
|
case 'completed':
|
|
15
18
|
case 'failed':
|
|
16
19
|
case 'killed':
|
|
17
|
-
return
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
20
|
+
return word;
|
|
21
|
+
default: {
|
|
22
|
+
const unhandled = word;
|
|
23
|
+
void unhandled;
|
|
21
24
|
return 'idle';
|
|
25
|
+
}
|
|
22
26
|
}
|
|
23
27
|
}
|
|
24
28
|
export function coerceWorkflowStatus(s) {
|
|
@@ -49,11 +53,9 @@ function deriveAgentLabel(agentType, agentName, name, id) {
|
|
|
49
53
|
const tail = rowIdTail(id).slice(-8);
|
|
50
54
|
return tail ? `agent ${tail}` : 'agent';
|
|
51
55
|
}
|
|
52
|
-
const CONTROL_VERB_LEGACY_NAMES = ['Task', 'Fork'];
|
|
53
56
|
const CONTROL_VERB_GOAL_NAMES = ['DeclareDone'];
|
|
54
57
|
export const CONTROL_TOOL_VERBS = frozenSet([
|
|
55
58
|
...CORE_RESERVED_AGENT_NAMES,
|
|
56
|
-
...CONTROL_VERB_LEGACY_NAMES,
|
|
57
59
|
...CONTROL_VERB_GOAL_NAMES,
|
|
58
60
|
]);
|
|
59
61
|
export function projectDescription(description) {
|
|
@@ -350,5 +352,5 @@ export const FLEET_TASK_ROW_KEYS_NOT_PROJECTED = {
|
|
|
350
352
|
},
|
|
351
353
|
};
|
|
352
354
|
export const FLEET_WORKFLOW_ROW_KEYS_NOT_PROJECTED = {};
|
|
353
|
-
const _fleetViewKeyPins = [true, true, true, true, true, true, true, true
|
|
355
|
+
const _fleetViewKeyPins = [true, true, true, true, true, true, true, true];
|
|
354
356
|
void _fleetViewKeyPins;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { AgentEvent } from '@sema-agent/sdk';
|
|
2
|
+
import type { EngineBoundRun } from './engineRowRef.js';
|
|
3
|
+
export declare function registerFrameBinding(frame: AgentEvent, binding: EngineBoundRun): void;
|
|
4
|
+
export declare function frameBindingOf(frame: AgentEvent): EngineBoundRun | undefined;
|
|
5
|
+
export declare function inheritFrameBinding<T extends AgentEvent>(from: AgentEvent, to: T): T;
|