@sema-agent/client-core 0.110.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 +169 -0
- package/README.md +50 -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/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/displayUntrusted.d.ts +1 -0
- package/dist/displayUntrusted.js +6 -0
- package/dist/engineHealthFacts.d.ts +11 -0
- package/dist/engineHealthFacts.js +21 -0
- package/dist/engineHealthProbeVerdict.d.ts +23 -0
- package/dist/engineHealthProbeVerdict.js +115 -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 +44 -0
- package/dist/engineUnavailable.js +492 -0
- package/dist/eventLeg.js +3 -3
- package/dist/generated/sdkFactTables.d.ts +1 -1
- package/dist/generated/sdkFactTables.js +1 -0
- package/dist/generated/settingsSchemaTables.d.ts +4 -0
- package/dist/generated/settingsSchemaTables.js +1 -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 +2 -0
- package/dist/hitl/decisionRefusal.js +7 -8
- 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 +67 -0
- package/dist/hitl/localAllowRedemption.js +256 -0
- package/dist/hitl/parkResolver.js +7 -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 +362 -0
- package/dist/hitl/standingRows.d.ts +3 -1
- package/dist/hitl/standingRows.js +18 -0
- package/dist/hitl/toolApprovalWire.d.ts +30 -8
- package/dist/hitl/toolApprovalWire.js +264 -121
- 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 +129 -0
- package/dist/i18n/messages.en.js +135 -7
- package/dist/i18n/messages.zh.js +142 -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 +43 -17
- package/dist/index.js +30 -12
- package/dist/interactiveHalt.js +2 -1
- package/dist/interactiveInterrupt.js +20 -2
- package/dist/liveModelCatalog.js +2 -2
- 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/mcpReconnect.js +3 -3
- 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 +3 -40
- package/dist/notifications.d.ts +19 -0
- package/dist/notifications.js +114 -12
- package/dist/ownKey.d.ts +6 -0
- package/dist/ownKey.js +31 -0
- 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 +9 -1
- package/dist/pluginHooksWire.js +40 -6
- 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/request/taskRequest.js +10 -6
- package/dist/requestCoordinate.d.ts +1 -0
- package/dist/requestCoordinate.js +13 -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 +16 -2
- package/dist/seam.js +10 -0
- package/dist/seatContract.d.ts +109 -9
- package/dist/seatContract.js +218 -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/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/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/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 +2118 -17
- package/package.json +6 -2
package/dist/abortableSleep.d.ts
CHANGED
|
@@ -9,3 +9,10 @@ export type DeadlineSettled<T> = {
|
|
|
9
9
|
kind: 'deadline';
|
|
10
10
|
};
|
|
11
11
|
export declare function settleWithinDeadline<T>(ms: number, run: (signal: AbortSignal) => Promise<T>): Promise<DeadlineSettled<T>>;
|
|
12
|
+
export interface RequestDeadline {
|
|
13
|
+
readonly signal: AbortSignal;
|
|
14
|
+
readonly expired: () => boolean;
|
|
15
|
+
readonly abort: () => void;
|
|
16
|
+
readonly race: <T>(p: Promise<T>) => Promise<T>;
|
|
17
|
+
}
|
|
18
|
+
export declare function requestDeadline(ms: number, cancel: AbortSignal | undefined): RequestDeadline;
|
package/dist/abortableSleep.js
CHANGED
|
@@ -50,3 +50,40 @@ export function settleWithinDeadline(ms, run) {
|
|
|
50
50
|
pending.then((value) => finish({ kind: 'value', value }), (error) => finish({ kind: 'error', detail: errorDetail(error) }));
|
|
51
51
|
});
|
|
52
52
|
}
|
|
53
|
+
const MAX_TIMER_MS = 2_147_483_647;
|
|
54
|
+
export function requestDeadline(ms, cancel) {
|
|
55
|
+
const ctl = new AbortController();
|
|
56
|
+
const stop = new AbortController();
|
|
57
|
+
let expired = false;
|
|
58
|
+
const gone = new Promise((_resolve, reject) => {
|
|
59
|
+
const fire = () => reject(Object.assign(new Error('aborted'), { name: 'AbortError' }));
|
|
60
|
+
if (ctl.signal.aborted)
|
|
61
|
+
fire();
|
|
62
|
+
else
|
|
63
|
+
ctl.signal.addEventListener('abort', fire, { once: true });
|
|
64
|
+
});
|
|
65
|
+
gone.catch(() => undefined);
|
|
66
|
+
void abortableSleep(Math.min(ms, MAX_TIMER_MS), stop.signal).then(() => {
|
|
67
|
+
if (stop.signal.aborted)
|
|
68
|
+
return;
|
|
69
|
+
expired = true;
|
|
70
|
+
ctl.abort();
|
|
71
|
+
});
|
|
72
|
+
const onCancel = () => ctl.abort();
|
|
73
|
+
if (cancel !== undefined) {
|
|
74
|
+
if (cancel.aborted)
|
|
75
|
+
ctl.abort();
|
|
76
|
+
else
|
|
77
|
+
cancel.addEventListener('abort', onCancel, { once: true });
|
|
78
|
+
}
|
|
79
|
+
return {
|
|
80
|
+
signal: ctl.signal,
|
|
81
|
+
expired: () => expired,
|
|
82
|
+
abort: () => {
|
|
83
|
+
stop.abort();
|
|
84
|
+
cancel?.removeEventListener('abort', onCancel);
|
|
85
|
+
ctl.abort();
|
|
86
|
+
},
|
|
87
|
+
race: (p) => Promise.race([p, gone]),
|
|
88
|
+
};
|
|
89
|
+
}
|
package/dist/adapt/arms.js
CHANGED
|
@@ -2,7 +2,7 @@ import { ccToolDenialKindForToolEnd, gateOutcomeOf } from '../gateOutcome.js';
|
|
|
2
2
|
import { terminalOwnerOf } from '../seam.js';
|
|
3
3
|
import { isSubFlowSegmentEnd, SEGMENT_END_IDENTITY_KEYS, snapshotSegmentIdentity, snapshotIsSubFlow } from '../adapter/types.js';
|
|
4
4
|
import { classifyPeerNotification, renderPeerFrameTranscriptText, sessionBoxNoticeOf } from '../peerFrames.js';
|
|
5
|
-
import { dropQueuedNotificationsForRun, freezeTaskNotificationFields, isEngineWorkflowNotified, isWorkflowCompletionCardEnqueued, markEngineWorkflowNotified, noteOwnWorkflowRun, normalizeTaskNotification, noteWorkflowCompletionCardEnqueued, renderTaskNotificationXml, taskNotificationRenderKeys } from '../notifications.js';
|
|
5
|
+
import { dropQueuedNotificationsForRun, freezeTaskNotificationFields, isEngineWorkflowNotified, isWorkflowCompletionCardEnqueued, markEngineWorkflowNotified, noteOwnWorkflowRun, normalizeTaskNotification, noteWorkflowCompletionCardEnqueued, renderTaskNotificationXml, resupplyTruncatedArmBody, settleWorkflowPointerOwed, takeWorkflowPointerSupplement, taskNotificationRenderKeys } from '../notifications.js';
|
|
6
6
|
import { retryStatusFromArm } from '../retryStatus.js';
|
|
7
7
|
import { steeringInjectedToAttachments } from '../steering.js';
|
|
8
8
|
import { projectDiagnosticsFrame } from '../diagnostics.js';
|
|
@@ -1015,6 +1015,8 @@ const taskNotificationArm = function* (m, { ctx, idOf, panel, inst, pass }) {
|
|
|
1015
1015
|
...(typeof n.task_type === 'string' ? { taskType: n.task_type } : {}),
|
|
1016
1016
|
});
|
|
1017
1017
|
dropQueuedNotificationsForRun(taskId);
|
|
1018
|
+
if (peerFrame === null && n.task_type === 'workflow')
|
|
1019
|
+
settleWorkflowPointerOwed(taskId);
|
|
1018
1020
|
if (n.task_type !== 'background_bash' && n.task_type !== 'monitor') {
|
|
1019
1021
|
const bgSessionId = n.task_type === 'background_agent' && typeof n.sessionId === 'string' && n.sessionId.length > 0 ? n.sessionId : undefined;
|
|
1020
1022
|
yield* panel.settleFromNotification(taskId, isCoreTaskNotificationTerminalNotSuccess(rawStatus), bgSessionId);
|
|
@@ -1031,6 +1033,9 @@ const taskNotificationArm = function* (m, { ctx, idOf, panel, inst, pass }) {
|
|
|
1031
1033
|
const boxNotice = peerFrame === null ? undefined : sessionBoxNoticeOf(peerFrame);
|
|
1032
1034
|
if (boxNotice !== undefined)
|
|
1033
1035
|
yield chrome({ kind: 'session_box_notice', laneProof: mainLane(), ...boxNotice, rowUuid });
|
|
1036
|
+
const truncated = resupplyTruncatedArmBody(n, 'task_notification', taskId);
|
|
1037
|
+
if (truncated !== undefined)
|
|
1038
|
+
yield chrome({ kind: 'resupply_truncated', laneProof: mainLane(), ...truncated });
|
|
1034
1039
|
yield transcript({
|
|
1035
1040
|
type: 'user',
|
|
1036
1041
|
message: {
|
|
@@ -1054,13 +1059,26 @@ const workflowCompleteArm = function* (frame) {
|
|
|
1054
1059
|
const runId = typeof m.runId === 'string' ? m.runId : undefined;
|
|
1055
1060
|
if (runId === undefined)
|
|
1056
1061
|
return;
|
|
1057
|
-
|
|
1062
|
+
const wfStatus = m.status === 'failed' ? 'failed' : 'completed';
|
|
1063
|
+
const extras = workflowCompletionExtrasOf(m);
|
|
1064
|
+
if (isEngineWorkflowNotified(runId)) {
|
|
1065
|
+
const supplement = takeWorkflowPointerSupplement(runId, wfStatus, extras.diagnostics, extras.completionId);
|
|
1066
|
+
if (supplement === undefined)
|
|
1067
|
+
return;
|
|
1068
|
+
yield chrome({
|
|
1069
|
+
kind: 'workflow_notification_enqueue',
|
|
1070
|
+
laneProof: mainLane(),
|
|
1071
|
+
runId,
|
|
1072
|
+
status: wfStatus,
|
|
1073
|
+
summary: supplement.summary,
|
|
1074
|
+
message: renderTaskNotificationXml(supplement),
|
|
1075
|
+
notification: supplement,
|
|
1076
|
+
});
|
|
1058
1077
|
return;
|
|
1078
|
+
}
|
|
1059
1079
|
markEngineWorkflowNotified(runId);
|
|
1060
|
-
const wfStatus = m.status === 'failed' ? 'failed' : 'completed';
|
|
1061
1080
|
const wfSummary = typeof m.summary === 'string' ? m.summary : '';
|
|
1062
1081
|
noteWorkflowCompletionCardEnqueued(runId);
|
|
1063
|
-
const extras = workflowCompletionExtrasOf(m);
|
|
1064
1082
|
const notification = freezeTaskNotificationFields({ taskId: runId, taskType: 'workflow', status: wfStatus, summary: wfSummary, ...(extras.completionId !== undefined ? { completionId: extras.completionId } : {}) });
|
|
1065
1083
|
yield chrome({
|
|
1066
1084
|
kind: 'workflow_notification_enqueue',
|
|
@@ -1072,6 +1090,9 @@ const workflowCompleteArm = function* (frame) {
|
|
|
1072
1090
|
notification,
|
|
1073
1091
|
...(extras.diagnostics !== undefined ? { diagnostics: extras.diagnostics } : {}),
|
|
1074
1092
|
});
|
|
1093
|
+
const truncated = resupplyTruncatedArmBody(m, 'workflow_complete', runId);
|
|
1094
|
+
if (truncated !== undefined)
|
|
1095
|
+
yield chrome({ kind: 'resupply_truncated', laneProof: mainLane(), ...truncated });
|
|
1075
1096
|
};
|
|
1076
1097
|
const retryStatusArm = function* (m, { ctx, flags }) {
|
|
1077
1098
|
const status = retryStatusFromArm(m, ctx.now());
|
|
@@ -2,6 +2,7 @@ import type { AdapterContext, AdapterOutput } from '../seam.js';
|
|
|
2
2
|
import { structuredToToolUseResult, type ToolKillCause, type ToolResultBody } from '../toolResult.js';
|
|
3
3
|
import { type Frame, type IdOf } from './ids.js';
|
|
4
4
|
import type { EngineRowRef } from '../engineRowRef.js';
|
|
5
|
+
import { SEMA_REFUSAL_NOTED_KEY } from '../engineRowRef.js';
|
|
5
6
|
import { type GateOutcomeView, type ToolInputRewriteView } from '../gateOutcome.js';
|
|
6
7
|
type RichToolUseResult = NonNullable<ReturnType<typeof structuredToToolUseResult>>;
|
|
7
8
|
export interface ToolResultOutcome {
|
|
@@ -37,10 +38,11 @@ export interface ToolResultRowFlagParts {
|
|
|
37
38
|
readonly _sema_interrupted_never_started?: true;
|
|
38
39
|
readonly _sema_approval_window_expired?: true;
|
|
39
40
|
readonly _sema_denial_limit_window_expired?: true;
|
|
41
|
+
readonly [SEMA_REFUSAL_NOTED_KEY]?: true;
|
|
40
42
|
readonly _sema_answered_by?: string;
|
|
41
43
|
readonly _sema_rewrite?: ToolInputRewriteView;
|
|
42
44
|
}
|
|
43
|
-
export declare function toolResultRowFlagParts(arm: object | null | undefined, gate: GateOutcomeView | undefined): ToolResultRowFlagParts;
|
|
45
|
+
export declare function toolResultRowFlagParts(arm: object | null | undefined, gate: GateOutcomeView | undefined, denialKind: string | undefined): ToolResultRowFlagParts;
|
|
44
46
|
interface ToolEndPayload {
|
|
45
47
|
output?: unknown;
|
|
46
48
|
structured?: unknown;
|
package/dist/adapt/toolCards.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { deriveTranscriptId } from '../seam.js';
|
|
2
2
|
import { degradedToolResultBody, detectEngineBgShellDetach, detectEngineBgShellReceipt, reportFindingsToolUseResult, structuredToToolUseResult, todoWriteToolUseResult, wireOutputToBody, } from '../toolResult.js';
|
|
3
3
|
import { chrome, mainLane, transcript } from './ids.js';
|
|
4
|
+
import { refusalNotedOf, SEMA_REFUSAL_NOTED_KEY } from '../engineRowRef.js';
|
|
4
5
|
import { flattenWireOutput } from './wireShapes.js';
|
|
5
6
|
import { toolResultBlocksOf } from '../toolResultContent.js';
|
|
6
7
|
import { bashExitOf, bashExitReadingFailed } from '../bashExitReading.js';
|
|
@@ -53,7 +54,7 @@ export function toolResultRowIdentity(sources, toolCallId, ctx) {
|
|
|
53
54
|
}
|
|
54
55
|
return { uuid: deriveTranscriptId({ toolCallId }, ctx) };
|
|
55
56
|
}
|
|
56
|
-
export function toolResultRowFlagParts(arm, gate) {
|
|
57
|
+
export function toolResultRowFlagParts(arm, gate, denialKind) {
|
|
57
58
|
if (arm === null || arm === undefined)
|
|
58
59
|
return {};
|
|
59
60
|
const notExecuted = readFrameTrueMark(arm, 'notExecuted');
|
|
@@ -65,6 +66,7 @@ export function toolResultRowFlagParts(arm, gate) {
|
|
|
65
66
|
...(readFrameStringKey(arm, 'errorCode') === TOOL_END_INTERRUPTED_NEVER_STARTED ? { _sema_interrupted_never_started: true } : {}),
|
|
66
67
|
...(isApprovalWindowExpiredGate(gate) ? { _sema_approval_window_expired: true } : {}),
|
|
67
68
|
...(isDenialLimitAutoDeniedGate(gate) ? { _sema_denial_limit_window_expired: true } : {}),
|
|
69
|
+
...(refusalNotedOf(denialKind, gate) ? { [SEMA_REFUSAL_NOTED_KEY]: true } : {}),
|
|
68
70
|
...(answeredBy !== undefined ? { _sema_answered_by: answeredBy } : {}),
|
|
69
71
|
...(rewrite !== undefined ? { _sema_rewrite: rewrite } : {}),
|
|
70
72
|
};
|
|
@@ -126,7 +128,7 @@ export function createToolCardLedger(ctx, idOf) {
|
|
|
126
128
|
...toolResultEnvelopeParts(outcome),
|
|
127
129
|
...(isCcToolDenialKind(end?.denialKind) ? { _sema_denial_kind: end.denialKind } : {}),
|
|
128
130
|
...(end?.gate !== undefined ? { _sema_gate: end.gate } : {}),
|
|
129
|
-
...toolResultRowFlagParts(end?.closeArm, end?.gate),
|
|
131
|
+
...toolResultRowFlagParts(end?.closeArm, end?.gate, end?.denialKind),
|
|
130
132
|
}, ctx.now());
|
|
131
133
|
}
|
|
132
134
|
function* closeCard(p, end) {
|
|
@@ -94,6 +94,7 @@ export interface ActiveRunSelfHealDeps {
|
|
|
94
94
|
submissionOrigin?: RejectedSubmissionOrigin;
|
|
95
95
|
injectedCarriers?: readonly object[];
|
|
96
96
|
sessionId?: string;
|
|
97
|
+
stillHere?: () => boolean | undefined;
|
|
97
98
|
wasRecentlyTerminatedByUs?: (taskId: string) => boolean;
|
|
98
99
|
interruptedSettle?: InterruptedSettleWindow;
|
|
99
100
|
}
|
|
@@ -135,6 +136,14 @@ export type SelfHealOutcome = {
|
|
|
135
136
|
kind: 'interrupted-settled';
|
|
136
137
|
taskId: string;
|
|
137
138
|
status: string;
|
|
139
|
+
} | {
|
|
140
|
+
kind: 'resend-withheld-left';
|
|
141
|
+
taskId: string;
|
|
142
|
+
releaseConfirmedByEngine?: true;
|
|
143
|
+
} | {
|
|
144
|
+
kind: 'resend-withheld-unconfirmed';
|
|
145
|
+
taskId: string;
|
|
146
|
+
releaseConfirmedByEngine?: true;
|
|
138
147
|
} | {
|
|
139
148
|
kind: 'interrupted-still-finishing';
|
|
140
149
|
taskId: string;
|
|
@@ -252,6 +261,14 @@ export interface SelfHealFollowDeclaration {
|
|
|
252
261
|
following?: boolean;
|
|
253
262
|
}
|
|
254
263
|
export declare function injectedResubmitAfter(outcome: SelfHealOutcome | null | undefined, runStatus: string | null | undefined): boolean;
|
|
264
|
+
export type InjectedResubmitWaitVerdict = 'resubmit' | 'gave-up' | 'left' | 'unconfirmed';
|
|
265
|
+
export interface InjectedResubmitWaitDeps extends Pick<ActiveRunSelfHealDeps, 'sessionId' | 'stillHere'> {
|
|
266
|
+
runs: () => DurableRunVerbs | undefined;
|
|
267
|
+
budgetMs?: number;
|
|
268
|
+
sleep?: (ms: number) => Promise<void>;
|
|
269
|
+
now?: () => number;
|
|
270
|
+
}
|
|
271
|
+
export declare function waitForInjectedResubmit(outcome: SelfHealOutcome | null | undefined, deps: InjectedResubmitWaitDeps): Promise<InjectedResubmitWaitVerdict>;
|
|
255
272
|
export declare function readCancelRequested(body: unknown): boolean | undefined;
|
|
256
273
|
export { atMostOnceFailureClass };
|
|
257
274
|
export declare function clearRunningChoiceOffer(taskId: string, sessionId?: string): void;
|
|
@@ -272,6 +289,10 @@ export interface ClaimReleaseWaitDeps {
|
|
|
272
289
|
session?: string;
|
|
273
290
|
}
|
|
274
291
|
export declare function waitForClaimRelease(taskId: string, deps: ClaimReleaseWaitDeps): Promise<ClaimReleaseVerdict>;
|
|
292
|
+
export type ConversationPresence = 'here' | 'left' | 'unconfirmed';
|
|
293
|
+
export declare function conversationLeftOf(deps: {
|
|
294
|
+
readonly stillHere?: () => boolean | undefined;
|
|
295
|
+
} | null | undefined): ConversationPresence;
|
|
275
296
|
export declare function attemptActiveRunSelfHeal(signal: ActiveRunBusySignal, runs: DurableRunVerbs | undefined, deps?: ActiveRunSelfHealDeps): Promise<SelfHealOutcome>;
|
|
276
297
|
export interface ActiveRunSelfHealCopy {
|
|
277
298
|
wayOut?: string;
|
|
@@ -285,4 +306,22 @@ export interface ActiveRunSelfHealCopy {
|
|
|
285
306
|
}
|
|
286
307
|
export declare const INTERACTIVE_WAY_OUT: string;
|
|
287
308
|
export declare function activeRunSelfHealRow(outcome: SelfHealOutcome, signal?: ActiveRunBusySignal | null, copy?: ActiveRunSelfHealCopy, origin?: RejectedSubmissionOrigin, follow?: SelfHealFollowDeclaration, lang?: UiLanguage): string;
|
|
309
|
+
export type ConversationLeftStopResult = {
|
|
310
|
+
kind: 'untouched';
|
|
311
|
+
} | {
|
|
312
|
+
kind: 'waiting';
|
|
313
|
+
certain: boolean;
|
|
314
|
+
} | {
|
|
315
|
+
kind: 'ended';
|
|
316
|
+
confirmedByEngine: boolean;
|
|
317
|
+
} | {
|
|
318
|
+
kind: 'nothing-to-end';
|
|
319
|
+
} | {
|
|
320
|
+
kind: 'refused';
|
|
321
|
+
detail: string;
|
|
322
|
+
} | {
|
|
323
|
+
kind: 'not-confirmed';
|
|
324
|
+
};
|
|
325
|
+
export declare function conversationLeftStopResultOf(outcome: SelfHealOutcome | null | undefined): ConversationLeftStopResult;
|
|
326
|
+
export declare function conversationLeftStopRow(result: ConversationLeftStopResult, taskId: string, copy?: ActiveRunSelfHealCopy, lang?: UiLanguage): string;
|
|
288
327
|
export declare function activeRunBusyHeadlessRow(signal: ActiveRunBusySignal, copy?: ActiveRunSelfHealCopy, lang?: UiLanguage): string;
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import { abortableSleep } from '../abortableSleep.js';
|
|
2
|
+
import { unrefTimer } from '../unrefTimer.js';
|
|
2
3
|
import { EN_MESSAGES } from '../i18n/messages.en.js';
|
|
3
4
|
import { msg, renderMessage } from '../i18n/translate.js';
|
|
4
5
|
import { registeredPlanReviewCardFacts } from '../planReviewCardFacts.js';
|
|
5
6
|
import { DEFAULT_SESSION_KEY } from '../sessionSlot.js';
|
|
6
7
|
import { ASK_PARK_AUTO_REOPEN_BLOCKS, askParkAutoReopenBlockedContent } from '../hitl/askParkAutoReopenBlock.js';
|
|
7
8
|
import { corruptStoredRowContent, corruptStoredRowWhere, effectiveWireErrorCode } from '../wireErrorTriage.js';
|
|
9
|
+
import { STEERING_NOT_RUNNING } from '../engineErrorCodes.js';
|
|
8
10
|
import { readThrownStatusSlot, slotReadOf } from '../wireFailureShape.js';
|
|
9
11
|
import { checkpointDeadlineStateOf, checkpointRowBarOf, checkpointRowBarSentence, rowBarWayOutContent } from '../checkpointRowVerdict.js';
|
|
10
12
|
import { guardedRead, readOwnDataNonEmptyString, readOwnDataValue } from '../ownKey.js';
|
|
@@ -76,6 +78,9 @@ export function selfHealSubmissionDisposition(outcome) {
|
|
|
76
78
|
return 'superseded';
|
|
77
79
|
case 'injected-deferred':
|
|
78
80
|
return 'deferred';
|
|
81
|
+
case 'resend-withheld-left':
|
|
82
|
+
case 'resend-withheld-unconfirmed':
|
|
83
|
+
return 'not-delivered';
|
|
79
84
|
default:
|
|
80
85
|
return 'not-delivered';
|
|
81
86
|
}
|
|
@@ -110,6 +115,54 @@ export function injectedResubmitAfter(outcome, runStatus) {
|
|
|
110
115
|
return false;
|
|
111
116
|
}
|
|
112
117
|
}
|
|
118
|
+
const INJECTED_RESUBMIT_WAIT_BUDGET_MS = 30 * 60_000;
|
|
119
|
+
const INJECTED_RESUBMIT_READ_STEPS_MS = Object.freeze([500, 1_000, 2_000, 4_000, 8_000]);
|
|
120
|
+
function injectedResubmitSleep(ms) {
|
|
121
|
+
return new Promise((resolve) => {
|
|
122
|
+
unrefTimer(setTimeout(resolve, ms));
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
async function readDeferredRunStatus(deps, taskId) {
|
|
126
|
+
try {
|
|
127
|
+
const verbs = deps.runs();
|
|
128
|
+
const get = verbs?.get;
|
|
129
|
+
if (typeof get !== 'function')
|
|
130
|
+
return null;
|
|
131
|
+
return readStatusGuarded(await get.call(verbs, taskId, sessionOpts(deps)));
|
|
132
|
+
}
|
|
133
|
+
catch {
|
|
134
|
+
return null;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
export async function waitForInjectedResubmit(outcome, deps) {
|
|
138
|
+
try {
|
|
139
|
+
if (typeof outcome !== 'object' || outcome === null || outcome.kind !== 'injected-deferred')
|
|
140
|
+
return 'gave-up';
|
|
141
|
+
if (typeof deps?.runs !== 'function' || typeof deps.runs()?.get !== 'function')
|
|
142
|
+
return 'gave-up';
|
|
143
|
+
const now = typeof deps.now === 'function' ? deps.now : () => Date.now();
|
|
144
|
+
const sleep = typeof deps.sleep === 'function' ? deps.sleep : injectedResubmitSleep;
|
|
145
|
+
const budgetMs = typeof deps.budgetMs === 'number' && Number.isFinite(deps.budgetMs) && deps.budgetMs >= 0 ? deps.budgetMs : INJECTED_RESUBMIT_WAIT_BUDGET_MS;
|
|
146
|
+
const startedAt = now();
|
|
147
|
+
for (let attempt = 0;; attempt++) {
|
|
148
|
+
const before = conversationLeftOf(deps);
|
|
149
|
+
if (before !== 'here')
|
|
150
|
+
return before;
|
|
151
|
+
const status = await readDeferredRunStatus(deps, outcome.taskId);
|
|
152
|
+
const after = conversationLeftOf(deps);
|
|
153
|
+
if (after !== 'here')
|
|
154
|
+
return after;
|
|
155
|
+
if (injectedResubmitAfter(outcome, status))
|
|
156
|
+
return 'resubmit';
|
|
157
|
+
if (now() - startedAt >= budgetMs)
|
|
158
|
+
return 'gave-up';
|
|
159
|
+
await sleep(INJECTED_RESUBMIT_READ_STEPS_MS[Math.min(attempt, INJECTED_RESUBMIT_READ_STEPS_MS.length - 1)] ?? 8_000);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
catch {
|
|
163
|
+
return 'gave-up';
|
|
164
|
+
}
|
|
165
|
+
}
|
|
113
166
|
const PLAN_REVIEW_CARRIER_KEY = '_sema_planReviewOutcome';
|
|
114
167
|
function planReviewCarrierOf(item) {
|
|
115
168
|
const meta = guardedRead(() => (typeof item === 'object' && item !== null && !Array.isArray(item) ? readOwnDataValue(item, PLAN_REVIEW_CARRIER_KEY) : undefined));
|
|
@@ -589,7 +642,40 @@ async function interruptedShortCircuitUnguarded(signal, runs, deps) {
|
|
|
589
642
|
return { kind: 'interrupted-still-finishing', taskId, waitedMs: verdict.waitedMs };
|
|
590
643
|
return null;
|
|
591
644
|
}
|
|
645
|
+
export function conversationLeftOf(deps) {
|
|
646
|
+
if (typeof deps !== 'object' || deps === null)
|
|
647
|
+
return 'here';
|
|
648
|
+
let port;
|
|
649
|
+
try {
|
|
650
|
+
port = deps.stillHere;
|
|
651
|
+
}
|
|
652
|
+
catch {
|
|
653
|
+
return 'unconfirmed';
|
|
654
|
+
}
|
|
655
|
+
if (typeof port !== 'function')
|
|
656
|
+
return 'here';
|
|
657
|
+
try {
|
|
658
|
+
const answer = port.call(deps);
|
|
659
|
+
return answer === true ? 'here' : answer === false ? 'left' : 'unconfirmed';
|
|
660
|
+
}
|
|
661
|
+
catch {
|
|
662
|
+
return 'unconfirmed';
|
|
663
|
+
}
|
|
664
|
+
}
|
|
592
665
|
export async function attemptActiveRunSelfHeal(signal, runs, deps) {
|
|
666
|
+
const outcome = await triageActiveRun(signal, runs, deps);
|
|
667
|
+
if (selfHealSubmissionDisposition(outcome) !== 'resending' || typeof outcome.taskId !== 'string')
|
|
668
|
+
return outcome;
|
|
669
|
+
const presence = conversationLeftOf(deps);
|
|
670
|
+
if (presence === 'here')
|
|
671
|
+
return outcome;
|
|
672
|
+
return {
|
|
673
|
+
kind: presence === 'left' ? 'resend-withheld-left' : 'resend-withheld-unconfirmed',
|
|
674
|
+
taskId: outcome.taskId,
|
|
675
|
+
...('releaseConfirmedByEngine' in outcome && outcome.releaseConfirmedByEngine === true ? { releaseConfirmedByEngine: true } : {}),
|
|
676
|
+
};
|
|
677
|
+
}
|
|
678
|
+
async function triageActiveRun(signal, runs, deps) {
|
|
593
679
|
const interrupted = await interruptedShortCircuit(signal, runs, deps);
|
|
594
680
|
if (interrupted !== null)
|
|
595
681
|
return interrupted;
|
|
@@ -989,7 +1075,7 @@ async function runningChoiceArm(taskId, status, busy, statusFromWire, runs, carr
|
|
|
989
1075
|
const delivery = atMostOnceFailureClass(e);
|
|
990
1076
|
const errorCode = failureWireCode(e);
|
|
991
1077
|
let runStatus;
|
|
992
|
-
if (delivery === 'rejected' && errorCode ===
|
|
1078
|
+
if (delivery === 'rejected' && errorCode === STEERING_NOT_RUNNING && typeof runs.get === 'function' && !probeCallerAborted()) {
|
|
993
1079
|
const probe = await probeRunStatusOnce(taskId, runs, runs.get, deps);
|
|
994
1080
|
if (probe.status !== null)
|
|
995
1081
|
runStatus = probe.status;
|
|
@@ -1080,7 +1166,6 @@ function wakeSessionClause(copy, lang) {
|
|
|
1080
1166
|
return say(lang, 'session.selfHeal.wakeOn.host', { where: host.trim() });
|
|
1081
1167
|
return say(lang, 'session.selfHeal.wakeOn.engine');
|
|
1082
1168
|
}
|
|
1083
|
-
const STEER_NOT_RUNNING_CODE = 'steering.not_running';
|
|
1084
1169
|
function decidePathClause(signal, lang) {
|
|
1085
1170
|
const decidePath = signal?.pendingGate?.decidePath;
|
|
1086
1171
|
if (!decidePath)
|
|
@@ -1164,6 +1249,13 @@ function injectedSubmissionRow(outcome, following = false, lang) {
|
|
|
1164
1249
|
}
|
|
1165
1250
|
if (outcome.kind === 'interrupted-still-finishing')
|
|
1166
1251
|
return say(lang, 'session.selfHeal.injected.interruptedFinishing', { lead, id });
|
|
1252
|
+
if (outcome.kind === 'resend-withheld-left') {
|
|
1253
|
+
return outcome.releaseConfirmedByEngine === true
|
|
1254
|
+
? say(lang, 'session.selfHeal.injected.resendWithheldLeftConfirmed', { lead, id })
|
|
1255
|
+
: say(lang, 'session.selfHeal.injected.resendWithheldLeftInferred', { lead, id });
|
|
1256
|
+
}
|
|
1257
|
+
if (outcome.kind === 'resend-withheld-unconfirmed')
|
|
1258
|
+
return say(lang, 'session.selfHeal.injected.resendWithheldUnconfirmed', { lead });
|
|
1167
1259
|
switch (selfHealSubmissionDisposition(outcome)) {
|
|
1168
1260
|
case 'held-for-decision':
|
|
1169
1261
|
return say(lang, 'session.selfHeal.injected.heldForDecision', { lead, id });
|
|
@@ -1291,7 +1383,7 @@ function activeRunSelfHealBaseRow(outcome, wayOut, following = false, keepSessio
|
|
|
1291
1383
|
});
|
|
1292
1384
|
}
|
|
1293
1385
|
case 'running-steer-failed':
|
|
1294
|
-
if (outcome.delivery === 'rejected' && outcome.errorCode ===
|
|
1386
|
+
if (outcome.delivery === 'rejected' && outcome.errorCode === STEERING_NOT_RUNNING && outcome.runStatus !== undefined && isSdkRunTerminal(outcome.runStatus)) {
|
|
1295
1387
|
return say(lang, 'session.selfHeal.row.steerFailed.runEnded', { taskId: outcome.taskId, status: outcome.runStatus });
|
|
1296
1388
|
}
|
|
1297
1389
|
return outcome.delivery === 'rejected'
|
|
@@ -1306,6 +1398,12 @@ function activeRunSelfHealBaseRow(outcome, wayOut, following = false, keepSessio
|
|
|
1306
1398
|
return outcome.releaseConfirmedByEngine === true
|
|
1307
1399
|
? say(lang, 'session.selfHeal.row.cancelled.confirmed', { taskId: outcome.taskId })
|
|
1308
1400
|
: say(lang, 'session.selfHeal.row.cancelled.reported', { taskId: outcome.taskId });
|
|
1401
|
+
case 'resend-withheld-left':
|
|
1402
|
+
return outcome.releaseConfirmedByEngine === true
|
|
1403
|
+
? say(lang, 'session.selfHeal.row.resendWithheldLeft.confirmed', { taskId: outcome.taskId })
|
|
1404
|
+
: say(lang, 'session.selfHeal.row.resendWithheldLeft.reported', { taskId: outcome.taskId });
|
|
1405
|
+
case 'resend-withheld-unconfirmed':
|
|
1406
|
+
return say(lang, 'session.selfHeal.row.resendWithheldUnconfirmed');
|
|
1309
1407
|
case 'running-cancel-timeout': {
|
|
1310
1408
|
const waited = `${String(Math.max(1, Math.round(outcome.waitedMs / 1000)))}s`;
|
|
1311
1409
|
if (outcome.aborted)
|
|
@@ -1377,6 +1475,76 @@ function activeRunSelfHealBaseRow(outcome, wayOut, following = false, keepSessio
|
|
|
1377
1475
|
});
|
|
1378
1476
|
}
|
|
1379
1477
|
}
|
|
1478
|
+
export function conversationLeftStopResultOf(outcome) {
|
|
1479
|
+
if (typeof outcome !== 'object' || outcome === null)
|
|
1480
|
+
return { kind: 'untouched' };
|
|
1481
|
+
switch (outcome.kind) {
|
|
1482
|
+
case 'running-cancelled':
|
|
1483
|
+
case 'stale-park-cancelled':
|
|
1484
|
+
case 'ask-decided-without-card':
|
|
1485
|
+
case 'resend-withheld-left':
|
|
1486
|
+
case 'resend-withheld-unconfirmed':
|
|
1487
|
+
return { kind: 'ended', confirmedByEngine: outcome.releaseConfirmedByEngine === true };
|
|
1488
|
+
case 'running-cancel-timeout':
|
|
1489
|
+
case 'stale-park-cancel-timeout':
|
|
1490
|
+
case 'ask-decided-release-unknown':
|
|
1491
|
+
case 'interrupted-still-finishing':
|
|
1492
|
+
return { kind: 'not-confirmed' };
|
|
1493
|
+
case 'running-cancel-failed':
|
|
1494
|
+
case 'stale-park-cancel-failed':
|
|
1495
|
+
return outcome.delivery === 'rejected' ? { kind: 'refused', detail: outcome.detail } : { kind: 'not-confirmed' };
|
|
1496
|
+
case 'running-settled':
|
|
1497
|
+
case 'running-not-found':
|
|
1498
|
+
case 'ask-run-not-found':
|
|
1499
|
+
case 'ask-run-settled':
|
|
1500
|
+
case 'interrupted-settled':
|
|
1501
|
+
return { kind: 'nothing-to-end' };
|
|
1502
|
+
case 'not-parked':
|
|
1503
|
+
return isSdkRunTerminal(outcome.status) ? { kind: 'nothing-to-end' } : { kind: 'untouched' };
|
|
1504
|
+
case 'ask-reopened':
|
|
1505
|
+
case 'plan-review-reopened':
|
|
1506
|
+
case 'decision-pending':
|
|
1507
|
+
return { kind: 'waiting', certain: true };
|
|
1508
|
+
case 'ask-reopen-failed':
|
|
1509
|
+
case 'plan-review-reopen-failed':
|
|
1510
|
+
return { kind: 'waiting', certain: false };
|
|
1511
|
+
case 'state-unknown':
|
|
1512
|
+
case 'stale-park-wait':
|
|
1513
|
+
case 'running-steered':
|
|
1514
|
+
case 'running-steer-failed':
|
|
1515
|
+
case 'running-attach':
|
|
1516
|
+
case 'injected-redundant':
|
|
1517
|
+
case 'injected-deferred':
|
|
1518
|
+
return { kind: 'untouched' };
|
|
1519
|
+
}
|
|
1520
|
+
}
|
|
1521
|
+
export function conversationLeftStopRow(result, taskId, copy, lang) {
|
|
1522
|
+
const endRun = endRunClause(copy, taskId, lang, 'interactive');
|
|
1523
|
+
try {
|
|
1524
|
+
switch (result.kind) {
|
|
1525
|
+
case 'untouched':
|
|
1526
|
+
break;
|
|
1527
|
+
case 'waiting':
|
|
1528
|
+
return result.certain === true
|
|
1529
|
+
? say(lang, 'session.selfHeal.stopLeft.waiting.certain', { taskId })
|
|
1530
|
+
: say(lang, 'session.selfHeal.stopLeft.waiting.uncertain', { taskId, endRun });
|
|
1531
|
+
case 'ended':
|
|
1532
|
+
return result.confirmedByEngine === true
|
|
1533
|
+
? say(lang, 'session.selfHeal.stopLeft.ended.confirmed', { taskId })
|
|
1534
|
+
: say(lang, 'session.selfHeal.stopLeft.ended.reported', { taskId });
|
|
1535
|
+
case 'nothing-to-end':
|
|
1536
|
+
return say(lang, 'session.selfHeal.stopLeft.nothingToEnd', { taskId });
|
|
1537
|
+
case 'refused':
|
|
1538
|
+
return say(lang, 'session.selfHeal.stopLeft.refused', { taskId, detail: typeof result.detail === 'string' ? result.detail : '', endRun });
|
|
1539
|
+
case 'not-confirmed':
|
|
1540
|
+
return say(lang, 'session.selfHeal.stopLeft.notConfirmed', { taskId, endRun });
|
|
1541
|
+
}
|
|
1542
|
+
}
|
|
1543
|
+
catch {
|
|
1544
|
+
return say(lang, 'session.selfHeal.stopLeft.untouched', { taskId, endRun });
|
|
1545
|
+
}
|
|
1546
|
+
return say(lang, 'session.selfHeal.stopLeft.untouched', { taskId, endRun });
|
|
1547
|
+
}
|
|
1380
1548
|
export function activeRunBusyHeadlessRow(signal, copy, lang) {
|
|
1381
1549
|
const override = copy?.headlessRowFor?.(signal);
|
|
1382
1550
|
if (typeof override === 'string')
|
|
@@ -5,17 +5,16 @@ import { ccToolDenialKindForToolEnd, gateOutcomeOf, toolInputRewriteOf } from '.
|
|
|
5
5
|
import { projectToolRoster, projectToolRosterDelta } from '../../toolRoster.js';
|
|
6
6
|
import { projectHandsSection } from '../../handsSeam.js';
|
|
7
7
|
import { readMcpAuthorization, readMcpLiveness } from '../../mcpLiveness.js';
|
|
8
|
-
import { contextUsageReadingOf, humanInputAttachmentsOf, guardedRead, markMcpSectionDroppedNamedRows, ownSnapshotTyped, promptManifestIdentityOfFrame, promptManifestSectionViewOf, readFrameStringKey, readFrameTrueMark, readOwnDataFiniteNumber, readOwnDataNonEmptyString, workflowCompletionExtrasOf } from '../../ownKey.js';
|
|
8
|
+
import { contextUsageReadingOf, humanInputAttachmentsOf, guardedRead, markMcpSectionDroppedNamedRows, ownSnapshotTyped, promptManifestIdentityOfFrame, promptManifestSectionViewOf, readFrameStringKey, readFrameTrueMark, readOwnDataFiniteNumber, readOwnDataNonEmptyString, resupplyTruncatedOf, workflowCompletionExtrasOf } from '../../ownKey.js';
|
|
9
9
|
import { humanInputAuthorKeys, runOriginKeys } from '../../inputAuthor.js';
|
|
10
10
|
import { SEGMENT_END_IDENTITY_KEYS, eventSeq, stripToolUseSideChannels } from '../types.js';
|
|
11
|
+
import { promptSuggestionBatchOf } from '../../promptSuggestionBatch.js';
|
|
11
12
|
import { frozenSet } from '../../frozenSet.js';
|
|
12
13
|
import { isCoreWorkflowRunTerminal } from '../../terminalStatuses.js';
|
|
13
14
|
import { envelopeUuidOf, mintEngineRowRef, readBoundRun, wireEventIdOf } from '../../engineRowRef.js';
|
|
14
15
|
function armBody(body) {
|
|
15
16
|
return body;
|
|
16
17
|
}
|
|
17
|
-
const SUGGESTION_BATCH_CAP = 8;
|
|
18
|
-
const SUGGESTION_CHARS_CAP = 200;
|
|
19
18
|
export const INTERNAL_SDK_ARM_TYPES = frozenSet([
|
|
20
19
|
'tool_disclosure',
|
|
21
20
|
'tool_progress',
|
|
@@ -174,6 +173,10 @@ function projectEvent(ev, ctx) {
|
|
|
174
173
|
status: wf.status,
|
|
175
174
|
summary: typeof wf.summary === 'string' ? wf.summary : '',
|
|
176
175
|
...workflowCompletionExtrasOf(wf),
|
|
176
|
+
...(() => {
|
|
177
|
+
const t = resupplyTruncatedOf(wf);
|
|
178
|
+
return t === undefined ? {} : { payloadTruncated: { bytes: t.bytes, droppedKeys: [...t.droppedKeys] } };
|
|
179
|
+
})(),
|
|
177
180
|
})));
|
|
178
181
|
}
|
|
179
182
|
case 'text':
|
|
@@ -403,16 +406,13 @@ function projectEvent(ev, ctx) {
|
|
|
403
406
|
})));
|
|
404
407
|
}
|
|
405
408
|
case 'suggestions': {
|
|
406
|
-
const
|
|
407
|
-
|
|
408
|
-
.slice(0, SUGGESTION_BATCH_CAP)
|
|
409
|
-
.map((s) => (s.length > SUGGESTION_CHARS_CAP ? `${s.slice(0, SUGGESTION_CHARS_CAP)}…` : s));
|
|
410
|
-
if (list.length === 0)
|
|
409
|
+
const batch = promptSuggestionBatchOf(ev.suggestions);
|
|
410
|
+
if (batch === undefined)
|
|
411
411
|
return nothing('empty_payload');
|
|
412
412
|
return projected(stamp(ctx, armBody({
|
|
413
413
|
type: 'prompt_suggestions',
|
|
414
|
-
suggestions: list,
|
|
415
|
-
...(
|
|
414
|
+
suggestions: [...batch.list],
|
|
415
|
+
...(batch.truncatedCount !== undefined ? { truncatedCount: batch.truncatedCount } : {}),
|
|
416
416
|
})));
|
|
417
417
|
}
|
|
418
418
|
case 'turn_end':
|
|
@@ -5,6 +5,7 @@ import type { SDKPermissionDenial, SDKResultError, SDKResultSuccess, TerminalRea
|
|
|
5
5
|
import { type RunTerminalCodedDetail, type RunTerminalRead } from '../../runTerminal.js';
|
|
6
6
|
import { type SemaModelUsage } from './turnUsageToModelUsage.js';
|
|
7
7
|
import { type ResultLimitWord } from '../../engineErrorCodes.js';
|
|
8
|
+
import type { RunCostSettlement } from '../../sessionCostReading.js';
|
|
8
9
|
import { type ResultWayOutFacts } from '../../providerRejection.js';
|
|
9
10
|
export interface SemaFlatUsage {
|
|
10
11
|
readonly inputTokens: number;
|
|
@@ -89,6 +90,7 @@ export interface RunCostFacts {
|
|
|
89
90
|
export declare function readRunCostFacts(stats: TaskStats | undefined, observed?: {
|
|
90
91
|
readonly usageMissingObserved?: boolean;
|
|
91
92
|
}): RunCostFacts | undefined;
|
|
93
|
+
export declare function runCostSettlementOf(stats: TaskStats | undefined): Exclude<RunCostSettlement, 'awaiting'>;
|
|
92
94
|
export interface ObservedTerminalParts extends PermissionDenialParts {
|
|
93
95
|
readonly _sema_usage_lower_bound?: true;
|
|
94
96
|
}
|
|
@@ -261,6 +261,17 @@ export function readRunCostFacts(stats, observed) {
|
|
|
261
261
|
reconcile,
|
|
262
262
|
};
|
|
263
263
|
}
|
|
264
|
+
export function runCostSettlementOf(stats) {
|
|
265
|
+
try {
|
|
266
|
+
const facts = readRunCostFacts(stats);
|
|
267
|
+
if (facts === undefined)
|
|
268
|
+
return 'lost';
|
|
269
|
+
return facts.reconcile.ownMicroUsd !== undefined ? 'priced' : 'unpriced';
|
|
270
|
+
}
|
|
271
|
+
catch {
|
|
272
|
+
return 'lost';
|
|
273
|
+
}
|
|
274
|
+
}
|
|
264
275
|
function structuredOutputParts(r) {
|
|
265
276
|
const so = r.structuredOutput;
|
|
266
277
|
return so !== undefined ? { structured_output: so } : {};
|
|
@@ -5,6 +5,7 @@ import type { ObservedTerminalParts } from './downstream/terminalToSdkResult.js'
|
|
|
5
5
|
import { type ToolHistoryErrorCarrier } from '../toolHistoryMismatch.js';
|
|
6
6
|
import { MODEL_OUTPUT_ERROR_PREFIX, OUTCOME_UNKNOWN_ROW_PREFIX, RUN_BLOCKED_MESSAGE_PREFIX, RUN_STOPPED_MESSAGE_PREFIX } from '../rowKind.js';
|
|
7
7
|
export { MODEL_OUTPUT_ERROR_PREFIX, OUTCOME_UNKNOWN_ROW_PREFIX, RUN_BLOCKED_MESSAGE_PREFIX, RUN_STOPPED_MESSAGE_PREFIX };
|
|
8
|
+
import { type PlanReviewCardFacts } from '../planReviewCardFacts.js';
|
|
8
9
|
export interface ActiveRunPendingGate {
|
|
9
10
|
readonly kind: string | null;
|
|
10
11
|
readonly decidePath: string | null;
|
|
@@ -37,5 +38,9 @@ export interface RunStreamHandle {
|
|
|
37
38
|
latestUsageMissing?: true;
|
|
38
39
|
observedTerminalParts?: () => ObservedTerminalParts;
|
|
39
40
|
}
|
|
41
|
+
export interface PlanReviewFrameClaim {
|
|
42
|
+
feed(frame: {} | null | undefined): PlanReviewCardFacts | undefined;
|
|
43
|
+
}
|
|
44
|
+
export declare function openPlanReviewFrameClaim(): PlanReviewFrameClaim;
|
|
40
45
|
export declare function isRunStreamActive(): boolean;
|
|
41
46
|
export declare function runStream(events: AsyncIterable<AgentEvent>, ctx: EmitContext, handle?: RunStreamHandle): AsyncGenerator<SDKMessage>;
|
|
@@ -20,7 +20,7 @@ import { MODEL_OUTPUT_ERROR_PREFIX, OUTCOME_UNKNOWN_ROW_PREFIX, RUN_BLOCKED_MESS
|
|
|
20
20
|
export { MODEL_OUTPUT_ERROR_PREFIX, OUTCOME_UNKNOWN_ROW_PREFIX, RUN_BLOCKED_MESSAGE_PREFIX, RUN_STOPPED_MESSAGE_PREFIX };
|
|
21
21
|
import { ccToolDenialKindForToolEnd, gateDeniedBy, gateOutcomeOf } from '../gateOutcome.js';
|
|
22
22
|
import { resumeReopenContent, resumeReopenFromError, suspendedReopenOf } from '../hitl/suspendedReopen.js';
|
|
23
|
-
import { openPlanBodyClaimLeg,
|
|
23
|
+
import { openPlanBodyClaimLeg, planReviewClaimStep } from '../planReviewCardFacts.js';
|
|
24
24
|
import { isCcToolDenialKind, isCcToolDenialKindADenial, isGateDeniedByWord } from '../gateVocabulary.js';
|
|
25
25
|
const ENGINE_TURN_USAGE_KEYS = Object.freeze(['inputTokens', 'totalInputTokens', 'outputTokens', 'cacheReadTokens', 'cacheWriteTokens', 'costMicroUsd']);
|
|
26
26
|
const _engineTurnUsageKeysPin = true;
|
|
@@ -454,6 +454,18 @@ function wireFrameIsSubFlow(ev) {
|
|
|
454
454
|
});
|
|
455
455
|
return snap === undefined || snapshotIsSubFlow(snap);
|
|
456
456
|
}
|
|
457
|
+
export function openPlanReviewFrameClaim() {
|
|
458
|
+
const leg = openPlanBodyClaimLeg();
|
|
459
|
+
return Object.freeze({
|
|
460
|
+
feed(frame) {
|
|
461
|
+
if (typeof frame !== 'object' || frame === null)
|
|
462
|
+
return undefined;
|
|
463
|
+
const subFlow = wireFrameIsSubFlow(frame);
|
|
464
|
+
const seq = guardedRead(() => eventSeq(frame));
|
|
465
|
+
return planReviewClaimStep(leg, frame, subFlow, seq);
|
|
466
|
+
},
|
|
467
|
+
});
|
|
468
|
+
}
|
|
457
469
|
function withStringFailureFields(ev) {
|
|
458
470
|
if (ev.type !== 'failed')
|
|
459
471
|
return ev;
|
|
@@ -592,7 +604,7 @@ async function* runStreamInner(events, ctx, handle = {}) {
|
|
|
592
604
|
}
|
|
593
605
|
seen.add(seq);
|
|
594
606
|
}
|
|
595
|
-
|
|
607
|
+
const planReviewAtTerminal = planReviewClaimStep(planLeg, ev, wireSubFlow, seq);
|
|
596
608
|
if (ev.type === 'tool_start') {
|
|
597
609
|
const callId = ev.toolCallId;
|
|
598
610
|
if (typeof callId === 'string' && callId.length > 0 && !toolInputAmbiguous.has(callId)) {
|
|
@@ -855,7 +867,7 @@ async function* runStreamInner(events, ctx, handle = {}) {
|
|
|
855
867
|
accepted: ev.type === 'done' && (doneTerminal?.kind === 'completed' || doneTerminal?.kind === 'paused'),
|
|
856
868
|
}).acceptedSinceMismatch;
|
|
857
869
|
}
|
|
858
|
-
const planReview =
|
|
870
|
+
const planReview = planReviewAtTerminal;
|
|
859
871
|
if (ev.type === 'done' && isReviewPark(doneTerminal) && ctx.emitChrome) {
|
|
860
872
|
try {
|
|
861
873
|
await ctx.emitChrome({ kind: 'plan_review_park', laneProof: mainLane(), result: ev.result, ...(planReview !== undefined ? { planReview } : {}) });
|