@sema-agent/core 7.5.2 → 7.6.1
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 +67 -0
- package/dist/agents/agent-transcript-tool.d.ts +2 -2
- package/dist/agents/cascade.d.ts +4 -5
- package/dist/agents/cascade.js +12 -10
- package/dist/agents/repair-loop.d.ts +7 -5
- package/dist/agents/repair-loop.js +13 -15
- package/dist/agents/retain-ledger.d.ts +2 -3
- package/dist/agents/send-message-tool.d.ts +2 -2
- package/dist/agents/session-util.d.ts +2 -2
- package/dist/agents/subagent.d.ts +27 -46
- package/dist/agents/subagent.js +119 -105
- package/dist/agents/suspend-guard.d.ts +31 -19
- package/dist/agents/suspend-guard.js +14 -8
- package/dist/agents/teacher.d.ts +2 -2
- package/dist/agents/teacher.js +9 -9
- package/dist/agents/team.d.ts +6 -5
- package/dist/agents/team.js +10 -8
- package/dist/agents/verify.d.ts +8 -9
- package/dist/agents/verify.js +17 -17
- package/dist/core/a2a.js +2 -1
- package/dist/core/agent-definition.d.ts +172 -0
- package/dist/core/agent-definition.js +1 -0
- package/dist/core/ask-origin.d.ts +60 -7
- package/dist/core/ask-origin.js +26 -1
- package/dist/core/checkpoint-store.d.ts +78 -76
- package/dist/core/checkpoint-store.js +17 -1
- package/dist/core/delegation-frames.d.ts +298 -0
- package/dist/core/delegation-frames.js +21 -0
- package/dist/core/engine-notice.d.ts +555 -0
- package/dist/core/engine-notice.js +55 -0
- package/dist/core/gate-fold.d.ts +12 -0
- package/dist/core/gate-fold.js +158 -0
- package/dist/core/gate-lanes.d.ts +93 -0
- package/dist/core/gate-lanes.js +626 -0
- package/dist/core/gate-outcome.d.ts +189 -0
- package/dist/core/gate-outcome.js +70 -0
- package/dist/core/hands-band.d.ts +134 -0
- package/dist/core/hands-band.js +1 -0
- package/dist/core/hooks.d.ts +22 -177
- package/dist/core/hooks.js +53 -851
- package/dist/core/mcp-failure.d.ts +142 -0
- package/dist/core/mcp-failure.js +145 -0
- package/dist/core/mcp-server-spec.d.ts +217 -0
- package/dist/core/mcp-server-spec.js +1 -0
- package/dist/core/mcp.d.ts +21 -77
- package/dist/core/mcp.js +76 -150
- package/dist/core/model-seat.d.ts +99 -0
- package/dist/core/model-seat.js +1 -0
- package/dist/core/pause-registry.d.ts +131 -0
- package/dist/core/pause-registry.js +27 -0
- package/dist/core/reminder-mint.d.ts +10 -0
- package/dist/core/reminder-mint.js +3 -0
- package/dist/core/runner/assemble-result.d.ts +32 -41
- package/dist/core/runner/assemble-result.js +55 -74
- package/dist/core/runner/contracts.d.ts +427 -69
- package/dist/core/runner/denial-limit-arms.d.ts +1 -1
- package/dist/core/runner/denial-limit-arms.js +3 -3
- package/dist/core/runner/gate-exit.d.ts +242 -0
- package/dist/core/runner/gate-exit.js +124 -0
- package/dist/core/runner/park-commit.d.ts +17 -23
- package/dist/core/runner/park-commit.js +14 -15
- package/dist/core/runner/prepare-ask-lane.d.ts +0 -3
- package/dist/core/runner/prepare-ask-lane.js +3 -5
- package/dist/core/runner/prepare-boundary-parks.d.ts +3 -6
- package/dist/core/runner/prepare-boundary-parks.js +3 -3
- package/dist/core/runner/prepare-caps-and-workflow.d.ts +2 -7
- package/dist/core/runner/prepare-caps-and-workflow.js +1 -1
- package/dist/core/runner/prepare-delegation-surface.d.ts +2 -7
- package/dist/core/runner/prepare-gate-stations.d.ts +4 -7
- package/dist/core/runner/prepare-gate-stations.js +29 -54
- package/dist/core/runner/prepare-inherited-gate.js +1 -1
- package/dist/core/runner/prepare-memory.d.ts +44 -26
- package/dist/core/runner/prepare-park-ask.d.ts +2 -4
- package/dist/core/runner/prepare-park-ask.js +5 -5
- package/dist/core/runner/prepare-task.d.ts +2 -2
- package/dist/core/runner/prepare-task.js +8 -9
- package/dist/core/runner/prepare-wiring-manifest.d.ts +7 -15
- package/dist/core/runner/prepare-wiring-manifest.js +9 -10
- package/dist/core/runner/runtask.d.ts +20 -102
- package/dist/core/runner/runtask.js +119 -121
- package/dist/core/runner/terminal-projection.d.ts +22 -0
- package/dist/core/runner/terminal-projection.js +28 -0
- package/dist/core/runner-deps.d.ts +1416 -0
- package/dist/core/runner-deps.js +1 -0
- package/dist/core/runtime-caps.d.ts +164 -0
- package/dist/core/runtime-caps.js +1 -0
- package/dist/core/store-contracts/checkpoint-store-contract.d.ts +4 -1
- package/dist/core/store-contracts/checkpoint-store-contract.js +8 -2
- package/dist/core/task-event.d.ts +910 -0
- package/dist/core/task-event.js +1 -0
- package/dist/core/task-limits.d.ts +110 -0
- package/dist/core/task-limits.js +1 -0
- package/dist/core/task-result.d.ts +809 -0
- package/dist/core/task-result.js +1 -0
- package/dist/core/task-spec.d.ts +1370 -0
- package/dist/core/task-spec.js +1 -0
- package/dist/core/task-stream.d.ts +382 -0
- package/dist/core/task-stream.js +1 -0
- package/dist/core/terminal-cause.d.ts +137 -0
- package/dist/core/terminal-cause.js +9 -0
- package/dist/core/tool-policy.d.ts +43 -139
- package/dist/core/tool-policy.js +79 -112
- package/dist/core/tool-spec.d.ts +1174 -0
- package/dist/core/tool-spec.js +1 -0
- package/dist/core/types.d.ts +27 -7789
- package/dist/core/types.js +2 -76
- package/dist/core/warm-resume.d.ts +2 -2
- package/dist/core/wiring-manifest.d.ts +6 -3
- package/dist/core/workflow-journal-store.js +3 -4
- package/dist/engine/harness/agent-harness.d.ts +1 -1
- package/dist/index.d.ts +12 -8
- package/dist/index.js +9 -6
- package/dist/orchestration/builtin-workflows.d.ts +2 -2
- package/dist/orchestration/builtin-workflows.js +1 -1
- package/dist/orchestration/goal.d.ts +2 -2
- package/dist/orchestration/goal.js +8 -7
- package/dist/orchestration/run-spec.d.ts +2 -2
- package/dist/orchestration/run-spec.js +5 -3
- package/dist/orchestration/run-workflow-tool.d.ts +4 -4
- package/dist/orchestration/run-workflow-tool.js +4 -4
- package/dist/orchestration/workflow-governance.d.ts +4 -4
- package/dist/orchestration/workflow-governance.js +4 -2
- package/dist/orchestration/workflow-primitives.d.ts +1 -1
- package/dist/orchestration/workflow-primitives.js +1 -1
- package/dist/orchestration/workflow.d.ts +15 -4
- package/dist/orchestration/workflow.js +64 -39
- package/dist/prompts/supervisor.d.ts +1 -1
- package/dist/prompts/supervisor.js +3 -3
- package/dist/scenarios/scenario-registry.d.ts +3 -3
- package/dist/scenarios/scenario-registry.js +1 -1
- package/dist/scenarios/teacher-quickstart.d.ts +2 -2
- package/dist/server/http.d.ts +2 -2
- package/dist/stores/file/fs-atomic.d.ts +88 -12
- package/dist/stores/file/fs-atomic.js +184 -55
- package/dist/stores/file/index.d.ts +1 -0
- package/dist/stores/file/index.js +1 -0
- package/package.json +3 -1
- package/test/export-surface.snapshot.json +82 -22
|
@@ -25,7 +25,8 @@ import type { LockedPreflight } from "../locked-config.js";
|
|
|
25
25
|
import type { MaterializedMcp } from "../mcp.js";
|
|
26
26
|
import type { SessionStore } from "../session.js";
|
|
27
27
|
import { type ToolResultStore } from "../tool-result-store.js";
|
|
28
|
-
import { type
|
|
28
|
+
import { type OnAsk, type ToolPolicy } from "../tool-policy.js";
|
|
29
|
+
import type { GateOutcome } from "../gate-outcome.js";
|
|
29
30
|
import type { RunnerDeps, RuntimeCaps, TaskSpec, ToolEffect, ToolExecuteContext } from "../types.js";
|
|
30
31
|
import { type UsageWindow } from "../usage-window-store.js";
|
|
31
32
|
import { type AutoModeArmReason, type WiringManifest, type WiringManifestMcpEntry } from "../wiring-manifest.js";
|
|
@@ -113,9 +114,7 @@ export interface PrepareWiringManifestInput {
|
|
|
113
114
|
/** borrowed-readonly — the built harness the peer drain binds to. */
|
|
114
115
|
harness: AgentHarness;
|
|
115
116
|
/** borrowed-readonly — the durable-suspend holder; the drain's parked predicate reads `token` at run time. Not written here. */
|
|
116
|
-
|
|
117
|
-
/** borrowed-readonly — the review holder; same read. Not written here. */
|
|
118
|
-
reviewRef: Prepared["reviewRef"];
|
|
117
|
+
pausedRef: Prepared["pausedRef"];
|
|
119
118
|
/** borrowed-readonly — the FROZEN approver seat (the notice's liveApprover fact). */
|
|
120
119
|
frozenOnAsk: OnAsk | undefined;
|
|
121
120
|
/** borrowed-readonly — the LIVE half of the inherited chain (the notice reads its content mandates). */
|
|
@@ -134,16 +133,9 @@ export interface PrepareWiringManifestResult {
|
|
|
134
133
|
/** borrowed-mutable — the call ids the gate blocked or suspended (`Prepared.blockedToolCalls`). Writers: the gate; readers
|
|
135
134
|
* delete one-shot. */
|
|
136
135
|
blockedToolCalls: Set<string>;
|
|
137
|
-
/** borrowed-mutable — the
|
|
136
|
+
/** borrowed-mutable — the gate-outcome sideband (`Prepared.gateOutcomes`). Writer: the gate station; the frame mint reads and
|
|
138
137
|
* deletes. Nothing else may write it. */
|
|
139
|
-
|
|
140
|
-
settledBy?: ApprovalSettledBy;
|
|
141
|
-
approver?: string;
|
|
142
|
-
resolution?: import("../tool-policy.js").AskDenyResolution;
|
|
143
|
-
autoDenied?: true;
|
|
144
|
-
}>;
|
|
145
|
-
/** borrowed-mutable — the bare-human-rejection sideband. Writer: resolveAskBound; the gate handler consumes one-shot. */
|
|
146
|
-
humanBareRejections: Set<string>;
|
|
138
|
+
gateOutcomes: Map<string, GateOutcome>;
|
|
147
139
|
/** borrowed-mutable — the turn's halt fact (`Prepared.batchHaltRef`). Writer: the judgment site; cleared at the next request. */
|
|
148
140
|
batchHaltRef: Prepared["batchHaltRef"];
|
|
149
141
|
/** owned — whether any consumer of the blocked set is wired (populate only then). */
|
|
@@ -178,8 +170,8 @@ export interface PrepareWiringManifestResult {
|
|
|
178
170
|
* server the leg's FROZEN entry snapshot declared, in declaration order, joined by name to this leg's
|
|
179
171
|
* materialization statuses. Pure projection — no connection logic, no second look at any transport:
|
|
180
172
|
* · a status `connected` ⇒ `connected` with the mounted roster size (the intake's post-filter count);
|
|
181
|
-
* · a status `failed` ⇒ `failed` with the
|
|
182
|
-
* and the remote text SECRET-REDACTED (an HTTP endpoint's error body rides the SDK's message
|
|
173
|
+
* · a status `failed` ⇒ `failed` with the failure record the materialization stamped (`errorCode`/`delivered`/
|
|
174
|
+
* `httpStatus` = the MCP vocabulary's `McpFailure` spread flat) and the remote text SECRET-REDACTED (an HTTP endpoint's error body rides the SDK's message
|
|
183
175
|
* verbatim, and a body that echoes the bearer it rejected must not reach a stream consumer),
|
|
184
176
|
* then neutralized + bounded to the reminder's own 240 (the same bound the once-per-session
|
|
185
177
|
* ledger applies to that text — one face, one width);
|
|
@@ -22,7 +22,7 @@ export function mcpManifestEntries(entries, statuses) {
|
|
|
22
22
|
name: entry.name,
|
|
23
23
|
...source,
|
|
24
24
|
status: "failed",
|
|
25
|
-
...(status.errorCode !== undefined ? { errorCode: status.errorCode } : {}),
|
|
25
|
+
...(status.errorCode !== undefined ? { errorCode: status.errorCode, delivered: status.delivered, ...(status.httpStatus !== undefined ? { httpStatus: status.httpStatus } : {}) } : {}),
|
|
26
26
|
...(status.error !== undefined ? { error: inlineUntrusted(status.error, 240) } : {}),
|
|
27
27
|
toolCount: 0,
|
|
28
28
|
};
|
|
@@ -87,17 +87,17 @@ const ungatedWarnedShapes = new WeakMap();
|
|
|
87
87
|
function announceDurableGateUnavailable(args) {
|
|
88
88
|
if (!args.forceDurableGate || args.storeWired)
|
|
89
89
|
return;
|
|
90
|
-
const cause = args.
|
|
90
|
+
const cause = args.taskStoreDisabled ? "task_store_disabled" : "no_deployment_store";
|
|
91
91
|
const inheritedContentMandate = (args.parentConstraints ?? []).some((pc) => pc.contentMandate === true);
|
|
92
92
|
const liveQuestionFace = args.liveQuestionFace && !inheritedContentMandate;
|
|
93
93
|
deliverEngineNotice(args.onNotice, {
|
|
94
94
|
code: "config.durable_gate_unavailable",
|
|
95
95
|
message: `Durable approval gate mandated but unavailable: the runtime entitlement forceDurableGate is in force for this ` +
|
|
96
|
-
`principal, but ${cause === "
|
|
96
|
+
`principal, but ${cause === "task_store_disabled" ? 'this task disabled the checkpoint store (checkpointStore: "disabled")' : "this deployment wired no checkpoint store"}, ` +
|
|
97
97
|
`so no interactive ask of this task can be parked for a durable answer. Asks resolve on the live chain instead ` +
|
|
98
98
|
`(${args.liveApprover ? "a live approver answers permission asks in-stream" : "permission asks are denied fail-closed — no live approver is wired"}; ` +
|
|
99
99
|
`${liveQuestionFace ? "a live question face answers AskUserQuestion in-stream" : args.liveQuestionFace ? "AskUserQuestion is withheld from the live face by an inherited durable mandate and refused" : "AskUserQuestion has no live face and is refused"}) ` +
|
|
100
|
-
`and NO durable approval record is written. ${cause === "
|
|
100
|
+
`and NO durable approval record is written. ${cause === "task_store_disabled" ? "Run this task with its store, or withdraw the entitlement for principals whose runs are machine-started." : "Wire a checkpoint store on this deployment, or withdraw the entitlement for principals served here."}`,
|
|
101
101
|
detail: {
|
|
102
102
|
sessionId: args.sessionId,
|
|
103
103
|
runId: args.runId,
|
|
@@ -109,7 +109,7 @@ function announceDurableGateUnavailable(args) {
|
|
|
109
109
|
});
|
|
110
110
|
}
|
|
111
111
|
export function prepareWiringManifest(input) {
|
|
112
|
-
const { spec, deps, internals, resume, sessionId, runId, hostTaskId, taskScope, hooks, preToolUseObservational, policyLayers, effectivePolicy, handsEnabled, mcp, irreversibleTools, egressTools, toolEffects, ownedEnv, executionEnv, offloadStore, onceLedger, usageWindows, envLifetimeSuspendAt, runtimeCaps, resolvedInteractionPosture, durableQuestionFace, liveQuestionFace, checkpointStore, sessions, modelGateManifest, autoModeArmReason, lockedPreflight, peerLaneRefs, peerLaneActive, harness,
|
|
112
|
+
const { spec, deps, internals, resume, sessionId, runId, hostTaskId, taskScope, hooks, preToolUseObservational, policyLayers, effectivePolicy, handsEnabled, mcp, irreversibleTools, egressTools, toolEffects, ownedEnv, executionEnv, offloadStore, onceLedger, usageWindows, envLifetimeSuspendAt, runtimeCaps, resolvedInteractionPosture, durableQuestionFace, liveQuestionFace, checkpointStore, sessions, modelGateManifest, autoModeArmReason, lockedPreflight, peerLaneRefs, peerLaneActive, harness, pausedRef, frozenOnAsk, liveInheritedGate, delegation } = input;
|
|
113
113
|
const onAsk = spec.onAsk ?? deps.onAsk;
|
|
114
114
|
const handWriteTools = handsEnabled && spec.handsReadOnly !== true
|
|
115
115
|
? Object.keys(HAND_TOOL_EFFECTS).filter((name) => {
|
|
@@ -144,8 +144,7 @@ export function prepareWiringManifest(input) {
|
|
|
144
144
|
}
|
|
145
145
|
const preToolContexts = new Map();
|
|
146
146
|
const blockedToolCalls = new Set();
|
|
147
|
-
const
|
|
148
|
-
const humanBareRejections = new Set();
|
|
147
|
+
const gateOutcomes = new Map();
|
|
149
148
|
const batchHaltRef = {};
|
|
150
149
|
const blockedTracked = Boolean(hooks?.postToolUse || hooks?.preToolUse || hooks?.postToolUseFailure || hooks?.postToolBatch);
|
|
151
150
|
const restoreSurfaceGap = ownedEnv !== undefined && isRemoteExecutionEnv(ownedEnv) && ownedEnv.capabilities.suspendable ? missingRestoreSurface(ownedEnv) : [];
|
|
@@ -220,7 +219,7 @@ export function prepareWiringManifest(input) {
|
|
|
220
219
|
ownTokens: () => internals?.peerSelfRef?.current.ownTokens ?? [],
|
|
221
220
|
refs: peerLaneRefs,
|
|
222
221
|
selfName: () => internals?.explicitAgentName,
|
|
223
|
-
parked: () =>
|
|
222
|
+
parked: () => pausedRef.current !== undefined,
|
|
224
223
|
});
|
|
225
224
|
}
|
|
226
225
|
const parkLaneArmed = wiringManifest.parkLane.effective === true;
|
|
@@ -231,7 +230,7 @@ export function prepareWiringManifest(input) {
|
|
|
231
230
|
resourceSuspendEligible ||
|
|
232
231
|
platformSuspendArmed ||
|
|
233
232
|
spec.enablePlanMode === true;
|
|
234
|
-
announceDurableGateUnavailable({ onNotice: deps.onNotice, forceDurableGate: runtimeCaps?.forceDurableGate === true, storeWired: checkpointStore !== undefined,
|
|
233
|
+
announceDurableGateUnavailable({ onNotice: deps.onNotice, forceDurableGate: runtimeCaps?.forceDurableGate === true, storeWired: checkpointStore !== undefined, taskStoreDisabled: spec.checkpointStore === "disabled", liveApprover: isLiveApproverSeat(frozenOnAsk), liveQuestionFace: liveQuestionFace !== undefined, parentConstraints: liveInheritedGate?.parentConstraints, sessionId, runId, principal: spec.principal });
|
|
235
234
|
const hookIdentity = mintHookInvocationIdentity({
|
|
236
235
|
sessionId,
|
|
237
236
|
taskId: hostTaskId,
|
|
@@ -243,5 +242,5 @@ export function prepareWiringManifest(input) {
|
|
|
243
242
|
});
|
|
244
243
|
const hookContextConsumerWired = hooks?.preToolUse !== undefined || hooks?.postToolUse !== undefined || hooks?.postToolUseFailure !== undefined;
|
|
245
244
|
const hookEnvFace = hookContextConsumerWired && (ownedEnv ?? deps.executionEnv) != null ? createHookEnvCapabilities(executionEnv) : undefined;
|
|
246
|
-
return { onAsk, preToolContexts, blockedToolCalls,
|
|
245
|
+
return { onAsk, preToolContexts, blockedToolCalls, gateOutcomes, batchHaltRef, blockedTracked, incompleteSuspendAdapter, durableSuspendInfraReady, resourceSuspendEligible, usageGovernance, platformSuspendArmed, durableApproval, wiringManifest, parkLaneArmed, gateMachineryActive, hookIdentity, hookEnvFace };
|
|
247
246
|
}
|
|
@@ -1,124 +1,42 @@
|
|
|
1
1
|
import { type Model } from "../../internal/llm.js";
|
|
2
|
-
import { type
|
|
3
|
-
import type { RunInternals } from "./prepare-task.js";
|
|
2
|
+
import { type CheckpointToken, type ResumeOutcome } from "../checkpoint-store.js";
|
|
4
3
|
import { type TaskOutcome } from "../task-outcome.js";
|
|
5
4
|
import { type SideQuerySpec, type SideQueryResult } from "../side-query.js";
|
|
6
5
|
import type { SessionStore } from "../session.js";
|
|
7
6
|
import { type RecoveredOrphan } from "../session-reconcile.js";
|
|
8
|
-
import {
|
|
7
|
+
import type { GateOutcome } from "../gate-outcome.js";
|
|
8
|
+
import { type McpDelivered } from "../mcp-failure.js";
|
|
9
9
|
import type { AgentDefinition, ModelRef, RunnerDeps, TaskEvent, TaskResult, TaskSpec, TaskStream } from "../types.js";
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
* hooks cannot be reconstructed from a checkpoint token (the session stores neither tool implementations
|
|
13
|
-
* nor the hand band), so the caller's trusted control plane re-supplies the same {@link TaskSpec} it ran
|
|
14
|
-
* with — minus the conversation bits: `sessionId` comes from the checkpoint and `objective` is replaced by
|
|
15
|
-
* an internally-generated continuation, so both are omitted.
|
|
16
|
-
*/
|
|
17
|
-
export type ResumeTaskConfig = Omit<TaskSpec, "objective" | "sessionId">;
|
|
18
|
-
/** design/45 resume plan threaded from {@link Runner.resume} into the shared run loop. */
|
|
19
|
-
interface ResumeRun {
|
|
20
|
-
cp: Checkpoint;
|
|
21
|
-
/**
|
|
22
|
-
* RB-152 (2026-07-25, 按面收口): did the APPROVED ACTION actually begin executing?
|
|
23
|
-
*
|
|
24
|
-
* The reopen compensation used to key on an error-code whitelist (`resume.env_failed` /
|
|
25
|
-
* `resume.session_not_found` / `resume.tool_unavailable`). That is a proxy for the thing that actually
|
|
26
|
-
* matters, and every time a NEW way to exit without running the action appeared, the whitelist did not
|
|
27
|
-
* know about it: a caller's abort landing anywhere between the CAS and `tool.execute` — across
|
|
28
|
-
* `SessionStore.acquire` (pluggable, cross-network on a durable backend), the MCP reconnect, the env
|
|
29
|
-
* rebuild, `resumeVM`, tool materialization — produced a `failed` result with NO errorCode, no reopen,
|
|
30
|
-
* and a human approval consumed for work that never happened. Two rounds of fixes (RB-77, RB-109) each
|
|
31
|
-
* moved that window rather than closing it, because both extended the whitelist.
|
|
32
|
-
*
|
|
33
|
-
* This binds the compensation to the FACT instead: set the instant before `tool.execute` for the gated
|
|
34
|
-
* call (the same `onExecuteStart` signal the orphan-reconcile split already trusts). Every terminal —
|
|
35
|
-
* throw OR returned result — asks one question: was the checkpoint consumed while this stayed false?
|
|
36
|
-
*/
|
|
37
|
-
pendingActionStarted?: boolean;
|
|
38
|
-
/** Validated against `cp.gate.kind` at the resume entry: human/irreversible_ask→`policy_ask`,
|
|
39
|
-
* resource_limit→`resource_limit` (design/74), needs_review→`dry_run_review` (design/76 §2.5),
|
|
40
|
-
* plan_review→`plan_review` (design/80 D-B). The gate-match guard in `resumeStream` enforces the
|
|
41
|
-
* correlation. design/144 §3: `wake` is the NON-GATE arm — only a checkpoint awaiting NO gate
|
|
42
|
-
* decision passes the resume entry with it (gate purity, `wake.gate_pending`); the run loop skips
|
|
43
|
-
* `applyResumeDecision` for it (no pending action to resolve) and re-enters via the continuation +
|
|
44
|
-
* pendingSteer tail alone. */
|
|
45
|
-
outcome: Extract<ResumeOutcome, {
|
|
46
|
-
gate: "policy_ask" | "resource_limit" | "dry_run_review" | "plan_review" | "wake";
|
|
47
|
-
}>;
|
|
48
|
-
/** design/144 §3 (X5) — the wake's own operator message, validated (`validatePendingSteer`) at the
|
|
49
|
-
* resume entry and carried SEPARATELY from the checkpoint's parked `pendingSteer`: a message-bearing
|
|
50
|
-
* wake of a checkpoint that ALSO holds a parked steer must deliver BOTH (park order: parked first,
|
|
51
|
-
* wake message second), each under its own trusted framing — the old merge-into-the-slot shape
|
|
52
|
-
* silently DISPLACED the parked (undelivered) supervisor steer. Wake outcomes only. */
|
|
53
|
-
wakeMessage?: Omit<PendingSteerEntry, "seq">;
|
|
54
|
-
/** design/373 §4.3 (D2) — the userPromptSubmit screen's `additionalContext` for {@link wakeMessage},
|
|
55
|
-
* captured at the resume ENTRY (the message is screened once, pre-CAS, on the resuming process's
|
|
56
|
-
* hook) and delivered by the drain as the engine's own reminder AHEAD of the wake frame — carrying
|
|
57
|
-
* it forward is what keeps the hook single-run (re-screening at the drain would be the double-run
|
|
58
|
-
* §4.3-3 reserves for the cross-process parked leg). Present only when a wake message passed a
|
|
59
|
-
* screen that supplied context. */
|
|
60
|
-
wakeMessageHookContext?: string;
|
|
61
|
-
/** Compensation hook (design/45/49): called iff the resumed run fails with `resume.env_failed` (post-CAS
|
|
62
|
-
* workspace `resumeVM` failed) OR `resume.tool_unavailable` (P-7: the approved tool vanished) — in both
|
|
63
|
-
* the CAS already consumed the checkpoint but the pending action never ran. `resumeStream` supplies a
|
|
64
|
-
* closure that reopens the checkpoint (`resolved → pending`) so a retry re-resumes the SAME suspended work
|
|
65
|
-
* instead of losing it to a forced "re-initiate". design/80 D-1 (reopen-by-reason): the `reason` is
|
|
66
|
-
* recorded on the reopened row so the next re-resume validates per reason — an `env_failed` reopen must
|
|
67
|
-
* replay the persisted winner (a system retry of the approved action), while a `tool_unavailable` reopen
|
|
68
|
-
* lets a human re-decide with the tool present (a fresh decision is allowed — preserves P-7). */
|
|
69
|
-
onEnvRestoreFailed?: (reason: ReopenReason) => Promise<void>;
|
|
70
|
-
/** RB-471/FR-C1 — set in the run body right after `applyResumeDecision` completes: the negative-
|
|
71
|
-
* decision twin of `pendingActionStarted`. A reject/deny consumes its gate BY BEING DELIVERED, and
|
|
72
|
-
* this bit is the delivery fact — every throw-arm cause (prepare failure, `session_not_found`, a
|
|
73
|
-
* pre-delivery abort) and the walltime-exhausted settle fire BEFORE it is set, so an undelivered
|
|
74
|
-
* negative decision still reopens as `env_failed` (the retry replays the persisted decision; it
|
|
75
|
-
* never re-asks — design/80 D-1), closing the RB-152/RB-70 loss class the first RB-471 cut reopened. */
|
|
76
|
-
decisionDelivered?: boolean;
|
|
77
|
-
}
|
|
10
|
+
import type { ResumeRun, ResumeTaskConfig, RunInternals, RunnerSelfSeat } from "./contracts.js";
|
|
11
|
+
export type { ResumeTaskConfig } from "./contracts.js";
|
|
78
12
|
/** The `tool_end` body fields projected from a harness tool result — output/truncated/totalChars via
|
|
79
13
|
* {@link toolOutputFrom} and the CC card via {@link structuredFrom}. Single construction point for BOTH
|
|
80
14
|
* the live loop's frames and the resumed batch's frames (`resolvePendingCall` + the deferred-sibling
|
|
81
15
|
* close): the resumed frames used to carry only `isError`, so a client rendering tool output from frames
|
|
82
16
|
* showed an empty body for every durable-approved call. Same projection = same source as the transcript.
|
|
83
|
-
* Also the one place
|
|
17
|
+
* Also the one place the gate outcome reaches a frame — see the parameter. */
|
|
84
18
|
declare function toolEndBodyFrom(result: unknown, isError: boolean,
|
|
85
|
-
/**
|
|
86
|
-
* live loop reads it off the gate's per-call sideband, the resumed leg off the decide
|
|
87
|
-
* a parameter and never derived from `result`: a tool's own `details`
|
|
88
|
-
* also replace) is writable by layers that adjudicate nothing, so reading
|
|
89
|
-
* let a failing tool claim a person approved it. Omitted ⇒ the
|
|
90
|
-
*
|
|
91
|
-
|
|
92
|
-
settledBy?: ApprovalSettledBy,
|
|
93
|
-
/** design/252 G-7 — WHOSE settlement, from the same caller and the same channel as `settledBy`, and
|
|
94
|
-
* for the same reason it is a parameter: an attribution read out of a tool's own result would let a
|
|
95
|
-
* tool name the person who approved it. Omitted ⇒ this call's settlement named nobody. */
|
|
96
|
-
approver?: string,
|
|
97
|
-
/** The ask resolver's deny-arm classification — same caller, same engine-owned channel and the same
|
|
98
|
-
* never-derived-from-`result` posture as the two above. Omitted ⇒ not an ask-resolution deny. */
|
|
99
|
-
resolution?: import("../tool-policy.js").AskDenyResolution,
|
|
19
|
+
/** The gate's record of the pass that admitted or refused this call, supplied by the CALLER of this
|
|
20
|
+
* projection — the live loop reads it off the gate's per-call sideband, the resumed leg off the decide's
|
|
21
|
+
* minted record. Deliberately a parameter and never derived from `result`: a tool's own `details`
|
|
22
|
+
* (which post-tool hooks may also replace) is writable by layers that adjudicate nothing, so reading
|
|
23
|
+
* provenance out of it would let a failing tool claim a person approved it. Omitted ⇒ the call never
|
|
24
|
+
* went through the gate (see the `tool_end.gate` doc, the one home). */
|
|
25
|
+
gate?: GateOutcome,
|
|
100
26
|
/** WHICH call this run's committed durable park is holding ({@link gatedCallIdOf}), for the frames the
|
|
101
|
-
* abort short-circuits. Same never-derived-from-`result` posture as the
|
|
27
|
+
* abort short-circuits. Same never-derived-from-`result` posture as the outcome above, and for the
|
|
102
28
|
* sharpest version of that reason: this one is an assertion about a DIFFERENT call, so a tool able to
|
|
103
29
|
* author it could point an approval UI at a call nobody is waiting on. Omitted ⇒ no park is holding a
|
|
104
30
|
* call (nothing parked, or the park that did holds none), and the frame then carries no id at all. */
|
|
105
|
-
gatedCallIdOfRun?: string
|
|
106
|
-
/** #557 — the classifier denial-limit fallback's own auto-deny marker, from the same engine-owned
|
|
107
|
-
* settlement sideband as `resolution` (same never-derived-from-`result` posture). Omitted ⇒ absent.
|
|
108
|
-
* The pair `settledBy:"timeout"` + `resolution:"window_expired"` WITHOUT this bit is the approval
|
|
109
|
-
* factory's own `approvalTimeoutMs` window; a durable park's expiry is neither — the decide lane's
|
|
110
|
-
* emitter passes no `resolution` at all (see the `tool_end.autoDenied` doc on the event type). */
|
|
111
|
-
autoDenied?: true): {
|
|
31
|
+
gatedCallIdOfRun?: string): {
|
|
112
32
|
output?: unknown;
|
|
113
33
|
truncated?: boolean;
|
|
114
34
|
totalChars?: number;
|
|
115
35
|
structured?: unknown;
|
|
116
36
|
errorCode?: string;
|
|
37
|
+
delivered?: McpDelivered;
|
|
117
38
|
gatedCallId?: string;
|
|
118
|
-
|
|
119
|
-
approver?: string;
|
|
120
|
-
resolution?: import("../tool-policy.js").AskDenyResolution;
|
|
121
|
-
autoDenied?: true;
|
|
39
|
+
gate?: GateOutcome;
|
|
122
40
|
};
|
|
123
41
|
/**
|
|
124
42
|
* scan-1/A1 — the BODY of the synthetic `tool_end` that closes a reconcile-recovered orphan. ONE
|
|
@@ -160,7 +78,7 @@ export declare function raceUntilDeadline<T>(p: Promise<T>, deadline: number): P
|
|
|
160
78
|
* A stateless task runner. Holds shared deps (the external brain, model catalog) and an
|
|
161
79
|
* in-memory session store so that passing a `sessionId` continues a prior conversation.
|
|
162
80
|
*/
|
|
163
|
-
export declare class Runner {
|
|
81
|
+
export declare class Runner implements RunnerSelfSeat {
|
|
164
82
|
private deps;
|
|
165
83
|
readonly sessions: SessionStore;
|
|
166
84
|
/** Per-sessionId serialization so two tasks never mutate one session concurrently. */
|
|
@@ -440,12 +358,12 @@ export declare class Runner {
|
|
|
440
358
|
* factory-minted remote/worktree lane captured an already-destroyed env (plain host/static lanes were
|
|
441
359
|
* false-green).
|
|
442
360
|
*
|
|
443
|
-
* design/49 v1.5 / design/76 §2.5: a
|
|
361
|
+
* design/49 v1.5 / design/76 §2.5: a committed durable pause (`pausedRef.current`, any gate kind)
|
|
444
362
|
* `suspendVM`-paused the env and persisted its `workspaceHandle` into the checkpoint — destroying it would
|
|
445
363
|
* discard the paused VM and make resume fail to restore. Skip teardown; `resume()` rebuilds + `resumeVM`s it. A
|
|
446
364
|
* cancelled pause is reaped via `TaskStream.destroy()` (design/51); an abandoned one is the service container
|
|
447
365
|
* reaper's backstop. The gate here MIRRORS the tail's reap-stash (same durable fact
|
|
448
|
-
* `
|
|
366
|
+
* `pausedRef.current === undefined`), so exactly one path owns the env's fate.
|
|
449
367
|
*/
|
|
450
368
|
private teardownOwnedEnv;
|
|
451
369
|
}
|