@arnilo/prism 0.9.0 → 0.11.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 +50 -1
- package/README.md +19 -16
- package/dist/agent-approval.d.ts +7 -1
- package/dist/agent-approval.js +15 -6
- package/dist/agent-run-lifecycle.d.ts +2 -1
- package/dist/agent-run-lifecycle.js +20 -6
- package/dist/agent-run-state.d.ts +26 -5
- package/dist/agent-run-state.js +97 -1
- package/dist/agent-session/event-subscriber.d.ts +2 -0
- package/dist/agent-session/event-subscriber.js +3 -0
- package/dist/agent-session/session/assemble.js +165 -16
- package/dist/agent-session/session/persist.js +11 -5
- package/dist/agent-session/session/provider-round.js +54 -13
- package/dist/agent-session/session/tool-round.d.ts +2 -2
- package/dist/agent-session/session/tool-round.js +86 -23
- package/dist/agent-session/session/types.d.ts +21 -2
- package/dist/agent-session/session.d.ts +66 -4
- package/dist/agent-session/session.js +159 -18
- package/dist/checkpoint-restore.d.ts +50 -14
- package/dist/checkpoint-restore.js +104 -28
- package/dist/context-budget.d.ts +11 -0
- package/dist/context-budget.js +33 -2
- package/dist/contracts-core/agent.d.ts +26 -5
- package/dist/contracts-core/extensions.d.ts +3 -0
- package/dist/contracts-core/guardrail-packs.d.ts +8 -3
- package/dist/contracts-core/loop.d.ts +36 -0
- package/dist/contracts-core/provider.d.ts +6 -1
- package/dist/contracts-core/run-limits.d.ts +10 -1
- package/dist/contracts-core/session.d.ts +2 -1
- package/dist/contracts-protocol.d.ts +6 -4
- package/dist/contracts-run-state.d.ts +48 -6
- package/dist/contributions.d.ts +2 -1
- package/dist/contributions.js +1 -0
- package/dist/extensions.d.ts +15 -1
- package/dist/extensions.js +68 -0
- package/dist/guardrail-packs/types.d.ts +10 -0
- package/dist/guardrail-packs/validation-respect.js +16 -0
- package/dist/guardrails.d.ts +42 -1
- package/dist/guardrails.js +124 -15
- package/dist/index.d.ts +7 -7
- package/dist/index.js +4 -4
- package/dist/leases.js +32 -6
- package/dist/middleware.d.ts +1 -1
- package/dist/node/contribution-discovery.d.ts +16 -1
- package/dist/node/contribution-discovery.js +47 -0
- package/dist/node/session-store-jsonl.js +67 -17
- package/dist/run-bundle.d.ts +6 -1
- package/dist/run-bundle.js +4 -1
- package/dist/run-limits.d.ts +11 -5
- package/dist/run-limits.js +13 -0
- package/dist/session-stores.js +61 -12
- package/dist/testing/prefix-stability-conformance.d.ts +73 -1
- package/dist/testing/prefix-stability-conformance.js +158 -27
- package/dist/tools.js +10 -3
- package/dist/usage-estimation.d.ts +7 -1
- package/dist/usage-estimation.js +16 -10
- package/docs/acp.md +2 -2
- package/docs/agent-events.md +15 -10
- package/docs/agent-session-runtime.md +10 -7
- package/docs/coding-agent-tools.md +1 -1
- package/docs/coding-tools.md +7 -11
- package/docs/compaction-llm.md +2 -0
- package/docs/compaction-observational-memory.md +21 -1
- package/docs/context-and-skills.md +6 -7
- package/docs/contribution-discovery.md +13 -0
- package/docs/durable-runs.md +14 -6
- package/docs/embeddings.md +7 -1
- package/docs/execution-timeline.md +9 -2
- package/docs/extensions.md +21 -5
- package/docs/guardrails.md +16 -6
- package/docs/hooks.md +282 -0
- package/docs/impeccable.md +1 -2
- package/docs/index.md +28 -21
- package/docs/input-and-prompt-assembly.md +1 -1
- package/docs/instruction-injection.md +1 -0
- package/docs/live-testing.md +3 -2
- package/docs/memory-fabric.md +29 -0
- package/docs/middleware-hooks.md +54 -4
- package/docs/migrate-to-0.11.md +65 -0
- package/docs/migration.md +24 -0
- package/docs/node-jsonl-session-store.md +4 -3
- package/docs/operations.md +1 -1
- package/docs/options-index.md +3 -1
- package/docs/peer-dependencies.md +3 -5
- package/docs/policy-and-audit.md +15 -2
- package/docs/prefix-stability-conformance.md +82 -9
- package/docs/provider-packages.md +20 -20
- package/docs/public-contracts.md +2 -1
- package/docs/rag.md +94 -7
- package/docs/release-and-install.md +62 -59
- package/docs/runs-and-usage.md +21 -10
- package/docs/scoped-agent-memory.md +17 -9
- package/docs/scoped-memory.md +138 -0
- package/docs/session-stores.md +2 -2
- package/docs/supervisors.md +14 -6
- package/docs/testing.md +17 -9
- package/docs/tools.md +1 -1
- package/docs/wiki.md +4 -2
- package/docs/workflows.md +2 -2
- package/package.json +8 -5
- package/docs/caveman.md +0 -130
- package/docs/graft.md +0 -149
- package/docs/ponytail.md +0 -129
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/** Shared host/round types for runInternal phase split (plan 059). Internal only. */
|
|
2
2
|
import type { ActiveDurableRun } from "../../agent-approval.js";
|
|
3
|
-
import type { PendingToolCall } from "../../agent-run-state.js";
|
|
3
|
+
import type { PendingToolCall, PersistedGuardrailPacks } from "../../agent-run-state.js";
|
|
4
4
|
import type { AttentionFoldLedger, AttentionStickyFrontier, PersistedAttentionFoldLedger, PersistedAttentionStickyFrontier } from "../../attention-compiler.js";
|
|
5
|
-
import type { Agent, AgentEvent, AgentFinishReason, AgentLoopStrategy, AgentRunResult, AIProvider, ErrorInfo, Guardrails, LoopContext, Message, ModelConfig, OwnershipScope, PendingDecision, PromptVersionRef, ProviderRequest, RunLedger, RunOptions, SessionEntry, SessionStore, Skill, ToolCallSummary, ToolDefinition, ToolEffectStore, ToolRegistry, ToolResult, Usage } from "../../contracts.js";
|
|
5
|
+
import type { Agent, AgentEvent, AgentFinishReason, AgentLoopStrategy, AgentRunResult, AIProvider, ErrorInfo, Guardrails, LoopContext, Message, ModelConfig, OwnershipScope, PendingDecision, PromptVersionRef, ProviderRequest, RunLedger, RunOptions, SessionEntry, SessionStore, Skill, StopHook, ToolCallSummary, ToolDefinition, ToolEffectStore, ToolRegistry, ToolResult, Usage } from "../../contracts.js";
|
|
6
6
|
import type { AgentIdentity } from "../../identity.js";
|
|
7
7
|
import type { AgentInput } from "../../input.js";
|
|
8
8
|
import type { SecretRedactor } from "../../redaction.js";
|
|
@@ -35,6 +35,12 @@ export type SessionHost = {
|
|
|
35
35
|
activeGuardrails?: Guardrails;
|
|
36
36
|
/** Plan 092 Task 2: packs compiled once at session construction; read-only for phases. */
|
|
37
37
|
readonly packGuardrails?: Guardrails;
|
|
38
|
+
/** Plan 104 T3: `ask` rules as the durable charge-time gate (`interrupt` records) and as plain
|
|
39
|
+
* blocks for a run that cannot suspend. */
|
|
40
|
+
readonly packAskGate?: Guardrails;
|
|
41
|
+
readonly packAskBlocks?: Guardrails;
|
|
42
|
+
/** Plan 104 T2: pack refs + live pack-owned state for a durable checkpoint. */
|
|
43
|
+
serializedGuardrailPackState(): PersistedGuardrailPacks | undefined;
|
|
38
44
|
activeMetadata?: Readonly<Record<string, unknown>>;
|
|
39
45
|
activePromptVersion?: PromptVersionRef;
|
|
40
46
|
activeLimits?: RunLimitTracker;
|
|
@@ -83,6 +89,8 @@ export type SessionHost = {
|
|
|
83
89
|
emit(event: AgentEvent): void;
|
|
84
90
|
rebuildHistory(): Promise<void>;
|
|
85
91
|
resolveRunSkills(options: RunOptions, tools: readonly ToolDefinition[]): readonly Skill[];
|
|
92
|
+
/** Redacted, cap-checked steer queue push (plan 106 R1 uses it for stop-hook continuations). */
|
|
93
|
+
steer(input: AgentInput): void;
|
|
86
94
|
appendEntry(entry: SessionEntry): Promise<void>;
|
|
87
95
|
redact<T>(value: T): T;
|
|
88
96
|
appendMessage(message: Message, runId: string): Promise<void>;
|
|
@@ -99,12 +107,21 @@ export type SessionHost = {
|
|
|
99
107
|
readonly status: AgentRunResult["status"];
|
|
100
108
|
readonly usage?: Usage;
|
|
101
109
|
readonly limit?: import("../../contracts.js").RunLimitBreach;
|
|
110
|
+
readonly attribution?: import("../../run-limits.js").BudgetExhaustionAttribution;
|
|
102
111
|
readonly error?: ErrorInfo;
|
|
103
112
|
readonly abortReason?: string;
|
|
104
113
|
readonly runState?: import("../../contracts.js").AgentRunState;
|
|
105
114
|
readonly interruption?: import("../../contracts.js").AgentRunInterruption;
|
|
106
115
|
}): AgentRunResult;
|
|
116
|
+
/**
|
|
117
|
+
* Plan 106 R2: dispatch `session_start` middleware once per session (first run start), awaited by
|
|
118
|
+
* the run assembler after the `agent_started`/`agent_resumed` emits. No-op on every later call.
|
|
119
|
+
*/
|
|
120
|
+
openSession(runId: string): Promise<void>;
|
|
121
|
+
/** Session teardown: close every subscriber, run-scoped and `acrossRuns` alike. */
|
|
107
122
|
closeSubscribers(): void;
|
|
123
|
+
/** Run end (finish, suspend, or deny): close only the subscribers that do not opt into `acrossRuns`. */
|
|
124
|
+
closeRunSubscribers(): void;
|
|
108
125
|
snapshot(): Promise<SessionContextSnapshot>;
|
|
109
126
|
};
|
|
110
127
|
export declare function asSessionHost(session: unknown): SessionHost;
|
|
@@ -151,6 +168,8 @@ export type RoundContext = {
|
|
|
151
168
|
toolResults: ToolResult[];
|
|
152
169
|
/** Set when a `RunOptions.turnPolicy` stop ended the loop (plan 084 Task 2). */
|
|
153
170
|
runStop?: RunStopInfo;
|
|
171
|
+
/** Merged agent + run stop hooks, in invocation order (plan 106 R1). Empty = wrapper skipped. */
|
|
172
|
+
stopHooks: readonly StopHook[];
|
|
154
173
|
runUsage: {
|
|
155
174
|
add(usage: Usage): void;
|
|
156
175
|
value(): Usage | undefined;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/** session (0.2.5 plan 025 Task 1 split). Moved verbatim from agent-session.ts; public surface unchanged behind the barrel. */
|
|
2
2
|
import { ActiveDurableRun, ActiveDurableRunExtras } from "../agent-approval.js";
|
|
3
|
-
import type { PendingToolCall, StoredAgentRunState } from "../agent-run-state.js";
|
|
3
|
+
import type { PendingToolCall, PersistedGuardrailPacks, StoredAgentRunState } from "../agent-run-state.js";
|
|
4
4
|
import { type AttentionFoldLedger, type AttentionStickyFrontier, type PersistedAttentionFoldLedger, type PersistedAttentionStickyFrontier } from "../attention-compiler.js";
|
|
5
|
-
import type { Agent, AgentEvent, AgentRunResult, AgentRunState, AgentRunStateOptions, AgentSession, AgentSessionConfig, AIProvider, CompactionOptions, CompactionResult, ContextMeter, ErrorInfo, Guardrails, Message, OwnershipScope, PendingDecision, PromptVersionRef, ProviderRequest, RunDecision, RunOptions, SessionEntry, Skill, SteerOptions, SubscribeOptions, ToolCallSummary, ToolDefinition, ToolEffectStore, Usage } from "../contracts.js";
|
|
5
|
+
import type { Agent, AgentEvent, AgentRunResult, AgentRunState, AgentRunStateOptions, AgentSession, AgentSessionConfig, AIProvider, CompactionOptions, CompactionResult, ContextMeter, ErrorInfo, GuardrailPackRef, Guardrails, Message, OwnershipScope, PendingDecision, PromptVersionRef, ProviderRequest, RunDecision, RunOptions, SessionEntry, Skill, SteerOptions, SubscribeOptions, ToolCallSummary, ToolDefinition, ToolEffectStore, Usage } from "../contracts.js";
|
|
6
6
|
import type { AgentIdentity } from "../identity.js";
|
|
7
7
|
import type { AgentInput } from "../input.js";
|
|
8
8
|
import type { RunLimitTracker } from "../run-limits.js";
|
|
@@ -14,6 +14,10 @@ export declare class RuntimeAgentSession implements AgentSession {
|
|
|
14
14
|
private readonly metadata?;
|
|
15
15
|
private readonly store;
|
|
16
16
|
private readonly subscribers;
|
|
17
|
+
/** Plan 106 R2: `session_start` is dispatched at the first run start, once per runtime session. */
|
|
18
|
+
private sessionOpened;
|
|
19
|
+
/** Plan 106 R2: `close()` dispatches `session_shutdown` and closes subscribers exactly once. */
|
|
20
|
+
private closed;
|
|
17
21
|
private currentLeafId?;
|
|
18
22
|
private history;
|
|
19
23
|
private activeRun?;
|
|
@@ -31,9 +35,15 @@ export declare class RuntimeAgentSession implements AgentSession {
|
|
|
31
35
|
private activeIdempotencyKey?;
|
|
32
36
|
private activeGuardrails?;
|
|
33
37
|
/** Plan 092 Task 2: guardrail packs compiled once in the constructor; merged into every run's `activeGuardrails`. */
|
|
34
|
-
|
|
38
|
+
packGuardrails?: Guardrails;
|
|
39
|
+
/** Plan 104 Task 3: `ask` rules as the durable charge-time gate (a match records `interrupt`). */
|
|
40
|
+
packAskGate?: Guardrails;
|
|
41
|
+
/** Plan 104 Task 3: the same `ask` rules as plain blocks for a run that cannot suspend. */
|
|
42
|
+
packAskBlocks?: Guardrails;
|
|
35
43
|
/** Original pack refs, carried into `fork()`/`clone()` so a branch cannot silently lose its policy. */
|
|
36
|
-
private
|
|
44
|
+
private packRefs?;
|
|
45
|
+
/** Plan 104 Task 2: compiled refs + live pack state, replaced by `restoreGuardrailPacks` on resume. */
|
|
46
|
+
private compiledGuardrailPacks?;
|
|
37
47
|
activeMetadata?: Readonly<Record<string, unknown>>;
|
|
38
48
|
activePromptVersion?: PromptVersionRef;
|
|
39
49
|
activeLimits?: RunLimitTracker;
|
|
@@ -95,11 +105,28 @@ export declare class RuntimeAgentSession implements AgentSession {
|
|
|
95
105
|
clearActivatedTools(): void;
|
|
96
106
|
/** Plan 018 Task 6: restore persisted loaded-skill bodies (already validated fail-closed at load). */
|
|
97
107
|
restoreLoadedSkillBodies(bodies: readonly LoadedSkillBodiesEntry[]): void;
|
|
108
|
+
/** Plan 104 T2: the refs this session actually enforces (restored ones after a resume). */
|
|
109
|
+
get guardrailPackRefs(): readonly GuardrailPackRef[] | undefined;
|
|
110
|
+
/** Plan 104 T2: pack refs + live pack-owned state for a durable checkpoint (opt-in with `persistSessionState`). */
|
|
111
|
+
serializedGuardrailPackState(): PersistedGuardrailPacks | undefined;
|
|
112
|
+
/**
|
|
113
|
+
* Plan 104 T2: recompile checkpoint packs before the resumed run's first turn. `state` present
|
|
114
|
+
* (even empty) marks a restore, so unknown ids, version mismatches, and codec-less state fail
|
|
115
|
+
* closed as `AgentRunStateError` — never a session that silently enforces less than it did.
|
|
116
|
+
*/
|
|
117
|
+
restoreGuardrailPacks(refs: readonly GuardrailPackRef[], state?: Readonly<Record<string, unknown>>): void;
|
|
98
118
|
private ledgerChain;
|
|
99
119
|
private ledgerFailure;
|
|
100
120
|
private snapshotGeneration;
|
|
101
121
|
private snapshotCache?;
|
|
102
122
|
private readonly snapshotCacheTtlMs;
|
|
123
|
+
/**
|
|
124
|
+
* Plan 103 T4: identity-keyed meter cache. Holds only the last public meter value
|
|
125
|
+
* plus the identity of everything the cold read consumed (`snapshotGeneration`,
|
|
126
|
+
* leaf, active meter/limits, and the history array reference + length, which catches
|
|
127
|
+
* in-place `history.push` during a run) — never history content, never an estimator.
|
|
128
|
+
*/
|
|
129
|
+
private meterCache?;
|
|
103
130
|
constructor(config: AgentSessionConfig & {
|
|
104
131
|
readonly agent: Agent;
|
|
105
132
|
});
|
|
@@ -111,15 +138,44 @@ export declare class RuntimeAgentSession implements AgentSession {
|
|
|
111
138
|
* `provider_turn_finished.budgets` resolves them. Before any provider turn in
|
|
112
139
|
* this session it estimates stored history, so a non-reporting model still
|
|
113
140
|
* shows a working meter instead of zero. Never billing; estimates are labeled.
|
|
141
|
+
*
|
|
142
|
+
* Plan 103 T4: reads are cached until the history generation, leaf, history
|
|
143
|
+
* length, or active-run identity changes, so a per-frame poll pays one estimate
|
|
144
|
+
* per mutation instead of one per read. The cached value is frozen and is
|
|
145
|
+
* identical (`===`) to the previous read while nothing changed.
|
|
114
146
|
*/
|
|
115
147
|
contextMeter(): ContextMeter;
|
|
148
|
+
/** Cold path of `contextMeter()`: one estimate over stored history plus cap/budget resolution. */
|
|
149
|
+
private measureContextMeter;
|
|
150
|
+
/**
|
|
151
|
+
* Live events for this session. A run-scoped subscriber (the default) is closed when the run ends,
|
|
152
|
+
* suspends, or is denied; `SubscribeOptions.acrossRuns: true` keeps one subscriber open across runs
|
|
153
|
+
* of the same session until the host closes it, the session tears it down, or its bounded queue
|
|
154
|
+
* overflows under the default policy. Subscribe before `run()`; the consumer loop and `run()` must
|
|
155
|
+
* run concurrently, since events are only emitted during a live run.
|
|
156
|
+
*/
|
|
116
157
|
subscribe(options?: SubscribeOptions): AsyncIterable<AgentEvent>;
|
|
158
|
+
private createSubscriber;
|
|
117
159
|
run(input: AgentInput, options?: RunOptions): Promise<AgentRunResult>;
|
|
118
160
|
steer(input: AgentInput, options?: SteerOptions): void;
|
|
119
161
|
resumeDurable(state: StoredAgentRunState, runState: AgentRunStateOptions, ownership?: OwnershipScope, signal?: AbortSignal, decisions?: ReadonlyMap<string, RunDecision>, extras?: ActiveDurableRunExtras): Promise<AgentRunResult>;
|
|
120
162
|
recordDurableResumption(runId: string, interruption: import("../contracts.js").AgentRunInterruption, version: number, ownership?: OwnershipScope): Promise<void>;
|
|
121
163
|
recordDurableDenial(runId: string, interruption: import("../contracts.js").AgentRunInterruption, version: number, ownership?: OwnershipScope): Promise<void>;
|
|
122
164
|
private runInternal;
|
|
165
|
+
/**
|
|
166
|
+
* Plan 106 R2: dispatch `session_start` once per session, at its first run start (including the
|
|
167
|
+
* first run of a session rebuilt from a durable checkpoint). The run assembler awaits it right
|
|
168
|
+
* after `agent_started`/`agent_resumed`, so session-scoped provisioning is done before the first
|
|
169
|
+
* turn while the runtime's synchronous emit burst stays intact. Middleware error policy decides
|
|
170
|
+
* whether a failure surfaces or becomes an `extension_error` event.
|
|
171
|
+
*/
|
|
172
|
+
openSession(runId: string): Promise<void>;
|
|
173
|
+
/**
|
|
174
|
+
* Plan 106 R2: session teardown. Dispatches `session_shutdown` middleware once (idempotent) and
|
|
175
|
+
* then closes every subscriber, run-scoped and `acrossRuns` alike. Call it after the active run
|
|
176
|
+
* settles; `closeSubscribers()` remains the subscriber-only seam.
|
|
177
|
+
*/
|
|
178
|
+
close(): Promise<void>;
|
|
123
179
|
prompt(input: string, options?: RunOptions): Promise<AgentRunResult>;
|
|
124
180
|
stream(input: AgentInput, options?: RunOptions & SubscribeOptions): AsyncGenerator<AgentEvent>;
|
|
125
181
|
buildRunResult(input: {
|
|
@@ -127,6 +183,7 @@ export declare class RuntimeAgentSession implements AgentSession {
|
|
|
127
183
|
readonly status: AgentRunResult["status"];
|
|
128
184
|
readonly usage?: Usage;
|
|
129
185
|
readonly limit?: import("../contracts.js").RunLimitBreach;
|
|
186
|
+
readonly attribution?: import("../run-limits.js").BudgetExhaustionAttribution;
|
|
130
187
|
readonly error?: ErrorInfo;
|
|
131
188
|
readonly abortReason?: string;
|
|
132
189
|
readonly stopReason?: import("../contracts.js").AgentFinishReason;
|
|
@@ -149,6 +206,11 @@ export declare class RuntimeAgentSession implements AgentSession {
|
|
|
149
206
|
resolveRunProvider(options: RunOptions): void;
|
|
150
207
|
resolveRunSkills(options: RunOptions, tools: readonly ToolDefinition[]): readonly Skill[];
|
|
151
208
|
emit(event: AgentEvent): void;
|
|
209
|
+
/**
|
|
210
|
+
* Run end (finish, suspension, or denial): closes the run-scoped subscribers only. Subscribers that
|
|
211
|
+
* opted into `SubscribeOptions.acrossRuns` stay open for the next run of this session.
|
|
212
|
+
*/
|
|
213
|
+
closeRunSubscribers(): void;
|
|
152
214
|
closeSubscribers(): void;
|
|
153
215
|
drainLedger(): Promise<void>;
|
|
154
216
|
applyPendingSteers(runId: string, metadata: Readonly<Record<string, unknown>>, signal: AbortSignal): Promise<boolean>;
|
|
@@ -3,8 +3,8 @@ import { policyList } from "../agent-tool-dispatch.js";
|
|
|
3
3
|
import { createAttentionFoldLedger, createAttentionStickyFrontier, resolveInputCap, restoreAttentionStickyFrontier, serializeAttentionFoldLedger, serializeAttentionStickyFrontier, } from "../attention-compiler.js";
|
|
4
4
|
import { createDefaultCompactionStrategy, isCompactionEntryData } from "../compaction.js";
|
|
5
5
|
import { estimateAssemblyTokens, estimateMessageTokens, estimateTextTokens } from "../context-budget.js";
|
|
6
|
-
import { DEFAULT_MAX_PENDING_STEER_BYTES, DEFAULT_MAX_PENDING_STEERS, DEFAULT_SNAPSHOT_CACHE_TTL_MS, HARD_MAX_SNAPSHOT_CACHE_TTL_MS, resolveShouldCompact, } from "../contracts.js";
|
|
7
|
-
import {
|
|
6
|
+
import { AgentRunStateError, DEFAULT_MAX_PENDING_STEER_BYTES, DEFAULT_MAX_PENDING_STEERS, DEFAULT_SNAPSHOT_CACHE_TTL_MS, HARD_MAX_SNAPSHOT_CACHE_TTL_MS, resolveShouldCompact, } from "../contracts.js";
|
|
7
|
+
import { compileGuardrailPacksWithState, GuardrailError, GuardrailPackError, runGuardrails } from "../guardrails.js";
|
|
8
8
|
import { applyDefaultProviderRequestOptions, createProviderRequestPolicyChain, normalizeProviderRequestPolicyResult, } from "../provider-request-policy.js";
|
|
9
9
|
import { redactAgentEvent, redactProviderRequest, redactRunLedgerRecord, redactSecrets, redactSessionEntry } from "../redaction.js";
|
|
10
10
|
import { createMemorySessionStore, createSessionEntry, getSessionBranchEntries, rebuildSessionContext } from "../session-stores.js";
|
|
@@ -23,6 +23,10 @@ export class RuntimeAgentSession {
|
|
|
23
23
|
metadata;
|
|
24
24
|
store;
|
|
25
25
|
subscribers = new Set();
|
|
26
|
+
/** Plan 106 R2: `session_start` is dispatched at the first run start, once per runtime session. */
|
|
27
|
+
sessionOpened = false;
|
|
28
|
+
/** Plan 106 R2: `close()` dispatches `session_shutdown` and closes subscribers exactly once. */
|
|
29
|
+
closed = false;
|
|
26
30
|
currentLeafId;
|
|
27
31
|
history = [];
|
|
28
32
|
activeRun;
|
|
@@ -41,8 +45,14 @@ export class RuntimeAgentSession {
|
|
|
41
45
|
activeGuardrails;
|
|
42
46
|
/** Plan 092 Task 2: guardrail packs compiled once in the constructor; merged into every run's `activeGuardrails`. */
|
|
43
47
|
packGuardrails;
|
|
48
|
+
/** Plan 104 Task 3: `ask` rules as the durable charge-time gate (a match records `interrupt`). */
|
|
49
|
+
packAskGate;
|
|
50
|
+
/** Plan 104 Task 3: the same `ask` rules as plain blocks for a run that cannot suspend. */
|
|
51
|
+
packAskBlocks;
|
|
44
52
|
/** Original pack refs, carried into `fork()`/`clone()` so a branch cannot silently lose its policy. */
|
|
45
|
-
|
|
53
|
+
packRefs;
|
|
54
|
+
/** Plan 104 Task 2: compiled refs + live pack state, replaced by `restoreGuardrailPacks` on resume. */
|
|
55
|
+
compiledGuardrailPacks;
|
|
46
56
|
activeMetadata;
|
|
47
57
|
activePromptVersion;
|
|
48
58
|
activeLimits;
|
|
@@ -127,11 +137,51 @@ export class RuntimeAgentSession {
|
|
|
127
137
|
for (const entry of bodies)
|
|
128
138
|
this.loadedSkills.add(entry.name);
|
|
129
139
|
}
|
|
140
|
+
/** Plan 104 T2: the refs this session actually enforces (restored ones after a resume). */
|
|
141
|
+
get guardrailPackRefs() {
|
|
142
|
+
return this.packRefs;
|
|
143
|
+
}
|
|
144
|
+
/** Plan 104 T2: pack refs + live pack-owned state for a durable checkpoint (opt-in with `persistSessionState`). */
|
|
145
|
+
serializedGuardrailPackState() {
|
|
146
|
+
const compiled = this.compiledGuardrailPacks;
|
|
147
|
+
if (!compiled || compiled.packs.length === 0)
|
|
148
|
+
return undefined;
|
|
149
|
+
const state = compiled.snapshotState();
|
|
150
|
+
return { packs: compiled.packs, ...(state ? { state } : {}) };
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Plan 104 T2: recompile checkpoint packs before the resumed run's first turn. `state` present
|
|
154
|
+
* (even empty) marks a restore, so unknown ids, version mismatches, and codec-less state fail
|
|
155
|
+
* closed as `AgentRunStateError` — never a session that silently enforces less than it did.
|
|
156
|
+
*/
|
|
157
|
+
restoreGuardrailPacks(refs, state) {
|
|
158
|
+
let compiled;
|
|
159
|
+
try {
|
|
160
|
+
compiled = compileGuardrailPacksWithState(refs, undefined, state ?? {});
|
|
161
|
+
}
|
|
162
|
+
catch (error) {
|
|
163
|
+
if (error instanceof GuardrailPackError)
|
|
164
|
+
throw new AgentRunStateError(`Cannot restore guardrail packs: ${error.message}`);
|
|
165
|
+
throw error;
|
|
166
|
+
}
|
|
167
|
+
this.compiledGuardrailPacks = compiled;
|
|
168
|
+
this.packGuardrails = compiled.guardrails;
|
|
169
|
+
this.packAskGate = compiled.askGate;
|
|
170
|
+
this.packAskBlocks = compiled.askBlocks;
|
|
171
|
+
this.packRefs = refs;
|
|
172
|
+
}
|
|
130
173
|
ledgerChain = Promise.resolve();
|
|
131
174
|
ledgerFailure;
|
|
132
175
|
snapshotGeneration = 0;
|
|
133
176
|
snapshotCache;
|
|
134
177
|
snapshotCacheTtlMs;
|
|
178
|
+
/**
|
|
179
|
+
* Plan 103 T4: identity-keyed meter cache. Holds only the last public meter value
|
|
180
|
+
* plus the identity of everything the cold read consumed (`snapshotGeneration`,
|
|
181
|
+
* leaf, active meter/limits, and the history array reference + length, which catches
|
|
182
|
+
* in-place `history.push` during a run) — never history content, never an estimator.
|
|
183
|
+
*/
|
|
184
|
+
meterCache;
|
|
135
185
|
constructor(config) {
|
|
136
186
|
this.id = config.id ?? randomId("session");
|
|
137
187
|
this.agent = config.agent;
|
|
@@ -139,11 +189,14 @@ export class RuntimeAgentSession {
|
|
|
139
189
|
this.store = config.store ?? config.agent.config.store ?? createMemorySessionStore();
|
|
140
190
|
this.currentLeafId = config.leafId;
|
|
141
191
|
this.snapshotCacheTtlMs = resolveSnapshotCacheTtlMs(config.snapshotCacheTtlMs);
|
|
142
|
-
this.
|
|
143
|
-
this.
|
|
192
|
+
this.compiledGuardrailPacks = compileGuardrailPacksWithState(config.guardrailPacks);
|
|
193
|
+
this.packGuardrails = this.compiledGuardrailPacks.guardrails;
|
|
194
|
+
this.packAskGate = this.compiledGuardrailPacks.askGate;
|
|
195
|
+
this.packAskBlocks = this.compiledGuardrailPacks.askBlocks;
|
|
196
|
+
this.packRefs = config.guardrailPacks;
|
|
144
197
|
const usageEstimation = config.agent.config.usageEstimation;
|
|
145
|
-
if (usageEstimation !== undefined && usageEstimation !== "fallback" && usageEstimation !== "off") {
|
|
146
|
-
throw new TypeError('usageEstimation must be "fallback" or "
|
|
198
|
+
if (usageEstimation !== undefined && usageEstimation !== "fallback" && usageEstimation !== "off" && usageEstimation !== "strict") {
|
|
199
|
+
throw new TypeError('usageEstimation must be "fallback", "off", or "strict"');
|
|
147
200
|
}
|
|
148
201
|
}
|
|
149
202
|
get leafId() {
|
|
@@ -156,8 +209,37 @@ export class RuntimeAgentSession {
|
|
|
156
209
|
* `provider_turn_finished.budgets` resolves them. Before any provider turn in
|
|
157
210
|
* this session it estimates stored history, so a non-reporting model still
|
|
158
211
|
* shows a working meter instead of zero. Never billing; estimates are labeled.
|
|
212
|
+
*
|
|
213
|
+
* Plan 103 T4: reads are cached until the history generation, leaf, history
|
|
214
|
+
* length, or active-run identity changes, so a per-frame poll pays one estimate
|
|
215
|
+
* per mutation instead of one per read. The cached value is frozen and is
|
|
216
|
+
* identical (`===`) to the previous read while nothing changed.
|
|
159
217
|
*/
|
|
160
218
|
contextMeter() {
|
|
219
|
+
const cached = this.meterCache;
|
|
220
|
+
if (cached &&
|
|
221
|
+
cached.leafId === this.currentLeafId &&
|
|
222
|
+
cached.generation === this.snapshotGeneration &&
|
|
223
|
+
cached.meter === this.activeInputMeter &&
|
|
224
|
+
cached.limits === this.activeLimits &&
|
|
225
|
+
cached.history === this.history &&
|
|
226
|
+
cached.historyLength === this.history.length) {
|
|
227
|
+
return cached.value;
|
|
228
|
+
}
|
|
229
|
+
const value = Object.freeze(this.measureContextMeter());
|
|
230
|
+
this.meterCache = {
|
|
231
|
+
leafId: this.currentLeafId,
|
|
232
|
+
generation: this.snapshotGeneration,
|
|
233
|
+
meter: this.activeInputMeter,
|
|
234
|
+
limits: this.activeLimits,
|
|
235
|
+
history: this.history,
|
|
236
|
+
historyLength: this.history.length,
|
|
237
|
+
value,
|
|
238
|
+
};
|
|
239
|
+
return value;
|
|
240
|
+
}
|
|
241
|
+
/** Cold path of `contextMeter()`: one estimate over stored history plus cap/budget resolution. */
|
|
242
|
+
measureContextMeter() {
|
|
161
243
|
const model = this.agent.config.model;
|
|
162
244
|
const inputTokens = this.activeInputMeter?.tokens ?? estimateMessageTokens(this.history, model.model).tokens;
|
|
163
245
|
const source = this.activeInputMeter?.source ?? "estimated";
|
|
@@ -179,7 +261,17 @@ export class RuntimeAgentSession {
|
|
|
179
261
|
...(inputCap === undefined ? {} : { usedRatio: inputTokens / inputCap }),
|
|
180
262
|
};
|
|
181
263
|
}
|
|
264
|
+
/**
|
|
265
|
+
* Live events for this session. A run-scoped subscriber (the default) is closed when the run ends,
|
|
266
|
+
* suspends, or is denied; `SubscribeOptions.acrossRuns: true` keeps one subscriber open across runs
|
|
267
|
+
* of the same session until the host closes it, the session tears it down, or its bounded queue
|
|
268
|
+
* overflows under the default policy. Subscribe before `run()`; the consumer loop and `run()` must
|
|
269
|
+
* run concurrently, since events are only emitted during a live run.
|
|
270
|
+
*/
|
|
182
271
|
subscribe(options = {}) {
|
|
272
|
+
return this.createSubscriber(options);
|
|
273
|
+
}
|
|
274
|
+
createSubscriber(options) {
|
|
183
275
|
const subscriber = new EventSubscriber(this.id, options, () => this.subscribers.delete(subscriber));
|
|
184
276
|
this.subscribers.add(subscriber);
|
|
185
277
|
return subscriber;
|
|
@@ -233,7 +325,7 @@ export class RuntimeAgentSession {
|
|
|
233
325
|
this.activeLedger = undefined;
|
|
234
326
|
this.activeOwnership = undefined;
|
|
235
327
|
this.activeRedactor = undefined;
|
|
236
|
-
this.
|
|
328
|
+
this.closeRunSubscribers();
|
|
237
329
|
}
|
|
238
330
|
}
|
|
239
331
|
async recordDurableDenial(runId, interruption, version, ownership) {
|
|
@@ -248,25 +340,58 @@ export class RuntimeAgentSession {
|
|
|
248
340
|
this.activeLedger = undefined;
|
|
249
341
|
this.activeOwnership = undefined;
|
|
250
342
|
this.activeRedactor = undefined;
|
|
251
|
-
this.
|
|
343
|
+
this.closeRunSubscribers();
|
|
252
344
|
}
|
|
253
345
|
}
|
|
254
346
|
async runInternal(input, options, runId, resumed) {
|
|
255
347
|
return executeRun(asSessionHost(this), input, options, runId, resumed);
|
|
256
348
|
}
|
|
349
|
+
/**
|
|
350
|
+
* Plan 106 R2: dispatch `session_start` once per session, at its first run start (including the
|
|
351
|
+
* first run of a session rebuilt from a durable checkpoint). The run assembler awaits it right
|
|
352
|
+
* after `agent_started`/`agent_resumed`, so session-scoped provisioning is done before the first
|
|
353
|
+
* turn while the runtime's synchronous emit burst stays intact. Middleware error policy decides
|
|
354
|
+
* whether a failure surfaces or becomes an `extension_error` event.
|
|
355
|
+
*/
|
|
356
|
+
async openSession(runId) {
|
|
357
|
+
if (this.sessionOpened)
|
|
358
|
+
return;
|
|
359
|
+
this.sessionOpened = true;
|
|
360
|
+
await this.agent.config.middleware?.run("session_start", { sessionId: this.id, runId });
|
|
361
|
+
}
|
|
362
|
+
/**
|
|
363
|
+
* Plan 106 R2: session teardown. Dispatches `session_shutdown` middleware once (idempotent) and
|
|
364
|
+
* then closes every subscriber, run-scoped and `acrossRuns` alike. Call it after the active run
|
|
365
|
+
* settles; `closeSubscribers()` remains the subscriber-only seam.
|
|
366
|
+
*/
|
|
367
|
+
async close() {
|
|
368
|
+
if (this.closed)
|
|
369
|
+
return;
|
|
370
|
+
this.closed = true;
|
|
371
|
+
try {
|
|
372
|
+
await this.agent.config.middleware?.run("session_shutdown", { sessionId: this.id });
|
|
373
|
+
}
|
|
374
|
+
finally {
|
|
375
|
+
this.closeSubscribers();
|
|
376
|
+
}
|
|
377
|
+
}
|
|
257
378
|
prompt(input, options) {
|
|
258
379
|
return this.run(input, options);
|
|
259
380
|
}
|
|
260
381
|
async *stream(input, options = {}) {
|
|
261
382
|
const { maxQueuedEvents, overflow, ...runOptions } = options;
|
|
262
|
-
const
|
|
383
|
+
const subscriber = this.createSubscriber({ maxQueuedEvents, overflow });
|
|
263
384
|
let runOwnedId;
|
|
264
385
|
let settled = false;
|
|
386
|
+
// This subscription is stream()'s own, so it does not depend on the run-end close: settling the
|
|
387
|
+
// run closes it too, which also unblocks the consumer loop when the run fails before it ever
|
|
388
|
+
// emits (a pre-flight validation rejection returns before run-end cleanup).
|
|
265
389
|
const runPromise = this.run(input, runOptions).finally(() => {
|
|
266
390
|
settled = true;
|
|
391
|
+
subscriber.close();
|
|
267
392
|
});
|
|
268
393
|
try {
|
|
269
|
-
for await (const event of
|
|
394
|
+
for await (const event of subscriber) {
|
|
270
395
|
if ("runId" in event && typeof event.runId === "string") {
|
|
271
396
|
if (runOwnedId === undefined && event.type === "agent_started")
|
|
272
397
|
runOwnedId = event.runId;
|
|
@@ -278,6 +403,7 @@ export class RuntimeAgentSession {
|
|
|
278
403
|
await runPromise;
|
|
279
404
|
}
|
|
280
405
|
finally {
|
|
406
|
+
subscriber.close();
|
|
281
407
|
if (!settled) {
|
|
282
408
|
this.abort(new Error("stream consumer closed"));
|
|
283
409
|
await runPromise.catch(() => undefined);
|
|
@@ -296,6 +422,7 @@ export class RuntimeAgentSession {
|
|
|
296
422
|
message: final.message,
|
|
297
423
|
usage: input.usage,
|
|
298
424
|
limit: input.limit,
|
|
425
|
+
attribution: input.attribution,
|
|
299
426
|
error: input.error,
|
|
300
427
|
abortReason: input.abortReason,
|
|
301
428
|
stopReason: input.stopReason,
|
|
@@ -333,7 +460,7 @@ export class RuntimeAgentSession {
|
|
|
333
460
|
store: this.store,
|
|
334
461
|
leafId: options.leafId ?? this.currentLeafId,
|
|
335
462
|
metadata: this.metadata,
|
|
336
|
-
...(this.
|
|
463
|
+
...(this.packRefs ? { guardrailPacks: this.packRefs } : {}),
|
|
337
464
|
});
|
|
338
465
|
}
|
|
339
466
|
async clone(options = {}) {
|
|
@@ -356,12 +483,12 @@ export class RuntimeAgentSession {
|
|
|
356
483
|
store: this.store,
|
|
357
484
|
leafId: branch.length ? remap.get(branch[branch.length - 1].id) : undefined,
|
|
358
485
|
metadata: this.metadata,
|
|
359
|
-
...(this.
|
|
486
|
+
...(this.packRefs ? { guardrailPacks: this.packRefs } : {}),
|
|
360
487
|
});
|
|
361
488
|
}
|
|
362
489
|
branchReader() {
|
|
363
|
-
// ponytail: prefer
|
|
364
|
-
//
|
|
490
|
+
// ponytail: prefer readBranchPath when present (memory, SQLite, Postgres) so snapshot does
|
|
491
|
+
// not list() the whole session. JSONL and other omitters fall back to list() + in-memory walk.
|
|
365
492
|
const read = this.store.readBranchPath;
|
|
366
493
|
return read ? (query) => read.call(this.store, query) : undefined;
|
|
367
494
|
}
|
|
@@ -418,6 +545,15 @@ export class RuntimeAgentSession {
|
|
|
418
545
|
});
|
|
419
546
|
}
|
|
420
547
|
}
|
|
548
|
+
/**
|
|
549
|
+
* Run end (finish, suspension, or denial): closes the run-scoped subscribers only. Subscribers that
|
|
550
|
+
* opted into `SubscribeOptions.acrossRuns` stay open for the next run of this session.
|
|
551
|
+
*/
|
|
552
|
+
closeRunSubscribers() {
|
|
553
|
+
for (const subscriber of this.subscribers)
|
|
554
|
+
if (!subscriber.acrossRuns)
|
|
555
|
+
subscriber.close();
|
|
556
|
+
}
|
|
421
557
|
closeSubscribers() {
|
|
422
558
|
for (const subscriber of this.subscribers)
|
|
423
559
|
subscriber.close();
|
|
@@ -528,10 +664,15 @@ export class RuntimeAgentSession {
|
|
|
528
664
|
signal,
|
|
529
665
|
};
|
|
530
666
|
this.emit({ type: "compaction_started", sessionId: this.id, runId });
|
|
531
|
-
|
|
667
|
+
// Plan 106 R3: pre-compaction seam — the strategy compacts exactly the context this returns.
|
|
668
|
+
const requested = (await this.agent.config.middleware?.run("compaction_request", context)) ?? context;
|
|
669
|
+
let result = await strategy.compact(requested);
|
|
532
670
|
result = { ...result, summary: redactSecrets(result.summary, secrets) };
|
|
533
|
-
const payload = (await this.agent.config.middleware?.run("compaction", {
|
|
534
|
-
context,
|
|
671
|
+
const payload = (await this.agent.config.middleware?.run("compaction", {
|
|
672
|
+
context: requested,
|
|
673
|
+
result,
|
|
674
|
+
})) ?? {
|
|
675
|
+
context: requested,
|
|
535
676
|
result,
|
|
536
677
|
};
|
|
537
678
|
result = { ...payload.result, summary: redactSecrets(payload.result.summary, secrets) };
|
|
@@ -1,12 +1,17 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Checkpoint restore hooks (plan 094 Task 3). A hook restores
|
|
3
|
-
* document version, workspace fingerprint) recorded in a
|
|
2
|
+
* Checkpoint restore hooks (plan 094 Task 3; reverse compensation plan 109 Task 2). A hook restores
|
|
3
|
+
* one external layer (git commit, document version, workspace fingerprint) recorded in a
|
|
4
|
+
* checkpoint's sidecar metadata.
|
|
4
5
|
*
|
|
5
|
-
* All-or-nothing: hooks run before the resume claims the checkpoint. The first hook that fails
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
6
|
+
* All-or-nothing: hooks run before the resume claims the checkpoint. The first hook that fails or
|
|
7
|
+
* times out aborts the resume with `CheckpointRestoreError` naming that hook, so the conversation
|
|
8
|
+
* restore never applies on top of a half-restored external world. A handler may also declare a
|
|
9
|
+
* `compensate` direction: on failure the applied layers — including the failing one, which may be
|
|
10
|
+
* half-applied — are undone in reverse order and the error carries a best-effort
|
|
11
|
+
* `CheckpointRestoreCompensation` report. Compensation never runs after the caller aborted, never
|
|
12
|
+
* masks the original failure, and the checkpoint stays resumable either way.
|
|
9
13
|
*/
|
|
14
|
+
import type { SecretRedactor } from "./redaction.js";
|
|
10
15
|
/** Per-hook ceiling for a restore (plan 094 Task 3 default). */
|
|
11
16
|
export declare const DEFAULT_CHECKPOINT_RESTORE_TIMEOUT_MS = 10000;
|
|
12
17
|
/** One hook that completed during a restore. */
|
|
@@ -20,26 +25,57 @@ export interface CheckpointRestoreAudit {
|
|
|
20
25
|
readonly durationMs: number;
|
|
21
26
|
}
|
|
22
27
|
/**
|
|
23
|
-
* Host code restoring one external layer. `signal` aborts on the per-hook timeout
|
|
24
|
-
* caller's abort, so a hook that talks to a remote system can cancel instead of dangling.
|
|
28
|
+
* Host code restoring or compensating one external layer. `signal` aborts on the per-hook timeout
|
|
29
|
+
* and on the caller's abort, so a hook that talks to a remote system can cancel instead of dangling.
|
|
25
30
|
*/
|
|
26
31
|
export type CheckpointRestoreHook<Context> = (checkpoint: Context, signal: AbortSignal) => void | Promise<void>;
|
|
32
|
+
/** Object form of a restore handler: an identity plus the layer's undo direction (plan 109 Task 2). */
|
|
33
|
+
interface CheckpointRestoreHandlerObject<Context> {
|
|
34
|
+
/** Stable name reported in the audit and in `CheckpointRestoreError.compensation`; defaults to the restore hook's name, then `hook[i]`. */
|
|
35
|
+
readonly id?: string;
|
|
36
|
+
readonly restore: CheckpointRestoreHook<Context>;
|
|
37
|
+
/** Undo for this layer, run when a later hook — or this one — fails. Absent = the layer has no undo. */
|
|
38
|
+
readonly compensate?: CheckpointRestoreHook<Context>;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* A restore handler: today's bare function, or `{ id?, restore, compensate? }` to declare an undo
|
|
42
|
+
* direction. Bare functions behave exactly as in plan 094 and are never compensated.
|
|
43
|
+
*/
|
|
44
|
+
export type CheckpointRestoreHandler<Context> = CheckpointRestoreHook<Context> | CheckpointRestoreHandlerObject<Context>;
|
|
45
|
+
/** Best-effort record of the reverse compensation pass after a failed restore (plan 109 Task 2). */
|
|
46
|
+
export interface CheckpointRestoreCompensation {
|
|
47
|
+
/** Names of the hooks whose `compensate` ran, most recently applied layer first. */
|
|
48
|
+
readonly ran: readonly string[];
|
|
49
|
+
/** First compensation that failed; the pass still continues with the remaining layers. */
|
|
50
|
+
readonly failed?: {
|
|
51
|
+
readonly hook: string;
|
|
52
|
+
readonly reason: string;
|
|
53
|
+
};
|
|
54
|
+
}
|
|
27
55
|
/** Thrown when a restore hook fails or times out; the checkpoint and conversation are untouched. */
|
|
28
56
|
export declare class CheckpointRestoreError extends Error {
|
|
29
57
|
readonly code = "ERR_PRISM_CHECKPOINT_RESTORE";
|
|
30
|
-
/** Name of the failing hook (`
|
|
58
|
+
/** Name of the failing hook (`id`, `hook.name`, or `hook[i]`). */
|
|
31
59
|
readonly hook: string;
|
|
32
|
-
|
|
60
|
+
/** Present only when at least one `compensate` ran; omitted otherwise, as in plan 094. */
|
|
61
|
+
readonly compensation?: CheckpointRestoreCompensation;
|
|
62
|
+
constructor(hook: string, cause: unknown, compensation?: CheckpointRestoreCompensation);
|
|
33
63
|
}
|
|
34
64
|
export interface RunCheckpointRestoreHooksOptions {
|
|
35
65
|
/** Per-hook timeout; defaults to `DEFAULT_CHECKPOINT_RESTORE_TIMEOUT_MS`. */
|
|
36
66
|
readonly timeoutMs?: number;
|
|
37
67
|
/** Caller abort: checked between hooks and combined into each hook's signal. */
|
|
38
68
|
readonly signal?: AbortSignal;
|
|
69
|
+
/** Applied to the bounded compensation reason; absent = the message is reported as-is (still capped). */
|
|
70
|
+
readonly redactor?: SecretRedactor;
|
|
39
71
|
}
|
|
40
72
|
/**
|
|
41
|
-
* Run restore
|
|
42
|
-
* `CheckpointRestoreError` immediately (later
|
|
43
|
-
*
|
|
73
|
+
* Run restore handlers sequentially and report the audit. A handler failure throws
|
|
74
|
+
* `CheckpointRestoreError` immediately (later handlers do not run) after a best-effort reverse
|
|
75
|
+
* compensation pass over the applied layers; with no `compensate` declared anywhere, the failure
|
|
76
|
+
* shape is exactly plan 094's. An already-aborted caller signal throws its own abort reason so the
|
|
77
|
+
* resume reads as cancelled rather than as a restore failure, and a caller abort during the pass
|
|
78
|
+
* stops it before the next handler runs.
|
|
44
79
|
*/
|
|
45
|
-
export declare function runCheckpointRestoreHooks<Context>(hooks: readonly
|
|
80
|
+
export declare function runCheckpointRestoreHooks<Context>(hooks: readonly CheckpointRestoreHandler<Context>[], context: Context, options?: RunCheckpointRestoreHooksOptions): Promise<CheckpointRestoreAudit>;
|
|
81
|
+
export {};
|