@noetaris/harness 0.3.1 → 0.3.2
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/dist/index.d.ts +5 -0
- package/dist/index.js +42 -3
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -600,6 +600,11 @@ interface AgentOptions {
|
|
|
600
600
|
* via `RunContext.instanceId`.
|
|
601
601
|
*/
|
|
602
602
|
readonly instanceId?: string;
|
|
603
|
+
/**
|
|
604
|
+
* Concrete store instances for slots declared with `required()` inside `h.store()`.
|
|
605
|
+
* Keyed by the store key used in the harness (e.g. `{ session: myStore }`).
|
|
606
|
+
*/
|
|
607
|
+
readonly stores?: Record<string, unknown>;
|
|
603
608
|
}
|
|
604
609
|
interface Agent {
|
|
605
610
|
/** The agent's unique identifier, as provided to createAgent(). */
|
package/dist/index.js
CHANGED
|
@@ -732,7 +732,7 @@ function noopStop() {
|
|
|
732
732
|
}
|
|
733
733
|
|
|
734
734
|
// src/agent/session-lifecycle.ts
|
|
735
|
-
function resolveSessionStore(storeEntries) {
|
|
735
|
+
function resolveSessionStore(storeEntries, overrides) {
|
|
736
736
|
let result = void 0;
|
|
737
737
|
for (const entry of storeEntries) {
|
|
738
738
|
if (entry.kind !== "store") continue;
|
|
@@ -740,7 +740,8 @@ function resolveSessionStore(storeEntries) {
|
|
|
740
740
|
if (value === null || typeof value !== "object") continue;
|
|
741
741
|
const rec = value;
|
|
742
742
|
if (!("session" in rec)) continue;
|
|
743
|
-
const
|
|
743
|
+
const rawSession = rec["session"];
|
|
744
|
+
const session = overrides !== void 0 && "session" in overrides ? overrides["session"] : rawSession;
|
|
744
745
|
if (session === null || typeof session !== "object") continue;
|
|
745
746
|
const s = session;
|
|
746
747
|
if (typeof s["load"] === "function" && typeof s["save"] === "function") {
|
|
@@ -1022,6 +1023,24 @@ var UnknownRunSlotError = class extends Error {
|
|
|
1022
1023
|
this.key = key;
|
|
1023
1024
|
}
|
|
1024
1025
|
};
|
|
1026
|
+
var MissingStoreSlotError = class extends Error {
|
|
1027
|
+
/** The store key (e.g. `"session"`) that was not provided. */
|
|
1028
|
+
key;
|
|
1029
|
+
constructor(key) {
|
|
1030
|
+
super(`required store slot "${key}" was not provided in createAgent options.stores`);
|
|
1031
|
+
this.name = "MissingStoreSlotError";
|
|
1032
|
+
this.key = key;
|
|
1033
|
+
}
|
|
1034
|
+
};
|
|
1035
|
+
var UnexpectedStoreSlotError = class extends Error {
|
|
1036
|
+
/** The unexpected store key. */
|
|
1037
|
+
key;
|
|
1038
|
+
constructor(key) {
|
|
1039
|
+
super(`store slot "${key}" was not declared as required() in the harness \u2014 do not pass it in options.stores`);
|
|
1040
|
+
this.name = "UnexpectedStoreSlotError";
|
|
1041
|
+
this.key = key;
|
|
1042
|
+
}
|
|
1043
|
+
};
|
|
1025
1044
|
var _agentInternals = /* @__PURE__ */ Symbol("_agentInternals");
|
|
1026
1045
|
function createAgent(id, h, slots, agentOptions) {
|
|
1027
1046
|
const internals = getInternals(h);
|
|
@@ -1070,7 +1089,27 @@ function createAgent(id, h, slots, agentOptions) {
|
|
|
1070
1089
|
}
|
|
1071
1090
|
}
|
|
1072
1091
|
}
|
|
1073
|
-
|
|
1092
|
+
let sessionIsRequired = false;
|
|
1093
|
+
for (const entry of storeEntries) {
|
|
1094
|
+
const storeValue = entry.value;
|
|
1095
|
+
if (storeValue === null || typeof storeValue !== "object") continue;
|
|
1096
|
+
const storeRec = storeValue;
|
|
1097
|
+
if ("session" in storeRec && isRequiredMarker(storeRec["session"])) {
|
|
1098
|
+
sessionIsRequired = true;
|
|
1099
|
+
}
|
|
1100
|
+
}
|
|
1101
|
+
const sessionStoreOverride = agentOptions?.stores?.["session"];
|
|
1102
|
+
const storeOverrides = {};
|
|
1103
|
+
if (sessionIsRequired) {
|
|
1104
|
+
if (sessionStoreOverride === void 0) throw new MissingStoreSlotError("session");
|
|
1105
|
+
storeOverrides["session"] = sessionStoreOverride;
|
|
1106
|
+
} else if (sessionStoreOverride !== void 0) {
|
|
1107
|
+
throw new UnexpectedStoreSlotError("session");
|
|
1108
|
+
}
|
|
1109
|
+
const capturedStore = resolveSessionStore(
|
|
1110
|
+
storeEntries,
|
|
1111
|
+
Object.keys(storeOverrides).length > 0 ? storeOverrides : void 0
|
|
1112
|
+
);
|
|
1074
1113
|
const agentInternals = {
|
|
1075
1114
|
agentId: id,
|
|
1076
1115
|
resolvedProviders,
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/harness/state-field.ts","../src/harness/ctx-markers.ts","../src/loop/loop-dsl.ts","../src/loop/loop-validator.ts","../src/harness/harness-builder.ts","../src/agent/ctx-interrupt.ts","../src/agent/ctx-emit.ts","../src/loop/loop-executor.ts","../src/agent/session-store.ts","../src/agent/concurrency-errors.ts","../src/agent/ctx-keep-alive.ts","../src/agent/session-lifecycle.ts","../src/agent/interrupt-resume.ts","../src/agent/run-handle.ts","../src/agent/create-agent.ts","../src/agent/event-callbacks.ts","../src/agent/observer.ts"],"sourcesContent":["// Phantom symbol — never accessible at runtime; required for reliable T inference\n// even when neither `default` nor `reduce` is provided\ndeclare const _fieldType: unique symbol\n\n/**\n * Descriptor for a single state field, produced by {@link field}.\n *\n * - `default` — factory called once on session start to populate the field when no\n * initial value is supplied.\n * - `reduce` — merge function invoked on resume: `reduce(storedValue, incomingValue)`.\n * When absent, incoming values overwrite stored ones on resume.\n */\nexport type FieldDefinition<T> = {\n readonly [_fieldType]: T\n readonly default?: () => T\n readonly reduce?: (current: T, update: T) => T\n}\n\n/**\n * Derives the concrete state record type from a schema object whose values are\n * {@link FieldDefinition} descriptors.\n *\n * @example\n * ```ts\n * const schema = { count: field<number>({ default: () => 0 }) }\n * type State = StateFromSchema<typeof schema> // { count: number }\n * ```\n */\n// use FieldDefinition<any> in bounds, not FieldDefinition<unknown> — reduce makes T invariant\nexport type StateFromSchema<S> = {\n [K in keyof S]: S[K] extends FieldDefinition<infer T> ? T : never\n}\n\ntype FieldOptions<T> = {\n default?: () => T\n reduce?: (current: T, update: T) => T\n}\n\n/**\n * Declare a typed state field with an optional default factory and optional\n * reduce function.\n *\n * @param options.default - Factory called once at session start.\n * @param options.reduce - Merge function for resume: `(stored, incoming) => merged`.\n *\n * @example\n * ```ts\n * const schema = {\n * messages: field<string[]>({ default: () => [], reduce: (a, b) => [...a, ...b] }),\n * }\n * ```\n */\nexport function field<T>(options?: FieldOptions<T>): FieldDefinition<T> {\n return { ...options } as FieldDefinition<T> // as: phantom [_fieldType] is type-level only; the runtime object can never carry the symbol property\n}\n","/** @internal Discriminant tag for {@link RequiredMarker}. */\nexport const REQUIRED_TAG = '__noetaris_required__' as const\n/** @internal Discriminant tag for {@link RuntimeMarker}. */\nexport const RUNTIME_TAG = '__noetaris_runtime__' as const\n\n// string literal _tag is the sole type-level discriminant; phantom symbols were tried but\n// TypeScript does not enforce non-exported unique symbol keys across module boundaries\n\n/**\n * Sentinel returned by {@link required} to mark a context slot that **must** be\n * supplied at `createAgent()` time (not at `agent.run()` time).\n */\nexport type RequiredMarker = { readonly _tag: typeof REQUIRED_TAG }\n\n/**\n * Sentinel returned by {@link runtime} to mark a context slot that **must** be\n * supplied at `agent.run()` time (not at `createAgent()` time).\n */\nexport type RuntimeMarker = { readonly _tag: typeof RUNTIME_TAG }\n\n// function guard prevents TypeScript from recursing into Function's own method properties\n// (call, bind, apply, etc.) when T is a function type, which would make the mapped type\n// unresolvable and break @ts-expect-error enforcement on concrete value checks\n/**\n * Recursive variant of `T` that allows any nested position to also be a\n * {@link RequiredMarker} or {@link RuntimeMarker}. Used as the `value`\n * parameter type on {@link Harness.provide}.\n */\nexport type DeepWithMarkers<T> =\n T extends (...args: any[]) => any\n ? T | RequiredMarker | RuntimeMarker\n : T extends object\n ? { [K in keyof T]: DeepWithMarkers<T[K]> | RequiredMarker | RuntimeMarker } | RequiredMarker | RuntimeMarker\n : T | RequiredMarker | RuntimeMarker\n\n/**\n * Return a {@link RequiredMarker} sentinel that instructs the harness to\n * require this slot at `createAgent()` time.\n *\n * @example\n * ```ts\n * h.provide('llm', required())\n * ```\n */\nexport function required(): RequiredMarker {\n return { _tag: REQUIRED_TAG }\n}\n\n/**\n * Return a {@link RuntimeMarker} sentinel that instructs the harness to\n * require this slot at `agent.run()` time instead of `createAgent()` time.\n *\n * @example\n * ```ts\n * h.provide('signal', runtime())\n * ```\n */\nexport function runtime(): RuntimeMarker {\n return { _tag: RUNTIME_TAG }\n}\n\n/**\n * Type guard — returns `true` when `value` is a {@link RequiredMarker}.\n */\nexport function isRequiredMarker(value: unknown): value is RequiredMarker {\n return value !== null && typeof value === 'object' && '_tag' in value && value._tag === REQUIRED_TAG\n}\n\n/**\n * Type guard — returns `true` when `value` is a {@link RuntimeMarker}.\n */\nexport function isRuntimeMarker(value: unknown): value is RuntimeMarker {\n return value !== null && typeof value === 'object' && '_tag' in value && value._tag === RUNTIME_TAG\n}\n","import type { KeepAliveFn } from '../agent/ctx-keep-alive.js'\n\n// -----------------------------------------------------------------------\n// Framework-reserved state fields — readable in run/route, not writable from run return\n// -----------------------------------------------------------------------\n\n/**\n * Framework-managed fields injected into every step function's `state` argument.\n *\n * - `$error` — the `Error` thrown by the previous step, or `null` if no error occurred.\n * Only populated on the error path; non-error-aware steps never see a non-null value here.\n * - `$interrupt` — set while a step is awaiting a resume response. The `response` field\n * is populated after {@link Agent.resume} is called.\n */\nexport interface FrameworkState {\n readonly $error: Error | null\n readonly $interrupt: {\n readonly interruptId: string\n readonly prompt: unknown\n readonly response?: unknown\n } | null\n}\n\n/**\n * The complete state type visible inside {@link RunFn} step functions:\n * the user-defined state `S` merged with {@link FrameworkState}.\n */\nexport type StepState<S> = S & FrameworkState\n\n// -----------------------------------------------------------------------\n// Step function signatures\n// -----------------------------------------------------------------------\n\n/**\n * State transformer. Receives the full step state and ctx; returns a partial update\n * of user-defined state fields only (framework-reserved fields are excluded from return).\n * May be async.\n */\nexport type RunFn<S, Ctx> = (\n state: StepState<S>,\n ctx: Ctx & {\n readonly agentId: string\n readonly sessionId: string\n readonly runId: string\n readonly signal: AbortSignal\n readonly interrupt: (prompt: unknown, id?: string) => Promise<unknown>\n readonly emit: (name: string, payload?: unknown) => void\n readonly keepAlive: KeepAliveFn\n },\n) => Promise<Partial<Omit<S, '$error' | '$interrupt'>>> | Partial<Omit<S, '$error' | '$interrupt'>>\n\n/**\n * Pure signal emitter. Receives step state without $error — the route is not called on the error\n * path unless the step opts in via `optin: '$error'` in the step config. Synchronous by design.\n * No ctx — pure read only.\n */\nexport type RouteFn<S> = (state: S & Omit<FrameworkState, '$error'>) => string\n\n/**\n * Pure signal emitter for error-aware steps (optin: '$error').\n * Receives the full step state including $error — the executor calls this on both the success\n * and error paths. Declare `optin: '$error'` in the step config to use this variant.\n */\nexport type ErrorAwareRouteFn<S> = (state: StepState<S>) => string\n\n/**\n * Options passed to `.step(name, options)`. At least one of `run` or `route` must be set.\n *\n * Two variants:\n * - Without `optin`: route receives state without `$error` (TypeScript-enforced). On error,\n * the framework falls through to `l.onError()` or pauses with `signal: \"$error\"` automatically.\n * - With `optin: '$error'`: route receives the full state including `$error`, and the executor\n * calls route on the error path. Use this when the step's route needs to inspect or handle errors.\n */\nexport type StepOptions<S, Ctx> =\n | {\n readonly optin: '$error'\n run?: RunFn<S, Ctx>\n route?: ErrorAwareRouteFn<S>\n }\n | {\n readonly optin?: undefined\n run?: RunFn<S, Ctx>\n route?: RouteFn<S>\n }\n\n// -----------------------------------------------------------------------\n// LoopDefinition — the captured topology produced by the builder\n// -----------------------------------------------------------------------\n\n/**\n * Where a signal transition routes to.\n * 'step' — routes to the named step.\n * 'end' — exits the loop; run resolves with the emitted signal.\n */\nexport type TransitionTarget =\n | { readonly kind: 'step'; readonly name: string }\n | { readonly kind: 'end' }\n\n/** A single `.on(signal).to(step)` or `.on(signal).end()` declaration. */\nexport interface SignalTransition {\n readonly signal: string\n readonly target: TransitionTarget\n}\n\n/**\n * Compiled step definition stored in LoopDefinition.\n * run and route are stored as-is (user functions — validated structurally, not semantically).\n * transitions: all .on() declarations attached to this step.\n * next: explicit .next(name) target, or undefined if none declared.\n * errorAware: true when the step was declared with optin: '$error' — the executor calls route\n * on the error path when this is true.\n */\nexport interface StepDef {\n readonly name: string\n readonly run: RunFn<unknown, unknown> | undefined\n readonly route: RouteFn<unknown> | undefined\n readonly transitions: readonly SignalTransition[]\n readonly next: string | undefined\n readonly errorAware: boolean\n}\n\n/**\n * Complete loop topology captured from the builder lambda.\n * Immutable snapshot — produced once, consumed by LoopValidator and (later) F6.\n *\n * startCalled: true if l.start() was invoked at least once.\n * entryStep: name of the first .step() declared after .start() was called; undefined if .start()\n * was never called or no step was declared after it.\n * steps: all declared steps in declaration order.\n * onError: the fallback step name from l.onError(), or undefined if not set.\n */\nexport interface LoopDefinition {\n readonly startCalled: boolean\n readonly entryStep: string | undefined\n readonly steps: readonly StepDef[]\n readonly onError: string | undefined\n}\n\n// -----------------------------------------------------------------------\n// LoopBuilder — the DSL object passed to the h.loop() builder lambda\n// -----------------------------------------------------------------------\n\n/**\n * Fluent chain returned by .on(signal). Caller must call either .to(step) or .end()\n * to complete the transition declaration.\n */\nexport interface OnChain<S, Ctx> {\n /** Route the signal to the named step. Returns the builder for further chaining. */\n to(step: string): LoopBuilder<S, Ctx>\n /** Exit the loop when this signal is emitted. Returns the builder for further chaining. */\n end(): LoopBuilder<S, Ctx>\n}\n\n/**\n * The DSL object passed as `l` to the h.loop(l => ...) builder lambda.\n * All methods mutate internal state and return `this` for chaining.\n */\nexport interface LoopBuilder<S, Ctx> {\n /** Mark the loop as having a declared entry. The first .step() called after .start() is the entry. */\n start(): LoopBuilder<S, Ctx>\n /** Declare a step. At least one of run or route must be set (validated later by LoopValidator). */\n step(name: string, options: StepOptions<S, Ctx>): LoopBuilder<S, Ctx>\n /**\n * Begin a signal transition declaration. Must be called immediately after .step() or after\n * a previous .on().to() or .on().end() chain (attaches to the most recently declared step).\n */\n on(signal: string): OnChain<S, Ctx>\n /**\n * Declare an explicit unconditional next target for the most recently declared step.\n * Mutually exclusive with route (validated by LoopValidator).\n */\n next(name: string): LoopBuilder<S, Ctx>\n /**\n * Declare a loop-level fallback error step. Any step whose run throws and whose\n * route does not handle $error will route to this step instead of pausing the session.\n * Only one onError target per loop; multiple calls replace the previous target (last wins).\n */\n onError(step: string): LoopBuilder<S, Ctx>\n}\n\n// -----------------------------------------------------------------------\n// Error class\n// -----------------------------------------------------------------------\n\n/** Thrown by extractLoopDefinition when the argument is not a createLoopBuilder() instance. */\nexport class InvalidLoopBuilderError extends Error {\n constructor() {\n super('argument is not a LoopBuilder instance — was it created by createLoopBuilder?')\n this.name = 'InvalidLoopBuilderError'\n }\n}\n\n// -----------------------------------------------------------------------\n// Internal implementation\n// -----------------------------------------------------------------------\n\n// Module-private symbol for internal state\nconst _builderState = Symbol('builderState')\n\n// Internal mutable step definition during collection\ninterface StepDefMutable {\n name: string\n run: RunFn<unknown, unknown> | undefined\n route: RouteFn<unknown> | undefined\n transitions: SignalTransition[]\n next: string | undefined\n errorAware: boolean\n}\n\n// Internal mutable builder state\ninterface BuilderState {\n startCalled: boolean\n entryStep: string | undefined\n steps: StepDefMutable[]\n onError: string | undefined\n}\n\n// Deep freeze utility\nfunction deepFreeze<T extends object>(obj: T): T {\n Object.freeze(obj)\n\n for (const value of Object.values(obj)) {\n if (value !== null && typeof value === 'object' && !Object.isFrozen(value)) {\n deepFreeze(value)\n }\n }\n\n return obj\n}\n\n/**\n * Create a new LoopBuilder instance for use in a h.loop() lambda.\n * The returned object accumulates all DSL calls in mutable internal state.\n */\nexport function createLoopBuilder<S, Ctx>(): LoopBuilder<S, Ctx> {\n const state: BuilderState = {\n startCalled: false,\n entryStep: undefined,\n steps: [],\n onError: undefined,\n }\n\n const builder: any = {\n start(this: any): LoopBuilder<S, Ctx> {\n state.startCalled = true\n return this\n },\n\n step(this: any, name: string, options: StepOptions<S, Ctx>): LoopBuilder<S, Ctx> {\n const stepDef: StepDefMutable = {\n name,\n run: options.run as RunFn<unknown, unknown> | undefined, // as: contravariance in state parameter\n route: options.route as RouteFn<unknown> | undefined, // as: contravariance in state parameter\n transitions: [],\n next: undefined,\n errorAware: options.optin === '$error',\n }\n state.steps.push(stepDef)\n\n // Set entryStep to the first step after start() was called\n if (state.startCalled && state.entryStep === undefined) {\n state.entryStep = name\n }\n\n return this\n },\n\n on(this: any, signal: string): OnChain<S, Ctx> {\n // Guard: if no step has been declared yet, return no-op OnChain\n if (state.steps.length === 0) {\n return {\n to: () => this,\n end: () => this,\n }\n }\n\n const currentStep = state.steps.at(-1)\n\n return {\n to: (step: string): LoopBuilder<S, Ctx> => {\n currentStep?.transitions.push({\n signal,\n target: { kind: 'step', name: step },\n })\n return this\n },\n end: (): LoopBuilder<S, Ctx> => {\n currentStep?.transitions.push({\n signal,\n target: { kind: 'end' },\n })\n return this\n },\n }\n },\n\n next(this: any, name: string): LoopBuilder<S, Ctx> {\n // Guard: if no step has been declared yet, this is a no-op\n if (state.steps.length > 0) {\n const currentStep = state.steps.at(-1)\n if (currentStep !== undefined) {\n currentStep.next = name\n }\n }\n return this\n },\n\n onError(this: any, step: string): LoopBuilder<S, Ctx> {\n state.onError = step\n return this\n },\n }\n\n // Attach the internal state symbol\n ;(builder as any)[_builderState] = state\n\n return builder as LoopBuilder<S, Ctx>\n}\n\n/**\n * Extract the LoopDefinition accumulated by a builder created with createLoopBuilder().\n * Called by harness-builder.ts immediately after the user's builder lambda returns.\n * Throws InvalidLoopBuilderError if the argument was not produced by createLoopBuilder().\n */\nexport function extractLoopDefinition(builder: LoopBuilder<unknown, unknown>): LoopDefinition {\n // Identity check: ensure builder has the internal state symbol\n if (builder === null || builder === undefined || !(_builderState in builder)) {\n throw new InvalidLoopBuilderError()\n }\n\n const state = (builder as any)[_builderState] as BuilderState\n\n // Convert mutable step definitions to immutable ones\n const immutableSteps: StepDef[] = state.steps.map((step) => {\n const transitions = Object.freeze([...step.transitions]) as readonly SignalTransition[]\n // Freeze each transition\n for (const transition of transitions) {\n Object.freeze(transition)\n Object.freeze(transition.target)\n }\n const stepDef: StepDef = {\n name: step.name,\n run: step.run,\n route: step.route,\n transitions,\n next: step.next,\n errorAware: step.errorAware,\n }\n return Object.freeze(stepDef)\n })\n\n // Create the frozen LoopDefinition\n const definition: LoopDefinition = {\n startCalled: state.startCalled,\n entryStep: state.entryStep,\n steps: Object.freeze(immutableSteps),\n onError: state.onError,\n }\n\n // Deep freeze the entire structure\n return deepFreeze(definition)\n}\n","import type { LoopDefinition } from './loop-dsl.js'\n\n// -----------------------------------------------------------------------\n// Error class\n// -----------------------------------------------------------------------\n\n/**\n * Thrown by validateLoop() when the LoopDefinition violates one or more structural rules.\n * violations: every rule violation found, as human-readable strings.\n * The full list is always reported — validateLoop() never fails fast on the first violation.\n */\nexport class LoopValidationError extends Error {\n readonly violations: readonly string[]\n\n constructor(violations: readonly string[]) {\n super(`loop validation failed:\\n${violations.map((v) => ` - ${v}`).join('\\n')}`)\n this.name = 'LoopValidationError'\n this.violations = violations\n }\n}\n\n// -----------------------------------------------------------------------\n// Public API\n// -----------------------------------------------------------------------\n\n/**\n * Validate a LoopDefinition against all structural rules.\n * Collects every violation before throwing, so developers see the full picture.\n *\n * @param def - a LoopDefinition produced by extractLoopDefinition()\n * @throws LoopValidationError if one or more validation rules are violated\n */\nexport function validateLoop(def: LoopDefinition): void {\n const violations: string[] = []\n\n // Build a set of all declared step names once — reuse for rules 6 and 8\n const names = new Set(def.steps.map((s) => s.name))\n\n // -----------------------------------------------------------------------\n // Rule 1 — Every step has at least `run` or `route`\n // -----------------------------------------------------------------------\n for (const step of def.steps) {\n if (step.run === undefined && step.route === undefined) {\n violations.push(`step \"${step.name}\" must have at least one of run or route`)\n }\n }\n\n // -----------------------------------------------------------------------\n // Rule 2 — A step with `route` must have at least one `.on()` transition\n // -----------------------------------------------------------------------\n for (const step of def.steps) {\n if (step.route !== undefined && step.transitions.length === 0) {\n violations.push(`step \"${step.name}\" has route but no .on() transitions — every signal must be handled`)\n }\n }\n\n // -----------------------------------------------------------------------\n // Rule 3 — A step without `route` must have a next target\n // -----------------------------------------------------------------------\n for (const [i, step] of def.steps.entries()) {\n if (step === undefined) continue\n if (step.route === undefined) {\n // Non-last steps have implicit next = the following step; they satisfy rule 3\n // Last step must have explicit next or be unreachable via rule 8\n const isLast = i === def.steps.length - 1\n if (isLast && step.next === undefined) {\n violations.push(\n `step \"${step.name}\" has no route, no explicit .next(), and no following step — no exit path`,\n )\n }\n }\n }\n\n // -----------------------------------------------------------------------\n // Rule 4 — A step cannot have both `route` and `.next()`\n // -----------------------------------------------------------------------\n for (const step of def.steps) {\n if (step.route !== undefined && step.next !== undefined) {\n violations.push(`step \"${step.name}\" has both route and .next() — these are mutually exclusive`)\n }\n }\n\n // -----------------------------------------------------------------------\n // Rule 5 — No duplicate step names\n // -----------------------------------------------------------------------\n const seen = new Set<string>()\n for (const step of def.steps) {\n if (seen.has(step.name)) {\n violations.push(`duplicate step name \"${step.name}\"`)\n }\n seen.add(step.name)\n }\n\n // -----------------------------------------------------------------------\n // Rule 6 — All `.to(name)` targets, `.next()` targets, and `onError` target\n // must reference a declared step\n // -----------------------------------------------------------------------\n for (const step of def.steps) {\n for (const transition of step.transitions) {\n if (transition.target.kind === 'step') {\n if (!names.has(transition.target.name)) {\n violations.push(\n `step \"${step.name}\" has .on(\"${transition.signal}\").to(\"${transition.target.name}\") but step \"${transition.target.name}\" is not declared`,\n )\n }\n }\n }\n\n if (step.next !== undefined) {\n if (!names.has(step.next)) {\n violations.push(\n `step \"${step.name}\" has .next(\"${step.next}\") but step \"${step.next}\" is not declared`,\n )\n }\n }\n }\n\n if (def.onError !== undefined) {\n if (!names.has(def.onError)) {\n violations.push(`onError target \"${def.onError}\" is not a declared step`)\n }\n }\n\n // -----------------------------------------------------------------------\n // Rule 7 — The loop must have an entry (`.start()`) and at least one exit (`.end()`)\n // -----------------------------------------------------------------------\n if (def.startCalled === false) {\n violations.push(`loop is missing .start() — call l.start() before declaring steps`)\n }\n\n if (def.startCalled && def.entryStep === undefined) {\n violations.push(`l.start() was called but no step was declared after it — declare at least one step`)\n }\n\n // Check for at least one exit (.end())\n let hasExit = false\n for (const step of def.steps) {\n for (const transition of step.transitions) {\n if (transition.target.kind === 'end') {\n hasExit = true\n break\n }\n }\n if (hasExit) break\n }\n\n if (!hasExit) {\n violations.push(`loop has no exit — add at least one .on(\"<signal>\").end()`)\n }\n\n // -----------------------------------------------------------------------\n // Rule 8 — No unreachable steps\n // -----------------------------------------------------------------------\n // Only checked if def.entryStep !== undefined (rule 7 covers missing entry)\n if (def.entryStep !== undefined) {\n // BFS from entryStep to find all reachable steps\n const reachable = new Set<string>([def.entryStep])\n const queue: string[] = [def.entryStep]\n\n // Also mark onError target as reachable upfront\n if (def.onError !== undefined) {\n reachable.add(def.onError)\n if (!queue.includes(def.onError)) {\n queue.push(def.onError)\n }\n }\n\n while (queue.length > 0) {\n const currentName = queue.shift()!\n const currentStep = def.steps.find((s) => s.name === currentName)\n\n if (!currentStep) continue\n\n // Add all steps reachable via signal transitions\n for (const transition of currentStep.transitions) {\n if (transition.target.kind === 'step') {\n if (!reachable.has(transition.target.name)) {\n reachable.add(transition.target.name)\n queue.push(transition.target.name)\n }\n }\n }\n\n // Add next target if explicit or implicit\n if (currentStep.route !== undefined) {\n // Step has route, so no implicit next\n if (currentStep.next !== undefined && !reachable.has(currentStep.next)) {\n reachable.add(currentStep.next)\n queue.push(currentStep.next)\n }\n } else {\n // Step has no route: follow explicit next or implicit next\n if (currentStep.next !== undefined) {\n if (!reachable.has(currentStep.next)) {\n reachable.add(currentStep.next)\n queue.push(currentStep.next)\n }\n } else {\n // Implicit next: the following step in def.steps, if any\n const currentIndex = def.steps.findIndex((s) => s.name === currentName)\n if (currentIndex !== -1 && currentIndex < def.steps.length - 1) {\n const nextStep = def.steps[currentIndex + 1]\n if (nextStep !== undefined) {\n const nextStepName = nextStep.name\n if (!reachable.has(nextStepName)) {\n reachable.add(nextStepName)\n queue.push(nextStepName)\n }\n }\n }\n }\n }\n }\n\n // Check for unreachable steps\n for (const step of def.steps) {\n if (!reachable.has(step.name)) {\n violations.push(`step \"${step.name}\" is unreachable from the entry step \"${def.entryStep}\"`)\n }\n }\n }\n\n // -----------------------------------------------------------------------\n // Rule 9 (derived) — A step without `route` must not declare `.on()` signal transitions\n // -----------------------------------------------------------------------\n for (const step of def.steps) {\n if (step.route === undefined && step.transitions.length > 0) {\n violations.push(\n `step \"${step.name}\" has .on() transitions but no route — .on() is only valid when route is set`,\n )\n }\n }\n\n // -----------------------------------------------------------------------\n // Throw if any violations found\n // -----------------------------------------------------------------------\n if (violations.length > 0) {\n throw new LoopValidationError(violations)\n }\n}\n","import type { FieldDefinition, StateFromSchema } from './state-field.js'\nimport type { RequiredMarker, RuntimeMarker, DeepWithMarkers } from './ctx-markers.js'\nimport type { LoopBuilder, LoopDefinition } from '../loop/loop-dsl.js'\nimport { createLoopBuilder, extractLoopDefinition } from '../loop/loop-dsl.js'\nimport { validateLoop } from '../loop/loop-validator.js'\n\n// -----------------------------------------------------------------------\n// Harness type — accumulated at the type level across provide() calls\n// -----------------------------------------------------------------------\n\n/**\n * Immutable builder that accumulates context-slot declarations, store bindings,\n * and the loop definition for an agent. Produced by {@link createHarness} and\n * consumed by {@link createAgent}.\n *\n * The four type parameters track what has been declared so far:\n * - `Ctx` — the full context shape expected by step functions.\n * - `State` — the state record shape derived from the schema passed to `createHarness()`.\n * - `Req` — keys declared as {@link required} (must be supplied to `createAgent`).\n * - `Run` — keys declared as {@link runtime} (must be supplied to `agent.run()`).\n *\n * Each call returns a **new** `Harness` instance; the original is unchanged.\n *\n * @example\n * ```ts\n * const h = createHarness<Ctx>()(schema)\n * .provide('llm', required())\n * .provide('model', 'claude-3-5-haiku-20241022')\n * .store({ session: new InMemorySessionStore() })\n * .loop(l => {\n * l.start().step('run', { run, route }).on('done').end()\n * })\n * ```\n */\nexport type Harness<\n Ctx,\n State,\n Req extends keyof Ctx = never,\n Run extends keyof Ctx = never,\n> = {\n /**\n * Declare a context slot.\n *\n * - Pass {@link required} to require the value at `createAgent()` time.\n * - Pass {@link runtime} to require the value at `agent.run()` time.\n * - Pass any concrete value (or a deep object mixing in markers) to bind it now.\n */\n provide<K extends keyof Ctx>(key: K, value: RequiredMarker): Harness<Ctx, State, Req | K, Run>\n provide<K extends keyof Ctx>(key: K, value: RuntimeMarker): Harness<Ctx, State, Req, Run | K>\n provide<K extends keyof Ctx>(key: K, value: DeepWithMarkers<Ctx[K]>): Harness<Ctx, State, Req, Run>\n\n /**\n * Bind session store(s). Pass `{ session: myStore }` to enable persistence and\n * interrupt/resume across processes.\n */\n // store() Req/Run are not affected at the type level; nested markers are runtime-validated only (F2 spike constraint)\n store(stores: DeepWithMarkers<{ session?: unknown } & Record<string, unknown>>): Harness<Ctx, State, Req, Run>\n\n /**\n * Define the execution loop using the {@link LoopBuilder} DSL.\n *\n * @param builder - Callback that receives a `LoopBuilder` and uses it to\n * declare steps, transitions, and the entry point.\n */\n // loop() parameter is LoopBuilder<State, Ctx> after F4 implementation\n loop(builder: (l: LoopBuilder<State, Ctx>) => void): Harness<Ctx, State, Req, Run>\n\n /**\n * Return the frozen {@link LoopDefinition} captured when {@link loop} was called.\n *\n * @throws {LoopNotDefinedError} if `h.loop()` has not been called on this harness instance.\n */\n definition(): LoopDefinition\n}\n\n// -----------------------------------------------------------------------\n// ProviderEntry — one entry produced by each provide() or store() call\n// -----------------------------------------------------------------------\n\nexport interface ProviderEntry {\n readonly kind: 'provide' | 'store'\n readonly key: string\n readonly value: unknown\n}\n\n// -----------------------------------------------------------------------\n// HarnessInternals — the structural contract between HarnessBuilder and createAgent (F5)\n// -----------------------------------------------------------------------\n\n// _req, _run, _state are type witnesses: never assigned at runtime, carry type-level info to F5\nexport interface HarnessInternals<\n Ctx,\n State,\n Req extends keyof Ctx,\n Run extends keyof Ctx,\n> {\n readonly stateSchema: Record<string, FieldDefinition<unknown>> | undefined\n readonly providers: readonly ProviderEntry[]\n readonly loopDef: LoopDefinition | undefined\n readonly _req: Req | undefined\n readonly _run: Run | undefined\n readonly _state: State | undefined\n}\n\n// -----------------------------------------------------------------------\n// Internal accessor — used by createAgent (F5) to unwrap internals\n// -----------------------------------------------------------------------\n\n// symbol key is module-private; external code cannot read or forge the internals slot\nconst _internals = Symbol('_internals')\n\nexport type HarnessWithInternals<\n Ctx,\n State,\n Req extends keyof Ctx,\n Run extends keyof Ctx,\n> = Harness<Ctx, State, Req, Run> & {\n readonly [_internals]: HarnessInternals<Ctx, State, Req, Run>\n}\n\nexport function getInternals<\n Ctx,\n State,\n Req extends keyof Ctx,\n Run extends keyof Ctx,\n>(harness: Harness<Ctx, State, Req, Run>): HarnessInternals<Ctx, State, Req, Run> {\n if (harness === null || typeof harness !== 'object' || !(_internals in harness)) {\n throw new HarnessInternalsError()\n }\n return (harness as HarnessWithInternals<Ctx, State, Req, Run>)[_internals] // as: `_internals in harness` check above guarantees the symbol key is present\n}\n\n// -----------------------------------------------------------------------\n// Error class\n// -----------------------------------------------------------------------\n\n/** @internal Thrown when {@link getInternals} is called on a non-harness value. */\nexport class HarnessInternalsError extends Error {\n constructor() {\n super('value is not a HarnessBuilder instance — was it created by createHarness?')\n this.name = 'HarnessInternalsError'\n }\n}\n\n/**\n * Thrown by {@link Harness.definition} when `h.loop()` has not been called yet.\n */\nexport class LoopNotDefinedError extends Error {\n constructor() {\n super('loop is not defined — call h.loop() before accessing h.definition()')\n this.name = 'LoopNotDefinedError'\n }\n}\n\n// -----------------------------------------------------------------------\n// createHarness — the public factory\n// -----------------------------------------------------------------------\n\n/**\n * Create a harness builder for the given context type.\n *\n * Call the returned function (optionally with a state schema) to get the\n * {@link Harness} builder on which you chain `.provide()`, `.store()`, and `.loop()`.\n *\n * @example\n * ```ts\n * interface Ctx { llm: LLM; model: string }\n * const schema = { messages: field<string[]>({ default: () => [] }) }\n *\n * const h = createHarness<Ctx>()(schema)\n * ```\n */\nexport function createHarness<Ctx = any>(): <S extends object = {}>( // any: allows createHarness() without an explicit Ctx type parameter\n stateSchema?: S,\n) => Harness<Ctx, StateFromSchema<S>> {\n return <S extends object = {}>(stateSchema?: S): Harness<Ctx, StateFromSchema<S>> => {\n const internals: HarnessInternals<Ctx, StateFromSchema<S>, never, never> = {\n stateSchema: stateSchema as Record<string, FieldDefinition<unknown>> | undefined, // as: S extends object; cast to internal schema representation\n providers: Object.freeze([]),\n loopDef: undefined,\n _req: undefined,\n _run: undefined,\n _state: undefined,\n }\n\n return createBuilderInstance(internals)\n }\n}\n\nfunction createBuilderInstance<\n Ctx,\n State,\n Req extends keyof Ctx = never,\n Run extends keyof Ctx = never,\n>(internals: HarnessInternals<Ctx, State, Req, Run>): HarnessWithInternals<Ctx, State, Req, Run> {\n const builder: any = { // any: TypeScript cannot infer overloaded call signatures from object literal method definitions\n provide<K extends keyof Ctx>(\n key: K,\n value: RequiredMarker | RuntimeMarker | DeepWithMarkers<Ctx[K]>,\n ): Harness<Ctx, State, any, any> { // any: Req/Run accumulation is tracked at the type level via overloads; method body uses any to avoid inference conflicts\n const newProviders = Object.freeze([\n ...internals.providers,\n { kind: 'provide' as const, key: String(key), value },\n ])\n const newInternals: HarnessInternals<Ctx, State, any, any> = { // any: same reason as return type annotation above\n stateSchema: internals.stateSchema,\n providers: newProviders,\n loopDef: internals.loopDef,\n _req: undefined,\n _run: undefined,\n _state: undefined,\n }\n return createBuilderInstance(newInternals)\n },\n\n store(stores: DeepWithMarkers<{ session?: unknown } & Record<string, unknown>>): Harness<Ctx, State, Req, Run> {\n const newProviders = Object.freeze([\n ...internals.providers,\n { kind: 'store' as const, key: '__store__', value: stores },\n ])\n const newInternals: HarnessInternals<Ctx, State, Req, Run> = {\n stateSchema: internals.stateSchema,\n providers: newProviders,\n loopDef: internals.loopDef,\n _req: undefined,\n _run: undefined,\n _state: undefined,\n }\n return createBuilderInstance(newInternals)\n },\n\n loop(builderFn: (l: LoopBuilder<State, Ctx>) => void): Harness<Ctx, State, Req, Run> {\n const lb = createLoopBuilder<State, Ctx>()\n builderFn(lb)\n const def = extractLoopDefinition(lb as LoopBuilder<unknown, unknown>) // as: generic S/Ctx erased for internal storage\n validateLoop(def)\n const newInternals: HarnessInternals<Ctx, State, Req, Run> = {\n stateSchema: internals.stateSchema,\n providers: internals.providers,\n loopDef: def,\n _req: undefined,\n _run: undefined,\n _state: undefined,\n }\n return createBuilderInstance(newInternals)\n },\n\n definition(): LoopDefinition {\n if (internals.loopDef === undefined) {\n throw new LoopNotDefinedError()\n }\n return internals.loopDef\n },\n\n [_internals]: internals,\n }\n\n return builder\n}\n","// -----------------------------------------------------------------------\n// InterruptPause — internal control-flow signal between ctx-interrupt and loop-executor\n// -----------------------------------------------------------------------\n\nexport class InterruptPause extends Error {\n readonly interruptId: string\n readonly prompt: unknown\n\n constructor(interruptId: string, prompt: unknown) {\n super(`interrupt requested for id \"${interruptId}\"`)\n this.name = 'InterruptPause'\n this.interruptId = interruptId\n this.prompt = prompt\n }\n}\n\n// -----------------------------------------------------------------------\n// isInterruptPause — type guard used by runLoop\n// -----------------------------------------------------------------------\n\nexport function isInterruptPause(error: unknown): error is InterruptPause {\n return error instanceof InterruptPause\n}\n\n// -----------------------------------------------------------------------\n// createInterruptFn — factory for ctx.interrupt()\n// -----------------------------------------------------------------------\n\nexport function createInterruptFn(\n state: Record<string, unknown>,\n callCountRef: { current: number },\n): (prompt: unknown, id?: string) => Promise<unknown> {\n return async (prompt: unknown, id?: string): Promise<unknown> => {\n const isAutoId = id === undefined\n const effectiveId = isAutoId ? `$auto:${callCountRef.current}` : id\n\n // only auto-id calls increment the counter\n if (isAutoId) {\n callCountRef.current++\n }\n\n const responses = state.$interruptResponses as Record<string, unknown>\n\n if (effectiveId in responses) {\n return responses[effectiveId]\n }\n\n state.$interrupt = { interruptId: effectiveId, prompt }\n throw new InterruptPause(effectiveId, prompt)\n }\n}\n","import type { Observer, StepContext } from './observer.js'\n\n/**\n * Create the ctx.emit function for a single runLoop invocation.\n * Returns a synchronous, fire-and-forget dispatcher.\n * Fires the matching listener (if registered) AND observer.onEvent (if observer\n * is set and stepCtxRef.current is non-null) independently for each call.\n */\nexport function createEmitFn(\n listeners: Record<string, (payload: unknown) => void>,\n observer?: Observer,\n stepCtxRef?: { current: StepContext | null },\n): (name: string, payload?: unknown) => void {\n return (name: string, payload?: unknown): void => {\n listeners[name]?.(payload)\n if (observer !== undefined && stepCtxRef !== undefined && stepCtxRef.current !== null) {\n observer.onEvent?.(stepCtxRef.current, name, payload)\n }\n }\n}\n\n/**\n * Extract the listeners map from agent.run() resources.\n * Returns an empty object if the 'listeners' key is absent or not a plain object.\n */\nexport function extractRunListeners(\n resources: Record<string, unknown>,\n): Record<string, (payload: unknown) => void> {\n const raw = resources['listeners']\n if (raw === null || typeof raw !== 'object' || Array.isArray(raw)) {\n return {}\n }\n // plain object: return as-is; listener values are not validated\n return raw as Record<string, (payload: unknown) => void> // as: duck-typed plain object confirmed above; values are caller's responsibility\n}\n","import type { LoopDefinition } from '../loop/loop-dsl.js'\nimport type { FieldDefinition } from '../harness/state-field.js'\nimport type { Observer, RunContext, StepContext } from '../agent/observer.js'\nimport { createInterruptFn, isInterruptPause } from '../agent/ctx-interrupt.js'\nimport { createEmitFn } from '../agent/ctx-emit.js'\n\n// -----------------------------------------------------------------------\n// LoopResult\n// -----------------------------------------------------------------------\n\nexport interface LoopResult {\n readonly state: Record<string, unknown>\n readonly signal: string | null\n readonly cursor: string | null\n readonly paused: boolean\n}\n\n// -----------------------------------------------------------------------\n// Error classes\n// -----------------------------------------------------------------------\n\nexport class UnknownSignalError extends Error {\n readonly step: string\n readonly signal: string\n constructor(step: string, signal: string) {\n super(`step \"${step}\" emitted signal \"${signal}\" with no matching .on() transition`)\n this.name = 'UnknownSignalError'\n this.step = step\n this.signal = signal\n }\n}\n\nexport class NoNextStepError extends Error {\n readonly step: string\n constructor(step: string) {\n super(\n `step \"${step}\" has no route, no explicit next, and is the last declared step — execution cannot continue`,\n )\n this.name = 'NoNextStepError'\n this.step = step\n }\n}\n\n// -----------------------------------------------------------------------\n// Private helpers\n// -----------------------------------------------------------------------\n\nfunction buildImplicitNextMap(graph: LoopDefinition): Map<string, string | null> {\n const map = new Map<string, string | null>()\n for (let i = 0; i < graph.steps.length; i++) {\n const step = graph.steps[i]!\n const next = i + 1 < graph.steps.length ? graph.steps[i + 1]!.name : null\n map.set(step.name, next)\n }\n return map\n}\n\nfunction applyUpdate(\n state: Record<string, unknown>,\n update: Record<string, unknown>,\n schema: Record<string, FieldDefinition<any>> | undefined, // any: FieldDefinition uses invariant T; any is required for heterogeneous schema maps\n): void {\n for (const [key, value] of Object.entries(update)) {\n if (key === '$error' || key === '$interrupt' || key === '$interruptResponses') continue\n const reducer = schema?.[key]?.reduce\n if (reducer !== undefined) {\n state[key] = reducer(state[key], value)\n } else {\n state[key] = value\n }\n }\n}\n\n// -----------------------------------------------------------------------\n// Public API\n// -----------------------------------------------------------------------\n\nexport interface LoopCallbacks {\n onBeforeStep?: (name: string, state: Record<string, unknown>) => void\n onAfterStep?: (name: string, state: Record<string, unknown>) => void\n onError?: (error: unknown, stepName: string) => void\n onComplete?: (state: Record<string, unknown>, signal: string) => void\n onInterrupt?: (prompt: unknown, interruptId: string) => void\n /**\n * Listeners for user-emitted events (ctx.emit). Keyed by event name.\n * A missing key means ctx.emit(name) is a no-op for that name.\n */\n listeners?: Record<string, (payload: unknown) => void>\n /** Observer for structured telemetry. All lifecycle methods are optional. F16b. */\n observer?: Observer\n /**\n * The UUID for this specific invocation. Included in RunContext for observer\n * methods. Absent when no observer is active (observer is still consistent).\n */\n runId?: string\n /**\n * Optional parent run UUID for cross-process trace correlation.\n * Included in RunContext when provided.\n */\n parentRunId?: string\n /**\n * Pre-filtered list of ObserverAware slots that expose setStepContext.\n * The loop calls slot.setStepContext(stepCtx) for each entry at every step\n * start, before invoking step.run. F36.\n */\n setStepContextSlots?: ReadonlyArray<{ setStepContext(ctx: StepContext): void }>\n}\n\nexport async function runLoop(\n graph: LoopDefinition,\n state: Record<string, unknown>,\n ctx: Record<string, unknown> & { readonly agentId: string; readonly sessionId: string },\n schema: Record<string, FieldDefinition<any>> | undefined, // any: see applyUpdate comment\n shouldStop?: () => boolean,\n startCursor?: string,\n callbacks?: LoopCallbacks,\n): Promise<LoopResult> {\n const { onBeforeStep, onAfterStep, onError, onComplete, onInterrupt } = callbacks ?? {}\n const obs = callbacks?.observer\n const implicitNextMap = buildImplicitNextMap(graph)\n\n // Initialize framework-reserved fields if absent\n if (!('$error' in state)) state.$error = null\n if (!('$interrupt' in state)) state.$interrupt = null\n if (!('$interruptResponses' in state)) state.$interruptResponses = {}\n\n const runStart = Date.now()\n const runCtx: RunContext = {\n agentId: ctx.agentId,\n sessionId: ctx.sessionId,\n runId: typeof callbacks?.runId === 'string' ? callbacks.runId : '',\n ...(typeof callbacks?.parentRunId === 'string' ? { parentRunId: callbacks.parentRunId } : {}),\n ...(typeof ctx.instanceId === 'string' ? { instanceId: ctx.instanceId } : {}),\n }\n obs?.onRunStart?.(runCtx)\n\n // callCountRef is shared between createInterruptFn and the per-step reset below\n const callCountRef = { current: 0 }\n const stepCtxRef: { current: StepContext | null } = { current: null }\n // mutate ctx in-place so step.run receives the same object reference (invariant for callers)\n ;(ctx as Record<string, unknown>)['interrupt'] = createInterruptFn(state, callCountRef) // as: Record<string, unknown> allows adding framework-injected fields to ctx\n ;(ctx as Record<string, unknown>)['emit'] = createEmitFn(callbacks?.listeners ?? {}, obs, stepCtxRef) // as: see interrupt line comment\n\n let cursor = startCursor ?? graph.entryStep!\n\n while (true) {\n if (shouldStop?.()) {\n obs?.onRunEnd?.(runCtx, { signal: '$stopped', durationMs: Date.now() - runStart })\n return { state, signal: null, cursor, paused: true }\n }\n\n // pass a shallow snapshot so onBeforeStep observers see pre-run values even after state is mutated\n onBeforeStep?.(cursor, { ...state })\n\n const step = graph.steps.find(s => s.name === cursor)!\n\n // reset per-step counter before run (even for decision nodes, per design)\n callCountRef.current = 0\n\n const stepCtx: StepContext = { agentId: ctx.agentId, sessionId: ctx.sessionId, stepName: cursor }\n stepCtxRef.current = stepCtx\n const stepStart = Date.now()\n obs?.onStepStart?.(stepCtx)\n if (callbacks?.setStepContextSlots !== undefined) {\n for (const slot of callbacks.setStepContextSlots) {\n slot.setStepContext(stepCtx)\n }\n }\n\n let runSucceeded = false\n\n if (step.run !== undefined) {\n // capture whether responses exist before the run; only clear interrupt state if they did\n const hadResponses = Object.keys(state.$interruptResponses as Record<string, unknown>).length > 0\n try {\n const update = await step.run(\n state as unknown as Parameters<typeof step.run>[0],\n ctx as Parameters<typeof step.run>[1],\n )\n applyUpdate(state, update as Record<string, unknown>, schema)\n // clear interrupt state only after a step that had stored responses to replay\n if (hadResponses) {\n state.$interrupt = null\n state.$interruptResponses = {}\n }\n runSucceeded = true\n } catch (e) {\n if (isInterruptPause(e)) {\n // InterruptPause was caught: $interrupt already written by createInterruptFn\n onInterrupt?.(e.prompt, e.interruptId)\n obs?.onInterrupt?.(stepCtx, { prompt: e.prompt, interruptId: e.interruptId })\n obs?.onRunEnd?.(runCtx, { signal: '$interrupt', durationMs: Date.now() - runStart })\n return { state, signal: '$interrupt', cursor, paused: true }\n }\n // domain error: normalize to Error and set $error; do not rethrow\n state.$error = e instanceof Error ? e : new Error(String(e))\n onError?.(state.$error, cursor)\n obs?.onStepError?.(stepCtx, { error: state.$error, durationMs: Date.now() - stepStart })\n }\n }\n\n if (runSucceeded) {\n // clear $error after a successful run, before calling route\n state.$error = null\n onAfterStep?.(cursor, state)\n obs?.onStepEnd?.(stepCtx, { durationMs: Date.now() - stepStart })\n }\n\n // route is called when: route exists AND (run succeeded, step has no run, OR step opted in\n // to error routing via optin: '$error' in the step config)\n const callRoute =\n step.route !== undefined &&\n (runSucceeded || step.run === undefined || step.errorAware)\n\n if (callRoute) {\n // callRoute implies step.route !== undefined; non-null assertion is sound here\n const routeFn = step.route!\n let signal: string\n try {\n signal = routeFn(state as unknown as Parameters<typeof routeFn>[0])\n } catch (e) {\n // route itself threw — treat as terminal error; state update from run already stands\n state.$error = e instanceof Error ? e : new Error(String(e))\n obs?.onRunEnd?.(runCtx, { signal: '$error', durationMs: Date.now() - runStart })\n return { state, signal: '$error', cursor, paused: true }\n }\n const transition = step.transitions.find(t => t.signal === signal)\n if (transition === undefined) {\n throw new UnknownSignalError(cursor, signal)\n }\n if (transition.target.kind === 'end') {\n onComplete?.(state, signal)\n obs?.onRunEnd?.(runCtx, { signal, durationMs: Date.now() - runStart })\n return { state, signal, cursor: null, paused: false }\n }\n cursor = transition.target.name\n } else if (step.run !== undefined && !runSucceeded) {\n // run threw, route bypassed (not error-aware) or no route: apply l.onError() fallback or pause\n if (graph.onError !== undefined) {\n cursor = graph.onError\n } else {\n obs?.onRunEnd?.(runCtx, { signal: '$error', durationMs: Date.now() - runStart })\n return { state, signal: '$error', cursor, paused: true }\n }\n } else {\n const next = step.next ?? implicitNextMap.get(cursor) ?? null\n if (next === null) {\n throw new NoNextStepError(cursor)\n }\n cursor = next\n }\n }\n}\n","type SchemaLike = Record<string, {\n readonly default?: (() => unknown) | undefined\n // any on reduce params: function parameter contravariance means typed reducers (e.g. (current: string[]) => string[])\n // are not assignable to (current: unknown) => unknown; any erases the bound safely for runtime use\n readonly reduce?: ((current: any, next: any) => unknown) | undefined // any: see above\n}>\n\n// -----------------------------------------------------------------------\n// ClaimOptions — lease duration passed to claim() and extendClaim()\n// -----------------------------------------------------------------------\n\n/**\n * Options passed to {@link SessionStore.claim}.\n *\n * `ttlMs` is the initial lease duration in milliseconds. The claim expires\n * if not renewed within this window — enabling crash recovery by other instances.\n */\nexport interface ClaimOptions {\n /** Lease duration in milliseconds. Must be a positive integer. */\n readonly ttlMs: number\n}\n\n// -----------------------------------------------------------------------\n// Lease — distributed lease handle returned by claim() and extendClaim()\n// -----------------------------------------------------------------------\n\n/**\n * A successfully acquired distributed lease on a session.\n *\n * Returned by {@link SessionStore.claim} when no other instance holds the\n * session. The framework holds this object for the duration of the run and\n * passes it to {@link SessionStore.release} and {@link SessionStore.extendClaim}.\n */\nexport interface Lease {\n /**\n * Wall-clock expiry timestamp (milliseconds since epoch).\n * The framework checks `Date.now() >= lease.expiresAt` at each step boundary\n * to detect TTL expiry without contacting the store.\n */\n readonly expiresAt: number\n /**\n * The `agentId` this lease was issued for.\n * Stored in the claim record for stuck-lease diagnosis.\n */\n readonly agentId: string\n /**\n * The `sessionId` this lease covers.\n */\n readonly sessionId: string\n /**\n * The `instanceId` of the holder, if provided to `createAgent()`.\n * Written into the store's claim record for operational diagnostics.\n * Absent when `instanceId` was not configured.\n */\n readonly instanceId?: string\n /**\n * Store-implementation-specific token — e.g. a Redis key name, a lock token,\n * or a database row ID. Opaque to the framework; passed back unmodified on\n * `release` and `extendClaim` calls so the store can locate the record.\n */\n readonly token: unknown\n}\n\n// -----------------------------------------------------------------------\n// StoredRunMetadata — operational metadata written into StoredRun\n// -----------------------------------------------------------------------\n\n/**\n * Operational metadata written by the framework into every {@link StoredRun}.\n *\n * The framework writes only `instanceId`. All other fields are reserved for\n * domain-specific operational annotations (tenantId, region, requestId, etc.).\n */\nexport interface StoredRunMetadata {\n /** The `instanceId` of the instance that produced this run. Absent when not configured. */\n instanceId?: string\n /** Open extension point — domain-specific fields. */\n [key: string]: unknown\n}\n\n// -----------------------------------------------------------------------\n// SessionStore — the persistence contract\n// -----------------------------------------------------------------------\n\n/**\n * Persistence contract for agent sessions.\n *\n * Implementations must be safe to call concurrently for **different** sessions;\n * concurrent calls for the **same** session are prevented by the harness concurrency guards.\n *\n * `loadHistory` and `branch` are optional extensions:\n * - `loadHistory` — full run history for a session (used by branching and debugging tools).\n * - `branch` — fork a session at a specific past run, returning a new session ID.\n */\nexport interface SessionStore {\n /**\n * Load the most recent {@link StoredRun} for the given session, or `null` if\n * the session has never been saved.\n */\n load(agentId: string, sessionId: string): Promise<StoredRun | null>\n\n /**\n * Persist a run record as a conditional write.\n *\n * Implementations must compare `run.version` against the version of the\n * currently stored record before writing:\n * - If the stored version equals `run.version - 1` (or there is no stored\n * record and `run.version === 0`), the write succeeds.\n * - Otherwise, another writer committed a newer version concurrently — the\n * implementation must throw `ConcurrentModificationError`.\n */\n save(agentId: string, sessionId: string, run: StoredRun): Promise<void>\n\n /**\n * Return the full ordered run history for a session, oldest first.\n * Optional — omit if your store does not support history.\n */\n loadHistory?(agentId: string, sessionId: string): Promise<StoredRun[]>\n\n /**\n * Fork the session at the state captured by `runId`, returning a new session ID\n * whose initial state equals the forked run's `finalState`.\n * Optional — omit if your store does not support branching.\n *\n * @throws {@link BranchNotFoundError} when `runId` is not found in history.\n */\n branch?(agentId: string, sessionId: string, runId: string): Promise<string>\n\n /**\n * Attempt to acquire a distributed claim on the session before starting a run.\n *\n * - Returns a {@link Lease} when the claim is acquired.\n * - Returns `null` when another instance already holds the claim — the framework\n * throws {@link SessionBusyError} immediately without starting any LLM work.\n *\n * Optional — stores that do not support distributed locking omit this method.\n * The framework checks for its presence before calling it.\n */\n claim?(agentId: string, sessionId: string, options: ClaimOptions): Promise<Lease | null>\n\n /**\n * Release a held claim after the run settles.\n *\n * Called by the framework after `save()` completes (or after an error that\n * prevents saving). Stores may use this to remove the lock record immediately\n * rather than waiting for TTL expiry.\n *\n * Optional — omit if your store does not support claim/release.\n */\n release?(lease: Lease): Promise<void>\n\n /**\n * Extend the TTL of an active claim.\n *\n * Called by `ctx.keepAlive()` (both one-shot and background interval modes).\n * The store must update `expiresAt` on the claim record; the new expiry is\n * `Date.now() + options.ttlMs`. The returned `Lease` object carries the updated\n * `expiresAt`; the framework replaces its held reference with the returned value.\n *\n * Optional — omit if your store does not support claim/release.\n */\n extendClaim?(lease: Lease, options: ClaimOptions): Promise<Lease>\n}\n\n// -----------------------------------------------------------------------\n// StoredRun — the per-run serialized record (replaces StoredSession)\n// -----------------------------------------------------------------------\n\n/**\n * Serializable snapshot of a single agent run, written to the store after\n * every run settles (either `'paused'` on an interrupt or `'completed'`).\n *\n * - `phase: 'paused'` — the run paused on an interrupt; `step` is the step that\n * issued the interrupt and `signal` is `'$interrupt'`.\n * - `phase: 'completed'` — the loop exited normally; `signal` holds the exit\n * signal (or is absent when the loop ended without emitting a signal).\n */\nexport interface StoredRun {\n readonly agentId: string\n readonly runId: string\n readonly sessionId: string\n readonly version: number\n readonly startedAt: string\n readonly settledAt: string\n readonly phase: 'paused' | 'completed'\n readonly initialState: Record<string, unknown>\n readonly finalState: Record<string, unknown>\n readonly signal?: string\n readonly step?: string\n /**\n * Operational metadata written by the framework.\n *\n * The framework writes `instanceId` when configured; all other fields are\n * domain-defined. Absent for runs produced before this field was added.\n */\n readonly metadata?: StoredRunMetadata\n}\n\n// -----------------------------------------------------------------------\n// SessionPhase — the agent.status() query result\n// -----------------------------------------------------------------------\n\n/**\n * Discriminated union returned by {@link Agent.status} describing the lifecycle\n * phase of a session.\n *\n * - `'fresh'` — no run has been stored yet.\n * - `'in-flight'` — a run is currently executing (in-process guard only; not\n * detectable cross-process from the store alone).\n * - `'paused'` — the last run settled on an interrupt; `step` identifies the\n * step that issued the interrupt.\n * - `'completed'` — the last run exited the loop; `signal` is the exit signal.\n */\nexport type SessionPhase =\n | { readonly phase: 'fresh' }\n | { readonly phase: 'in-flight'; readonly step: null }\n | { readonly phase: 'paused'; readonly signal?: string; readonly step: string }\n | { readonly phase: 'completed'; readonly signal?: string }\n\n// -----------------------------------------------------------------------\n// storedSessionToPhase — converts a raw load result to SessionPhase\n// -----------------------------------------------------------------------\n\nexport function storedSessionToPhase(loaded: StoredRun | null): SessionPhase {\n if (loaded === null) {\n return { phase: 'fresh' }\n }\n\n if (loaded.phase === 'paused') {\n const step = loaded.step ?? ''\n if (loaded.signal !== undefined) {\n return { phase: 'paused', step, signal: loaded.signal }\n }\n return { phase: 'paused', step }\n }\n\n // completed\n if (loaded.signal !== undefined) {\n return { phase: 'completed', signal: loaded.signal }\n }\n return { phase: 'completed' }\n}\n\n// -----------------------------------------------------------------------\n// initializeState — state merge for fresh sessions and resumptions\n// -----------------------------------------------------------------------\n\nexport function initializeState(\n stored: StoredRun | null,\n initialStateArg: Record<string, unknown>,\n schema: SchemaLike | undefined,\n): Record<string, unknown> {\n const argKeys = new Set(Object.keys(initialStateArg))\n\n if (stored === null) {\n return buildFreshState(initialStateArg, argKeys, schema)\n }\n\n return buildResumedState(stored, initialStateArg, argKeys, schema)\n}\n\nfunction buildFreshState(\n initialStateArg: Record<string, unknown>,\n argKeys: Set<string>,\n schema: SchemaLike | undefined,\n): Record<string, unknown> {\n const result: Record<string, unknown> = { ...initialStateArg }\n\n if (schema === undefined || Object.keys(schema).length === 0) {\n return result\n }\n\n for (const key of Object.keys(schema)) {\n if (argKeys.has(key)) {\n // initialStateArg wins — already in result via spread\n continue\n }\n const field = schema[key]\n if (field !== undefined && field.default !== undefined) {\n result[key] = field.default()\n }\n }\n\n return result\n}\n\nfunction buildResumedState(\n stored: StoredRun,\n initialStateArg: Record<string, unknown>,\n argKeys: Set<string>,\n schema: SchemaLike | undefined,\n): Record<string, unknown> {\n const result: Record<string, unknown> = { ...stored.finalState }\n\n // Apply initialStateArg fields on top of stored state\n for (const key of argKeys) {\n const fieldDef = schema?.[key]\n if (fieldDef?.reduce !== undefined) {\n result[key] = fieldDef.reduce(stored.finalState[key], initialStateArg[key])\n } else {\n result[key] = initialStateArg[key]\n }\n }\n\n // Apply schema defaults for keys absent from both stored.finalState and initialStateArg\n if (schema !== undefined) {\n for (const key of Object.keys(schema)) {\n if (argKeys.has(key)) continue\n if (key in stored.finalState) continue\n const field = schema[key]\n if (field !== undefined && field.default !== undefined) {\n result[key] = field.default()\n }\n }\n }\n\n return result\n}\n","/**\n * Thrown by {@link Agent.run} or {@link Agent.resume} when the given session\n * is already executing a run in the same process.\n *\n * Wait for the in-flight {@link RunHandle} to settle before starting a new run.\n */\nexport class SessionInFlightError extends Error {\n /** The session that was already in-flight. */\n readonly sessionId: string\n\n constructor(sessionId: string) {\n super(`session \"${sessionId}\" is already in-flight`)\n this.name = 'SessionInFlightError'\n this.sessionId = sessionId\n }\n}\n\n/**\n * Thrown by {@link Agent.run} when the session is paused on an unanswered\n * interrupt. Call {@link Agent.resume} (or `handle.resume()`) instead.\n */\nexport class SessionPendingInterruptError extends Error {\n /** The session that is awaiting an interrupt response. */\n readonly sessionId: string\n\n constructor(sessionId: string) {\n super(`session \"${sessionId}\" is paused on an interrupt — use agent.resume() instead of agent.run()`)\n this.name = 'SessionPendingInterruptError'\n this.sessionId = sessionId\n }\n}\n\n/**\n * Thrown by the harness when the session store's `load()` call rejects.\n * The original error is available on the `cause` property.\n */\nexport class StoreLoadError extends Error {\n readonly cause: unknown\n\n constructor(cause: unknown) {\n super('session store failed to load session')\n this.name = 'StoreLoadError'\n this.cause = cause\n }\n}\n\n/**\n * Thrown by {@link Agent.run} when `store.claim()` returns `null` —\n * another instance already holds the session claim.\n *\n * The caller may inspect `retryAfter` to implement a `429 Retry-After`\n * response or a retry backoff. How to respond is not the framework's concern.\n */\nexport class SessionBusyError extends Error {\n /** The session that is currently claimed by another instance. */\n readonly sessionId: string\n /**\n * Hint: earliest time (milliseconds since epoch) when a retry may succeed.\n * Derived from the original claim's `expiresAt`. Present when the store\n * includes expiry information in a busy response; absent otherwise.\n */\n // declare: avoids useDefineForClassFields emitting an undefined own property initializer;\n // the field is only written when retryAfter is provided (exactOptionalPropertyTypes guard)\n declare readonly retryAfter?: number\n\n constructor(sessionId: string, retryAfter?: number) {\n super(`session \"${sessionId}\" is currently claimed by another instance`)\n this.name = 'SessionBusyError'\n this.sessionId = sessionId\n // conditional assignment: avoids producing retryAfter: undefined as an own property\n // which exactOptionalPropertyTypes forbids at call sites\n if (retryAfter !== undefined) this.retryAfter = retryAfter\n }\n}\n\n/**\n * Thrown by the framework at a step boundary when the active lease has expired\n * without renewal.\n *\n * The run stops without saving state — the session remains at its last\n * checkpoint, allowing another instance to claim and resume it.\n */\nexport class LeaseExpiredError extends Error {\n /** The session whose lease expired. */\n readonly sessionId: string\n\n constructor(sessionId: string) {\n super(`lease for session \"${sessionId}\" has expired — run stopped without saving`)\n this.name = 'LeaseExpiredError'\n this.sessionId = sessionId\n }\n}\n\n","import type { SessionStore, Lease } from './session-store.js'\n\n/**\n * A mutable reference to the currently held lease.\n * `null` when claim/lease is not in use (no-store or store without claim()).\n * Updated in-place by `extendClaim()` responses.\n */\nexport type LeaseRef = { current: Lease | null }\n\n/**\n * Options for background renewal mode.\n */\nexport interface KeepAliveOptions {\n /**\n * Renewal interval in milliseconds. A background timer calls\n * `store.extendClaim()` at this cadence.\n * Must be less than the original claim `ttlMs` to ensure renewal\n * reaches the store before expiry.\n */\n readonly every: number\n}\n\n/**\n * The stop function returned by `ctx.keepAlive({ every })`.\n * Always call this in a `finally` block to cancel the background timer.\n */\nexport type StopFn = () => void\n\n/**\n * The `ctx.keepAlive` function type injected into the step ctx.\n *\n * - Called with no arguments: one-shot TTL extension. Returns a Promise.\n * - Called with `{ every: ms }`: starts a background interval renewal timer.\n * Returns a `StopFn` synchronously.\n */\nexport type KeepAliveFn =\n ((() => Promise<void>) & ((options: KeepAliveOptions) => StopFn))\n\n/**\n * Create the `ctx.keepAlive` function for a single run.\n *\n * @param leaseRef - Mutable reference to the active lease.\n * @param store - The session store, or `undefined` when no store configured.\n * @param originalTtlMs - The `ttlMs` from the `ClaimOptions` used in the initial claim.\n * @returns The `keepAlive` function to inject into step `ctx`.\n */\nexport function createKeepAliveFn(\n leaseRef: LeaseRef,\n store: SessionStore | undefined,\n originalTtlMs: number,\n): KeepAliveFn {\n function keepAlive(options?: KeepAliveOptions): Promise<void> | StopFn {\n const isBackground = typeof options === 'object' && options !== null && 'every' in options\n const extendClaim = store?.extendClaim\n\n if (isBackground) {\n // background renewal mode\n if (leaseRef.current === null || typeof extendClaim !== 'function') {\n // no-op: no active lease or store doesn't support extendClaim\n return noopStop\n }\n\n let handle: ReturnType<typeof setInterval> | null = setInterval(() => {\n if (leaseRef.current === null) {\n // lease was released after timer started — skip but keep timer running\n return\n }\n // swallow errors — timer must continue regardless of extendClaim failures\n void (async () => {\n try {\n const renewed = await extendClaim.call(store, leaseRef.current!, { ttlMs: originalTtlMs })\n leaseRef.current = renewed\n } catch {\n /* swallow: expiry check at step boundary is the safety net */\n }\n })()\n }, options.every)\n\n return function stop() {\n if (handle !== null) {\n clearInterval(handle)\n handle = null\n }\n }\n }\n\n // one-shot mode\n if (leaseRef.current === null || typeof extendClaim !== 'function') {\n return Promise.resolve()\n }\n\n const snapshot = leaseRef.current\n return (async () => {\n const renewed = await extendClaim.call(store, snapshot, { ttlMs: originalTtlMs })\n leaseRef.current = renewed\n })()\n }\n\n // as: overloaded function — runtime discriminates on options presence\n return keepAlive as KeepAliveFn\n}\n\nfunction noopStop(): void {\n // no-op stop: no timer was started\n}\n","import type { FieldDefinition } from '../harness/state-field.js'\nimport type { ProviderEntry } from '../harness/harness-builder.js'\nimport type { LoopDefinition } from '../loop/loop-dsl.js'\nimport type { LoopResult } from '../loop/loop-executor.js'\nimport { runLoop } from '../loop/loop-executor.js'\nimport type { Observer, StepContext } from './observer.js'\nimport {\n type SessionStore,\n type StoredRun,\n type StoredRunMetadata,\n type SessionPhase,\n initializeState,\n storedSessionToPhase,\n} from './session-store.js'\nimport { StoreLoadError, LeaseExpiredError } from './concurrency-errors.js'\nimport { createKeepAliveFn, type LeaseRef } from './ctx-keep-alive.js'\n\n// -----------------------------------------------------------------------\n// SessionRunOptions — optional parameters for runWithSession\n// -----------------------------------------------------------------------\n\nexport interface SessionRunOptions {\n /** Checked at the top of each loop iteration; returning true halts the run. */\n readonly shouldStop?: () => boolean\n /**\n * Called if the session store fails. `phase` is `'load'` (store failed at run start),\n * `'persist'` (store failed at run end/pause), or `'claim'` (claim returned null or threw).\n * Run result is still returned when phase is 'persist'.\n */\n readonly onStoreError?: (error: unknown, phase: 'load' | 'persist' | 'claim') => void\n /** Called just before each step executes. Used by RunHandle to track currentStep and fire onBeforeStep. */\n readonly onBeforeStep?: (name: string, state: Record<string, unknown>) => void\n /** Called after a step's run completes successfully and applyUpdate has been applied. */\n readonly onAfterStep?: (name: string, state: Record<string, unknown>) => void\n /** Called immediately when a step's run throws a non-interrupt error, before error routing. */\n readonly onError?: (error: unknown, stepName: string) => void\n /** Called when the loop exits via .on(signal).end() (paused: false). */\n readonly onComplete?: (state: Record<string, unknown>, signal: string) => void\n /** Called when ctx.interrupt() pauses the run (isInterruptPause is true). */\n readonly onInterrupt?: (prompt: unknown, interruptId: string) => void\n /** Listeners for user-emitted events (ctx.emit). Keyed by event name. */\n readonly listeners?: Record<string, (payload: unknown) => void>\n /** Structured telemetry observer for this run. All methods optional. F16b. */\n readonly observer?: Observer\n /**\n * Active lease reference. The factory closes over this ref; it is updated\n * in-place by `extendClaim()` calls. Absent when no claim is in use.\n */\n readonly leaseRef?: LeaseRef\n /**\n * The `instanceId` from `AgentOptions`, if provided. Written into\n * `StoredRun.metadata` on every terminal save and into `RunContext` for observers.\n */\n readonly instanceId?: string\n /**\n * The original claim `ttlMs` — passed to `createKeepAliveFn` as `originalTtlMs`\n * so `ctx.keepAlive()` uses the same TTL for renewals. Defaults to 30_000 when absent.\n */\n readonly claimTtlMs?: number\n /**\n * Optional parent run UUID — set when parentRunId was passed as a resource\n * to agent.run(). Threaded through to RunContext for cross-process trace\n * correlation. Absent for top-level runs.\n */\n readonly parentRunId?: string\n /**\n * Pre-filtered list of ObserverAware slots that expose setStepContext.\n * Passed through to runLoop callbacks. Absent when no slots expose setStepContext. F36.\n */\n readonly setStepContextSlots?: ReadonlyArray<{ setStepContext(ctx: StepContext): void }>\n}\n\n// -----------------------------------------------------------------------\n// resolveSessionStore — extract SessionStore from storeEntries\n// -----------------------------------------------------------------------\n\nexport function resolveSessionStore(\n storeEntries: readonly ProviderEntry[],\n): SessionStore | undefined {\n let result: SessionStore | undefined = undefined\n\n for (const entry of storeEntries) {\n if (entry.kind !== 'store') continue\n\n const value = entry.value\n if (value === null || typeof value !== 'object') continue\n\n const rec = value as Record<string, unknown> // as: TypeScript cannot narrow `object` to `Record<string, unknown>` for index access\n if (!('session' in rec)) continue\n\n const session = rec['session']\n if (session === null || typeof session !== 'object') continue\n\n const s = session as Record<string, unknown> // as: same narrowing needed to index into the duck-typed session object\n if (typeof s['load'] === 'function' && typeof s['save'] === 'function') {\n // last valid store wins\n result = session as unknown as SessionStore // as: duck-typing confirmed above; no instanceof available for a structural interface\n }\n }\n\n return result\n}\n\n// -----------------------------------------------------------------------\n// querySessionPhase — implements agent.status() query\n// -----------------------------------------------------------------------\n\nexport async function querySessionPhase(\n store: SessionStore | undefined,\n agentId: string,\n sessionId: string,\n): Promise<SessionPhase> {\n if (store === undefined) {\n return { phase: 'fresh' }\n }\n\n const loaded = await store.load(agentId, sessionId)\n return storedSessionToPhase(loaded)\n}\n\n// -----------------------------------------------------------------------\n// runWithSession — full session lifecycle wrapper around runLoop\n// -----------------------------------------------------------------------\n\nexport async function runWithSession(\n store: SessionStore | undefined,\n agentId: string,\n sessionId: string,\n runId: string,\n graph: LoopDefinition,\n initialStateArg: Record<string, unknown>,\n schema: Record<string, FieldDefinition<any>> | undefined, // any: FieldDefinition uses invariant T; heterogeneous schema maps require any\n ctx: Record<string, unknown> & { readonly agentId: string; readonly sessionId: string },\n options?: SessionRunOptions,\n): Promise<LoopResult> {\n // Inject keepAlive into ctx — no-op when no lease is active (leaseRef.current === null)\n const leaseRef = options?.leaseRef ?? { current: null }\n const keepAlive = createKeepAliveFn(leaseRef, store, options?.claimTtlMs ?? 30_000)\n ;(ctx as Record<string, unknown>)['keepAlive'] = keepAlive // mutate in-place like runLoop does for interrupt/emit\n\n // Build composedShouldStop — checks caller predicate AND lease expiry\n let leaseExpired = false\n const composedShouldStop = (): boolean => {\n if (options?.shouldStop?.() === true) return true\n if (leaseRef.current !== null && leaseRef.current.expiresAt <= Date.now()) {\n leaseExpired = true\n return true\n }\n return false\n }\n\n if (store === undefined) {\n const state = initializeState(null, initialStateArg, schema)\n const result = await runLoop(graph, state, ctx, schema, composedShouldStop, undefined, {\n ...options,\n runId,\n ...(options?.parentRunId !== undefined ? { parentRunId: options.parentRunId } : {}),\n })\n if (leaseExpired) {\n const expiredError = new LeaseExpiredError(sessionId)\n options?.onStoreError?.(expiredError, 'claim')\n throw expiredError\n }\n return result\n }\n\n // Load phase — on failure: fire onStoreError('load') and return synthetic error result\n // Run never begins; 'await run' always resolves (never rejects) per docs/agent.md guarantee\n let loaded: StoredRun | null\n try {\n loaded = await store.load(agentId, sessionId)\n } catch (error: unknown) {\n const storeError = new StoreLoadError(error)\n options?.onStoreError?.(storeError, 'load')\n const failState = initializeState(null, initialStateArg, schema)\n ;(failState as Record<string, unknown>)['$error'] = storeError\n return { state: failState, signal: '$error', paused: false, cursor: null }\n }\n\n // Short-circuit for completed sessions — return stored result immediately without executing\n if (loaded !== null && loaded.phase === 'completed') {\n return {\n state: loaded.finalState,\n signal: loaded.signal ?? null,\n cursor: null,\n paused: false,\n }\n }\n\n // Merge stored snapshot (or null for fresh) with caller-supplied initial state\n const state = initializeState(loaded, initialStateArg, schema)\n // Snapshot before runLoop — runLoop mutates state in place so we must copy before execution\n const initialStateSnapshot = { ...state }\n const startedAt = new Date().toISOString()\n\n // Execute — errors from runLoop propagate uncaught (except LeaseExpiredError handled below)\n const result = await runLoop(graph, state, ctx, schema, composedShouldStop, loaded?.step, {\n ...options,\n runId,\n ...(options?.parentRunId !== undefined ? { parentRunId: options.parentRunId } : {}),\n })\n\n // Lease-expired path — do NOT persist; signal error to caller\n if (leaseExpired) {\n const expiredError = new LeaseExpiredError(sessionId)\n options?.onStoreError?.(expiredError, 'claim')\n throw expiredError\n }\n\n const settledAt = new Date().toISOString()\n\n // Build optional metadata\n const metadata: StoredRunMetadata | undefined =\n options?.instanceId !== undefined ? { instanceId: options.instanceId } : undefined\n\n // Terminal save — errors are swallowed; LoopResult is always returned\n try {\n const version = (loaded?.version ?? -1) + 1\n if (result.paused) {\n const saved: StoredRun = {\n agentId,\n runId,\n sessionId,\n version,\n startedAt,\n settledAt,\n phase: 'paused',\n initialState: initialStateSnapshot,\n finalState: result.state,\n step: result.cursor!,\n ...(result.signal !== null ? { signal: result.signal } : {}),\n ...(metadata !== undefined ? { metadata } : {}),\n }\n await store.save(agentId, sessionId, saved)\n } else {\n const saved: StoredRun = {\n agentId,\n runId,\n sessionId,\n version,\n startedAt,\n settledAt,\n phase: 'completed',\n initialState: initialStateSnapshot,\n finalState: result.state,\n ...(result.signal !== null ? { signal: result.signal } : {}),\n ...(metadata !== undefined ? { metadata } : {}),\n }\n await store.save(agentId, sessionId, saved)\n }\n } catch (error) {\n options?.onStoreError?.(error, 'persist')\n // terminal save error is swallowed; LoopResult is returned to caller regardless\n }\n\n return result\n}\n","import type { SessionStore, StoredRun } from './session-store.js'\n\n// -----------------------------------------------------------------------\n// NoInterruptError\n// -----------------------------------------------------------------------\n\n/**\n * Thrown by {@link RunHandle.resume} or {@link Agent.resume} when the session\n * is not currently paused on a matching interrupt.\n *\n * Common causes: the run has not yet settled, the session does not exist,\n * or the supplied `interruptId` does not match the pending interrupt.\n */\nexport class NoInterruptError extends Error {\n constructor() {\n super(\n 'resume() called but the session is not paused on a matching interrupt — ' +\n 'verify the session exists, its phase is \"paused\", and interruptId matches',\n )\n this.name = 'NoInterruptError'\n }\n}\n\n// -----------------------------------------------------------------------\n// injectInterruptResponse\n// -----------------------------------------------------------------------\n\nexport async function injectInterruptResponse(\n store: SessionStore,\n agentId: string,\n sessionId: string,\n interruptId: string,\n response: unknown,\n): Promise<void> {\n const loaded = await store.load(agentId, sessionId)\n\n if (loaded === null) throw new NoInterruptError()\n if (loaded.phase !== 'paused') throw new NoInterruptError()\n\n const interrupt = loaded.finalState.$interrupt as { interruptId: string } | null // as: $interrupt is a framework-reserved field with known shape\n if (interrupt === null) throw new NoInterruptError()\n if (interrupt.interruptId !== interruptId) throw new NoInterruptError()\n\n const existingResponses = (loaded.finalState.$interruptResponses as Record<string, unknown>) ?? {}\n const newState: Record<string, unknown> = {\n ...loaded.finalState,\n $interrupt: null,\n $interruptResponses: { ...existingResponses, [interruptId]: response },\n }\n\n const updated: StoredRun = {\n agentId: loaded.agentId,\n runId: loaded.runId,\n sessionId: loaded.sessionId,\n version: loaded.version + 1,\n startedAt: loaded.startedAt,\n settledAt: loaded.settledAt,\n phase: 'paused',\n initialState: loaded.initialState,\n finalState: newState,\n ...(loaded.step !== undefined ? { step: loaded.step } : {}),\n ...(loaded.signal !== undefined ? { signal: loaded.signal } : {}),\n }\n\n await store.save(agentId, sessionId, updated)\n}\n","/**\n * The resolved value of a {@link RunHandle} promise: the final state and the\n * signal that caused the loop to exit.\n *\n * `signal` is `null` when the loop exited via `.end()` without an explicit signal,\n * `'$interrupt'` when paused on an interrupt, or any custom signal string returned\n * by a route function.\n */\nexport interface RunOutcome {\n readonly state: Record<string, unknown>\n readonly signal: string | null\n}\n\n/**\n * Handle returned synchronously by {@link Agent.run} and {@link Agent.resume}.\n *\n * Implements `PromiseLike<RunOutcome>` so it can be `await`-ed directly.\n *\n * @example\n * ```ts\n * const handle = agent.run({}, { llm })\n * console.log(handle.sessionId) // available immediately\n * const { state, signal } = await handle\n * ```\n */\nexport interface RunHandle extends PromiseLike<RunOutcome> {\n /** Cancel the in-flight run at the next safe point between steps. Idempotent. */\n stop(): void\n\n /**\n * Provide a response to a pending `ctx.interrupt()` call and start a new run.\n * Returns a new {@link RunHandle} for the resumed execution.\n *\n * Throws {@link NoInterruptError} when the run has not settled on `signal: '$interrupt'`.\n *\n * @param response - The value to deliver as the interrupt response.\n * @param interruptId - The `interruptId` from `state.$interrupt`.\n */\n resume(response: unknown, interruptId: string): RunHandle\n\n /** The session identity for this run. */\n readonly sessionId: string\n\n /**\n * Unique identifier for this specific invocation.\n * One UUID per `agent.run()` or `agent.resume()` call.\n */\n readonly runId: string\n\n /**\n * The name of the step currently executing in this process.\n * `null` before the first step runs, after execution settles, and always\n * when inspected cross-process.\n */\n readonly currentStep: string | null\n}\n\nimport { NoInterruptError } from './interrupt-resume.js'\n\nexport function createRunHandle(\n sessionId: string,\n runId: string,\n execution: Promise<RunOutcome>,\n stopFlag: { stopped: boolean },\n stepRef: { current: string | null },\n resumeFn?: (response: unknown, interruptId: string) => RunHandle,\n): RunHandle {\n let settledOutcome: RunOutcome | null = null\n\n // NOTE: raw .then(onFulfilled, onRejected) is intentional here — NOT a coding-standards\n // violation. async/await requires wrapping in a new async function, which changes control\n // flow and does not populate `settledOutcome` as a side-effect at resolution time.\n // .then() attaches handlers to an already-running Promise, allowing us to capture the\n // fulfilled RunOutcome into the closure variable synchronously within the callback at the\n // moment of resolution. run.resume() reads settledOutcome synchronously, so this is the\n // only correct pattern; replacing it with async/await would break synchronous access.\n const settled = execution.then(\n (outcome: RunOutcome): RunOutcome => {\n settledOutcome = outcome\n stepRef.current = null\n return outcome\n },\n (err: unknown): RunOutcome => {\n stepRef.current = null\n throw err\n },\n )\n\n const handle: RunHandle = {\n then<TResult1 = RunOutcome, TResult2 = never>(\n onfulfilled?: ((value: RunOutcome) => TResult1 | PromiseLike<TResult1>) | null | undefined,\n onrejected?: ((reason: unknown) => TResult2 | PromiseLike<TResult2>) | null | undefined,\n ): Promise<TResult1 | TResult2> {\n return settled.then(onfulfilled, onrejected)\n },\n\n stop(): void {\n stopFlag.stopped = true\n },\n\n resume(response: unknown, interruptId: string): RunHandle {\n // backward-compatibility: 4-arg handle (no resumeFn) + unsettled → old stub error\n if (settledOutcome === null && resumeFn === undefined) {\n throw new Error('not implemented — requires F9')\n }\n if (settledOutcome === null) {\n throw new NoInterruptError()\n }\n if (settledOutcome.signal !== '$interrupt') {\n throw new NoInterruptError()\n }\n if (resumeFn === undefined) {\n throw new NoInterruptError()\n }\n return resumeFn(response, interruptId)\n },\n\n get sessionId(): string {\n return sessionId\n },\n\n get runId(): string {\n return runId\n },\n\n get currentStep(): string | null {\n return stepRef.current\n },\n }\n\n return handle\n}\n","import {\n getInternals,\n type Harness,\n type HarnessInternals,\n type ProviderEntry,\n} from '../harness/harness-builder.js'\nimport { isRequiredMarker, isRuntimeMarker } from '../harness/ctx-markers.js'\nimport type { LoopDefinition } from '../loop/loop-dsl.js'\nimport type { FieldDefinition } from '../harness/state-field.js'\nimport type { SessionPhase, ClaimOptions, Lease } from './session-store.js'\nimport { resolveSessionStore, runWithSession, querySessionPhase, type SessionRunOptions } from './session-lifecycle.js'\nimport { runLoop } from '../loop/loop-executor.js'\nimport { createRunHandle, type RunHandle, type RunOutcome } from './run-handle.js'\nimport { NoInterruptError, injectInterruptResponse } from './interrupt-resume.js'\nimport {\n SessionInFlightError,\n SessionPendingInterruptError,\n SessionBusyError,\n LeaseExpiredError,\n StoreLoadError,\n} from './concurrency-errors.js'\nimport type { LeaseRef } from './ctx-keep-alive.js'\nimport { randomUUID } from 'node:crypto'\nimport { extractRunEvents } from './event-callbacks.js'\nimport { extractRunListeners } from './ctx-emit.js'\nimport type { Observer, StepContext } from './observer.js'\nimport { initializeState } from './session-store.js'\n\n// -----------------------------------------------------------------------\n// Module-level constants\n// -----------------------------------------------------------------------\n\nconst NOOP_OBSERVER: Observer = {}\n\n// -----------------------------------------------------------------------\n// Module-private helpers\n// -----------------------------------------------------------------------\n\nfunction extractRunObserver(resources: Record<string, unknown>): Observer | undefined {\n const raw = resources['observer']\n if (raw === null || typeof raw !== 'object' || Array.isArray(raw)) return undefined\n return raw as Observer // as: duck-typed plain object confirmed; methods not validated\n}\n\n/** Options passed to createAgent(). */\nexport interface AgentOptions {\n /**\n * Stable identifier for the process or replica running this agent instance.\n * Written to `StoredRun.metadata` on every save and propagated to observers\n * via `RunContext.instanceId`.\n */\n readonly instanceId?: string\n}\n\n// -----------------------------------------------------------------------\n// Agent — the minimal public object returned by createAgent\n// -----------------------------------------------------------------------\n\nexport interface Agent {\n /** The agent's unique identifier, as provided to createAgent(). */\n readonly id: string\n\n /**\n * Start a new run. Returns a RunHandle synchronously before execution begins.\n */\n run(initialState: Record<string, unknown>, resources: Record<string, unknown>): RunHandle\n\n /**\n * Cross-process entry point for responding to a pending interrupt.\n * Returns a RunHandle synchronously; the execution promise performs the resume.\n *\n * The optional fourth argument `resources` accepts:\n * - `observer?: Observer` — structured telemetry for the resumed run (see Observability)\n * - `events?.onStoreError?` — raw store-error callback (unchanged from prior shape)\n */\n resume(\n response: unknown,\n sessionId: string,\n interruptId: string,\n resources?: Record<string, unknown>,\n ): RunHandle\n\n /**\n * Query the session store for the current phase of a session.\n */\n status(sessionId: string): Promise<SessionPhase>\n}\n\n// -----------------------------------------------------------------------\n// AgentInternals — the resolved internal state\n// -----------------------------------------------------------------------\n\nexport interface AgentInternals {\n readonly agentId: string\n readonly resolvedProviders: ReadonlyMap<string, unknown>\n readonly storeEntries: readonly ProviderEntry[]\n readonly loopDef: LoopDefinition\n readonly stateSchema: Record<string, FieldDefinition<unknown>> | undefined\n /** Keys declared as runtime() in the harness — must be filled in agent.run() resources. */\n readonly runtimeKeys: ReadonlySet<string>\n /** Keys declared as required() in the harness — must NOT appear in agent.run() resources. */\n readonly requiredKeys: ReadonlySet<string>\n}\n\n// -----------------------------------------------------------------------\n// Error classes\n// -----------------------------------------------------------------------\n\n/** Thrown by {@link createAgent} when the harness has no `.loop()` declaration. */\nexport class MissingLoopError extends Error {\n constructor() {\n super('harness has no loop — call h.loop() before createAgent(id, h, slots)')\n this.name = 'MissingLoopError'\n }\n}\n\n/** Thrown by {@link createAgent} when a `required()` slot is absent from `slots`. */\nexport class MissingSlotError extends Error {\n /** The missing slot key. */\n readonly key: string\n\n constructor(key: string) {\n super(`required slot \"${key}\" was not provided in createAgent slots`)\n this.name = 'MissingSlotError'\n this.key = key\n }\n}\n\n/** Thrown by {@link createAgent} when a `runtime()` slot is passed in `slots` instead of `agent.run()`. */\nexport class RuntimeSlotInAgentError extends Error {\n /** The offending slot key. */\n readonly key: string\n\n constructor(key: string) {\n super(`slot \"${key}\" is a runtime() slot — provide it in agent.run(), not createAgent()`)\n this.name = 'RuntimeSlotInAgentError'\n this.key = key\n }\n}\n\n/** Thrown by {@link createAgent} when `slots` contains a key not declared in the harness. */\nexport class UnknownSlotError extends Error {\n /** The unknown slot key. */\n readonly key: string\n\n constructor(key: string) {\n super(`slot \"${key}\" is not declared in the harness — remove it or add h.provide(\"${key}\", required())`)\n this.name = 'UnknownSlotError'\n this.key = key\n }\n}\n\n/** @internal Thrown when `getAgentInternals` is called on a non-agent value. */\nexport class AgentInternalsError extends Error {\n constructor() {\n super('value was not produced by createAgent — cannot read AgentInternals')\n this.name = 'AgentInternalsError'\n }\n}\n\n/** Thrown by {@link Agent.run} when a `runtime()` slot is absent from `resources`. */\nexport class MissingRuntimeSlotError extends Error {\n /** The missing runtime slot key. */\n readonly key: string\n constructor(key: string) {\n super(`runtime slot \"${key}\" was not provided in agent.run() resources`)\n this.name = 'MissingRuntimeSlotError'\n this.key = key\n }\n}\n\n/** Thrown by {@link Agent.run} when a `required()` slot is passed in `resources` instead of `createAgent()`. */\nexport class RequiredSlotInRunError extends Error {\n /** The offending slot key. */\n readonly key: string\n constructor(key: string) {\n super(`slot \"${key}\" is a required() slot — provide it in createAgent(), not agent.run()`)\n this.name = 'RequiredSlotInRunError'\n this.key = key\n }\n}\n\n/** Thrown by {@link Agent.run} when `resources` contains a key that was not declared as `runtime()`. */\nexport class UnknownRunSlotError extends Error {\n /** The unknown resource key. */\n readonly key: string\n constructor(key: string) {\n super(`slot \"${key}\" is not a runtime() slot — do not pass it in agent.run() resources`)\n this.name = 'UnknownRunSlotError'\n this.key = key\n }\n}\n\n// -----------------------------------------------------------------------\n// Module-private symbol for AttachInternals\n// -----------------------------------------------------------------------\n\nconst _agentInternals = Symbol('_agentInternals')\n\ntype AgentWithInternals = Agent & {\n readonly [_agentInternals]: AgentInternals\n}\n\n// -----------------------------------------------------------------------\n// createAgent — the public factory\n// -----------------------------------------------------------------------\n\n/**\n * Instantiate an agent from a fully-configured {@link Harness}.\n *\n * Validates that all `required()` slots are present in `slots`, that no\n * `runtime()` slots are passed here, and that the harness has a loop defined.\n *\n * @param id - A stable, human-readable identifier for this agent (used as the\n * first argument to every store operation).\n * @param h - The harness produced by `createHarness()...loop()`.\n * @param slots - Values for every slot declared with `required()` in the harness.\n * @param options - Optional agent-level options (e.g., instanceId).\n *\n * @throws {@link MissingLoopError} when `h.loop()` was never called.\n * @throws {@link MissingSlotError} when a `required()` slot is absent from `slots`.\n * @throws {@link RuntimeSlotInAgentError} when a `runtime()` slot is passed in `slots`.\n * @throws {@link UnknownSlotError} when `slots` contains a key not declared in the harness.\n *\n * @example\n * ```ts\n * const agent = createAgent('my-agent', h, { llm: new Claude('claude-3-5-haiku-20241022') })\n * const handle = agent.run({}, {})\n * const { state, signal } = await handle\n * ```\n */\nexport function createAgent<Ctx, State, Req extends keyof Ctx, Run extends keyof Ctx>(\n id: string,\n h: Harness<Ctx, State, Req, Run>,\n slots: Pick<Ctx, Req>,\n agentOptions?: AgentOptions,\n): Agent {\n // Get harness internals; propagate HarnessInternalsError if h is not a real Harness\n const internals: HarnessInternals<Ctx, State, Req, Run> = getInternals(h)\n\n // Validation 1: loop exists\n if (internals.loopDef === undefined) {\n throw new MissingLoopError()\n }\n\n // Build a map of provider entries with kind 'provide' for slot validation\n const providerMap = new Map<string, ProviderEntry>()\n for (const entry of internals.providers) {\n if (entry.kind === 'provide') {\n providerMap.set(entry.key, entry)\n }\n }\n\n // Validation 2: no unknown keys in slots\n for (const key of Object.keys(slots)) {\n if (!providerMap.has(key)) {\n throw new UnknownSlotError(key)\n }\n }\n\n // Validation 3: no runtime() markers in slots\n for (const key of Object.keys(slots)) {\n const entry = providerMap.get(key)\n if (entry && isRuntimeMarker(entry.value)) {\n throw new RuntimeSlotInAgentError(key)\n }\n }\n\n // Validation 4: all required() slots are provided\n for (const entry of internals.providers) {\n if (entry.kind === 'provide' && isRequiredMarker(entry.value)) {\n if (!(entry.key in slots)) {\n throw new MissingSlotError(entry.key)\n }\n }\n }\n\n // Build resolvedProviders map: iterate all providers in order, last-registered-wins\n const resolvedProviders = new Map<string, unknown>()\n const storeEntries: ProviderEntry[] = []\n const runtimeKeys = new Set<string>()\n const requiredKeys = new Set<string>()\n\n for (const entry of internals.providers) {\n if (entry.kind === 'store') {\n storeEntries.push(entry)\n } else if (entry.kind === 'provide') {\n if (isRequiredMarker(entry.value)) {\n // Replace required() marker with the slot value\n resolvedProviders.set(entry.key, (slots as Record<string, unknown>)[entry.key]) // as: Req extends keyof Ctx erases to plain index at runtime\n requiredKeys.add(entry.key)\n } else if (isRuntimeMarker(entry.value)) {\n runtimeKeys.add(entry.key)\n // runtime() markers are not included in resolvedProviders\n } else {\n // Concrete value: include as-is\n resolvedProviders.set(entry.key, entry.value)\n }\n }\n }\n\n // Resolve session store from store entries at construction time\n const capturedStore = resolveSessionStore(storeEntries)\n\n // Construct AgentInternals\n const agentInternals: AgentInternals = {\n agentId: id,\n resolvedProviders,\n storeEntries,\n loopDef: internals.loopDef, // Guaranteed to be non-undefined by validation 1\n stateSchema: internals.stateSchema,\n runtimeKeys,\n requiredKeys,\n }\n\n // Reserved keys are skipped during agent.run() resource validation\n const reservedRunKeys = new Set(['sessionId', 'signal', 'events', 'listeners', 'observer', 'claimOptions', 'parentRunId'])\n\n // one per agent instance; tracks all session IDs currently executing\n const inFlightSessions = new Set<string>()\n\n // one per agent instance; tracks session IDs paused on an unanswered interrupt\n // cleared when agent.resume() or run.resume() is called; populated when a run settles with signal: \"$interrupt\"\n const interruptPendingSessions = new Set<string>()\n\n // -----------------------------------------------------------------------\n // makeAgentResumeHandle — factory for cross-process resume RunHandles\n // -----------------------------------------------------------------------\n\n const makeAgentResumeHandle = (\n resp: unknown,\n sId: string,\n iId: string,\n resumeOpts?: { onStoreError?: (error: unknown, phase: 'load' | 'persist' | 'claim') => void },\n observer?: Observer,\n setStepContextSlots?: ReadonlyArray<{ setStepContext(ctx: StepContext): void }>,\n ): RunHandle => {\n let _stopped = false\n const abortController = new AbortController()\n const flag = {\n get stopped(): boolean { return _stopped },\n set stopped(v: boolean) { _stopped = v; if (v) abortController.abort() },\n }\n const ref: { current: string | null } = { current: null }\n const rId = randomUUID()\n\n const exec = (async (): Promise<RunOutcome> => {\n await Promise.resolve()\n const claimOptions: ClaimOptions = { ttlMs: 30_000 }\n let leaseRef: LeaseRef | undefined = undefined\n try {\n if (typeof capturedStore?.claim === 'function') {\n let lease: Lease | null\n try {\n lease = await capturedStore.claim(id, sId, claimOptions)\n } catch (claimError: unknown) {\n const loadError = new StoreLoadError(claimError)\n resumeOpts?.onStoreError?.(loadError, 'claim')\n const failState = initializeState(null, {}, agentInternals.stateSchema)\n ;(failState as Record<string, unknown>)['$error'] = loadError\n return { state: failState, signal: '$error' }\n }\n if (lease === null) {\n const busyError = new SessionBusyError(sId)\n resumeOpts?.onStoreError?.(busyError, 'claim')\n const failState = initializeState(null, {}, agentInternals.stateSchema)\n ;(failState as Record<string, unknown>)['$error'] = busyError\n return { state: failState, signal: '$error' }\n }\n leaseRef = { current: lease }\n }\n try {\n if (capturedStore === undefined) throw new NoInterruptError()\n try {\n await injectInterruptResponse(capturedStore, id, sId, iId, resp)\n } catch (injectError: unknown) {\n if (injectError instanceof NoInterruptError) throw injectError\n // store I/O failure during interrupt injection — report as 'claim' phase error\n const storeError = new StoreLoadError(injectError)\n resumeOpts?.onStoreError?.(storeError, 'claim')\n const failState = initializeState(null, {}, agentInternals.stateSchema)\n ;(failState as Record<string, unknown>)['$error'] = storeError\n return { state: failState, signal: '$error' }\n }\n const agentCtx: Record<string, unknown> & { readonly agentId: string; readonly sessionId: string; readonly runId: string; readonly signal: AbortSignal } = {\n ...Object.fromEntries(agentInternals.resolvedProviders),\n agentId: id,\n sessionId: sId,\n runId: rId,\n signal: abortController.signal,\n }\n const r = await runWithSession(\n capturedStore,\n id,\n sId,\n rId,\n agentInternals.loopDef,\n {},\n agentInternals.stateSchema,\n agentCtx,\n {\n shouldStop: () => flag.stopped,\n onBeforeStep: (n: string) => { ref.current = n },\n ...(resumeOpts?.onStoreError !== undefined ? { onStoreError: resumeOpts.onStoreError } : {}),\n ...(leaseRef !== undefined ? { leaseRef, claimTtlMs: claimOptions.ttlMs } : {}),\n ...(observer !== undefined ? { observer } : {}),\n ...(setStepContextSlots !== undefined && setStepContextSlots.length > 0 ? { setStepContextSlots } : {}),\n },\n )\n if (r.signal === '$interrupt') interruptPendingSessions.add(sId)\n return { state: r.state, signal: r.signal }\n } catch (error: unknown) {\n if (error instanceof LeaseExpiredError) {\n const failState = initializeState(null, {}, agentInternals.stateSchema)\n ;(failState as Record<string, unknown>)['$error'] = error\n return { state: failState, signal: '$error' }\n }\n throw error\n } finally {\n if (leaseRef !== undefined && typeof capturedStore?.release === 'function') {\n try { await capturedStore.release(leaseRef.current!) } catch { /* swallow */ }\n }\n }\n } finally {\n inFlightSessions.delete(sId)\n }\n })()\n\n const resumeFn = (r: unknown, i: string): RunHandle => {\n // Synchronous fence — same invariant as agent.resume()\n if (inFlightSessions.has(sId)) throw new SessionInFlightError(sId)\n interruptPendingSessions.delete(sId)\n inFlightSessions.add(sId)\n return makeAgentResumeHandle(r, sId, i)\n }\n return createRunHandle(sId, rId, exec, flag, ref, resumeFn)\n }\n\n // Create and return Agent with attached internals\n const agent: AgentWithInternals = {\n id,\n run: (initialState: Record<string, unknown>, resources: Record<string, unknown>): RunHandle => {\n // Validation pass 1: unknown keys (not reserved, not runtime, not required)\n for (const key of Object.keys(resources)) {\n if (reservedRunKeys.has(key)) continue\n if (!agentInternals.runtimeKeys.has(key) && !agentInternals.requiredKeys.has(key)) {\n throw new UnknownRunSlotError(key)\n }\n }\n\n // Validation pass 2: required() keys passed in resources\n for (const key of Object.keys(resources)) {\n if (reservedRunKeys.has(key)) continue\n if (agentInternals.requiredKeys.has(key)) {\n throw new RequiredSlotInRunError(key)\n }\n }\n\n // Validation pass 3: missing runtime() keys\n for (const key of agentInternals.runtimeKeys) {\n if (!(key in resources)) {\n throw new MissingRuntimeSlotError(key)\n }\n }\n\n // Session ID resolution\n const sessionId =\n typeof resources['sessionId'] === 'string' ? resources['sessionId'] : randomUUID()\n\n // Run ID — unique per agent.run() invocation, available synchronously on RunHandle\n const runId = randomUUID()\n\n // Synchronous concurrency fences — must precede any await (per docs/agent.md Concurrency section)\n if (inFlightSessions.has(sessionId)) throw new SessionInFlightError(sessionId)\n if (interruptPendingSessions.has(sessionId)) throw new SessionPendingInterruptError(sessionId)\n inFlightSessions.add(sessionId)\n\n // AbortSignal and stop-flag wiring\n let _stopped = false\n const abortController = new AbortController()\n const stopFlag = {\n get stopped(): boolean { return _stopped },\n set stopped(v: boolean) { _stopped = v; if (v) abortController.abort() },\n }\n const rawSignal = resources['signal']\n let ctxSignal: AbortSignal = abortController.signal\n if (rawSignal instanceof AbortSignal) {\n ctxSignal = rawSignal\n rawSignal.addEventListener('abort', () => { stopFlag.stopped = true; abortController.abort() }, { once: true })\n if (rawSignal.aborted) stopFlag.stopped = true\n }\n\n // Fresh stepRef per call for currentStep tracking\n const stepRef: { current: string | null } = { current: null }\n\n // Assemble ctx: resolvedProviders merged with runtime slots and sessionId, runId, and signal\n const runtimeSlots: Record<string, unknown> = {}\n for (const key of agentInternals.runtimeKeys) {\n if (reservedRunKeys.has(key)) continue // reserved keys are consumed by framework, not injected into ctx\n runtimeSlots[key] = resources[key]\n }\n const ctx: Record<string, unknown> & { readonly agentId: string; readonly sessionId: string; readonly runId: string; readonly signal: AbortSignal } = {\n ...Object.fromEntries(agentInternals.resolvedProviders),\n ...runtimeSlots,\n agentId: id,\n sessionId,\n runId,\n signal: ctxSignal,\n ...(agentOptions?.instanceId !== undefined ? { instanceId: agentOptions.instanceId } : {}),\n }\n\n // Extract event callbacks and listeners from resources (reserved keys)\n const events = extractRunEvents(resources)\n const listeners = extractRunListeners(resources)\n\n // Extract observer and bind to any ObserverAware slots synchronously before async execution begins\n const observer = extractRunObserver(resources)\n for (const slot of [...agentInternals.resolvedProviders.values(), ...Object.values(runtimeSlots)]) {\n if (slot !== null && typeof slot === 'object' && typeof (slot as Record<string, unknown>)['bindObserver'] === 'function') { // as: duck-typed structural check; slot typed as unknown at this point\n (slot as { bindObserver: (o: Observer) => void }).bindObserver(observer ?? NOOP_OBSERVER) // as: narrowed by duck-type check on line above\n }\n }\n\n // Build setStepContextSlots: pre-filter all slots that expose setStepContext (F36)\n const setStepContextSlots: Array<{ setStepContext(ctx: StepContext): void }> = []\n for (const slot of [...agentInternals.resolvedProviders.values(), ...Object.values(runtimeSlots)]) {\n if (\n slot !== null &&\n typeof slot === 'object' &&\n typeof (slot as Record<string, unknown>)['setStepContext'] === 'function' // as: duck-type check\n ) {\n setStepContextSlots.push(slot as { setStepContext(ctx: StepContext): void }) // as: narrowed by duck-type check on line above\n }\n }\n\n // Extract parentRunId from resources (reserved key)\n const parentRunId =\n typeof resources['parentRunId'] === 'string' ? resources['parentRunId'] : undefined\n\n const options: SessionRunOptions = {\n shouldStop: () => stopFlag.stopped,\n onBeforeStep: (name: string, state: Record<string, unknown>) => {\n stepRef.current = name\n events.onBeforeStep?.(name, state)\n },\n // spread optional event callbacks only when defined (exactOptionalPropertyTypes requires omission, not undefined)\n ...(events.onStoreError !== undefined ? { onStoreError: events.onStoreError } : {}),\n ...(events.onAfterStep !== undefined ? { onAfterStep: events.onAfterStep } : {}),\n ...(events.onError !== undefined ? { onError: events.onError } : {}),\n ...(events.onComplete !== undefined ? { onComplete: events.onComplete } : {}),\n ...(events.onInterrupt !== undefined ? { onInterrupt: events.onInterrupt } : {}),\n ...(Object.keys(listeners).length > 0 ? { listeners } : {}),\n ...(observer !== undefined ? { observer } : {}),\n ...(agentOptions?.instanceId !== undefined ? { instanceId: agentOptions.instanceId } : {}),\n ...(parentRunId !== undefined ? { parentRunId } : {}),\n ...(setStepContextSlots.length > 0 ? { setStepContextSlots } : {}),\n }\n\n // lastResult captures the LoopResult for same-process in-memory resume chaining\n let lastResult: { state: Record<string, unknown>; cursor: string | null } | null = null\n\n // Launch execution asynchronously — agent.run() returns before any async work begins\n const execution = (async (): Promise<RunOutcome> => {\n // Yield so agent.run() can return the RunHandle before any loop iteration starts\n await Promise.resolve()\n\n // Parse claimOptions from resources (reserved key); default ttlMs=30_000\n const rawClaimOpts = resources['claimOptions']\n const claimOptions: ClaimOptions =\n typeof rawClaimOpts === 'object' && rawClaimOpts !== null &&\n typeof (rawClaimOpts as Record<string, unknown>)['ttlMs'] === 'number'\n ? (rawClaimOpts as ClaimOptions)\n : { ttlMs: 30_000 }\n\n let leaseRef: LeaseRef | undefined = undefined\n\n try {\n if (typeof capturedStore?.claim === 'function') {\n let lease: Lease | null\n try {\n lease = await capturedStore.claim(id, sessionId, claimOptions)\n } catch (claimError: unknown) {\n const loadError = new StoreLoadError(claimError)\n events.onStoreError?.(loadError, 'claim')\n const failState = initializeState(null, initialState, agentInternals.stateSchema)\n ;(failState as Record<string, unknown>)['$error'] = loadError\n return { state: failState, signal: '$error' }\n }\n if (lease === null) {\n const busyError = new SessionBusyError(sessionId)\n events.onStoreError?.(busyError, 'claim')\n const failState = initializeState(null, initialState, agentInternals.stateSchema)\n ;(failState as Record<string, unknown>)['$error'] = busyError\n return { state: failState, signal: '$error' }\n }\n leaseRef = { current: lease }\n }\n try {\n const r = await runWithSession(\n capturedStore,\n id,\n sessionId,\n runId,\n agentInternals.loopDef,\n initialState,\n agentInternals.stateSchema,\n ctx,\n {\n ...options,\n ...(leaseRef !== undefined ? { leaseRef, claimTtlMs: claimOptions.ttlMs } : {}),\n },\n )\n if (r.signal === '$interrupt') interruptPendingSessions.add(sessionId)\n lastResult = { state: r.state, cursor: r.cursor }\n return { state: r.state, signal: r.signal }\n } catch (error: unknown) {\n if (error instanceof LeaseExpiredError) {\n // onStoreError already called by runWithSession before throwing\n const failState = initializeState(null, initialState, agentInternals.stateSchema)\n ;(failState as Record<string, unknown>)['$error'] = error\n return { state: failState, signal: '$error' }\n }\n throw error\n } finally {\n if (leaseRef !== undefined && typeof capturedStore?.release === 'function') {\n try { await capturedStore.release(leaseRef.current!) } catch { /* swallow */ }\n }\n }\n } finally {\n inFlightSessions.delete(sessionId)\n }\n })()\n\n // buildResumeFn — creates a recursive resumeFn for same-process chaining via run.resume()\n const buildResumeFn = (): ((response: unknown, interruptId: string) => RunHandle) => {\n return (response: unknown, interruptId: string): RunHandle => {\n // Synchronous fence — same invariant as agent.run()\n if (inFlightSessions.has(sessionId)) throw new SessionInFlightError(sessionId)\n interruptPendingSessions.delete(sessionId)\n inFlightSessions.add(sessionId)\n\n let _resumeStopped = false\n const resumeAbortController = new AbortController()\n const resumeStopFlag = {\n get stopped(): boolean { return _resumeStopped },\n set stopped(v: boolean) { _resumeStopped = v; if (v) resumeAbortController.abort() },\n }\n const resumeStepRef: { current: string | null } = { current: null }\n const resumeRunId = randomUUID()\n\n const resumeExecution = (async (): Promise<RunOutcome> => {\n await Promise.resolve()\n try {\n // Create a new ctx for this resume invocation with updated runId and signal\n const resumeCtx: Record<string, unknown> & { readonly agentId: string; readonly sessionId: string; readonly runId: string; readonly signal: AbortSignal } = {\n ...ctx,\n runId: resumeRunId,\n signal: resumeAbortController.signal,\n }\n\n if (capturedStore !== undefined) {\n // Cross-process path: inject response into store, reload, and re-run\n await injectInterruptResponse(capturedStore, id, sessionId, interruptId, response)\n const r = await runWithSession(\n capturedStore,\n id,\n sessionId,\n resumeRunId,\n agentInternals.loopDef,\n {},\n agentInternals.stateSchema,\n resumeCtx,\n {\n shouldStop: () => resumeStopFlag.stopped,\n onBeforeStep: (n: string, s: Record<string, unknown>) => {\n resumeStepRef.current = n\n events.onBeforeStep?.(n, s)\n },\n // spread optional event callbacks only when defined (exactOptionalPropertyTypes requires omission, not undefined)\n ...(events.onStoreError !== undefined ? { onStoreError: events.onStoreError } : {}),\n ...(events.onAfterStep !== undefined ? { onAfterStep: events.onAfterStep } : {}),\n ...(events.onError !== undefined ? { onError: events.onError } : {}),\n ...(events.onComplete !== undefined ? { onComplete: events.onComplete } : {}),\n ...(events.onInterrupt !== undefined ? { onInterrupt: events.onInterrupt } : {}),\n ...(Object.keys(listeners).length > 0 ? { listeners } : {}),\n ...(observer !== undefined ? { observer } : {}),\n ...(setStepContextSlots.length > 0 ? { setStepContextSlots } : {}),\n },\n )\n if (r.signal === '$interrupt') interruptPendingSessions.add(sessionId)\n lastResult = { state: r.state, cursor: r.cursor }\n return { state: r.state, signal: r.signal }\n }\n\n // Same-process in-memory path: mutate shared state and re-run from cursor\n const prev = lastResult\n if (prev === null) throw new NoInterruptError()\n const state = prev.state\n const existing = (state.$interruptResponses as Record<string, unknown>) ?? {}\n state.$interruptResponses = { ...existing, [interruptId]: response }\n state.$interrupt = null\n const cursor = prev.cursor ?? undefined\n const r = await runLoop(\n agentInternals.loopDef,\n state,\n resumeCtx,\n agentInternals.stateSchema,\n () => resumeStopFlag.stopped,\n cursor,\n {\n runId: resumeRunId,\n onBeforeStep: (n: string, s: Record<string, unknown>) => {\n resumeStepRef.current = n\n events.onBeforeStep?.(n, s)\n },\n ...(events.onAfterStep !== undefined ? { onAfterStep: events.onAfterStep } : {}),\n ...(events.onError !== undefined ? { onError: events.onError } : {}),\n ...(events.onComplete !== undefined ? { onComplete: events.onComplete } : {}),\n ...(events.onInterrupt !== undefined ? { onInterrupt: events.onInterrupt } : {}),\n ...(Object.keys(listeners).length > 0 ? { listeners } : {}),\n ...(observer !== undefined ? { observer } : {}),\n ...(setStepContextSlots.length > 0 ? { setStepContextSlots } : {}),\n },\n )\n if (r.signal === '$interrupt') interruptPendingSessions.add(sessionId)\n lastResult = { state: r.state, cursor: r.cursor }\n return { state: r.state, signal: r.signal }\n } catch (error: unknown) {\n if (error instanceof LeaseExpiredError) {\n // onStoreError already called by runWithSession before throwing\n const failState = initializeState(null, initialState, agentInternals.stateSchema)\n ;(failState as Record<string, unknown>)['$error'] = error\n return { state: failState, signal: '$error' }\n }\n throw error\n } finally {\n inFlightSessions.delete(sessionId)\n }\n })()\n\n return createRunHandle(sessionId, resumeRunId, resumeExecution, resumeStopFlag, resumeStepRef, buildResumeFn())\n }\n }\n\n return createRunHandle(sessionId, runId, execution, stopFlag, stepRef, buildResumeFn())\n },\n\n resume: (\n response: unknown,\n sessionId: string,\n interruptId: string,\n resources?: Record<string, unknown>,\n ): RunHandle => {\n // SessionInFlightError fence is first — before any extraction or binding (Invariant 3)\n if (inFlightSessions.has(sessionId)) throw new SessionInFlightError(sessionId)\n interruptPendingSessions.delete(sessionId)\n inFlightSessions.add(sessionId)\n const events = extractRunEvents(resources ?? {})\n const resumeOpts = events.onStoreError !== undefined\n ? { onStoreError: events.onStoreError }\n : undefined\n const observer = extractRunObserver(resources ?? {})\n // bind observer unconditionally on all ObserverAware resolvedProviders (Invariant 1)\n for (const slot of agentInternals.resolvedProviders.values()) {\n if (slot !== null && typeof slot === 'object' && typeof (slot as Record<string, unknown>)['bindObserver'] === 'function') { // as: duck-typed structural check\n (slot as { bindObserver: (o: Observer) => void }).bindObserver(observer ?? NOOP_OBSERVER) // as: narrowed by duck-type check on line above\n }\n }\n // Build setStepContextSlots from resolvedProviders only (no runtime slots in resume path)\n const setStepContextSlots: Array<{ setStepContext(ctx: StepContext): void }> = []\n for (const slot of agentInternals.resolvedProviders.values()) {\n if (\n slot !== null &&\n typeof slot === 'object' &&\n typeof (slot as Record<string, unknown>)['setStepContext'] === 'function' // as: duck-type check\n ) {\n setStepContextSlots.push(slot as { setStepContext(ctx: StepContext): void }) // as: narrowed by duck-type check on line above\n }\n }\n return makeAgentResumeHandle(response, sessionId, interruptId, resumeOpts, observer ?? undefined, setStepContextSlots.length > 0 ? setStepContextSlots : undefined)\n },\n\n status: (sessionId: string) => querySessionPhase(capturedStore, id, sessionId),\n [_agentInternals]: agentInternals,\n }\n\n return agent\n}\n\n// -----------------------------------------------------------------------\n// getAgentInternals — accessor for AgentInternals\n// -----------------------------------------------------------------------\n\nexport function getAgentInternals(agent: Agent): AgentInternals {\n if (agent === null || typeof agent !== 'object' || !(_agentInternals in agent)) {\n throw new AgentInternalsError()\n }\n return (agent as AgentWithInternals)[_agentInternals] // as: _agentInternals in agent guard above guarantees the symbol key is present\n}\n","/**\n * Framework-fired event callbacks for a single agent.run() invocation.\n * All fields are optional — omit any you do not need.\n * Callbacks are fire-and-forget; their return value is ignored.\n * Scoped to the run — released when the run settles.\n *\n * Note: user-emitted events (formerly onLlmCall etc.) are replaced by\n * ctx.emit(name, payload) + the 'listeners' resource key. See agent.md.\n */\nexport interface RunEvents {\n /** Called just before a step's run function is invoked. */\n onBeforeStep?: (name: string, state: Record<string, unknown>) => void\n /** Called just after a step's run function completes successfully (state update applied). */\n onAfterStep?: (name: string, state: Record<string, unknown>) => void\n /**\n * Called when the loop exits normally via .on(signal).end().\n * Not called for paused outcomes (stop, abort, error, interrupt).\n */\n onComplete?: (state: Record<string, unknown>, signal: string) => void\n /**\n * Called immediately when a step's run throws a non-interrupt error, before error routing.\n * Fires regardless of how the error is ultimately handled. Does not affect routing or state.\n */\n onError?: (error: unknown, stepName: string) => void\n /**\n * Called when ctx.interrupt() pauses the run (i.e. when isInterruptPause is true).\n * Fires with the prompt and interruptId from the InterruptPause exception, before the\n * run resolves with signal: \"$interrupt\".\n */\n onInterrupt?: (prompt: unknown, interruptId: string) => void\n /**\n * Called if the session store fails at load, persist, or claim phase.\n * phase: 'load' — store failed at run start (run never executed).\n * phase: 'persist' — store failed at run end (run completed but state not saved).\n * phase: 'claim' — store.claim() returned null (busy) or threw (network error).\n */\n onStoreError?: (error: unknown, phase: 'load' | 'persist' | 'claim') => void\n}\n\n/**\n * Extract and validate the events object from agent.run() resources.\n * Returns an empty RunEvents if no events key is present.\n */\nexport function extractRunEvents(resources: Record<string, unknown>): RunEvents {\n const raw = resources['events']\n if (raw === null || typeof raw !== 'object' || Array.isArray(raw)) {\n return {}\n }\n // plain object: return as-is; callbacks are optional and missing keys are undefined\n return raw as RunEvents // as: duck-typed plain object confirmed above; RunEvents fields are all optional\n}\n","/**\n * Identifies the agent and session for run-level observer callbacks.\n */\nexport interface RunContext {\n readonly agentId: string\n readonly sessionId: string\n /**\n * The UUID for this specific run invocation. Always present in RunContext\n * passed to observer methods.\n */\n readonly runId: string\n /**\n * Optional parent run UUID for cross-process trace correlation. Present\n * when parentRunId was passed to agent.run() resources. Absent for top-level\n * runs or when not provided by the caller.\n */\n readonly parentRunId?: string\n /**\n * The physical instance ID of the agent process, if configured via\n * `createAgent()` options. Absent when `instanceId` was not provided.\n */\n readonly instanceId?: string\n}\n\n/**\n * Identifies the agent, session, and current step for step-level observer callbacks.\n */\nexport interface StepContext {\n readonly agentId: string\n readonly sessionId: string\n readonly stepName: string\n}\n\n/**\n * Observability hook interface. All methods are optional — implement only\n * the hooks you need.\n *\n * Pass an `Observer` implementation in `agent.run()` resources under the key\n * `'observer'`, or bind it to an {@link ObserverAware} slot before running.\n *\n * LLM adapters emit `'llm.response'` events via `onEvent` carrying an\n * `LLMUsageEvent` payload for token tracking.\n *\n * @example\n * ```ts\n * const obs: Observer = {\n * onRunStart: (ctx) => console.log('run started', ctx.sessionId),\n * onEvent: (ctx, type, payload) => metrics.record(type, payload),\n * }\n * agent.run({}, { llm, observer: obs })\n * ```\n */\nexport interface Observer {\n /** Called once when a run begins, before the first step executes. */\n onRunStart?: (ctx: RunContext) => void\n /** Called once when a run settles (completed or stopped). */\n onRunEnd?: (ctx: RunContext, event: { signal: string; durationMs: number }) => void\n /** Called immediately before each step's `run` function is invoked. */\n onStepStart?: (ctx: StepContext) => void\n /** Called after a step completes successfully. */\n onStepEnd?: (ctx: StepContext, event: { durationMs: number }) => void\n /** Called when a step's `run` function throws. */\n onStepError?: (ctx: StepContext, event: { error: unknown; durationMs: number }) => void\n /** Called when a step issues a `ctx.interrupt()`. */\n onInterrupt?: (ctx: StepContext, event: { prompt: unknown; interruptId: string }) => void\n /**\n * Called for arbitrary named events emitted by step code via `ctx.emit()` or\n * by LLM adapters (e.g. `'llm.response'`).\n */\n onEvent?: (ctx: StepContext, type: string, payload: unknown) => void\n}\n\n/**\n * Implemented by resources (e.g. LLM adapters) that accept an {@link Observer}\n * at run time. The harness calls `bindObserver` on every slot value that\n * implements this interface before the first step runs.\n *\n * Optionally, the harness calls `setStepContext` at the start of each step for\n * every slot that exposes it. Adapters use this to attribute per-step telemetry\n * (e.g. `observer.onEvent`) to the correct step without manual calls from step code.\n */\nexport interface ObserverAware {\n /**\n * Receive the run's observer. The harness calls this once per `agent.run()`\n * invocation before execution begins.\n */\n bindObserver(observer: Observer): void\n\n /**\n * Receive the current step context. The harness calls this at the start of\n * each step for every slot that exposes this method, before calling `step.run`.\n *\n * Adapters that emit `observer.onEvent` in their `invoke()` method store the\n * provided `StepContext` and use it as the first argument to `onEvent`, so\n * events are attributed to the correct step automatically.\n */\n setStepContext?(ctx: StepContext): void\n}\n\n/**\n * Combine multiple {@link Observer} instances into one. Each hook on the\n * composite forwards to all constituent observers in order.\n *\n * @example\n * ```ts\n * const observer = composeObservers(otelObserver, metricsObserver)\n * ```\n */\nexport function composeObservers(...observers: Observer[]): Observer {\n return {\n onRunStart: (ctx) => {\n for (const o of observers) o.onRunStart?.(ctx)\n },\n onRunEnd: (ctx, event) => {\n for (const o of observers) o.onRunEnd?.(ctx, event)\n },\n onStepStart: (ctx) => {\n for (const o of observers) o.onStepStart?.(ctx)\n },\n onStepEnd: (ctx, event) => {\n for (const o of observers) o.onStepEnd?.(ctx, event)\n },\n onStepError: (ctx, event) => {\n for (const o of observers) o.onStepError?.(ctx, event)\n },\n onInterrupt: (ctx, event) => {\n for (const o of observers) o.onInterrupt?.(ctx, event)\n },\n onEvent: (ctx, type, payload) => {\n for (const o of observers) o.onEvent?.(ctx, type, payload)\n },\n }\n}\n"],"mappings":"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","names":["field","state","result","r"]}
|
|
1
|
+
{"version":3,"sources":["../src/harness/state-field.ts","../src/harness/ctx-markers.ts","../src/loop/loop-dsl.ts","../src/loop/loop-validator.ts","../src/harness/harness-builder.ts","../src/agent/ctx-interrupt.ts","../src/agent/ctx-emit.ts","../src/loop/loop-executor.ts","../src/agent/session-store.ts","../src/agent/concurrency-errors.ts","../src/agent/ctx-keep-alive.ts","../src/agent/session-lifecycle.ts","../src/agent/interrupt-resume.ts","../src/agent/run-handle.ts","../src/agent/create-agent.ts","../src/agent/event-callbacks.ts","../src/agent/observer.ts"],"sourcesContent":["// Phantom symbol — never accessible at runtime; required for reliable T inference\n// even when neither `default` nor `reduce` is provided\ndeclare const _fieldType: unique symbol\n\n/**\n * Descriptor for a single state field, produced by {@link field}.\n *\n * - `default` — factory called once on session start to populate the field when no\n * initial value is supplied.\n * - `reduce` — merge function invoked on resume: `reduce(storedValue, incomingValue)`.\n * When absent, incoming values overwrite stored ones on resume.\n */\nexport type FieldDefinition<T> = {\n readonly [_fieldType]: T\n readonly default?: () => T\n readonly reduce?: (current: T, update: T) => T\n}\n\n/**\n * Derives the concrete state record type from a schema object whose values are\n * {@link FieldDefinition} descriptors.\n *\n * @example\n * ```ts\n * const schema = { count: field<number>({ default: () => 0 }) }\n * type State = StateFromSchema<typeof schema> // { count: number }\n * ```\n */\n// use FieldDefinition<any> in bounds, not FieldDefinition<unknown> — reduce makes T invariant\nexport type StateFromSchema<S> = {\n [K in keyof S]: S[K] extends FieldDefinition<infer T> ? T : never\n}\n\ntype FieldOptions<T> = {\n default?: () => T\n reduce?: (current: T, update: T) => T\n}\n\n/**\n * Declare a typed state field with an optional default factory and optional\n * reduce function.\n *\n * @param options.default - Factory called once at session start.\n * @param options.reduce - Merge function for resume: `(stored, incoming) => merged`.\n *\n * @example\n * ```ts\n * const schema = {\n * messages: field<string[]>({ default: () => [], reduce: (a, b) => [...a, ...b] }),\n * }\n * ```\n */\nexport function field<T>(options?: FieldOptions<T>): FieldDefinition<T> {\n return { ...options } as FieldDefinition<T> // as: phantom [_fieldType] is type-level only; the runtime object can never carry the symbol property\n}\n","/** @internal Discriminant tag for {@link RequiredMarker}. */\nexport const REQUIRED_TAG = '__noetaris_required__' as const\n/** @internal Discriminant tag for {@link RuntimeMarker}. */\nexport const RUNTIME_TAG = '__noetaris_runtime__' as const\n\n// string literal _tag is the sole type-level discriminant; phantom symbols were tried but\n// TypeScript does not enforce non-exported unique symbol keys across module boundaries\n\n/**\n * Sentinel returned by {@link required} to mark a context slot that **must** be\n * supplied at `createAgent()` time (not at `agent.run()` time).\n */\nexport type RequiredMarker = { readonly _tag: typeof REQUIRED_TAG }\n\n/**\n * Sentinel returned by {@link runtime} to mark a context slot that **must** be\n * supplied at `agent.run()` time (not at `createAgent()` time).\n */\nexport type RuntimeMarker = { readonly _tag: typeof RUNTIME_TAG }\n\n// function guard prevents TypeScript from recursing into Function's own method properties\n// (call, bind, apply, etc.) when T is a function type, which would make the mapped type\n// unresolvable and break @ts-expect-error enforcement on concrete value checks\n/**\n * Recursive variant of `T` that allows any nested position to also be a\n * {@link RequiredMarker} or {@link RuntimeMarker}. Used as the `value`\n * parameter type on {@link Harness.provide}.\n */\nexport type DeepWithMarkers<T> =\n T extends (...args: any[]) => any\n ? T | RequiredMarker | RuntimeMarker\n : T extends object\n ? { [K in keyof T]: DeepWithMarkers<T[K]> | RequiredMarker | RuntimeMarker } | RequiredMarker | RuntimeMarker\n : T | RequiredMarker | RuntimeMarker\n\n/**\n * Return a {@link RequiredMarker} sentinel that instructs the harness to\n * require this slot at `createAgent()` time.\n *\n * @example\n * ```ts\n * h.provide('llm', required())\n * ```\n */\nexport function required(): RequiredMarker {\n return { _tag: REQUIRED_TAG }\n}\n\n/**\n * Return a {@link RuntimeMarker} sentinel that instructs the harness to\n * require this slot at `agent.run()` time instead of `createAgent()` time.\n *\n * @example\n * ```ts\n * h.provide('signal', runtime())\n * ```\n */\nexport function runtime(): RuntimeMarker {\n return { _tag: RUNTIME_TAG }\n}\n\n/**\n * Type guard — returns `true` when `value` is a {@link RequiredMarker}.\n */\nexport function isRequiredMarker(value: unknown): value is RequiredMarker {\n return value !== null && typeof value === 'object' && '_tag' in value && value._tag === REQUIRED_TAG\n}\n\n/**\n * Type guard — returns `true` when `value` is a {@link RuntimeMarker}.\n */\nexport function isRuntimeMarker(value: unknown): value is RuntimeMarker {\n return value !== null && typeof value === 'object' && '_tag' in value && value._tag === RUNTIME_TAG\n}\n","import type { KeepAliveFn } from '../agent/ctx-keep-alive.js'\n\n// -----------------------------------------------------------------------\n// Framework-reserved state fields — readable in run/route, not writable from run return\n// -----------------------------------------------------------------------\n\n/**\n * Framework-managed fields injected into every step function's `state` argument.\n *\n * - `$error` — the `Error` thrown by the previous step, or `null` if no error occurred.\n * Only populated on the error path; non-error-aware steps never see a non-null value here.\n * - `$interrupt` — set while a step is awaiting a resume response. The `response` field\n * is populated after {@link Agent.resume} is called.\n */\nexport interface FrameworkState {\n readonly $error: Error | null\n readonly $interrupt: {\n readonly interruptId: string\n readonly prompt: unknown\n readonly response?: unknown\n } | null\n}\n\n/**\n * The complete state type visible inside {@link RunFn} step functions:\n * the user-defined state `S` merged with {@link FrameworkState}.\n */\nexport type StepState<S> = S & FrameworkState\n\n// -----------------------------------------------------------------------\n// Step function signatures\n// -----------------------------------------------------------------------\n\n/**\n * State transformer. Receives the full step state and ctx; returns a partial update\n * of user-defined state fields only (framework-reserved fields are excluded from return).\n * May be async.\n */\nexport type RunFn<S, Ctx> = (\n state: StepState<S>,\n ctx: Ctx & {\n readonly agentId: string\n readonly sessionId: string\n readonly runId: string\n readonly signal: AbortSignal\n readonly interrupt: (prompt: unknown, id?: string) => Promise<unknown>\n readonly emit: (name: string, payload?: unknown) => void\n readonly keepAlive: KeepAliveFn\n },\n) => Promise<Partial<Omit<S, '$error' | '$interrupt'>>> | Partial<Omit<S, '$error' | '$interrupt'>>\n\n/**\n * Pure signal emitter. Receives step state without $error — the route is not called on the error\n * path unless the step opts in via `optin: '$error'` in the step config. Synchronous by design.\n * No ctx — pure read only.\n */\nexport type RouteFn<S> = (state: S & Omit<FrameworkState, '$error'>) => string\n\n/**\n * Pure signal emitter for error-aware steps (optin: '$error').\n * Receives the full step state including $error — the executor calls this on both the success\n * and error paths. Declare `optin: '$error'` in the step config to use this variant.\n */\nexport type ErrorAwareRouteFn<S> = (state: StepState<S>) => string\n\n/**\n * Options passed to `.step(name, options)`. At least one of `run` or `route` must be set.\n *\n * Two variants:\n * - Without `optin`: route receives state without `$error` (TypeScript-enforced). On error,\n * the framework falls through to `l.onError()` or pauses with `signal: \"$error\"` automatically.\n * - With `optin: '$error'`: route receives the full state including `$error`, and the executor\n * calls route on the error path. Use this when the step's route needs to inspect or handle errors.\n */\nexport type StepOptions<S, Ctx> =\n | {\n readonly optin: '$error'\n run?: RunFn<S, Ctx>\n route?: ErrorAwareRouteFn<S>\n }\n | {\n readonly optin?: undefined\n run?: RunFn<S, Ctx>\n route?: RouteFn<S>\n }\n\n// -----------------------------------------------------------------------\n// LoopDefinition — the captured topology produced by the builder\n// -----------------------------------------------------------------------\n\n/**\n * Where a signal transition routes to.\n * 'step' — routes to the named step.\n * 'end' — exits the loop; run resolves with the emitted signal.\n */\nexport type TransitionTarget =\n | { readonly kind: 'step'; readonly name: string }\n | { readonly kind: 'end' }\n\n/** A single `.on(signal).to(step)` or `.on(signal).end()` declaration. */\nexport interface SignalTransition {\n readonly signal: string\n readonly target: TransitionTarget\n}\n\n/**\n * Compiled step definition stored in LoopDefinition.\n * run and route are stored as-is (user functions — validated structurally, not semantically).\n * transitions: all .on() declarations attached to this step.\n * next: explicit .next(name) target, or undefined if none declared.\n * errorAware: true when the step was declared with optin: '$error' — the executor calls route\n * on the error path when this is true.\n */\nexport interface StepDef {\n readonly name: string\n readonly run: RunFn<unknown, unknown> | undefined\n readonly route: RouteFn<unknown> | undefined\n readonly transitions: readonly SignalTransition[]\n readonly next: string | undefined\n readonly errorAware: boolean\n}\n\n/**\n * Complete loop topology captured from the builder lambda.\n * Immutable snapshot — produced once, consumed by LoopValidator and (later) F6.\n *\n * startCalled: true if l.start() was invoked at least once.\n * entryStep: name of the first .step() declared after .start() was called; undefined if .start()\n * was never called or no step was declared after it.\n * steps: all declared steps in declaration order.\n * onError: the fallback step name from l.onError(), or undefined if not set.\n */\nexport interface LoopDefinition {\n readonly startCalled: boolean\n readonly entryStep: string | undefined\n readonly steps: readonly StepDef[]\n readonly onError: string | undefined\n}\n\n// -----------------------------------------------------------------------\n// LoopBuilder — the DSL object passed to the h.loop() builder lambda\n// -----------------------------------------------------------------------\n\n/**\n * Fluent chain returned by .on(signal). Caller must call either .to(step) or .end()\n * to complete the transition declaration.\n */\nexport interface OnChain<S, Ctx> {\n /** Route the signal to the named step. Returns the builder for further chaining. */\n to(step: string): LoopBuilder<S, Ctx>\n /** Exit the loop when this signal is emitted. Returns the builder for further chaining. */\n end(): LoopBuilder<S, Ctx>\n}\n\n/**\n * The DSL object passed as `l` to the h.loop(l => ...) builder lambda.\n * All methods mutate internal state and return `this` for chaining.\n */\nexport interface LoopBuilder<S, Ctx> {\n /** Mark the loop as having a declared entry. The first .step() called after .start() is the entry. */\n start(): LoopBuilder<S, Ctx>\n /** Declare a step. At least one of run or route must be set (validated later by LoopValidator). */\n step(name: string, options: StepOptions<S, Ctx>): LoopBuilder<S, Ctx>\n /**\n * Begin a signal transition declaration. Must be called immediately after .step() or after\n * a previous .on().to() or .on().end() chain (attaches to the most recently declared step).\n */\n on(signal: string): OnChain<S, Ctx>\n /**\n * Declare an explicit unconditional next target for the most recently declared step.\n * Mutually exclusive with route (validated by LoopValidator).\n */\n next(name: string): LoopBuilder<S, Ctx>\n /**\n * Declare a loop-level fallback error step. Any step whose run throws and whose\n * route does not handle $error will route to this step instead of pausing the session.\n * Only one onError target per loop; multiple calls replace the previous target (last wins).\n */\n onError(step: string): LoopBuilder<S, Ctx>\n}\n\n// -----------------------------------------------------------------------\n// Error class\n// -----------------------------------------------------------------------\n\n/** Thrown by extractLoopDefinition when the argument is not a createLoopBuilder() instance. */\nexport class InvalidLoopBuilderError extends Error {\n constructor() {\n super('argument is not a LoopBuilder instance — was it created by createLoopBuilder?')\n this.name = 'InvalidLoopBuilderError'\n }\n}\n\n// -----------------------------------------------------------------------\n// Internal implementation\n// -----------------------------------------------------------------------\n\n// Module-private symbol for internal state\nconst _builderState = Symbol('builderState')\n\n// Internal mutable step definition during collection\ninterface StepDefMutable {\n name: string\n run: RunFn<unknown, unknown> | undefined\n route: RouteFn<unknown> | undefined\n transitions: SignalTransition[]\n next: string | undefined\n errorAware: boolean\n}\n\n// Internal mutable builder state\ninterface BuilderState {\n startCalled: boolean\n entryStep: string | undefined\n steps: StepDefMutable[]\n onError: string | undefined\n}\n\n// Deep freeze utility\nfunction deepFreeze<T extends object>(obj: T): T {\n Object.freeze(obj)\n\n for (const value of Object.values(obj)) {\n if (value !== null && typeof value === 'object' && !Object.isFrozen(value)) {\n deepFreeze(value)\n }\n }\n\n return obj\n}\n\n/**\n * Create a new LoopBuilder instance for use in a h.loop() lambda.\n * The returned object accumulates all DSL calls in mutable internal state.\n */\nexport function createLoopBuilder<S, Ctx>(): LoopBuilder<S, Ctx> {\n const state: BuilderState = {\n startCalled: false,\n entryStep: undefined,\n steps: [],\n onError: undefined,\n }\n\n const builder: any = {\n start(this: any): LoopBuilder<S, Ctx> {\n state.startCalled = true\n return this\n },\n\n step(this: any, name: string, options: StepOptions<S, Ctx>): LoopBuilder<S, Ctx> {\n const stepDef: StepDefMutable = {\n name,\n run: options.run as RunFn<unknown, unknown> | undefined, // as: contravariance in state parameter\n route: options.route as RouteFn<unknown> | undefined, // as: contravariance in state parameter\n transitions: [],\n next: undefined,\n errorAware: options.optin === '$error',\n }\n state.steps.push(stepDef)\n\n // Set entryStep to the first step after start() was called\n if (state.startCalled && state.entryStep === undefined) {\n state.entryStep = name\n }\n\n return this\n },\n\n on(this: any, signal: string): OnChain<S, Ctx> {\n // Guard: if no step has been declared yet, return no-op OnChain\n if (state.steps.length === 0) {\n return {\n to: () => this,\n end: () => this,\n }\n }\n\n const currentStep = state.steps.at(-1)\n\n return {\n to: (step: string): LoopBuilder<S, Ctx> => {\n currentStep?.transitions.push({\n signal,\n target: { kind: 'step', name: step },\n })\n return this\n },\n end: (): LoopBuilder<S, Ctx> => {\n currentStep?.transitions.push({\n signal,\n target: { kind: 'end' },\n })\n return this\n },\n }\n },\n\n next(this: any, name: string): LoopBuilder<S, Ctx> {\n // Guard: if no step has been declared yet, this is a no-op\n if (state.steps.length > 0) {\n const currentStep = state.steps.at(-1)\n if (currentStep !== undefined) {\n currentStep.next = name\n }\n }\n return this\n },\n\n onError(this: any, step: string): LoopBuilder<S, Ctx> {\n state.onError = step\n return this\n },\n }\n\n // Attach the internal state symbol\n ;(builder as any)[_builderState] = state\n\n return builder as LoopBuilder<S, Ctx>\n}\n\n/**\n * Extract the LoopDefinition accumulated by a builder created with createLoopBuilder().\n * Called by harness-builder.ts immediately after the user's builder lambda returns.\n * Throws InvalidLoopBuilderError if the argument was not produced by createLoopBuilder().\n */\nexport function extractLoopDefinition(builder: LoopBuilder<unknown, unknown>): LoopDefinition {\n // Identity check: ensure builder has the internal state symbol\n if (builder === null || builder === undefined || !(_builderState in builder)) {\n throw new InvalidLoopBuilderError()\n }\n\n const state = (builder as any)[_builderState] as BuilderState\n\n // Convert mutable step definitions to immutable ones\n const immutableSteps: StepDef[] = state.steps.map((step) => {\n const transitions = Object.freeze([...step.transitions]) as readonly SignalTransition[]\n // Freeze each transition\n for (const transition of transitions) {\n Object.freeze(transition)\n Object.freeze(transition.target)\n }\n const stepDef: StepDef = {\n name: step.name,\n run: step.run,\n route: step.route,\n transitions,\n next: step.next,\n errorAware: step.errorAware,\n }\n return Object.freeze(stepDef)\n })\n\n // Create the frozen LoopDefinition\n const definition: LoopDefinition = {\n startCalled: state.startCalled,\n entryStep: state.entryStep,\n steps: Object.freeze(immutableSteps),\n onError: state.onError,\n }\n\n // Deep freeze the entire structure\n return deepFreeze(definition)\n}\n","import type { LoopDefinition } from './loop-dsl.js'\n\n// -----------------------------------------------------------------------\n// Error class\n// -----------------------------------------------------------------------\n\n/**\n * Thrown by validateLoop() when the LoopDefinition violates one or more structural rules.\n * violations: every rule violation found, as human-readable strings.\n * The full list is always reported — validateLoop() never fails fast on the first violation.\n */\nexport class LoopValidationError extends Error {\n readonly violations: readonly string[]\n\n constructor(violations: readonly string[]) {\n super(`loop validation failed:\\n${violations.map((v) => ` - ${v}`).join('\\n')}`)\n this.name = 'LoopValidationError'\n this.violations = violations\n }\n}\n\n// -----------------------------------------------------------------------\n// Public API\n// -----------------------------------------------------------------------\n\n/**\n * Validate a LoopDefinition against all structural rules.\n * Collects every violation before throwing, so developers see the full picture.\n *\n * @param def - a LoopDefinition produced by extractLoopDefinition()\n * @throws LoopValidationError if one or more validation rules are violated\n */\nexport function validateLoop(def: LoopDefinition): void {\n const violations: string[] = []\n\n // Build a set of all declared step names once — reuse for rules 6 and 8\n const names = new Set(def.steps.map((s) => s.name))\n\n // -----------------------------------------------------------------------\n // Rule 1 — Every step has at least `run` or `route`\n // -----------------------------------------------------------------------\n for (const step of def.steps) {\n if (step.run === undefined && step.route === undefined) {\n violations.push(`step \"${step.name}\" must have at least one of run or route`)\n }\n }\n\n // -----------------------------------------------------------------------\n // Rule 2 — A step with `route` must have at least one `.on()` transition\n // -----------------------------------------------------------------------\n for (const step of def.steps) {\n if (step.route !== undefined && step.transitions.length === 0) {\n violations.push(`step \"${step.name}\" has route but no .on() transitions — every signal must be handled`)\n }\n }\n\n // -----------------------------------------------------------------------\n // Rule 3 — A step without `route` must have a next target\n // -----------------------------------------------------------------------\n for (const [i, step] of def.steps.entries()) {\n if (step === undefined) continue\n if (step.route === undefined) {\n // Non-last steps have implicit next = the following step; they satisfy rule 3\n // Last step must have explicit next or be unreachable via rule 8\n const isLast = i === def.steps.length - 1\n if (isLast && step.next === undefined) {\n violations.push(\n `step \"${step.name}\" has no route, no explicit .next(), and no following step — no exit path`,\n )\n }\n }\n }\n\n // -----------------------------------------------------------------------\n // Rule 4 — A step cannot have both `route` and `.next()`\n // -----------------------------------------------------------------------\n for (const step of def.steps) {\n if (step.route !== undefined && step.next !== undefined) {\n violations.push(`step \"${step.name}\" has both route and .next() — these are mutually exclusive`)\n }\n }\n\n // -----------------------------------------------------------------------\n // Rule 5 — No duplicate step names\n // -----------------------------------------------------------------------\n const seen = new Set<string>()\n for (const step of def.steps) {\n if (seen.has(step.name)) {\n violations.push(`duplicate step name \"${step.name}\"`)\n }\n seen.add(step.name)\n }\n\n // -----------------------------------------------------------------------\n // Rule 6 — All `.to(name)` targets, `.next()` targets, and `onError` target\n // must reference a declared step\n // -----------------------------------------------------------------------\n for (const step of def.steps) {\n for (const transition of step.transitions) {\n if (transition.target.kind === 'step') {\n if (!names.has(transition.target.name)) {\n violations.push(\n `step \"${step.name}\" has .on(\"${transition.signal}\").to(\"${transition.target.name}\") but step \"${transition.target.name}\" is not declared`,\n )\n }\n }\n }\n\n if (step.next !== undefined) {\n if (!names.has(step.next)) {\n violations.push(\n `step \"${step.name}\" has .next(\"${step.next}\") but step \"${step.next}\" is not declared`,\n )\n }\n }\n }\n\n if (def.onError !== undefined) {\n if (!names.has(def.onError)) {\n violations.push(`onError target \"${def.onError}\" is not a declared step`)\n }\n }\n\n // -----------------------------------------------------------------------\n // Rule 7 — The loop must have an entry (`.start()`) and at least one exit (`.end()`)\n // -----------------------------------------------------------------------\n if (def.startCalled === false) {\n violations.push(`loop is missing .start() — call l.start() before declaring steps`)\n }\n\n if (def.startCalled && def.entryStep === undefined) {\n violations.push(`l.start() was called but no step was declared after it — declare at least one step`)\n }\n\n // Check for at least one exit (.end())\n let hasExit = false\n for (const step of def.steps) {\n for (const transition of step.transitions) {\n if (transition.target.kind === 'end') {\n hasExit = true\n break\n }\n }\n if (hasExit) break\n }\n\n if (!hasExit) {\n violations.push(`loop has no exit — add at least one .on(\"<signal>\").end()`)\n }\n\n // -----------------------------------------------------------------------\n // Rule 8 — No unreachable steps\n // -----------------------------------------------------------------------\n // Only checked if def.entryStep !== undefined (rule 7 covers missing entry)\n if (def.entryStep !== undefined) {\n // BFS from entryStep to find all reachable steps\n const reachable = new Set<string>([def.entryStep])\n const queue: string[] = [def.entryStep]\n\n // Also mark onError target as reachable upfront\n if (def.onError !== undefined) {\n reachable.add(def.onError)\n if (!queue.includes(def.onError)) {\n queue.push(def.onError)\n }\n }\n\n while (queue.length > 0) {\n const currentName = queue.shift()!\n const currentStep = def.steps.find((s) => s.name === currentName)\n\n if (!currentStep) continue\n\n // Add all steps reachable via signal transitions\n for (const transition of currentStep.transitions) {\n if (transition.target.kind === 'step') {\n if (!reachable.has(transition.target.name)) {\n reachable.add(transition.target.name)\n queue.push(transition.target.name)\n }\n }\n }\n\n // Add next target if explicit or implicit\n if (currentStep.route !== undefined) {\n // Step has route, so no implicit next\n if (currentStep.next !== undefined && !reachable.has(currentStep.next)) {\n reachable.add(currentStep.next)\n queue.push(currentStep.next)\n }\n } else {\n // Step has no route: follow explicit next or implicit next\n if (currentStep.next !== undefined) {\n if (!reachable.has(currentStep.next)) {\n reachable.add(currentStep.next)\n queue.push(currentStep.next)\n }\n } else {\n // Implicit next: the following step in def.steps, if any\n const currentIndex = def.steps.findIndex((s) => s.name === currentName)\n if (currentIndex !== -1 && currentIndex < def.steps.length - 1) {\n const nextStep = def.steps[currentIndex + 1]\n if (nextStep !== undefined) {\n const nextStepName = nextStep.name\n if (!reachable.has(nextStepName)) {\n reachable.add(nextStepName)\n queue.push(nextStepName)\n }\n }\n }\n }\n }\n }\n\n // Check for unreachable steps\n for (const step of def.steps) {\n if (!reachable.has(step.name)) {\n violations.push(`step \"${step.name}\" is unreachable from the entry step \"${def.entryStep}\"`)\n }\n }\n }\n\n // -----------------------------------------------------------------------\n // Rule 9 (derived) — A step without `route` must not declare `.on()` signal transitions\n // -----------------------------------------------------------------------\n for (const step of def.steps) {\n if (step.route === undefined && step.transitions.length > 0) {\n violations.push(\n `step \"${step.name}\" has .on() transitions but no route — .on() is only valid when route is set`,\n )\n }\n }\n\n // -----------------------------------------------------------------------\n // Throw if any violations found\n // -----------------------------------------------------------------------\n if (violations.length > 0) {\n throw new LoopValidationError(violations)\n }\n}\n","import type { FieldDefinition, StateFromSchema } from './state-field.js'\nimport type { RequiredMarker, RuntimeMarker, DeepWithMarkers } from './ctx-markers.js'\nimport type { LoopBuilder, LoopDefinition } from '../loop/loop-dsl.js'\nimport { createLoopBuilder, extractLoopDefinition } from '../loop/loop-dsl.js'\nimport { validateLoop } from '../loop/loop-validator.js'\n\n// -----------------------------------------------------------------------\n// Harness type — accumulated at the type level across provide() calls\n// -----------------------------------------------------------------------\n\n/**\n * Immutable builder that accumulates context-slot declarations, store bindings,\n * and the loop definition for an agent. Produced by {@link createHarness} and\n * consumed by {@link createAgent}.\n *\n * The four type parameters track what has been declared so far:\n * - `Ctx` — the full context shape expected by step functions.\n * - `State` — the state record shape derived from the schema passed to `createHarness()`.\n * - `Req` — keys declared as {@link required} (must be supplied to `createAgent`).\n * - `Run` — keys declared as {@link runtime} (must be supplied to `agent.run()`).\n *\n * Each call returns a **new** `Harness` instance; the original is unchanged.\n *\n * @example\n * ```ts\n * const h = createHarness<Ctx>()(schema)\n * .provide('llm', required())\n * .provide('model', 'claude-3-5-haiku-20241022')\n * .store({ session: new InMemorySessionStore() })\n * .loop(l => {\n * l.start().step('run', { run, route }).on('done').end()\n * })\n * ```\n */\nexport type Harness<\n Ctx,\n State,\n Req extends keyof Ctx = never,\n Run extends keyof Ctx = never,\n> = {\n /**\n * Declare a context slot.\n *\n * - Pass {@link required} to require the value at `createAgent()` time.\n * - Pass {@link runtime} to require the value at `agent.run()` time.\n * - Pass any concrete value (or a deep object mixing in markers) to bind it now.\n */\n provide<K extends keyof Ctx>(key: K, value: RequiredMarker): Harness<Ctx, State, Req | K, Run>\n provide<K extends keyof Ctx>(key: K, value: RuntimeMarker): Harness<Ctx, State, Req, Run | K>\n provide<K extends keyof Ctx>(key: K, value: DeepWithMarkers<Ctx[K]>): Harness<Ctx, State, Req, Run>\n\n /**\n * Bind session store(s). Pass `{ session: myStore }` to enable persistence and\n * interrupt/resume across processes.\n */\n // store() Req/Run are not affected at the type level; nested markers are runtime-validated only (F2 spike constraint)\n store(stores: DeepWithMarkers<{ session?: unknown } & Record<string, unknown>>): Harness<Ctx, State, Req, Run>\n\n /**\n * Define the execution loop using the {@link LoopBuilder} DSL.\n *\n * @param builder - Callback that receives a `LoopBuilder` and uses it to\n * declare steps, transitions, and the entry point.\n */\n // loop() parameter is LoopBuilder<State, Ctx> after F4 implementation\n loop(builder: (l: LoopBuilder<State, Ctx>) => void): Harness<Ctx, State, Req, Run>\n\n /**\n * Return the frozen {@link LoopDefinition} captured when {@link loop} was called.\n *\n * @throws {LoopNotDefinedError} if `h.loop()` has not been called on this harness instance.\n */\n definition(): LoopDefinition\n}\n\n// -----------------------------------------------------------------------\n// ProviderEntry — one entry produced by each provide() or store() call\n// -----------------------------------------------------------------------\n\nexport interface ProviderEntry {\n readonly kind: 'provide' | 'store'\n readonly key: string\n readonly value: unknown\n}\n\n// -----------------------------------------------------------------------\n// HarnessInternals — the structural contract between HarnessBuilder and createAgent (F5)\n// -----------------------------------------------------------------------\n\n// _req, _run, _state are type witnesses: never assigned at runtime, carry type-level info to F5\nexport interface HarnessInternals<\n Ctx,\n State,\n Req extends keyof Ctx,\n Run extends keyof Ctx,\n> {\n readonly stateSchema: Record<string, FieldDefinition<unknown>> | undefined\n readonly providers: readonly ProviderEntry[]\n readonly loopDef: LoopDefinition | undefined\n readonly _req: Req | undefined\n readonly _run: Run | undefined\n readonly _state: State | undefined\n}\n\n// -----------------------------------------------------------------------\n// Internal accessor — used by createAgent (F5) to unwrap internals\n// -----------------------------------------------------------------------\n\n// symbol key is module-private; external code cannot read or forge the internals slot\nconst _internals = Symbol('_internals')\n\nexport type HarnessWithInternals<\n Ctx,\n State,\n Req extends keyof Ctx,\n Run extends keyof Ctx,\n> = Harness<Ctx, State, Req, Run> & {\n readonly [_internals]: HarnessInternals<Ctx, State, Req, Run>\n}\n\nexport function getInternals<\n Ctx,\n State,\n Req extends keyof Ctx,\n Run extends keyof Ctx,\n>(harness: Harness<Ctx, State, Req, Run>): HarnessInternals<Ctx, State, Req, Run> {\n if (harness === null || typeof harness !== 'object' || !(_internals in harness)) {\n throw new HarnessInternalsError()\n }\n return (harness as HarnessWithInternals<Ctx, State, Req, Run>)[_internals] // as: `_internals in harness` check above guarantees the symbol key is present\n}\n\n// -----------------------------------------------------------------------\n// Error class\n// -----------------------------------------------------------------------\n\n/** @internal Thrown when {@link getInternals} is called on a non-harness value. */\nexport class HarnessInternalsError extends Error {\n constructor() {\n super('value is not a HarnessBuilder instance — was it created by createHarness?')\n this.name = 'HarnessInternalsError'\n }\n}\n\n/**\n * Thrown by {@link Harness.definition} when `h.loop()` has not been called yet.\n */\nexport class LoopNotDefinedError extends Error {\n constructor() {\n super('loop is not defined — call h.loop() before accessing h.definition()')\n this.name = 'LoopNotDefinedError'\n }\n}\n\n// -----------------------------------------------------------------------\n// createHarness — the public factory\n// -----------------------------------------------------------------------\n\n/**\n * Create a harness builder for the given context type.\n *\n * Call the returned function (optionally with a state schema) to get the\n * {@link Harness} builder on which you chain `.provide()`, `.store()`, and `.loop()`.\n *\n * @example\n * ```ts\n * interface Ctx { llm: LLM; model: string }\n * const schema = { messages: field<string[]>({ default: () => [] }) }\n *\n * const h = createHarness<Ctx>()(schema)\n * ```\n */\nexport function createHarness<Ctx = any>(): <S extends object = {}>( // any: allows createHarness() without an explicit Ctx type parameter\n stateSchema?: S,\n) => Harness<Ctx, StateFromSchema<S>> {\n return <S extends object = {}>(stateSchema?: S): Harness<Ctx, StateFromSchema<S>> => {\n const internals: HarnessInternals<Ctx, StateFromSchema<S>, never, never> = {\n stateSchema: stateSchema as Record<string, FieldDefinition<unknown>> | undefined, // as: S extends object; cast to internal schema representation\n providers: Object.freeze([]),\n loopDef: undefined,\n _req: undefined,\n _run: undefined,\n _state: undefined,\n }\n\n return createBuilderInstance(internals)\n }\n}\n\nfunction createBuilderInstance<\n Ctx,\n State,\n Req extends keyof Ctx = never,\n Run extends keyof Ctx = never,\n>(internals: HarnessInternals<Ctx, State, Req, Run>): HarnessWithInternals<Ctx, State, Req, Run> {\n const builder: any = { // any: TypeScript cannot infer overloaded call signatures from object literal method definitions\n provide<K extends keyof Ctx>(\n key: K,\n value: RequiredMarker | RuntimeMarker | DeepWithMarkers<Ctx[K]>,\n ): Harness<Ctx, State, any, any> { // any: Req/Run accumulation is tracked at the type level via overloads; method body uses any to avoid inference conflicts\n const newProviders = Object.freeze([\n ...internals.providers,\n { kind: 'provide' as const, key: String(key), value },\n ])\n const newInternals: HarnessInternals<Ctx, State, any, any> = { // any: same reason as return type annotation above\n stateSchema: internals.stateSchema,\n providers: newProviders,\n loopDef: internals.loopDef,\n _req: undefined,\n _run: undefined,\n _state: undefined,\n }\n return createBuilderInstance(newInternals)\n },\n\n store(stores: DeepWithMarkers<{ session?: unknown } & Record<string, unknown>>): Harness<Ctx, State, Req, Run> {\n const newProviders = Object.freeze([\n ...internals.providers,\n { kind: 'store' as const, key: '__store__', value: stores },\n ])\n const newInternals: HarnessInternals<Ctx, State, Req, Run> = {\n stateSchema: internals.stateSchema,\n providers: newProviders,\n loopDef: internals.loopDef,\n _req: undefined,\n _run: undefined,\n _state: undefined,\n }\n return createBuilderInstance(newInternals)\n },\n\n loop(builderFn: (l: LoopBuilder<State, Ctx>) => void): Harness<Ctx, State, Req, Run> {\n const lb = createLoopBuilder<State, Ctx>()\n builderFn(lb)\n const def = extractLoopDefinition(lb as LoopBuilder<unknown, unknown>) // as: generic S/Ctx erased for internal storage\n validateLoop(def)\n const newInternals: HarnessInternals<Ctx, State, Req, Run> = {\n stateSchema: internals.stateSchema,\n providers: internals.providers,\n loopDef: def,\n _req: undefined,\n _run: undefined,\n _state: undefined,\n }\n return createBuilderInstance(newInternals)\n },\n\n definition(): LoopDefinition {\n if (internals.loopDef === undefined) {\n throw new LoopNotDefinedError()\n }\n return internals.loopDef\n },\n\n [_internals]: internals,\n }\n\n return builder\n}\n","// -----------------------------------------------------------------------\n// InterruptPause — internal control-flow signal between ctx-interrupt and loop-executor\n// -----------------------------------------------------------------------\n\nexport class InterruptPause extends Error {\n readonly interruptId: string\n readonly prompt: unknown\n\n constructor(interruptId: string, prompt: unknown) {\n super(`interrupt requested for id \"${interruptId}\"`)\n this.name = 'InterruptPause'\n this.interruptId = interruptId\n this.prompt = prompt\n }\n}\n\n// -----------------------------------------------------------------------\n// isInterruptPause — type guard used by runLoop\n// -----------------------------------------------------------------------\n\nexport function isInterruptPause(error: unknown): error is InterruptPause {\n return error instanceof InterruptPause\n}\n\n// -----------------------------------------------------------------------\n// createInterruptFn — factory for ctx.interrupt()\n// -----------------------------------------------------------------------\n\nexport function createInterruptFn(\n state: Record<string, unknown>,\n callCountRef: { current: number },\n): (prompt: unknown, id?: string) => Promise<unknown> {\n return async (prompt: unknown, id?: string): Promise<unknown> => {\n const isAutoId = id === undefined\n const effectiveId = isAutoId ? `$auto:${callCountRef.current}` : id\n\n // only auto-id calls increment the counter\n if (isAutoId) {\n callCountRef.current++\n }\n\n const responses = state.$interruptResponses as Record<string, unknown>\n\n if (effectiveId in responses) {\n return responses[effectiveId]\n }\n\n state.$interrupt = { interruptId: effectiveId, prompt }\n throw new InterruptPause(effectiveId, prompt)\n }\n}\n","import type { Observer, StepContext } from './observer.js'\n\n/**\n * Create the ctx.emit function for a single runLoop invocation.\n * Returns a synchronous, fire-and-forget dispatcher.\n * Fires the matching listener (if registered) AND observer.onEvent (if observer\n * is set and stepCtxRef.current is non-null) independently for each call.\n */\nexport function createEmitFn(\n listeners: Record<string, (payload: unknown) => void>,\n observer?: Observer,\n stepCtxRef?: { current: StepContext | null },\n): (name: string, payload?: unknown) => void {\n return (name: string, payload?: unknown): void => {\n listeners[name]?.(payload)\n if (observer !== undefined && stepCtxRef !== undefined && stepCtxRef.current !== null) {\n observer.onEvent?.(stepCtxRef.current, name, payload)\n }\n }\n}\n\n/**\n * Extract the listeners map from agent.run() resources.\n * Returns an empty object if the 'listeners' key is absent or not a plain object.\n */\nexport function extractRunListeners(\n resources: Record<string, unknown>,\n): Record<string, (payload: unknown) => void> {\n const raw = resources['listeners']\n if (raw === null || typeof raw !== 'object' || Array.isArray(raw)) {\n return {}\n }\n // plain object: return as-is; listener values are not validated\n return raw as Record<string, (payload: unknown) => void> // as: duck-typed plain object confirmed above; values are caller's responsibility\n}\n","import type { LoopDefinition } from '../loop/loop-dsl.js'\nimport type { FieldDefinition } from '../harness/state-field.js'\nimport type { Observer, RunContext, StepContext } from '../agent/observer.js'\nimport { createInterruptFn, isInterruptPause } from '../agent/ctx-interrupt.js'\nimport { createEmitFn } from '../agent/ctx-emit.js'\n\n// -----------------------------------------------------------------------\n// LoopResult\n// -----------------------------------------------------------------------\n\nexport interface LoopResult {\n readonly state: Record<string, unknown>\n readonly signal: string | null\n readonly cursor: string | null\n readonly paused: boolean\n}\n\n// -----------------------------------------------------------------------\n// Error classes\n// -----------------------------------------------------------------------\n\nexport class UnknownSignalError extends Error {\n readonly step: string\n readonly signal: string\n constructor(step: string, signal: string) {\n super(`step \"${step}\" emitted signal \"${signal}\" with no matching .on() transition`)\n this.name = 'UnknownSignalError'\n this.step = step\n this.signal = signal\n }\n}\n\nexport class NoNextStepError extends Error {\n readonly step: string\n constructor(step: string) {\n super(\n `step \"${step}\" has no route, no explicit next, and is the last declared step — execution cannot continue`,\n )\n this.name = 'NoNextStepError'\n this.step = step\n }\n}\n\n// -----------------------------------------------------------------------\n// Private helpers\n// -----------------------------------------------------------------------\n\nfunction buildImplicitNextMap(graph: LoopDefinition): Map<string, string | null> {\n const map = new Map<string, string | null>()\n for (let i = 0; i < graph.steps.length; i++) {\n const step = graph.steps[i]!\n const next = i + 1 < graph.steps.length ? graph.steps[i + 1]!.name : null\n map.set(step.name, next)\n }\n return map\n}\n\nfunction applyUpdate(\n state: Record<string, unknown>,\n update: Record<string, unknown>,\n schema: Record<string, FieldDefinition<any>> | undefined, // any: FieldDefinition uses invariant T; any is required for heterogeneous schema maps\n): void {\n for (const [key, value] of Object.entries(update)) {\n if (key === '$error' || key === '$interrupt' || key === '$interruptResponses') continue\n const reducer = schema?.[key]?.reduce\n if (reducer !== undefined) {\n state[key] = reducer(state[key], value)\n } else {\n state[key] = value\n }\n }\n}\n\n// -----------------------------------------------------------------------\n// Public API\n// -----------------------------------------------------------------------\n\nexport interface LoopCallbacks {\n onBeforeStep?: (name: string, state: Record<string, unknown>) => void\n onAfterStep?: (name: string, state: Record<string, unknown>) => void\n onError?: (error: unknown, stepName: string) => void\n onComplete?: (state: Record<string, unknown>, signal: string) => void\n onInterrupt?: (prompt: unknown, interruptId: string) => void\n /**\n * Listeners for user-emitted events (ctx.emit). Keyed by event name.\n * A missing key means ctx.emit(name) is a no-op for that name.\n */\n listeners?: Record<string, (payload: unknown) => void>\n /** Observer for structured telemetry. All lifecycle methods are optional. F16b. */\n observer?: Observer\n /**\n * The UUID for this specific invocation. Included in RunContext for observer\n * methods. Absent when no observer is active (observer is still consistent).\n */\n runId?: string\n /**\n * Optional parent run UUID for cross-process trace correlation.\n * Included in RunContext when provided.\n */\n parentRunId?: string\n /**\n * Pre-filtered list of ObserverAware slots that expose setStepContext.\n * The loop calls slot.setStepContext(stepCtx) for each entry at every step\n * start, before invoking step.run. F36.\n */\n setStepContextSlots?: ReadonlyArray<{ setStepContext(ctx: StepContext): void }>\n}\n\nexport async function runLoop(\n graph: LoopDefinition,\n state: Record<string, unknown>,\n ctx: Record<string, unknown> & { readonly agentId: string; readonly sessionId: string },\n schema: Record<string, FieldDefinition<any>> | undefined, // any: see applyUpdate comment\n shouldStop?: () => boolean,\n startCursor?: string,\n callbacks?: LoopCallbacks,\n): Promise<LoopResult> {\n const { onBeforeStep, onAfterStep, onError, onComplete, onInterrupt } = callbacks ?? {}\n const obs = callbacks?.observer\n const implicitNextMap = buildImplicitNextMap(graph)\n\n // Initialize framework-reserved fields if absent\n if (!('$error' in state)) state.$error = null\n if (!('$interrupt' in state)) state.$interrupt = null\n if (!('$interruptResponses' in state)) state.$interruptResponses = {}\n\n const runStart = Date.now()\n const runCtx: RunContext = {\n agentId: ctx.agentId,\n sessionId: ctx.sessionId,\n runId: typeof callbacks?.runId === 'string' ? callbacks.runId : '',\n ...(typeof callbacks?.parentRunId === 'string' ? { parentRunId: callbacks.parentRunId } : {}),\n ...(typeof ctx.instanceId === 'string' ? { instanceId: ctx.instanceId } : {}),\n }\n obs?.onRunStart?.(runCtx)\n\n // callCountRef is shared between createInterruptFn and the per-step reset below\n const callCountRef = { current: 0 }\n const stepCtxRef: { current: StepContext | null } = { current: null }\n // mutate ctx in-place so step.run receives the same object reference (invariant for callers)\n ;(ctx as Record<string, unknown>)['interrupt'] = createInterruptFn(state, callCountRef) // as: Record<string, unknown> allows adding framework-injected fields to ctx\n ;(ctx as Record<string, unknown>)['emit'] = createEmitFn(callbacks?.listeners ?? {}, obs, stepCtxRef) // as: see interrupt line comment\n\n let cursor = startCursor ?? graph.entryStep!\n\n while (true) {\n if (shouldStop?.()) {\n obs?.onRunEnd?.(runCtx, { signal: '$stopped', durationMs: Date.now() - runStart })\n return { state, signal: null, cursor, paused: true }\n }\n\n // pass a shallow snapshot so onBeforeStep observers see pre-run values even after state is mutated\n onBeforeStep?.(cursor, { ...state })\n\n const step = graph.steps.find(s => s.name === cursor)!\n\n // reset per-step counter before run (even for decision nodes, per design)\n callCountRef.current = 0\n\n const stepCtx: StepContext = { agentId: ctx.agentId, sessionId: ctx.sessionId, stepName: cursor }\n stepCtxRef.current = stepCtx\n const stepStart = Date.now()\n obs?.onStepStart?.(stepCtx)\n if (callbacks?.setStepContextSlots !== undefined) {\n for (const slot of callbacks.setStepContextSlots) {\n slot.setStepContext(stepCtx)\n }\n }\n\n let runSucceeded = false\n\n if (step.run !== undefined) {\n // capture whether responses exist before the run; only clear interrupt state if they did\n const hadResponses = Object.keys(state.$interruptResponses as Record<string, unknown>).length > 0\n try {\n const update = await step.run(\n state as unknown as Parameters<typeof step.run>[0],\n ctx as Parameters<typeof step.run>[1],\n )\n applyUpdate(state, update as Record<string, unknown>, schema)\n // clear interrupt state only after a step that had stored responses to replay\n if (hadResponses) {\n state.$interrupt = null\n state.$interruptResponses = {}\n }\n runSucceeded = true\n } catch (e) {\n if (isInterruptPause(e)) {\n // InterruptPause was caught: $interrupt already written by createInterruptFn\n onInterrupt?.(e.prompt, e.interruptId)\n obs?.onInterrupt?.(stepCtx, { prompt: e.prompt, interruptId: e.interruptId })\n obs?.onRunEnd?.(runCtx, { signal: '$interrupt', durationMs: Date.now() - runStart })\n return { state, signal: '$interrupt', cursor, paused: true }\n }\n // domain error: normalize to Error and set $error; do not rethrow\n state.$error = e instanceof Error ? e : new Error(String(e))\n onError?.(state.$error, cursor)\n obs?.onStepError?.(stepCtx, { error: state.$error, durationMs: Date.now() - stepStart })\n }\n }\n\n if (runSucceeded) {\n // clear $error after a successful run, before calling route\n state.$error = null\n onAfterStep?.(cursor, state)\n obs?.onStepEnd?.(stepCtx, { durationMs: Date.now() - stepStart })\n }\n\n // route is called when: route exists AND (run succeeded, step has no run, OR step opted in\n // to error routing via optin: '$error' in the step config)\n const callRoute =\n step.route !== undefined &&\n (runSucceeded || step.run === undefined || step.errorAware)\n\n if (callRoute) {\n // callRoute implies step.route !== undefined; non-null assertion is sound here\n const routeFn = step.route!\n let signal: string\n try {\n signal = routeFn(state as unknown as Parameters<typeof routeFn>[0])\n } catch (e) {\n // route itself threw — treat as terminal error; state update from run already stands\n state.$error = e instanceof Error ? e : new Error(String(e))\n obs?.onRunEnd?.(runCtx, { signal: '$error', durationMs: Date.now() - runStart })\n return { state, signal: '$error', cursor, paused: true }\n }\n const transition = step.transitions.find(t => t.signal === signal)\n if (transition === undefined) {\n throw new UnknownSignalError(cursor, signal)\n }\n if (transition.target.kind === 'end') {\n onComplete?.(state, signal)\n obs?.onRunEnd?.(runCtx, { signal, durationMs: Date.now() - runStart })\n return { state, signal, cursor: null, paused: false }\n }\n cursor = transition.target.name\n } else if (step.run !== undefined && !runSucceeded) {\n // run threw, route bypassed (not error-aware) or no route: apply l.onError() fallback or pause\n if (graph.onError !== undefined) {\n cursor = graph.onError\n } else {\n obs?.onRunEnd?.(runCtx, { signal: '$error', durationMs: Date.now() - runStart })\n return { state, signal: '$error', cursor, paused: true }\n }\n } else {\n const next = step.next ?? implicitNextMap.get(cursor) ?? null\n if (next === null) {\n throw new NoNextStepError(cursor)\n }\n cursor = next\n }\n }\n}\n","type SchemaLike = Record<string, {\n readonly default?: (() => unknown) | undefined\n // any on reduce params: function parameter contravariance means typed reducers (e.g. (current: string[]) => string[])\n // are not assignable to (current: unknown) => unknown; any erases the bound safely for runtime use\n readonly reduce?: ((current: any, next: any) => unknown) | undefined // any: see above\n}>\n\n// -----------------------------------------------------------------------\n// ClaimOptions — lease duration passed to claim() and extendClaim()\n// -----------------------------------------------------------------------\n\n/**\n * Options passed to {@link SessionStore.claim}.\n *\n * `ttlMs` is the initial lease duration in milliseconds. The claim expires\n * if not renewed within this window — enabling crash recovery by other instances.\n */\nexport interface ClaimOptions {\n /** Lease duration in milliseconds. Must be a positive integer. */\n readonly ttlMs: number\n}\n\n// -----------------------------------------------------------------------\n// Lease — distributed lease handle returned by claim() and extendClaim()\n// -----------------------------------------------------------------------\n\n/**\n * A successfully acquired distributed lease on a session.\n *\n * Returned by {@link SessionStore.claim} when no other instance holds the\n * session. The framework holds this object for the duration of the run and\n * passes it to {@link SessionStore.release} and {@link SessionStore.extendClaim}.\n */\nexport interface Lease {\n /**\n * Wall-clock expiry timestamp (milliseconds since epoch).\n * The framework checks `Date.now() >= lease.expiresAt` at each step boundary\n * to detect TTL expiry without contacting the store.\n */\n readonly expiresAt: number\n /**\n * The `agentId` this lease was issued for.\n * Stored in the claim record for stuck-lease diagnosis.\n */\n readonly agentId: string\n /**\n * The `sessionId` this lease covers.\n */\n readonly sessionId: string\n /**\n * The `instanceId` of the holder, if provided to `createAgent()`.\n * Written into the store's claim record for operational diagnostics.\n * Absent when `instanceId` was not configured.\n */\n readonly instanceId?: string\n /**\n * Store-implementation-specific token — e.g. a Redis key name, a lock token,\n * or a database row ID. Opaque to the framework; passed back unmodified on\n * `release` and `extendClaim` calls so the store can locate the record.\n */\n readonly token: unknown\n}\n\n// -----------------------------------------------------------------------\n// StoredRunMetadata — operational metadata written into StoredRun\n// -----------------------------------------------------------------------\n\n/**\n * Operational metadata written by the framework into every {@link StoredRun}.\n *\n * The framework writes only `instanceId`. All other fields are reserved for\n * domain-specific operational annotations (tenantId, region, requestId, etc.).\n */\nexport interface StoredRunMetadata {\n /** The `instanceId` of the instance that produced this run. Absent when not configured. */\n instanceId?: string\n /** Open extension point — domain-specific fields. */\n [key: string]: unknown\n}\n\n// -----------------------------------------------------------------------\n// SessionStore — the persistence contract\n// -----------------------------------------------------------------------\n\n/**\n * Persistence contract for agent sessions.\n *\n * Implementations must be safe to call concurrently for **different** sessions;\n * concurrent calls for the **same** session are prevented by the harness concurrency guards.\n *\n * `loadHistory` and `branch` are optional extensions:\n * - `loadHistory` — full run history for a session (used by branching and debugging tools).\n * - `branch` — fork a session at a specific past run, returning a new session ID.\n */\nexport interface SessionStore {\n /**\n * Load the most recent {@link StoredRun} for the given session, or `null` if\n * the session has never been saved.\n */\n load(agentId: string, sessionId: string): Promise<StoredRun | null>\n\n /**\n * Persist a run record as a conditional write.\n *\n * Implementations must compare `run.version` against the version of the\n * currently stored record before writing:\n * - If the stored version equals `run.version - 1` (or there is no stored\n * record and `run.version === 0`), the write succeeds.\n * - Otherwise, another writer committed a newer version concurrently — the\n * implementation must throw `ConcurrentModificationError`.\n */\n save(agentId: string, sessionId: string, run: StoredRun): Promise<void>\n\n /**\n * Return the full ordered run history for a session, oldest first.\n * Optional — omit if your store does not support history.\n */\n loadHistory?(agentId: string, sessionId: string): Promise<StoredRun[]>\n\n /**\n * Fork the session at the state captured by `runId`, returning a new session ID\n * whose initial state equals the forked run's `finalState`.\n * Optional — omit if your store does not support branching.\n *\n * @throws {@link BranchNotFoundError} when `runId` is not found in history.\n */\n branch?(agentId: string, sessionId: string, runId: string): Promise<string>\n\n /**\n * Attempt to acquire a distributed claim on the session before starting a run.\n *\n * - Returns a {@link Lease} when the claim is acquired.\n * - Returns `null` when another instance already holds the claim — the framework\n * throws {@link SessionBusyError} immediately without starting any LLM work.\n *\n * Optional — stores that do not support distributed locking omit this method.\n * The framework checks for its presence before calling it.\n */\n claim?(agentId: string, sessionId: string, options: ClaimOptions): Promise<Lease | null>\n\n /**\n * Release a held claim after the run settles.\n *\n * Called by the framework after `save()` completes (or after an error that\n * prevents saving). Stores may use this to remove the lock record immediately\n * rather than waiting for TTL expiry.\n *\n * Optional — omit if your store does not support claim/release.\n */\n release?(lease: Lease): Promise<void>\n\n /**\n * Extend the TTL of an active claim.\n *\n * Called by `ctx.keepAlive()` (both one-shot and background interval modes).\n * The store must update `expiresAt` on the claim record; the new expiry is\n * `Date.now() + options.ttlMs`. The returned `Lease` object carries the updated\n * `expiresAt`; the framework replaces its held reference with the returned value.\n *\n * Optional — omit if your store does not support claim/release.\n */\n extendClaim?(lease: Lease, options: ClaimOptions): Promise<Lease>\n}\n\n// -----------------------------------------------------------------------\n// StoredRun — the per-run serialized record (replaces StoredSession)\n// -----------------------------------------------------------------------\n\n/**\n * Serializable snapshot of a single agent run, written to the store after\n * every run settles (either `'paused'` on an interrupt or `'completed'`).\n *\n * - `phase: 'paused'` — the run paused on an interrupt; `step` is the step that\n * issued the interrupt and `signal` is `'$interrupt'`.\n * - `phase: 'completed'` — the loop exited normally; `signal` holds the exit\n * signal (or is absent when the loop ended without emitting a signal).\n */\nexport interface StoredRun {\n readonly agentId: string\n readonly runId: string\n readonly sessionId: string\n readonly version: number\n readonly startedAt: string\n readonly settledAt: string\n readonly phase: 'paused' | 'completed'\n readonly initialState: Record<string, unknown>\n readonly finalState: Record<string, unknown>\n readonly signal?: string\n readonly step?: string\n /**\n * Operational metadata written by the framework.\n *\n * The framework writes `instanceId` when configured; all other fields are\n * domain-defined. Absent for runs produced before this field was added.\n */\n readonly metadata?: StoredRunMetadata\n}\n\n// -----------------------------------------------------------------------\n// SessionPhase — the agent.status() query result\n// -----------------------------------------------------------------------\n\n/**\n * Discriminated union returned by {@link Agent.status} describing the lifecycle\n * phase of a session.\n *\n * - `'fresh'` — no run has been stored yet.\n * - `'in-flight'` — a run is currently executing (in-process guard only; not\n * detectable cross-process from the store alone).\n * - `'paused'` — the last run settled on an interrupt; `step` identifies the\n * step that issued the interrupt.\n * - `'completed'` — the last run exited the loop; `signal` is the exit signal.\n */\nexport type SessionPhase =\n | { readonly phase: 'fresh' }\n | { readonly phase: 'in-flight'; readonly step: null }\n | { readonly phase: 'paused'; readonly signal?: string; readonly step: string }\n | { readonly phase: 'completed'; readonly signal?: string }\n\n// -----------------------------------------------------------------------\n// storedSessionToPhase — converts a raw load result to SessionPhase\n// -----------------------------------------------------------------------\n\nexport function storedSessionToPhase(loaded: StoredRun | null): SessionPhase {\n if (loaded === null) {\n return { phase: 'fresh' }\n }\n\n if (loaded.phase === 'paused') {\n const step = loaded.step ?? ''\n if (loaded.signal !== undefined) {\n return { phase: 'paused', step, signal: loaded.signal }\n }\n return { phase: 'paused', step }\n }\n\n // completed\n if (loaded.signal !== undefined) {\n return { phase: 'completed', signal: loaded.signal }\n }\n return { phase: 'completed' }\n}\n\n// -----------------------------------------------------------------------\n// initializeState — state merge for fresh sessions and resumptions\n// -----------------------------------------------------------------------\n\nexport function initializeState(\n stored: StoredRun | null,\n initialStateArg: Record<string, unknown>,\n schema: SchemaLike | undefined,\n): Record<string, unknown> {\n const argKeys = new Set(Object.keys(initialStateArg))\n\n if (stored === null) {\n return buildFreshState(initialStateArg, argKeys, schema)\n }\n\n return buildResumedState(stored, initialStateArg, argKeys, schema)\n}\n\nfunction buildFreshState(\n initialStateArg: Record<string, unknown>,\n argKeys: Set<string>,\n schema: SchemaLike | undefined,\n): Record<string, unknown> {\n const result: Record<string, unknown> = { ...initialStateArg }\n\n if (schema === undefined || Object.keys(schema).length === 0) {\n return result\n }\n\n for (const key of Object.keys(schema)) {\n if (argKeys.has(key)) {\n // initialStateArg wins — already in result via spread\n continue\n }\n const field = schema[key]\n if (field !== undefined && field.default !== undefined) {\n result[key] = field.default()\n }\n }\n\n return result\n}\n\nfunction buildResumedState(\n stored: StoredRun,\n initialStateArg: Record<string, unknown>,\n argKeys: Set<string>,\n schema: SchemaLike | undefined,\n): Record<string, unknown> {\n const result: Record<string, unknown> = { ...stored.finalState }\n\n // Apply initialStateArg fields on top of stored state\n for (const key of argKeys) {\n const fieldDef = schema?.[key]\n if (fieldDef?.reduce !== undefined) {\n result[key] = fieldDef.reduce(stored.finalState[key], initialStateArg[key])\n } else {\n result[key] = initialStateArg[key]\n }\n }\n\n // Apply schema defaults for keys absent from both stored.finalState and initialStateArg\n if (schema !== undefined) {\n for (const key of Object.keys(schema)) {\n if (argKeys.has(key)) continue\n if (key in stored.finalState) continue\n const field = schema[key]\n if (field !== undefined && field.default !== undefined) {\n result[key] = field.default()\n }\n }\n }\n\n return result\n}\n","/**\n * Thrown by {@link Agent.run} or {@link Agent.resume} when the given session\n * is already executing a run in the same process.\n *\n * Wait for the in-flight {@link RunHandle} to settle before starting a new run.\n */\nexport class SessionInFlightError extends Error {\n /** The session that was already in-flight. */\n readonly sessionId: string\n\n constructor(sessionId: string) {\n super(`session \"${sessionId}\" is already in-flight`)\n this.name = 'SessionInFlightError'\n this.sessionId = sessionId\n }\n}\n\n/**\n * Thrown by {@link Agent.run} when the session is paused on an unanswered\n * interrupt. Call {@link Agent.resume} (or `handle.resume()`) instead.\n */\nexport class SessionPendingInterruptError extends Error {\n /** The session that is awaiting an interrupt response. */\n readonly sessionId: string\n\n constructor(sessionId: string) {\n super(`session \"${sessionId}\" is paused on an interrupt — use agent.resume() instead of agent.run()`)\n this.name = 'SessionPendingInterruptError'\n this.sessionId = sessionId\n }\n}\n\n/**\n * Thrown by the harness when the session store's `load()` call rejects.\n * The original error is available on the `cause` property.\n */\nexport class StoreLoadError extends Error {\n readonly cause: unknown\n\n constructor(cause: unknown) {\n super('session store failed to load session')\n this.name = 'StoreLoadError'\n this.cause = cause\n }\n}\n\n/**\n * Thrown by {@link Agent.run} when `store.claim()` returns `null` —\n * another instance already holds the session claim.\n *\n * The caller may inspect `retryAfter` to implement a `429 Retry-After`\n * response or a retry backoff. How to respond is not the framework's concern.\n */\nexport class SessionBusyError extends Error {\n /** The session that is currently claimed by another instance. */\n readonly sessionId: string\n /**\n * Hint: earliest time (milliseconds since epoch) when a retry may succeed.\n * Derived from the original claim's `expiresAt`. Present when the store\n * includes expiry information in a busy response; absent otherwise.\n */\n // declare: avoids useDefineForClassFields emitting an undefined own property initializer;\n // the field is only written when retryAfter is provided (exactOptionalPropertyTypes guard)\n declare readonly retryAfter?: number\n\n constructor(sessionId: string, retryAfter?: number) {\n super(`session \"${sessionId}\" is currently claimed by another instance`)\n this.name = 'SessionBusyError'\n this.sessionId = sessionId\n // conditional assignment: avoids producing retryAfter: undefined as an own property\n // which exactOptionalPropertyTypes forbids at call sites\n if (retryAfter !== undefined) this.retryAfter = retryAfter\n }\n}\n\n/**\n * Thrown by the framework at a step boundary when the active lease has expired\n * without renewal.\n *\n * The run stops without saving state — the session remains at its last\n * checkpoint, allowing another instance to claim and resume it.\n */\nexport class LeaseExpiredError extends Error {\n /** The session whose lease expired. */\n readonly sessionId: string\n\n constructor(sessionId: string) {\n super(`lease for session \"${sessionId}\" has expired — run stopped without saving`)\n this.name = 'LeaseExpiredError'\n this.sessionId = sessionId\n }\n}\n\n","import type { SessionStore, Lease } from './session-store.js'\n\n/**\n * A mutable reference to the currently held lease.\n * `null` when claim/lease is not in use (no-store or store without claim()).\n * Updated in-place by `extendClaim()` responses.\n */\nexport type LeaseRef = { current: Lease | null }\n\n/**\n * Options for background renewal mode.\n */\nexport interface KeepAliveOptions {\n /**\n * Renewal interval in milliseconds. A background timer calls\n * `store.extendClaim()` at this cadence.\n * Must be less than the original claim `ttlMs` to ensure renewal\n * reaches the store before expiry.\n */\n readonly every: number\n}\n\n/**\n * The stop function returned by `ctx.keepAlive({ every })`.\n * Always call this in a `finally` block to cancel the background timer.\n */\nexport type StopFn = () => void\n\n/**\n * The `ctx.keepAlive` function type injected into the step ctx.\n *\n * - Called with no arguments: one-shot TTL extension. Returns a Promise.\n * - Called with `{ every: ms }`: starts a background interval renewal timer.\n * Returns a `StopFn` synchronously.\n */\nexport type KeepAliveFn =\n ((() => Promise<void>) & ((options: KeepAliveOptions) => StopFn))\n\n/**\n * Create the `ctx.keepAlive` function for a single run.\n *\n * @param leaseRef - Mutable reference to the active lease.\n * @param store - The session store, or `undefined` when no store configured.\n * @param originalTtlMs - The `ttlMs` from the `ClaimOptions` used in the initial claim.\n * @returns The `keepAlive` function to inject into step `ctx`.\n */\nexport function createKeepAliveFn(\n leaseRef: LeaseRef,\n store: SessionStore | undefined,\n originalTtlMs: number,\n): KeepAliveFn {\n function keepAlive(options?: KeepAliveOptions): Promise<void> | StopFn {\n const isBackground = typeof options === 'object' && options !== null && 'every' in options\n const extendClaim = store?.extendClaim\n\n if (isBackground) {\n // background renewal mode\n if (leaseRef.current === null || typeof extendClaim !== 'function') {\n // no-op: no active lease or store doesn't support extendClaim\n return noopStop\n }\n\n let handle: ReturnType<typeof setInterval> | null = setInterval(() => {\n if (leaseRef.current === null) {\n // lease was released after timer started — skip but keep timer running\n return\n }\n // swallow errors — timer must continue regardless of extendClaim failures\n void (async () => {\n try {\n const renewed = await extendClaim.call(store, leaseRef.current!, { ttlMs: originalTtlMs })\n leaseRef.current = renewed\n } catch {\n /* swallow: expiry check at step boundary is the safety net */\n }\n })()\n }, options.every)\n\n return function stop() {\n if (handle !== null) {\n clearInterval(handle)\n handle = null\n }\n }\n }\n\n // one-shot mode\n if (leaseRef.current === null || typeof extendClaim !== 'function') {\n return Promise.resolve()\n }\n\n const snapshot = leaseRef.current\n return (async () => {\n const renewed = await extendClaim.call(store, snapshot, { ttlMs: originalTtlMs })\n leaseRef.current = renewed\n })()\n }\n\n // as: overloaded function — runtime discriminates on options presence\n return keepAlive as KeepAliveFn\n}\n\nfunction noopStop(): void {\n // no-op stop: no timer was started\n}\n","import type { FieldDefinition } from '../harness/state-field.js'\nimport type { ProviderEntry } from '../harness/harness-builder.js'\nimport type { LoopDefinition } from '../loop/loop-dsl.js'\nimport type { LoopResult } from '../loop/loop-executor.js'\nimport { runLoop } from '../loop/loop-executor.js'\nimport type { Observer, StepContext } from './observer.js'\nimport {\n type SessionStore,\n type StoredRun,\n type StoredRunMetadata,\n type SessionPhase,\n initializeState,\n storedSessionToPhase,\n} from './session-store.js'\nimport { StoreLoadError, LeaseExpiredError } from './concurrency-errors.js'\nimport { createKeepAliveFn, type LeaseRef } from './ctx-keep-alive.js'\n\n// -----------------------------------------------------------------------\n// SessionRunOptions — optional parameters for runWithSession\n// -----------------------------------------------------------------------\n\nexport interface SessionRunOptions {\n /** Checked at the top of each loop iteration; returning true halts the run. */\n readonly shouldStop?: () => boolean\n /**\n * Called if the session store fails. `phase` is `'load'` (store failed at run start),\n * `'persist'` (store failed at run end/pause), or `'claim'` (claim returned null or threw).\n * Run result is still returned when phase is 'persist'.\n */\n readonly onStoreError?: (error: unknown, phase: 'load' | 'persist' | 'claim') => void\n /** Called just before each step executes. Used by RunHandle to track currentStep and fire onBeforeStep. */\n readonly onBeforeStep?: (name: string, state: Record<string, unknown>) => void\n /** Called after a step's run completes successfully and applyUpdate has been applied. */\n readonly onAfterStep?: (name: string, state: Record<string, unknown>) => void\n /** Called immediately when a step's run throws a non-interrupt error, before error routing. */\n readonly onError?: (error: unknown, stepName: string) => void\n /** Called when the loop exits via .on(signal).end() (paused: false). */\n readonly onComplete?: (state: Record<string, unknown>, signal: string) => void\n /** Called when ctx.interrupt() pauses the run (isInterruptPause is true). */\n readonly onInterrupt?: (prompt: unknown, interruptId: string) => void\n /** Listeners for user-emitted events (ctx.emit). Keyed by event name. */\n readonly listeners?: Record<string, (payload: unknown) => void>\n /** Structured telemetry observer for this run. All methods optional. F16b. */\n readonly observer?: Observer\n /**\n * Active lease reference. The factory closes over this ref; it is updated\n * in-place by `extendClaim()` calls. Absent when no claim is in use.\n */\n readonly leaseRef?: LeaseRef\n /**\n * The `instanceId` from `AgentOptions`, if provided. Written into\n * `StoredRun.metadata` on every terminal save and into `RunContext` for observers.\n */\n readonly instanceId?: string\n /**\n * The original claim `ttlMs` — passed to `createKeepAliveFn` as `originalTtlMs`\n * so `ctx.keepAlive()` uses the same TTL for renewals. Defaults to 30_000 when absent.\n */\n readonly claimTtlMs?: number\n /**\n * Optional parent run UUID — set when parentRunId was passed as a resource\n * to agent.run(). Threaded through to RunContext for cross-process trace\n * correlation. Absent for top-level runs.\n */\n readonly parentRunId?: string\n /**\n * Pre-filtered list of ObserverAware slots that expose setStepContext.\n * Passed through to runLoop callbacks. Absent when no slots expose setStepContext. F36.\n */\n readonly setStepContextSlots?: ReadonlyArray<{ setStepContext(ctx: StepContext): void }>\n}\n\n// -----------------------------------------------------------------------\n// resolveSessionStore — extract SessionStore from storeEntries\n// -----------------------------------------------------------------------\n\nexport function resolveSessionStore(\n storeEntries: readonly ProviderEntry[],\n overrides?: Record<string, unknown>,\n): SessionStore | undefined {\n let result: SessionStore | undefined = undefined\n\n for (const entry of storeEntries) {\n if (entry.kind !== 'store') continue\n\n const value = entry.value\n if (value === null || typeof value !== 'object') continue\n\n const rec = value as Record<string, unknown> // as: TypeScript cannot narrow `object` to `Record<string, unknown>` for index access\n if (!('session' in rec)) continue\n\n // Prefer override when provided (fulfils a required() marker declared at harness-build time)\n const rawSession = rec['session']\n const session = (overrides !== undefined && 'session' in overrides) ? overrides['session'] : rawSession\n if (session === null || typeof session !== 'object') continue\n\n const s = session as Record<string, unknown> // as: same narrowing needed to index into the duck-typed session object\n if (typeof s['load'] === 'function' && typeof s['save'] === 'function') {\n // last valid store wins\n result = session as unknown as SessionStore // as: duck-typing confirmed above; no instanceof available for a structural interface\n }\n }\n\n return result\n}\n\n// -----------------------------------------------------------------------\n// querySessionPhase — implements agent.status() query\n// -----------------------------------------------------------------------\n\nexport async function querySessionPhase(\n store: SessionStore | undefined,\n agentId: string,\n sessionId: string,\n): Promise<SessionPhase> {\n if (store === undefined) {\n return { phase: 'fresh' }\n }\n\n const loaded = await store.load(agentId, sessionId)\n return storedSessionToPhase(loaded)\n}\n\n// -----------------------------------------------------------------------\n// runWithSession — full session lifecycle wrapper around runLoop\n// -----------------------------------------------------------------------\n\nexport async function runWithSession(\n store: SessionStore | undefined,\n agentId: string,\n sessionId: string,\n runId: string,\n graph: LoopDefinition,\n initialStateArg: Record<string, unknown>,\n schema: Record<string, FieldDefinition<any>> | undefined, // any: FieldDefinition uses invariant T; heterogeneous schema maps require any\n ctx: Record<string, unknown> & { readonly agentId: string; readonly sessionId: string },\n options?: SessionRunOptions,\n): Promise<LoopResult> {\n // Inject keepAlive into ctx — no-op when no lease is active (leaseRef.current === null)\n const leaseRef = options?.leaseRef ?? { current: null }\n const keepAlive = createKeepAliveFn(leaseRef, store, options?.claimTtlMs ?? 30_000)\n ;(ctx as Record<string, unknown>)['keepAlive'] = keepAlive // mutate in-place like runLoop does for interrupt/emit\n\n // Build composedShouldStop — checks caller predicate AND lease expiry\n let leaseExpired = false\n const composedShouldStop = (): boolean => {\n if (options?.shouldStop?.() === true) return true\n if (leaseRef.current !== null && leaseRef.current.expiresAt <= Date.now()) {\n leaseExpired = true\n return true\n }\n return false\n }\n\n if (store === undefined) {\n const state = initializeState(null, initialStateArg, schema)\n const result = await runLoop(graph, state, ctx, schema, composedShouldStop, undefined, {\n ...options,\n runId,\n ...(options?.parentRunId !== undefined ? { parentRunId: options.parentRunId } : {}),\n })\n if (leaseExpired) {\n const expiredError = new LeaseExpiredError(sessionId)\n options?.onStoreError?.(expiredError, 'claim')\n throw expiredError\n }\n return result\n }\n\n // Load phase — on failure: fire onStoreError('load') and return synthetic error result\n // Run never begins; 'await run' always resolves (never rejects) per docs/agent.md guarantee\n let loaded: StoredRun | null\n try {\n loaded = await store.load(agentId, sessionId)\n } catch (error: unknown) {\n const storeError = new StoreLoadError(error)\n options?.onStoreError?.(storeError, 'load')\n const failState = initializeState(null, initialStateArg, schema)\n ;(failState as Record<string, unknown>)['$error'] = storeError\n return { state: failState, signal: '$error', paused: false, cursor: null }\n }\n\n // Short-circuit for completed sessions — return stored result immediately without executing\n if (loaded !== null && loaded.phase === 'completed') {\n return {\n state: loaded.finalState,\n signal: loaded.signal ?? null,\n cursor: null,\n paused: false,\n }\n }\n\n // Merge stored snapshot (or null for fresh) with caller-supplied initial state\n const state = initializeState(loaded, initialStateArg, schema)\n // Snapshot before runLoop — runLoop mutates state in place so we must copy before execution\n const initialStateSnapshot = { ...state }\n const startedAt = new Date().toISOString()\n\n // Execute — errors from runLoop propagate uncaught (except LeaseExpiredError handled below)\n const result = await runLoop(graph, state, ctx, schema, composedShouldStop, loaded?.step, {\n ...options,\n runId,\n ...(options?.parentRunId !== undefined ? { parentRunId: options.parentRunId } : {}),\n })\n\n // Lease-expired path — do NOT persist; signal error to caller\n if (leaseExpired) {\n const expiredError = new LeaseExpiredError(sessionId)\n options?.onStoreError?.(expiredError, 'claim')\n throw expiredError\n }\n\n const settledAt = new Date().toISOString()\n\n // Build optional metadata\n const metadata: StoredRunMetadata | undefined =\n options?.instanceId !== undefined ? { instanceId: options.instanceId } : undefined\n\n // Terminal save — errors are swallowed; LoopResult is always returned\n try {\n const version = (loaded?.version ?? -1) + 1\n if (result.paused) {\n const saved: StoredRun = {\n agentId,\n runId,\n sessionId,\n version,\n startedAt,\n settledAt,\n phase: 'paused',\n initialState: initialStateSnapshot,\n finalState: result.state,\n step: result.cursor!,\n ...(result.signal !== null ? { signal: result.signal } : {}),\n ...(metadata !== undefined ? { metadata } : {}),\n }\n await store.save(agentId, sessionId, saved)\n } else {\n const saved: StoredRun = {\n agentId,\n runId,\n sessionId,\n version,\n startedAt,\n settledAt,\n phase: 'completed',\n initialState: initialStateSnapshot,\n finalState: result.state,\n ...(result.signal !== null ? { signal: result.signal } : {}),\n ...(metadata !== undefined ? { metadata } : {}),\n }\n await store.save(agentId, sessionId, saved)\n }\n } catch (error) {\n options?.onStoreError?.(error, 'persist')\n // terminal save error is swallowed; LoopResult is returned to caller regardless\n }\n\n return result\n}\n","import type { SessionStore, StoredRun } from './session-store.js'\n\n// -----------------------------------------------------------------------\n// NoInterruptError\n// -----------------------------------------------------------------------\n\n/**\n * Thrown by {@link RunHandle.resume} or {@link Agent.resume} when the session\n * is not currently paused on a matching interrupt.\n *\n * Common causes: the run has not yet settled, the session does not exist,\n * or the supplied `interruptId` does not match the pending interrupt.\n */\nexport class NoInterruptError extends Error {\n constructor() {\n super(\n 'resume() called but the session is not paused on a matching interrupt — ' +\n 'verify the session exists, its phase is \"paused\", and interruptId matches',\n )\n this.name = 'NoInterruptError'\n }\n}\n\n// -----------------------------------------------------------------------\n// injectInterruptResponse\n// -----------------------------------------------------------------------\n\nexport async function injectInterruptResponse(\n store: SessionStore,\n agentId: string,\n sessionId: string,\n interruptId: string,\n response: unknown,\n): Promise<void> {\n const loaded = await store.load(agentId, sessionId)\n\n if (loaded === null) throw new NoInterruptError()\n if (loaded.phase !== 'paused') throw new NoInterruptError()\n\n const interrupt = loaded.finalState.$interrupt as { interruptId: string } | null // as: $interrupt is a framework-reserved field with known shape\n if (interrupt === null) throw new NoInterruptError()\n if (interrupt.interruptId !== interruptId) throw new NoInterruptError()\n\n const existingResponses = (loaded.finalState.$interruptResponses as Record<string, unknown>) ?? {}\n const newState: Record<string, unknown> = {\n ...loaded.finalState,\n $interrupt: null,\n $interruptResponses: { ...existingResponses, [interruptId]: response },\n }\n\n const updated: StoredRun = {\n agentId: loaded.agentId,\n runId: loaded.runId,\n sessionId: loaded.sessionId,\n version: loaded.version + 1,\n startedAt: loaded.startedAt,\n settledAt: loaded.settledAt,\n phase: 'paused',\n initialState: loaded.initialState,\n finalState: newState,\n ...(loaded.step !== undefined ? { step: loaded.step } : {}),\n ...(loaded.signal !== undefined ? { signal: loaded.signal } : {}),\n }\n\n await store.save(agentId, sessionId, updated)\n}\n","/**\n * The resolved value of a {@link RunHandle} promise: the final state and the\n * signal that caused the loop to exit.\n *\n * `signal` is `null` when the loop exited via `.end()` without an explicit signal,\n * `'$interrupt'` when paused on an interrupt, or any custom signal string returned\n * by a route function.\n */\nexport interface RunOutcome {\n readonly state: Record<string, unknown>\n readonly signal: string | null\n}\n\n/**\n * Handle returned synchronously by {@link Agent.run} and {@link Agent.resume}.\n *\n * Implements `PromiseLike<RunOutcome>` so it can be `await`-ed directly.\n *\n * @example\n * ```ts\n * const handle = agent.run({}, { llm })\n * console.log(handle.sessionId) // available immediately\n * const { state, signal } = await handle\n * ```\n */\nexport interface RunHandle extends PromiseLike<RunOutcome> {\n /** Cancel the in-flight run at the next safe point between steps. Idempotent. */\n stop(): void\n\n /**\n * Provide a response to a pending `ctx.interrupt()` call and start a new run.\n * Returns a new {@link RunHandle} for the resumed execution.\n *\n * Throws {@link NoInterruptError} when the run has not settled on `signal: '$interrupt'`.\n *\n * @param response - The value to deliver as the interrupt response.\n * @param interruptId - The `interruptId` from `state.$interrupt`.\n */\n resume(response: unknown, interruptId: string): RunHandle\n\n /** The session identity for this run. */\n readonly sessionId: string\n\n /**\n * Unique identifier for this specific invocation.\n * One UUID per `agent.run()` or `agent.resume()` call.\n */\n readonly runId: string\n\n /**\n * The name of the step currently executing in this process.\n * `null` before the first step runs, after execution settles, and always\n * when inspected cross-process.\n */\n readonly currentStep: string | null\n}\n\nimport { NoInterruptError } from './interrupt-resume.js'\n\nexport function createRunHandle(\n sessionId: string,\n runId: string,\n execution: Promise<RunOutcome>,\n stopFlag: { stopped: boolean },\n stepRef: { current: string | null },\n resumeFn?: (response: unknown, interruptId: string) => RunHandle,\n): RunHandle {\n let settledOutcome: RunOutcome | null = null\n\n // NOTE: raw .then(onFulfilled, onRejected) is intentional here — NOT a coding-standards\n // violation. async/await requires wrapping in a new async function, which changes control\n // flow and does not populate `settledOutcome` as a side-effect at resolution time.\n // .then() attaches handlers to an already-running Promise, allowing us to capture the\n // fulfilled RunOutcome into the closure variable synchronously within the callback at the\n // moment of resolution. run.resume() reads settledOutcome synchronously, so this is the\n // only correct pattern; replacing it with async/await would break synchronous access.\n const settled = execution.then(\n (outcome: RunOutcome): RunOutcome => {\n settledOutcome = outcome\n stepRef.current = null\n return outcome\n },\n (err: unknown): RunOutcome => {\n stepRef.current = null\n throw err\n },\n )\n\n const handle: RunHandle = {\n then<TResult1 = RunOutcome, TResult2 = never>(\n onfulfilled?: ((value: RunOutcome) => TResult1 | PromiseLike<TResult1>) | null | undefined,\n onrejected?: ((reason: unknown) => TResult2 | PromiseLike<TResult2>) | null | undefined,\n ): Promise<TResult1 | TResult2> {\n return settled.then(onfulfilled, onrejected)\n },\n\n stop(): void {\n stopFlag.stopped = true\n },\n\n resume(response: unknown, interruptId: string): RunHandle {\n // backward-compatibility: 4-arg handle (no resumeFn) + unsettled → old stub error\n if (settledOutcome === null && resumeFn === undefined) {\n throw new Error('not implemented — requires F9')\n }\n if (settledOutcome === null) {\n throw new NoInterruptError()\n }\n if (settledOutcome.signal !== '$interrupt') {\n throw new NoInterruptError()\n }\n if (resumeFn === undefined) {\n throw new NoInterruptError()\n }\n return resumeFn(response, interruptId)\n },\n\n get sessionId(): string {\n return sessionId\n },\n\n get runId(): string {\n return runId\n },\n\n get currentStep(): string | null {\n return stepRef.current\n },\n }\n\n return handle\n}\n","import {\n getInternals,\n type Harness,\n type HarnessInternals,\n type ProviderEntry,\n} from '../harness/harness-builder.js'\nimport { isRequiredMarker, isRuntimeMarker } from '../harness/ctx-markers.js'\nimport type { LoopDefinition } from '../loop/loop-dsl.js'\nimport type { FieldDefinition } from '../harness/state-field.js'\nimport type { SessionPhase, ClaimOptions, Lease } from './session-store.js'\nimport { resolveSessionStore, runWithSession, querySessionPhase, type SessionRunOptions } from './session-lifecycle.js'\nimport { runLoop } from '../loop/loop-executor.js'\nimport { createRunHandle, type RunHandle, type RunOutcome } from './run-handle.js'\nimport { NoInterruptError, injectInterruptResponse } from './interrupt-resume.js'\nimport {\n SessionInFlightError,\n SessionPendingInterruptError,\n SessionBusyError,\n LeaseExpiredError,\n StoreLoadError,\n} from './concurrency-errors.js'\nimport type { LeaseRef } from './ctx-keep-alive.js'\nimport { randomUUID } from 'node:crypto'\nimport { extractRunEvents } from './event-callbacks.js'\nimport { extractRunListeners } from './ctx-emit.js'\nimport type { Observer, StepContext } from './observer.js'\nimport { initializeState } from './session-store.js'\n\n// -----------------------------------------------------------------------\n// Module-level constants\n// -----------------------------------------------------------------------\n\nconst NOOP_OBSERVER: Observer = {}\n\n// -----------------------------------------------------------------------\n// Module-private helpers\n// -----------------------------------------------------------------------\n\nfunction extractRunObserver(resources: Record<string, unknown>): Observer | undefined {\n const raw = resources['observer']\n if (raw === null || typeof raw !== 'object' || Array.isArray(raw)) return undefined\n return raw as Observer // as: duck-typed plain object confirmed; methods not validated\n}\n\n/** Options passed to createAgent(). */\nexport interface AgentOptions {\n /**\n * Stable identifier for the process or replica running this agent instance.\n * Written to `StoredRun.metadata` on every save and propagated to observers\n * via `RunContext.instanceId`.\n */\n readonly instanceId?: string\n /**\n * Concrete store instances for slots declared with `required()` inside `h.store()`.\n * Keyed by the store key used in the harness (e.g. `{ session: myStore }`).\n */\n readonly stores?: Record<string, unknown>\n}\n\n// -----------------------------------------------------------------------\n// Agent — the minimal public object returned by createAgent\n// -----------------------------------------------------------------------\n\nexport interface Agent {\n /** The agent's unique identifier, as provided to createAgent(). */\n readonly id: string\n\n /**\n * Start a new run. Returns a RunHandle synchronously before execution begins.\n */\n run(initialState: Record<string, unknown>, resources: Record<string, unknown>): RunHandle\n\n /**\n * Cross-process entry point for responding to a pending interrupt.\n * Returns a RunHandle synchronously; the execution promise performs the resume.\n *\n * The optional fourth argument `resources` accepts:\n * - `observer?: Observer` — structured telemetry for the resumed run (see Observability)\n * - `events?.onStoreError?` — raw store-error callback (unchanged from prior shape)\n */\n resume(\n response: unknown,\n sessionId: string,\n interruptId: string,\n resources?: Record<string, unknown>,\n ): RunHandle\n\n /**\n * Query the session store for the current phase of a session.\n */\n status(sessionId: string): Promise<SessionPhase>\n}\n\n// -----------------------------------------------------------------------\n// AgentInternals — the resolved internal state\n// -----------------------------------------------------------------------\n\nexport interface AgentInternals {\n readonly agentId: string\n readonly resolvedProviders: ReadonlyMap<string, unknown>\n readonly storeEntries: readonly ProviderEntry[]\n readonly loopDef: LoopDefinition\n readonly stateSchema: Record<string, FieldDefinition<unknown>> | undefined\n /** Keys declared as runtime() in the harness — must be filled in agent.run() resources. */\n readonly runtimeKeys: ReadonlySet<string>\n /** Keys declared as required() in the harness — must NOT appear in agent.run() resources. */\n readonly requiredKeys: ReadonlySet<string>\n}\n\n// -----------------------------------------------------------------------\n// Error classes\n// -----------------------------------------------------------------------\n\n/** Thrown by {@link createAgent} when the harness has no `.loop()` declaration. */\nexport class MissingLoopError extends Error {\n constructor() {\n super('harness has no loop — call h.loop() before createAgent(id, h, slots)')\n this.name = 'MissingLoopError'\n }\n}\n\n/** Thrown by {@link createAgent} when a `required()` slot is absent from `slots`. */\nexport class MissingSlotError extends Error {\n /** The missing slot key. */\n readonly key: string\n\n constructor(key: string) {\n super(`required slot \"${key}\" was not provided in createAgent slots`)\n this.name = 'MissingSlotError'\n this.key = key\n }\n}\n\n/** Thrown by {@link createAgent} when a `runtime()` slot is passed in `slots` instead of `agent.run()`. */\nexport class RuntimeSlotInAgentError extends Error {\n /** The offending slot key. */\n readonly key: string\n\n constructor(key: string) {\n super(`slot \"${key}\" is a runtime() slot — provide it in agent.run(), not createAgent()`)\n this.name = 'RuntimeSlotInAgentError'\n this.key = key\n }\n}\n\n/** Thrown by {@link createAgent} when `slots` contains a key not declared in the harness. */\nexport class UnknownSlotError extends Error {\n /** The unknown slot key. */\n readonly key: string\n\n constructor(key: string) {\n super(`slot \"${key}\" is not declared in the harness — remove it or add h.provide(\"${key}\", required())`)\n this.name = 'UnknownSlotError'\n this.key = key\n }\n}\n\n/** @internal Thrown when `getAgentInternals` is called on a non-agent value. */\nexport class AgentInternalsError extends Error {\n constructor() {\n super('value was not produced by createAgent — cannot read AgentInternals')\n this.name = 'AgentInternalsError'\n }\n}\n\n/** Thrown by {@link Agent.run} when a `runtime()` slot is absent from `resources`. */\nexport class MissingRuntimeSlotError extends Error {\n /** The missing runtime slot key. */\n readonly key: string\n constructor(key: string) {\n super(`runtime slot \"${key}\" was not provided in agent.run() resources`)\n this.name = 'MissingRuntimeSlotError'\n this.key = key\n }\n}\n\n/** Thrown by {@link Agent.run} when a `required()` slot is passed in `resources` instead of `createAgent()`. */\nexport class RequiredSlotInRunError extends Error {\n /** The offending slot key. */\n readonly key: string\n constructor(key: string) {\n super(`slot \"${key}\" is a required() slot — provide it in createAgent(), not agent.run()`)\n this.name = 'RequiredSlotInRunError'\n this.key = key\n }\n}\n\n/** Thrown by {@link Agent.run} when `resources` contains a key that was not declared as `runtime()`. */\nexport class UnknownRunSlotError extends Error {\n /** The unknown resource key. */\n readonly key: string\n constructor(key: string) {\n super(`slot \"${key}\" is not a runtime() slot — do not pass it in agent.run() resources`)\n this.name = 'UnknownRunSlotError'\n this.key = key\n }\n}\n\n/** Thrown by {@link createAgent} when a `required()` store marker has no matching entry in `agentOptions.stores`. */\nexport class MissingStoreSlotError extends Error {\n /** The store key (e.g. `\"session\"`) that was not provided. */\n readonly key: string\n constructor(key: string) {\n super(`required store slot \"${key}\" was not provided in createAgent options.stores`)\n this.name = 'MissingStoreSlotError'\n this.key = key\n }\n}\n\n/** Thrown by {@link createAgent} when `agentOptions.stores` contains a key that is not declared as `required()` in the harness. */\nexport class UnexpectedStoreSlotError extends Error {\n /** The unexpected store key. */\n readonly key: string\n constructor(key: string) {\n super(`store slot \"${key}\" was not declared as required() in the harness — do not pass it in options.stores`)\n this.name = 'UnexpectedStoreSlotError'\n this.key = key\n }\n}\n\n// -----------------------------------------------------------------------\n// Module-private symbol for AttachInternals\n// -----------------------------------------------------------------------\n\nconst _agentInternals = Symbol('_agentInternals')\n\ntype AgentWithInternals = Agent & {\n readonly [_agentInternals]: AgentInternals\n}\n\n// -----------------------------------------------------------------------\n// createAgent — the public factory\n// -----------------------------------------------------------------------\n\n/**\n * Instantiate an agent from a fully-configured {@link Harness}.\n *\n * Validates that all `required()` slots are present in `slots`, that no\n * `runtime()` slots are passed here, and that the harness has a loop defined.\n *\n * @param id - A stable, human-readable identifier for this agent (used as the\n * first argument to every store operation).\n * @param h - The harness produced by `createHarness()...loop()`.\n * @param slots - Values for every slot declared with `required()` in the harness.\n * @param options - Optional agent-level options (e.g., instanceId).\n *\n * @throws {@link MissingLoopError} when `h.loop()` was never called.\n * @throws {@link MissingSlotError} when a `required()` slot is absent from `slots`.\n * @throws {@link RuntimeSlotInAgentError} when a `runtime()` slot is passed in `slots`.\n * @throws {@link UnknownSlotError} when `slots` contains a key not declared in the harness.\n *\n * @example\n * ```ts\n * const agent = createAgent('my-agent', h, { llm: new Claude('claude-3-5-haiku-20241022') })\n * const handle = agent.run({}, {})\n * const { state, signal } = await handle\n * ```\n */\nexport function createAgent<Ctx, State, Req extends keyof Ctx, Run extends keyof Ctx>(\n id: string,\n h: Harness<Ctx, State, Req, Run>,\n slots: Pick<Ctx, Req>,\n agentOptions?: AgentOptions,\n): Agent {\n // Get harness internals; propagate HarnessInternalsError if h is not a real Harness\n const internals: HarnessInternals<Ctx, State, Req, Run> = getInternals(h)\n\n // Validation 1: loop exists\n if (internals.loopDef === undefined) {\n throw new MissingLoopError()\n }\n\n // Build a map of provider entries with kind 'provide' for slot validation\n const providerMap = new Map<string, ProviderEntry>()\n for (const entry of internals.providers) {\n if (entry.kind === 'provide') {\n providerMap.set(entry.key, entry)\n }\n }\n\n // Validation 2: no unknown keys in slots\n for (const key of Object.keys(slots)) {\n if (!providerMap.has(key)) {\n throw new UnknownSlotError(key)\n }\n }\n\n // Validation 3: no runtime() markers in slots\n for (const key of Object.keys(slots)) {\n const entry = providerMap.get(key)\n if (entry && isRuntimeMarker(entry.value)) {\n throw new RuntimeSlotInAgentError(key)\n }\n }\n\n // Validation 4: all required() slots are provided\n for (const entry of internals.providers) {\n if (entry.kind === 'provide' && isRequiredMarker(entry.value)) {\n if (!(entry.key in slots)) {\n throw new MissingSlotError(entry.key)\n }\n }\n }\n\n // Build resolvedProviders map: iterate all providers in order, last-registered-wins\n const resolvedProviders = new Map<string, unknown>()\n const storeEntries: ProviderEntry[] = []\n const runtimeKeys = new Set<string>()\n const requiredKeys = new Set<string>()\n\n for (const entry of internals.providers) {\n if (entry.kind === 'store') {\n storeEntries.push(entry)\n } else if (entry.kind === 'provide') {\n if (isRequiredMarker(entry.value)) {\n // Replace required() marker with the slot value\n resolvedProviders.set(entry.key, (slots as Record<string, unknown>)[entry.key]) // as: Req extends keyof Ctx erases to plain index at runtime\n requiredKeys.add(entry.key)\n } else if (isRuntimeMarker(entry.value)) {\n runtimeKeys.add(entry.key)\n // runtime() markers are not included in resolvedProviders\n } else {\n // Concrete value: include as-is\n resolvedProviders.set(entry.key, entry.value)\n }\n }\n }\n\n // Validate the 'session' store slot — the only store key with framework-managed lifecycle.\n // Other store keys (user-defined, future ctx.store.<name>) are not processed here.\n let sessionIsRequired = false\n for (const entry of storeEntries) {\n const storeValue = entry.value\n if (storeValue === null || typeof storeValue !== 'object') continue\n const storeRec = storeValue as Record<string, unknown> // as: same narrowing as resolveSessionStore\n if ('session' in storeRec && isRequiredMarker(storeRec['session'])) {\n sessionIsRequired = true // last-registered store entry wins, consistent with resolveSessionStore\n }\n }\n const sessionStoreOverride = agentOptions?.stores?.['session']\n const storeOverrides: Record<string, unknown> = {}\n if (sessionIsRequired) {\n if (sessionStoreOverride === undefined) throw new MissingStoreSlotError('session')\n storeOverrides['session'] = sessionStoreOverride\n } else if (sessionStoreOverride !== undefined) {\n throw new UnexpectedStoreSlotError('session')\n }\n\n // Resolve session store from store entries at construction time\n const capturedStore = resolveSessionStore(\n storeEntries,\n Object.keys(storeOverrides).length > 0 ? storeOverrides : undefined,\n )\n\n // Construct AgentInternals\n const agentInternals: AgentInternals = {\n agentId: id,\n resolvedProviders,\n storeEntries,\n loopDef: internals.loopDef, // Guaranteed to be non-undefined by validation 1\n stateSchema: internals.stateSchema,\n runtimeKeys,\n requiredKeys,\n }\n\n // Reserved keys are skipped during agent.run() resource validation\n const reservedRunKeys = new Set(['sessionId', 'signal', 'events', 'listeners', 'observer', 'claimOptions', 'parentRunId'])\n\n // one per agent instance; tracks all session IDs currently executing\n const inFlightSessions = new Set<string>()\n\n // one per agent instance; tracks session IDs paused on an unanswered interrupt\n // cleared when agent.resume() or run.resume() is called; populated when a run settles with signal: \"$interrupt\"\n const interruptPendingSessions = new Set<string>()\n\n // -----------------------------------------------------------------------\n // makeAgentResumeHandle — factory for cross-process resume RunHandles\n // -----------------------------------------------------------------------\n\n const makeAgentResumeHandle = (\n resp: unknown,\n sId: string,\n iId: string,\n resumeOpts?: { onStoreError?: (error: unknown, phase: 'load' | 'persist' | 'claim') => void },\n observer?: Observer,\n setStepContextSlots?: ReadonlyArray<{ setStepContext(ctx: StepContext): void }>,\n ): RunHandle => {\n let _stopped = false\n const abortController = new AbortController()\n const flag = {\n get stopped(): boolean { return _stopped },\n set stopped(v: boolean) { _stopped = v; if (v) abortController.abort() },\n }\n const ref: { current: string | null } = { current: null }\n const rId = randomUUID()\n\n const exec = (async (): Promise<RunOutcome> => {\n await Promise.resolve()\n const claimOptions: ClaimOptions = { ttlMs: 30_000 }\n let leaseRef: LeaseRef | undefined = undefined\n try {\n if (typeof capturedStore?.claim === 'function') {\n let lease: Lease | null\n try {\n lease = await capturedStore.claim(id, sId, claimOptions)\n } catch (claimError: unknown) {\n const loadError = new StoreLoadError(claimError)\n resumeOpts?.onStoreError?.(loadError, 'claim')\n const failState = initializeState(null, {}, agentInternals.stateSchema)\n ;(failState as Record<string, unknown>)['$error'] = loadError\n return { state: failState, signal: '$error' }\n }\n if (lease === null) {\n const busyError = new SessionBusyError(sId)\n resumeOpts?.onStoreError?.(busyError, 'claim')\n const failState = initializeState(null, {}, agentInternals.stateSchema)\n ;(failState as Record<string, unknown>)['$error'] = busyError\n return { state: failState, signal: '$error' }\n }\n leaseRef = { current: lease }\n }\n try {\n if (capturedStore === undefined) throw new NoInterruptError()\n try {\n await injectInterruptResponse(capturedStore, id, sId, iId, resp)\n } catch (injectError: unknown) {\n if (injectError instanceof NoInterruptError) throw injectError\n // store I/O failure during interrupt injection — report as 'claim' phase error\n const storeError = new StoreLoadError(injectError)\n resumeOpts?.onStoreError?.(storeError, 'claim')\n const failState = initializeState(null, {}, agentInternals.stateSchema)\n ;(failState as Record<string, unknown>)['$error'] = storeError\n return { state: failState, signal: '$error' }\n }\n const agentCtx: Record<string, unknown> & { readonly agentId: string; readonly sessionId: string; readonly runId: string; readonly signal: AbortSignal } = {\n ...Object.fromEntries(agentInternals.resolvedProviders),\n agentId: id,\n sessionId: sId,\n runId: rId,\n signal: abortController.signal,\n }\n const r = await runWithSession(\n capturedStore,\n id,\n sId,\n rId,\n agentInternals.loopDef,\n {},\n agentInternals.stateSchema,\n agentCtx,\n {\n shouldStop: () => flag.stopped,\n onBeforeStep: (n: string) => { ref.current = n },\n ...(resumeOpts?.onStoreError !== undefined ? { onStoreError: resumeOpts.onStoreError } : {}),\n ...(leaseRef !== undefined ? { leaseRef, claimTtlMs: claimOptions.ttlMs } : {}),\n ...(observer !== undefined ? { observer } : {}),\n ...(setStepContextSlots !== undefined && setStepContextSlots.length > 0 ? { setStepContextSlots } : {}),\n },\n )\n if (r.signal === '$interrupt') interruptPendingSessions.add(sId)\n return { state: r.state, signal: r.signal }\n } catch (error: unknown) {\n if (error instanceof LeaseExpiredError) {\n const failState = initializeState(null, {}, agentInternals.stateSchema)\n ;(failState as Record<string, unknown>)['$error'] = error\n return { state: failState, signal: '$error' }\n }\n throw error\n } finally {\n if (leaseRef !== undefined && typeof capturedStore?.release === 'function') {\n try { await capturedStore.release(leaseRef.current!) } catch { /* swallow */ }\n }\n }\n } finally {\n inFlightSessions.delete(sId)\n }\n })()\n\n const resumeFn = (r: unknown, i: string): RunHandle => {\n // Synchronous fence — same invariant as agent.resume()\n if (inFlightSessions.has(sId)) throw new SessionInFlightError(sId)\n interruptPendingSessions.delete(sId)\n inFlightSessions.add(sId)\n return makeAgentResumeHandle(r, sId, i)\n }\n return createRunHandle(sId, rId, exec, flag, ref, resumeFn)\n }\n\n // Create and return Agent with attached internals\n const agent: AgentWithInternals = {\n id,\n run: (initialState: Record<string, unknown>, resources: Record<string, unknown>): RunHandle => {\n // Validation pass 1: unknown keys (not reserved, not runtime, not required)\n for (const key of Object.keys(resources)) {\n if (reservedRunKeys.has(key)) continue\n if (!agentInternals.runtimeKeys.has(key) && !agentInternals.requiredKeys.has(key)) {\n throw new UnknownRunSlotError(key)\n }\n }\n\n // Validation pass 2: required() keys passed in resources\n for (const key of Object.keys(resources)) {\n if (reservedRunKeys.has(key)) continue\n if (agentInternals.requiredKeys.has(key)) {\n throw new RequiredSlotInRunError(key)\n }\n }\n\n // Validation pass 3: missing runtime() keys\n for (const key of agentInternals.runtimeKeys) {\n if (!(key in resources)) {\n throw new MissingRuntimeSlotError(key)\n }\n }\n\n // Session ID resolution\n const sessionId =\n typeof resources['sessionId'] === 'string' ? resources['sessionId'] : randomUUID()\n\n // Run ID — unique per agent.run() invocation, available synchronously on RunHandle\n const runId = randomUUID()\n\n // Synchronous concurrency fences — must precede any await (per docs/agent.md Concurrency section)\n if (inFlightSessions.has(sessionId)) throw new SessionInFlightError(sessionId)\n if (interruptPendingSessions.has(sessionId)) throw new SessionPendingInterruptError(sessionId)\n inFlightSessions.add(sessionId)\n\n // AbortSignal and stop-flag wiring\n let _stopped = false\n const abortController = new AbortController()\n const stopFlag = {\n get stopped(): boolean { return _stopped },\n set stopped(v: boolean) { _stopped = v; if (v) abortController.abort() },\n }\n const rawSignal = resources['signal']\n let ctxSignal: AbortSignal = abortController.signal\n if (rawSignal instanceof AbortSignal) {\n ctxSignal = rawSignal\n rawSignal.addEventListener('abort', () => { stopFlag.stopped = true; abortController.abort() }, { once: true })\n if (rawSignal.aborted) stopFlag.stopped = true\n }\n\n // Fresh stepRef per call for currentStep tracking\n const stepRef: { current: string | null } = { current: null }\n\n // Assemble ctx: resolvedProviders merged with runtime slots and sessionId, runId, and signal\n const runtimeSlots: Record<string, unknown> = {}\n for (const key of agentInternals.runtimeKeys) {\n if (reservedRunKeys.has(key)) continue // reserved keys are consumed by framework, not injected into ctx\n runtimeSlots[key] = resources[key]\n }\n const ctx: Record<string, unknown> & { readonly agentId: string; readonly sessionId: string; readonly runId: string; readonly signal: AbortSignal } = {\n ...Object.fromEntries(agentInternals.resolvedProviders),\n ...runtimeSlots,\n agentId: id,\n sessionId,\n runId,\n signal: ctxSignal,\n ...(agentOptions?.instanceId !== undefined ? { instanceId: agentOptions.instanceId } : {}),\n }\n\n // Extract event callbacks and listeners from resources (reserved keys)\n const events = extractRunEvents(resources)\n const listeners = extractRunListeners(resources)\n\n // Extract observer and bind to any ObserverAware slots synchronously before async execution begins\n const observer = extractRunObserver(resources)\n for (const slot of [...agentInternals.resolvedProviders.values(), ...Object.values(runtimeSlots)]) {\n if (slot !== null && typeof slot === 'object' && typeof (slot as Record<string, unknown>)['bindObserver'] === 'function') { // as: duck-typed structural check; slot typed as unknown at this point\n (slot as { bindObserver: (o: Observer) => void }).bindObserver(observer ?? NOOP_OBSERVER) // as: narrowed by duck-type check on line above\n }\n }\n\n // Build setStepContextSlots: pre-filter all slots that expose setStepContext (F36)\n const setStepContextSlots: Array<{ setStepContext(ctx: StepContext): void }> = []\n for (const slot of [...agentInternals.resolvedProviders.values(), ...Object.values(runtimeSlots)]) {\n if (\n slot !== null &&\n typeof slot === 'object' &&\n typeof (slot as Record<string, unknown>)['setStepContext'] === 'function' // as: duck-type check\n ) {\n setStepContextSlots.push(slot as { setStepContext(ctx: StepContext): void }) // as: narrowed by duck-type check on line above\n }\n }\n\n // Extract parentRunId from resources (reserved key)\n const parentRunId =\n typeof resources['parentRunId'] === 'string' ? resources['parentRunId'] : undefined\n\n const options: SessionRunOptions = {\n shouldStop: () => stopFlag.stopped,\n onBeforeStep: (name: string, state: Record<string, unknown>) => {\n stepRef.current = name\n events.onBeforeStep?.(name, state)\n },\n // spread optional event callbacks only when defined (exactOptionalPropertyTypes requires omission, not undefined)\n ...(events.onStoreError !== undefined ? { onStoreError: events.onStoreError } : {}),\n ...(events.onAfterStep !== undefined ? { onAfterStep: events.onAfterStep } : {}),\n ...(events.onError !== undefined ? { onError: events.onError } : {}),\n ...(events.onComplete !== undefined ? { onComplete: events.onComplete } : {}),\n ...(events.onInterrupt !== undefined ? { onInterrupt: events.onInterrupt } : {}),\n ...(Object.keys(listeners).length > 0 ? { listeners } : {}),\n ...(observer !== undefined ? { observer } : {}),\n ...(agentOptions?.instanceId !== undefined ? { instanceId: agentOptions.instanceId } : {}),\n ...(parentRunId !== undefined ? { parentRunId } : {}),\n ...(setStepContextSlots.length > 0 ? { setStepContextSlots } : {}),\n }\n\n // lastResult captures the LoopResult for same-process in-memory resume chaining\n let lastResult: { state: Record<string, unknown>; cursor: string | null } | null = null\n\n // Launch execution asynchronously — agent.run() returns before any async work begins\n const execution = (async (): Promise<RunOutcome> => {\n // Yield so agent.run() can return the RunHandle before any loop iteration starts\n await Promise.resolve()\n\n // Parse claimOptions from resources (reserved key); default ttlMs=30_000\n const rawClaimOpts = resources['claimOptions']\n const claimOptions: ClaimOptions =\n typeof rawClaimOpts === 'object' && rawClaimOpts !== null &&\n typeof (rawClaimOpts as Record<string, unknown>)['ttlMs'] === 'number'\n ? (rawClaimOpts as ClaimOptions)\n : { ttlMs: 30_000 }\n\n let leaseRef: LeaseRef | undefined = undefined\n\n try {\n if (typeof capturedStore?.claim === 'function') {\n let lease: Lease | null\n try {\n lease = await capturedStore.claim(id, sessionId, claimOptions)\n } catch (claimError: unknown) {\n const loadError = new StoreLoadError(claimError)\n events.onStoreError?.(loadError, 'claim')\n const failState = initializeState(null, initialState, agentInternals.stateSchema)\n ;(failState as Record<string, unknown>)['$error'] = loadError\n return { state: failState, signal: '$error' }\n }\n if (lease === null) {\n const busyError = new SessionBusyError(sessionId)\n events.onStoreError?.(busyError, 'claim')\n const failState = initializeState(null, initialState, agentInternals.stateSchema)\n ;(failState as Record<string, unknown>)['$error'] = busyError\n return { state: failState, signal: '$error' }\n }\n leaseRef = { current: lease }\n }\n try {\n const r = await runWithSession(\n capturedStore,\n id,\n sessionId,\n runId,\n agentInternals.loopDef,\n initialState,\n agentInternals.stateSchema,\n ctx,\n {\n ...options,\n ...(leaseRef !== undefined ? { leaseRef, claimTtlMs: claimOptions.ttlMs } : {}),\n },\n )\n if (r.signal === '$interrupt') interruptPendingSessions.add(sessionId)\n lastResult = { state: r.state, cursor: r.cursor }\n return { state: r.state, signal: r.signal }\n } catch (error: unknown) {\n if (error instanceof LeaseExpiredError) {\n // onStoreError already called by runWithSession before throwing\n const failState = initializeState(null, initialState, agentInternals.stateSchema)\n ;(failState as Record<string, unknown>)['$error'] = error\n return { state: failState, signal: '$error' }\n }\n throw error\n } finally {\n if (leaseRef !== undefined && typeof capturedStore?.release === 'function') {\n try { await capturedStore.release(leaseRef.current!) } catch { /* swallow */ }\n }\n }\n } finally {\n inFlightSessions.delete(sessionId)\n }\n })()\n\n // buildResumeFn — creates a recursive resumeFn for same-process chaining via run.resume()\n const buildResumeFn = (): ((response: unknown, interruptId: string) => RunHandle) => {\n return (response: unknown, interruptId: string): RunHandle => {\n // Synchronous fence — same invariant as agent.run()\n if (inFlightSessions.has(sessionId)) throw new SessionInFlightError(sessionId)\n interruptPendingSessions.delete(sessionId)\n inFlightSessions.add(sessionId)\n\n let _resumeStopped = false\n const resumeAbortController = new AbortController()\n const resumeStopFlag = {\n get stopped(): boolean { return _resumeStopped },\n set stopped(v: boolean) { _resumeStopped = v; if (v) resumeAbortController.abort() },\n }\n const resumeStepRef: { current: string | null } = { current: null }\n const resumeRunId = randomUUID()\n\n const resumeExecution = (async (): Promise<RunOutcome> => {\n await Promise.resolve()\n try {\n // Create a new ctx for this resume invocation with updated runId and signal\n const resumeCtx: Record<string, unknown> & { readonly agentId: string; readonly sessionId: string; readonly runId: string; readonly signal: AbortSignal } = {\n ...ctx,\n runId: resumeRunId,\n signal: resumeAbortController.signal,\n }\n\n if (capturedStore !== undefined) {\n // Cross-process path: inject response into store, reload, and re-run\n await injectInterruptResponse(capturedStore, id, sessionId, interruptId, response)\n const r = await runWithSession(\n capturedStore,\n id,\n sessionId,\n resumeRunId,\n agentInternals.loopDef,\n {},\n agentInternals.stateSchema,\n resumeCtx,\n {\n shouldStop: () => resumeStopFlag.stopped,\n onBeforeStep: (n: string, s: Record<string, unknown>) => {\n resumeStepRef.current = n\n events.onBeforeStep?.(n, s)\n },\n // spread optional event callbacks only when defined (exactOptionalPropertyTypes requires omission, not undefined)\n ...(events.onStoreError !== undefined ? { onStoreError: events.onStoreError } : {}),\n ...(events.onAfterStep !== undefined ? { onAfterStep: events.onAfterStep } : {}),\n ...(events.onError !== undefined ? { onError: events.onError } : {}),\n ...(events.onComplete !== undefined ? { onComplete: events.onComplete } : {}),\n ...(events.onInterrupt !== undefined ? { onInterrupt: events.onInterrupt } : {}),\n ...(Object.keys(listeners).length > 0 ? { listeners } : {}),\n ...(observer !== undefined ? { observer } : {}),\n ...(setStepContextSlots.length > 0 ? { setStepContextSlots } : {}),\n },\n )\n if (r.signal === '$interrupt') interruptPendingSessions.add(sessionId)\n lastResult = { state: r.state, cursor: r.cursor }\n return { state: r.state, signal: r.signal }\n }\n\n // Same-process in-memory path: mutate shared state and re-run from cursor\n const prev = lastResult\n if (prev === null) throw new NoInterruptError()\n const state = prev.state\n const existing = (state.$interruptResponses as Record<string, unknown>) ?? {}\n state.$interruptResponses = { ...existing, [interruptId]: response }\n state.$interrupt = null\n const cursor = prev.cursor ?? undefined\n const r = await runLoop(\n agentInternals.loopDef,\n state,\n resumeCtx,\n agentInternals.stateSchema,\n () => resumeStopFlag.stopped,\n cursor,\n {\n runId: resumeRunId,\n onBeforeStep: (n: string, s: Record<string, unknown>) => {\n resumeStepRef.current = n\n events.onBeforeStep?.(n, s)\n },\n ...(events.onAfterStep !== undefined ? { onAfterStep: events.onAfterStep } : {}),\n ...(events.onError !== undefined ? { onError: events.onError } : {}),\n ...(events.onComplete !== undefined ? { onComplete: events.onComplete } : {}),\n ...(events.onInterrupt !== undefined ? { onInterrupt: events.onInterrupt } : {}),\n ...(Object.keys(listeners).length > 0 ? { listeners } : {}),\n ...(observer !== undefined ? { observer } : {}),\n ...(setStepContextSlots.length > 0 ? { setStepContextSlots } : {}),\n },\n )\n if (r.signal === '$interrupt') interruptPendingSessions.add(sessionId)\n lastResult = { state: r.state, cursor: r.cursor }\n return { state: r.state, signal: r.signal }\n } catch (error: unknown) {\n if (error instanceof LeaseExpiredError) {\n // onStoreError already called by runWithSession before throwing\n const failState = initializeState(null, initialState, agentInternals.stateSchema)\n ;(failState as Record<string, unknown>)['$error'] = error\n return { state: failState, signal: '$error' }\n }\n throw error\n } finally {\n inFlightSessions.delete(sessionId)\n }\n })()\n\n return createRunHandle(sessionId, resumeRunId, resumeExecution, resumeStopFlag, resumeStepRef, buildResumeFn())\n }\n }\n\n return createRunHandle(sessionId, runId, execution, stopFlag, stepRef, buildResumeFn())\n },\n\n resume: (\n response: unknown,\n sessionId: string,\n interruptId: string,\n resources?: Record<string, unknown>,\n ): RunHandle => {\n // SessionInFlightError fence is first — before any extraction or binding (Invariant 3)\n if (inFlightSessions.has(sessionId)) throw new SessionInFlightError(sessionId)\n interruptPendingSessions.delete(sessionId)\n inFlightSessions.add(sessionId)\n const events = extractRunEvents(resources ?? {})\n const resumeOpts = events.onStoreError !== undefined\n ? { onStoreError: events.onStoreError }\n : undefined\n const observer = extractRunObserver(resources ?? {})\n // bind observer unconditionally on all ObserverAware resolvedProviders (Invariant 1)\n for (const slot of agentInternals.resolvedProviders.values()) {\n if (slot !== null && typeof slot === 'object' && typeof (slot as Record<string, unknown>)['bindObserver'] === 'function') { // as: duck-typed structural check\n (slot as { bindObserver: (o: Observer) => void }).bindObserver(observer ?? NOOP_OBSERVER) // as: narrowed by duck-type check on line above\n }\n }\n // Build setStepContextSlots from resolvedProviders only (no runtime slots in resume path)\n const setStepContextSlots: Array<{ setStepContext(ctx: StepContext): void }> = []\n for (const slot of agentInternals.resolvedProviders.values()) {\n if (\n slot !== null &&\n typeof slot === 'object' &&\n typeof (slot as Record<string, unknown>)['setStepContext'] === 'function' // as: duck-type check\n ) {\n setStepContextSlots.push(slot as { setStepContext(ctx: StepContext): void }) // as: narrowed by duck-type check on line above\n }\n }\n return makeAgentResumeHandle(response, sessionId, interruptId, resumeOpts, observer ?? undefined, setStepContextSlots.length > 0 ? setStepContextSlots : undefined)\n },\n\n status: (sessionId: string) => querySessionPhase(capturedStore, id, sessionId),\n [_agentInternals]: agentInternals,\n }\n\n return agent\n}\n\n// -----------------------------------------------------------------------\n// getAgentInternals — accessor for AgentInternals\n// -----------------------------------------------------------------------\n\nexport function getAgentInternals(agent: Agent): AgentInternals {\n if (agent === null || typeof agent !== 'object' || !(_agentInternals in agent)) {\n throw new AgentInternalsError()\n }\n return (agent as AgentWithInternals)[_agentInternals] // as: _agentInternals in agent guard above guarantees the symbol key is present\n}\n","/**\n * Framework-fired event callbacks for a single agent.run() invocation.\n * All fields are optional — omit any you do not need.\n * Callbacks are fire-and-forget; their return value is ignored.\n * Scoped to the run — released when the run settles.\n *\n * Note: user-emitted events (formerly onLlmCall etc.) are replaced by\n * ctx.emit(name, payload) + the 'listeners' resource key. See agent.md.\n */\nexport interface RunEvents {\n /** Called just before a step's run function is invoked. */\n onBeforeStep?: (name: string, state: Record<string, unknown>) => void\n /** Called just after a step's run function completes successfully (state update applied). */\n onAfterStep?: (name: string, state: Record<string, unknown>) => void\n /**\n * Called when the loop exits normally via .on(signal).end().\n * Not called for paused outcomes (stop, abort, error, interrupt).\n */\n onComplete?: (state: Record<string, unknown>, signal: string) => void\n /**\n * Called immediately when a step's run throws a non-interrupt error, before error routing.\n * Fires regardless of how the error is ultimately handled. Does not affect routing or state.\n */\n onError?: (error: unknown, stepName: string) => void\n /**\n * Called when ctx.interrupt() pauses the run (i.e. when isInterruptPause is true).\n * Fires with the prompt and interruptId from the InterruptPause exception, before the\n * run resolves with signal: \"$interrupt\".\n */\n onInterrupt?: (prompt: unknown, interruptId: string) => void\n /**\n * Called if the session store fails at load, persist, or claim phase.\n * phase: 'load' — store failed at run start (run never executed).\n * phase: 'persist' — store failed at run end (run completed but state not saved).\n * phase: 'claim' — store.claim() returned null (busy) or threw (network error).\n */\n onStoreError?: (error: unknown, phase: 'load' | 'persist' | 'claim') => void\n}\n\n/**\n * Extract and validate the events object from agent.run() resources.\n * Returns an empty RunEvents if no events key is present.\n */\nexport function extractRunEvents(resources: Record<string, unknown>): RunEvents {\n const raw = resources['events']\n if (raw === null || typeof raw !== 'object' || Array.isArray(raw)) {\n return {}\n }\n // plain object: return as-is; callbacks are optional and missing keys are undefined\n return raw as RunEvents // as: duck-typed plain object confirmed above; RunEvents fields are all optional\n}\n","/**\n * Identifies the agent and session for run-level observer callbacks.\n */\nexport interface RunContext {\n readonly agentId: string\n readonly sessionId: string\n /**\n * The UUID for this specific run invocation. Always present in RunContext\n * passed to observer methods.\n */\n readonly runId: string\n /**\n * Optional parent run UUID for cross-process trace correlation. Present\n * when parentRunId was passed to agent.run() resources. Absent for top-level\n * runs or when not provided by the caller.\n */\n readonly parentRunId?: string\n /**\n * The physical instance ID of the agent process, if configured via\n * `createAgent()` options. Absent when `instanceId` was not provided.\n */\n readonly instanceId?: string\n}\n\n/**\n * Identifies the agent, session, and current step for step-level observer callbacks.\n */\nexport interface StepContext {\n readonly agentId: string\n readonly sessionId: string\n readonly stepName: string\n}\n\n/**\n * Observability hook interface. All methods are optional — implement only\n * the hooks you need.\n *\n * Pass an `Observer` implementation in `agent.run()` resources under the key\n * `'observer'`, or bind it to an {@link ObserverAware} slot before running.\n *\n * LLM adapters emit `'llm.response'` events via `onEvent` carrying an\n * `LLMUsageEvent` payload for token tracking.\n *\n * @example\n * ```ts\n * const obs: Observer = {\n * onRunStart: (ctx) => console.log('run started', ctx.sessionId),\n * onEvent: (ctx, type, payload) => metrics.record(type, payload),\n * }\n * agent.run({}, { llm, observer: obs })\n * ```\n */\nexport interface Observer {\n /** Called once when a run begins, before the first step executes. */\n onRunStart?: (ctx: RunContext) => void\n /** Called once when a run settles (completed or stopped). */\n onRunEnd?: (ctx: RunContext, event: { signal: string; durationMs: number }) => void\n /** Called immediately before each step's `run` function is invoked. */\n onStepStart?: (ctx: StepContext) => void\n /** Called after a step completes successfully. */\n onStepEnd?: (ctx: StepContext, event: { durationMs: number }) => void\n /** Called when a step's `run` function throws. */\n onStepError?: (ctx: StepContext, event: { error: unknown; durationMs: number }) => void\n /** Called when a step issues a `ctx.interrupt()`. */\n onInterrupt?: (ctx: StepContext, event: { prompt: unknown; interruptId: string }) => void\n /**\n * Called for arbitrary named events emitted by step code via `ctx.emit()` or\n * by LLM adapters (e.g. `'llm.response'`).\n */\n onEvent?: (ctx: StepContext, type: string, payload: unknown) => void\n}\n\n/**\n * Implemented by resources (e.g. LLM adapters) that accept an {@link Observer}\n * at run time. The harness calls `bindObserver` on every slot value that\n * implements this interface before the first step runs.\n *\n * Optionally, the harness calls `setStepContext` at the start of each step for\n * every slot that exposes it. Adapters use this to attribute per-step telemetry\n * (e.g. `observer.onEvent`) to the correct step without manual calls from step code.\n */\nexport interface ObserverAware {\n /**\n * Receive the run's observer. The harness calls this once per `agent.run()`\n * invocation before execution begins.\n */\n bindObserver(observer: Observer): void\n\n /**\n * Receive the current step context. The harness calls this at the start of\n * each step for every slot that exposes this method, before calling `step.run`.\n *\n * Adapters that emit `observer.onEvent` in their `invoke()` method store the\n * provided `StepContext` and use it as the first argument to `onEvent`, so\n * events are attributed to the correct step automatically.\n */\n setStepContext?(ctx: StepContext): void\n}\n\n/**\n * Combine multiple {@link Observer} instances into one. Each hook on the\n * composite forwards to all constituent observers in order.\n *\n * @example\n * ```ts\n * const observer = composeObservers(otelObserver, metricsObserver)\n * ```\n */\nexport function composeObservers(...observers: Observer[]): Observer {\n return {\n onRunStart: (ctx) => {\n for (const o of observers) o.onRunStart?.(ctx)\n },\n onRunEnd: (ctx, event) => {\n for (const o of observers) o.onRunEnd?.(ctx, event)\n },\n onStepStart: (ctx) => {\n for (const o of observers) o.onStepStart?.(ctx)\n },\n onStepEnd: (ctx, event) => {\n for (const o of observers) o.onStepEnd?.(ctx, event)\n },\n onStepError: (ctx, event) => {\n for (const o of observers) o.onStepError?.(ctx, event)\n },\n onInterrupt: (ctx, event) => {\n for (const o of observers) o.onInterrupt?.(ctx, event)\n },\n onEvent: (ctx, type, payload) => {\n for (const o of observers) o.onEvent?.(ctx, type, payload)\n },\n }\n}\n"],"mappings":"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","names":["field","state","result","r"]}
|