@statelyai/agent 2.0.0-alpha.11 → 2.0.0-alpha.13
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/ai-sdk.cjs +4 -5
- package/dist/ai-sdk.d.cts +7 -4
- package/dist/ai-sdk.d.mts +7 -4
- package/dist/ai-sdk.mjs +1 -2
- package/dist/{events-JiVPYrct.mjs → decision-BezSD_YC.mjs} +327 -20
- package/dist/{events-CRQj3VtP.cjs → decision-dWGhBh0P.cjs} +401 -28
- package/dist/errors-BQRk9eiZ.d.cts +19 -0
- package/dist/errors-C9rxnWbX.d.mts +19 -0
- package/dist/errors-CeSXQx0v.mjs +23 -0
- package/dist/errors-DUBBzRLP.cjs +28 -0
- package/dist/event-log-store-CNT_7F0V.cjs +452 -0
- package/dist/event-log-store-CriMgX1D.d.mts +144 -0
- package/dist/event-log-store-D7pWtIhb.mjs +411 -0
- package/dist/event-log-store-Ruq18mGp.d.cts +144 -0
- package/dist/index.cjs +1050 -705
- package/dist/index.d.cts +538 -565
- package/dist/index.d.mts +538 -565
- package/dist/index.mjs +950 -644
- package/dist/machines.cjs +752 -0
- package/dist/machines.d.cts +372 -0
- package/dist/machines.d.mts +372 -0
- package/dist/machines.mjs +741 -0
- package/dist/otel.cjs +268 -0
- package/dist/otel.d.cts +67 -0
- package/dist/otel.d.mts +67 -0
- package/dist/otel.mjs +267 -0
- package/dist/run-agent-C3mFDGTf.d.mts +1111 -0
- package/dist/run-agent-DnvtcnTZ.d.cts +1111 -0
- package/dist/setup-agent-DAZZSjDS.mjs +1711 -0
- package/dist/setup-agent-DP95MFrI.cjs +1836 -0
- package/dist/sqlite.cjs +135 -0
- package/dist/sqlite.d.cts +57 -0
- package/dist/sqlite.d.mts +57 -0
- package/dist/sqlite.mjs +133 -0
- package/dist/{text-logic-CaKqgX4Y.d.mts → text-logic-BDxwQNsD.d.cts} +155 -72
- package/dist/{text-logic-Ckhr2kKC.d.cts → text-logic-TkKPw8Aq.d.mts} +155 -72
- package/dist/{types-qm00QF91.d.mts → types-QbEfCVny.d.cts} +1 -1
- package/dist/{types-C9QiMjre.d.cts → types-_FXoFBGO.d.mts} +1 -1
- package/package.json +47 -39
- package/readme.md +49 -12
- package/schemas/agent-workflow.json +40 -21
- package/skills/generate-machine/SKILL.md +267 -0
- package/dist/adapter.cjs +0 -15
- package/dist/adapter.d.cts +0 -4
- package/dist/adapter.d.mts +0 -4
- package/dist/adapter.mjs +0 -2
- package/dist/decision-C3k4ve51.mjs +0 -227
- package/dist/decision-D8wJrM8W.cjs +0 -286
- package/dist/openai-compat.cjs +0 -309
- package/dist/openai-compat.d.cts +0 -59
- package/dist/openai-compat.d.mts +0 -59
- package/dist/openai-compat.mjs +0 -308
- package/dist/steps-BALp1eZo.d.mts +0 -198
- package/dist/steps-CVe54GPP.cjs +0 -420
- package/dist/steps-CkyyyuHd.mjs +0 -379
- package/dist/steps-MjnQI4aB.d.cts +0 -198
- package/dist/steps.cjs +0 -12
- package/dist/steps.d.cts +0 -3
- package/dist/steps.d.mts +0 -3
- package/dist/steps.mjs +0 -3
- package/dist/utils-BYqT_Dyv.d.cts +0 -108
- package/dist/utils-Do5wIJrh.d.mts +0 -108
- package/dist/zod.cjs +0 -31
- package/dist/zod.d.cts +0 -30
- package/dist/zod.d.mts +0 -30
- package/dist/zod.mjs +0 -30
|
@@ -0,0 +1,1111 @@
|
|
|
1
|
+
import { c as AgentTools, d as ChosenEvent, n as AgentMessage } from "./types-QbEfCVny.cjs";
|
|
2
|
+
import { t as AgentError } from "./errors-BQRk9eiZ.cjs";
|
|
3
|
+
import { G as AgentRequestSource, H as AgentEventDescriptor, M as AgentDecisionRequest, N as AgentPlanInput, W as AgentRequestOptions, d as AgentTextRequest, f as AgentUsage, l as AgentRequestExecutors, p as AgentUserInput, t as AgentCallUsage, u as AgentRequestMode } from "./text-logic-BDxwQNsD.cjs";
|
|
4
|
+
import { i as AgentLogEntry, o as JsonValue } from "./event-log-store-Ruq18mGp.cjs";
|
|
5
|
+
import { AnyActorLogic, AnyActorRef, AnyMachineSnapshot, AnyStateMachine, AsyncActorLogic, EmittedFrom, EventFromLogic, EventObject, ExecutableActionObject, InputFrom, InspectionEvent, OutputFrom, Snapshot, SnapshotFrom, createActor } from "xstate";
|
|
6
|
+
|
|
7
|
+
//#region src/internal/registry.d.ts
|
|
8
|
+
type AgentExecutionOptions = Pick<AgentRequestOptions, "schemas" | "actors"> & {
|
|
9
|
+
models?: object;
|
|
10
|
+
};
|
|
11
|
+
//#endregion
|
|
12
|
+
//#region src/steps.d.ts
|
|
13
|
+
/**
|
|
14
|
+
* A pending text request surfaced by step discovery ({@link getAgentRequests}
|
|
15
|
+
* / {@link AgentStep.requests}): the machine has spawned a
|
|
16
|
+
* `TextLogic`-backed invoke and is waiting on its result. Resolve it with
|
|
17
|
+
* {@link executeAgentRequest} (or by hand, then feed the output into
|
|
18
|
+
* {@link resolveAgentStep} via `xstate.done.actor` + `actorId`).
|
|
19
|
+
*/
|
|
20
|
+
interface AgentRequest<TInput extends AgentTextRequest = AgentTextRequest> {
|
|
21
|
+
kind: "text";
|
|
22
|
+
id: string;
|
|
23
|
+
src: AgentRequestSource;
|
|
24
|
+
mode?: AgentRequestMode;
|
|
25
|
+
input: TInput;
|
|
26
|
+
tools: AgentTools;
|
|
27
|
+
events: AgentEventDescriptor[];
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* A pending **plan** request re-surfaced by step discovery: the machine
|
|
31
|
+
* invoked `agent.plan`, which applies an ordered sequence of legal events
|
|
32
|
+
* (each one a decision) rather than a single one. Unlike text/decision
|
|
33
|
+
* requests — surfaced once and resolved once — a plan request **re-surfaces on
|
|
34
|
+
* every step** while the plan is in flight, its `events`/`applied`/
|
|
35
|
+
* `stepsRemaining` updated each time, until it terminates.
|
|
36
|
+
*
|
|
37
|
+
* All fields are plain serializable data. Resolve ONE decision per step from
|
|
38
|
+
* `events` (via {@link resolveDecision}, wiring `canTake` to
|
|
39
|
+
* `snapshot.can` exactly like a single decision) then apply it: a real machine
|
|
40
|
+
* event advances the plan (the next step re-surfaces this request); the
|
|
41
|
+
* reserved `agent.plan.done` move, a `stopOn` event, an exhausted budget, or no
|
|
42
|
+
* legal events completes it (its invoke resolves with `{ steps, stopped }`).
|
|
43
|
+
* {@link resolveAgentRequests} does all of this natively — one decision (or one
|
|
44
|
+
* completion) per call.
|
|
45
|
+
*
|
|
46
|
+
* The in-progress plan state (`applied` trail + remaining budget) lives in the
|
|
47
|
+
* plan invoke child's own `createLogic` snapshot `context`
|
|
48
|
+
* (`children.<id>.snapshot.context`), so it survives a full JSON
|
|
49
|
+
* `getPersistedSnapshot` → restore round-trip: a host that persists the step
|
|
50
|
+
* after every event and reloads resumes the plan identically.
|
|
51
|
+
*/
|
|
52
|
+
interface AgentPlanRequest {
|
|
53
|
+
kind: "plan";
|
|
54
|
+
/** Durable invoke id of the `agent.plan` invoke. */
|
|
55
|
+
id: string;
|
|
56
|
+
/** Invoke src (`'agent.plan'` or a registered plan-logic source name). */
|
|
57
|
+
src: AgentRequestSource;
|
|
58
|
+
/** The resolved plan input (`model`/`system`/`prompt`/`allowedEvents`/`stopOn`/`maxSteps`/…). */
|
|
59
|
+
input: AgentPlanInput;
|
|
60
|
+
/**
|
|
61
|
+
* The legal candidates for the NEXT plan step: the currently
|
|
62
|
+
* snapshot-legal machine events (∩ declared `allowedEvents`) plus the
|
|
63
|
+
* reserved `agent.plan.done` move.
|
|
64
|
+
*/
|
|
65
|
+
events: AgentEventDescriptor[];
|
|
66
|
+
/** The events applied so far in this plan, in order (the trail). */
|
|
67
|
+
applied: ChosenEvent[];
|
|
68
|
+
/** How many more events the plan may apply (`maxSteps - applied.length`). */
|
|
69
|
+
stepsRemaining: number;
|
|
70
|
+
}
|
|
71
|
+
/** `AgentStep.requests` element: a text, decision, or plan request. */
|
|
72
|
+
type AgentStepRequest = AgentRequest | AgentDecisionRequest | AgentPlanRequest;
|
|
73
|
+
/**
|
|
74
|
+
* Resolves one **text** request against a host's {@link AgentRequestExecutors}
|
|
75
|
+
* — merges the request's tools, dispatches to `generateText`/`streamText` per
|
|
76
|
+
* `mode`, and validates the result against the request's `outputSchema` if
|
|
77
|
+
* present. Accepts either a `kind: 'text'` `AgentEffect` (the thin-loop shape
|
|
78
|
+
* from `getAgentEffects`) or a legacy {@link AgentRequest} envelope.
|
|
79
|
+
* **Text-only**: passing a `kind: 'decision'` request throws, directing the
|
|
80
|
+
* caller to `resolveDecision(request, executors.decide, ...)` instead. By default
|
|
81
|
+
* returns the normalized output; pass `{ verbose: true }` to also get the
|
|
82
|
+
* raw executor result (tool calls, usage, finish reason — needed for
|
|
83
|
+
* observability and event-sourced replay).
|
|
84
|
+
*/
|
|
85
|
+
/** A `kind: 'text'` `AgentEffect` (structural, to avoid an import cycle with effects.ts). */
|
|
86
|
+
interface TextEffectLike {
|
|
87
|
+
kind: "text";
|
|
88
|
+
requestId: string;
|
|
89
|
+
request: AgentTextRequest;
|
|
90
|
+
mode?: AgentRequestMode;
|
|
91
|
+
}
|
|
92
|
+
declare function executeAgentRequest(request: AgentRequest | TextEffectLike, executors: Partial<AgentRequestExecutors>): Promise<unknown>;
|
|
93
|
+
declare function executeAgentRequest(request: AgentRequest | TextEffectLike, executors: Partial<AgentRequestExecutors>, options: {
|
|
94
|
+
verbose: true;
|
|
95
|
+
}): Promise<{
|
|
96
|
+
output: unknown;
|
|
97
|
+
raw: unknown;
|
|
98
|
+
}>;
|
|
99
|
+
//#endregion
|
|
100
|
+
//#region src/effects.d.ts
|
|
101
|
+
/**
|
|
102
|
+
* One thing a host does at the frontier. Effect kinds mirror what a machine
|
|
103
|
+
* can start in a single transition, each carrying everything the host needs to
|
|
104
|
+
* run it and to journal its completion so replay is deterministic:
|
|
105
|
+
*
|
|
106
|
+
* - `text` — a `TextLogic`/`agent.generateText` invoke. Resolve with the model
|
|
107
|
+
* (`executeAgentRequest`), then journal `toDoneEvent(output)` (or
|
|
108
|
+
* `toErrorEvent(error)`).
|
|
109
|
+
* - `decision` — an `agent.decide`/`DecisionLogic` invoke. Resolve with
|
|
110
|
+
* `resolveDecision` and journal the CHOSEN machine event directly (a decision
|
|
111
|
+
* has no output value of its own; the chosen event advances the machine).
|
|
112
|
+
* - `plan` — an `agent.plan` invoke (multi-event). Drive it a step at a time
|
|
113
|
+
* (see `resolveAgentRequests`), journaling each applied event.
|
|
114
|
+
* - `task` — any other invoke/spawn: a plain host-run task keyed by `src` +
|
|
115
|
+
* `input`. Run it, then journal `toDoneEvent`/`toErrorEvent`.
|
|
116
|
+
* - `delay` — an `after(...)` timer. Schedule it; when it fires, journal
|
|
117
|
+
* `event` (a normal external entry).
|
|
118
|
+
* - `execute` — a fire-and-forget action (a custom entry action, `sendTo`,
|
|
119
|
+
* `cancel`, …). Run `exec()` once at the frontier; NEVER journaled, never
|
|
120
|
+
* replayed (replay re-derives it).
|
|
121
|
+
*/
|
|
122
|
+
type AgentEffect = {
|
|
123
|
+
kind: "text";
|
|
124
|
+
requestId: string;
|
|
125
|
+
request: AgentTextRequest; /** `'stream'` when the authored request wants `streamText`; default `'generate'`. */
|
|
126
|
+
mode?: AgentRequestMode;
|
|
127
|
+
toDoneEvent(output: unknown): EventObject;
|
|
128
|
+
toErrorEvent(error: unknown): EventObject;
|
|
129
|
+
} | {
|
|
130
|
+
kind: "decision";
|
|
131
|
+
requestId: string;
|
|
132
|
+
request: AgentDecisionRequest;
|
|
133
|
+
} | {
|
|
134
|
+
kind: "plan";
|
|
135
|
+
requestId: string;
|
|
136
|
+
request: AgentPlanRequest;
|
|
137
|
+
} | {
|
|
138
|
+
kind: "task";
|
|
139
|
+
requestId: string;
|
|
140
|
+
id: string;
|
|
141
|
+
src: string;
|
|
142
|
+
input: unknown;
|
|
143
|
+
toDoneEvent(output: unknown): EventObject;
|
|
144
|
+
toErrorEvent(error: unknown): EventObject;
|
|
145
|
+
} | {
|
|
146
|
+
kind: "delay";
|
|
147
|
+
requestId: string;
|
|
148
|
+
id: string;
|
|
149
|
+
delayMs: number; /** The `{ type: 'xstate.timer', id }` event the host journals when the timer fires. */
|
|
150
|
+
event: EventObject;
|
|
151
|
+
} | {
|
|
152
|
+
kind: "execute";
|
|
153
|
+
action: ExecutableActionObject;
|
|
154
|
+
exec(): void;
|
|
155
|
+
};
|
|
156
|
+
/**
|
|
157
|
+
* The reserved journal event type of the {@link initEntry} first entry: it
|
|
158
|
+
* carries the machine `input` so a log replays with no side-channel. Named in
|
|
159
|
+
* the `agent.*` builtin-actor namespace so it never collides with a machine's
|
|
160
|
+
* own event vocabulary. Consumed by {@link replay}; never fed to `transition`.
|
|
161
|
+
*/
|
|
162
|
+
declare const AGENT_INIT_EVENT_TYPE: "@agent.init";
|
|
163
|
+
/**
|
|
164
|
+
* The reserved event type `runAgent` delivers to the running machine after
|
|
165
|
+
* every settled model call that reported usage — the one seam that puts a
|
|
166
|
+
* call's tokens in reach of ordinary `context` and guards, so a token budget
|
|
167
|
+
* is a plain machine transition instead of host bookkeeping.
|
|
168
|
+
*
|
|
169
|
+
* Like {@link AGENT_INIT_EVENT_TYPE} it lives in the reserved `@agent.*`
|
|
170
|
+
* namespace: it can never collide with a machine's own vocabulary, and
|
|
171
|
+
* `getAcceptedEvents`/`parseAgentEvent` never offer it — a model can neither
|
|
172
|
+
* be shown it as a decision candidate nor forge one.
|
|
173
|
+
*
|
|
174
|
+
* Delivery is opt-in BY CONSTRUCTION: the event is sent only when the live
|
|
175
|
+
* snapshot can currently take it (i.e. the machine declares an
|
|
176
|
+
* `'@agent.usage'` transition, usually machine-level `on`). A machine without
|
|
177
|
+
* one sees no extra transition, no extra trace event, and no extra log entry.
|
|
178
|
+
* When it IS taken it rides the event log like any other external input, so
|
|
179
|
+
* events-only recovery (`runAgent({ events })`) replays the folded tokens
|
|
180
|
+
* without re-calling a model.
|
|
181
|
+
*/
|
|
182
|
+
declare const AGENT_USAGE_EVENT_TYPE: "@agent.usage";
|
|
183
|
+
/**
|
|
184
|
+
* The payload of the reserved {@link AGENT_USAGE_EVENT_TYPE} event: the
|
|
185
|
+
* settled call's normalized usage plus enough attribution to bill it (per
|
|
186
|
+
* model, per request). Every field is JSON-safe, so the event round-trips
|
|
187
|
+
* through the durable event log unchanged.
|
|
188
|
+
*
|
|
189
|
+
* Attribution fields are optional because not every call site has them — a
|
|
190
|
+
* `getRequests` interpret-pass call reports usage with no invoke identity at
|
|
191
|
+
* all, and only text requests carry a registered `name`.
|
|
192
|
+
*/
|
|
193
|
+
interface AgentUsageEvent extends EventObject {
|
|
194
|
+
type: typeof AGENT_USAGE_EVENT_TYPE;
|
|
195
|
+
/** The settled call's token usage, as reported by the executor. */
|
|
196
|
+
usage: AgentCallUsage;
|
|
197
|
+
/** Which kind of request reported it. */
|
|
198
|
+
kind?: "text" | "decision" | "plan";
|
|
199
|
+
/** The reporting request's durable invoke id. */
|
|
200
|
+
id?: string;
|
|
201
|
+
/** The reporting request's invoke `src`. */
|
|
202
|
+
src?: string;
|
|
203
|
+
/** The model ref the request targeted. */
|
|
204
|
+
model?: string;
|
|
205
|
+
/** The reporting text request's registered `name`, when it declared one. */
|
|
206
|
+
name?: string;
|
|
207
|
+
}
|
|
208
|
+
/**
|
|
209
|
+
* Reads a settled call's token usage off a RAW executor result — the same
|
|
210
|
+
* normalization `runAgent` applies before it delivers
|
|
211
|
+
* {@link AGENT_USAGE_EVENT_TYPE}. Returns `undefined` when the executor
|
|
212
|
+
* reported none.
|
|
213
|
+
*
|
|
214
|
+
* The seam for the step-loop path, where the host holds the raw result itself:
|
|
215
|
+
*
|
|
216
|
+
* ```ts
|
|
217
|
+
* const { output, raw } = await executeAgentRequest(effect, executors, { verbose: true });
|
|
218
|
+
* const usage = getCallUsage(raw);
|
|
219
|
+
* if (usage) append({ type: AGENT_USAGE_EVENT_TYPE, usage }); // journal + transition, like any event
|
|
220
|
+
* append(effect.toDoneEvent(output));
|
|
221
|
+
* ```
|
|
222
|
+
*
|
|
223
|
+
* See "Token usage on this path" in docs/steps.md for the full loop.
|
|
224
|
+
*/
|
|
225
|
+
declare function getCallUsage(raw: unknown): AgentCallUsage | undefined;
|
|
226
|
+
/** Options controlling the durable envelope created by {@link createReplayEntry}. */
|
|
227
|
+
interface CreateReplayEntryOptions {
|
|
228
|
+
/** Explicit machine version; defaults to the machine's structural hash. */
|
|
229
|
+
machineVersion?: string;
|
|
230
|
+
/** Stable entry id; defaults to `evt_` plus the zero-padded index. */
|
|
231
|
+
id?: string;
|
|
232
|
+
/** RFC 3339 acceptance time; defaults to the current wall clock. */
|
|
233
|
+
recordedAt?: string;
|
|
234
|
+
causationId?: string;
|
|
235
|
+
correlationId?: string;
|
|
236
|
+
metadata?: Record<string, JsonValue>;
|
|
237
|
+
/** Omit hashes when recording only a post-snapshot suffix without its prefix. */
|
|
238
|
+
verification?: boolean;
|
|
239
|
+
}
|
|
240
|
+
/**
|
|
241
|
+
* Creates a JSON-safe, self-describing entry and records the state/effect
|
|
242
|
+
* hashes produced after replaying it. `entries` must be the complete prefix.
|
|
243
|
+
*/
|
|
244
|
+
declare function createReplayEntry<TMachine extends AnyStateMachine>(machine: TMachine, entries: readonly AgentLogEntry[], event: EventObject, options?: CreateReplayEntryOptions): AgentLogEntry;
|
|
245
|
+
/** Reserved first replay entry carrying machine input and verification hashes. */
|
|
246
|
+
declare function initEntry<TMachine extends AnyStateMachine>(machine: TMachine, input?: unknown, options?: CreateReplayEntryOptions): AgentLogEntry;
|
|
247
|
+
/** Options accepted by {@link getAgentEffects} and {@link replay}. */
|
|
248
|
+
interface GetAgentEffectsOptions extends Partial<AgentExecutionOptions> {
|
|
249
|
+
/**
|
|
250
|
+
* The journal so far — an `EventObject[]` OR an `AgentLogEntry[]` (both
|
|
251
|
+
* accepted). Occurrence counts (the `n` in a `requestId`) are derived from
|
|
252
|
+
* it, so requestIds are stable across replay by construction.
|
|
253
|
+
*/
|
|
254
|
+
history?: readonly (EventObject | AgentLogEntry)[];
|
|
255
|
+
}
|
|
256
|
+
/**
|
|
257
|
+
* Maps a transition's ORDERED executable actions (plus the still-owed effects
|
|
258
|
+
* visible only on the snapshot) into an ordered {@link AgentEffect} list the
|
|
259
|
+
* host starts at the frontier.
|
|
260
|
+
*
|
|
261
|
+
* Ordering is load-bearing: a single transition's actions are emitted in
|
|
262
|
+
* document order (a custom entry action, a spawn, and a `sendTo` in that order
|
|
263
|
+
* yield `execute`, then `task`/agent effect, then `execute` — never a
|
|
264
|
+
* reordered set). Effects visible only on the snapshot (an `agent.plan` that
|
|
265
|
+
* re-surfaces every step, and children spawned by an EARLIER transition that
|
|
266
|
+
* have not completed yet — the fan-out / crash-resume case) are appended after
|
|
267
|
+
* the action-derived effects, deduped by site id.
|
|
268
|
+
*
|
|
269
|
+
* Every `requestId` is `${siteId}#${n}`, `n` the 1-based occurrence derived
|
|
270
|
+
* from `options.history` — so the same log yields identical requestIds on every
|
|
271
|
+
* replay. XState alpha.24 prunes a child when its matching completion is
|
|
272
|
+
* folded; the history check also prevents older/restored snapshots from
|
|
273
|
+
* re-surfacing completed work. A re-entered invoke site instead re-derives
|
|
274
|
+
* from the action list each fresh entry (so `#2`, `#3`, … stay correct).
|
|
275
|
+
*/
|
|
276
|
+
declare function getAgentEffects(machine: AnyActorLogic, snapshot: AnyMachineSnapshot, actions: readonly ExecutableActionObject[], options?: GetAgentEffectsOptions): AgentEffect[];
|
|
277
|
+
/** The result of a {@link replay}: the final snapshot and the effects still owed. */
|
|
278
|
+
interface ReplayResult<TMachine extends AnyActorLogic> {
|
|
279
|
+
snapshot: SnapshotFrom<TMachine>;
|
|
280
|
+
effects: AgentEffect[];
|
|
281
|
+
}
|
|
282
|
+
/** Options for {@link replay}. */
|
|
283
|
+
interface ReplayOptions extends Partial<AgentExecutionOptions> {
|
|
284
|
+
/**
|
|
285
|
+
* Machine input, used only when `entries` has no reserved {@link initEntry}
|
|
286
|
+
* first entry. An init entry (the self-contained log) takes precedence.
|
|
287
|
+
*/
|
|
288
|
+
input?: unknown;
|
|
289
|
+
/** Explicit expected machine version; defaults to the structural hash. */
|
|
290
|
+
machineVersion?: string;
|
|
291
|
+
/** Check recorded hashes when present; `'strict'` additionally requires them. */
|
|
292
|
+
verify?: boolean | "strict";
|
|
293
|
+
}
|
|
294
|
+
declare class AgentReplayMachineMismatchError extends AgentError {
|
|
295
|
+
readonly eventId: string;
|
|
296
|
+
readonly index: number;
|
|
297
|
+
readonly expected: {
|
|
298
|
+
machineId: string;
|
|
299
|
+
machineVersion: string;
|
|
300
|
+
};
|
|
301
|
+
readonly actual: {
|
|
302
|
+
machineId: string;
|
|
303
|
+
machineVersion: string;
|
|
304
|
+
};
|
|
305
|
+
constructor(eventId: string, index: number, expected: {
|
|
306
|
+
machineId: string;
|
|
307
|
+
machineVersion: string;
|
|
308
|
+
}, actual: {
|
|
309
|
+
machineId: string;
|
|
310
|
+
machineVersion: string;
|
|
311
|
+
});
|
|
312
|
+
}
|
|
313
|
+
declare class AgentReplayDivergenceError extends AgentError {
|
|
314
|
+
readonly eventId: string;
|
|
315
|
+
readonly index: number;
|
|
316
|
+
readonly kind: "state" | "effects" | "missing-verification";
|
|
317
|
+
readonly expected?: string | undefined;
|
|
318
|
+
readonly actual?: string | undefined;
|
|
319
|
+
constructor(eventId: string, index: number, kind: "state" | "effects" | "missing-verification", expected?: string | undefined, actual?: string | undefined);
|
|
320
|
+
}
|
|
321
|
+
/** JSON Patch operation returned by {@link diffEventLogs}. */
|
|
322
|
+
type AgentLogPatchOperation = {
|
|
323
|
+
op: "add";
|
|
324
|
+
path: string;
|
|
325
|
+
value: JsonValue;
|
|
326
|
+
} | {
|
|
327
|
+
op: "remove";
|
|
328
|
+
path: string;
|
|
329
|
+
} | {
|
|
330
|
+
op: "replace";
|
|
331
|
+
path: string;
|
|
332
|
+
value: JsonValue;
|
|
333
|
+
};
|
|
334
|
+
interface AgentEffectDiff {
|
|
335
|
+
added: JsonValue[];
|
|
336
|
+
removed: JsonValue[];
|
|
337
|
+
changed: Array<{
|
|
338
|
+
before: JsonValue;
|
|
339
|
+
after: JsonValue;
|
|
340
|
+
}>;
|
|
341
|
+
}
|
|
342
|
+
interface AgentEventLogDiff<TMachine extends AnyStateMachine> {
|
|
343
|
+
commonPrefix: {
|
|
344
|
+
length: number;
|
|
345
|
+
throughEventId?: string;
|
|
346
|
+
};
|
|
347
|
+
parentOnly: AgentLogEntry[];
|
|
348
|
+
forkOnly: AgentLogEntry[];
|
|
349
|
+
parent: ReplayResult<TMachine>;
|
|
350
|
+
fork: ReplayResult<TMachine>;
|
|
351
|
+
stateChanges: AgentLogPatchOperation[];
|
|
352
|
+
effectChanges: AgentEffectDiff;
|
|
353
|
+
}
|
|
354
|
+
/**
|
|
355
|
+
* Folds a journal through `initialTransition`/`transition` WITHOUT executing
|
|
356
|
+
* anything, then returns the final snapshot plus the still-owed effects
|
|
357
|
+
* ({@link getAgentEffects} of the final frontier, occurrence counts taken from
|
|
358
|
+
* the whole log). Crash recovery, fork resume, and time travel in one call.
|
|
359
|
+
*
|
|
360
|
+
* `entries` is a versioned {@link AgentLogEntry} array. A reserved
|
|
361
|
+
* {@link initEntry} first envelope carries `{ type: '@agent.init', input }`,
|
|
362
|
+
* so a complete log replays with no side-channel; when absent,
|
|
363
|
+
* `options.input` is used instead.
|
|
364
|
+
* Raised/internal events are never in the journal — replay re-derives them
|
|
365
|
+
* deterministically from the machine's own logic.
|
|
366
|
+
*/
|
|
367
|
+
declare function replay<TMachine extends AnyStateMachine>(machine: TMachine, entries: readonly AgentLogEntry[], options?: ReplayOptions): ReplayResult<TMachine>;
|
|
368
|
+
/** Requires and checks every entry's recorded state/effect hashes. */
|
|
369
|
+
declare function verifyReplay<TMachine extends AnyStateMachine>(machine: TMachine, entries: readonly AgentLogEntry[], options?: Omit<ReplayOptions, "verify">): ReplayResult<TMachine>;
|
|
370
|
+
/** Structural event-tail, logical-state, and owed-effect comparison. */
|
|
371
|
+
declare function diffEventLogs<TMachine extends AnyStateMachine>(machine: TMachine, parentEntries: readonly AgentLogEntry[], forkEntries: readonly AgentLogEntry[], options?: ReplayOptions): AgentEventLogDiff<TMachine>;
|
|
372
|
+
//#endregion
|
|
373
|
+
//#region src/internal/state-request-pass.d.ts
|
|
374
|
+
/**
|
|
375
|
+
* One model request read off the machine's CURRENT snapshot by a
|
|
376
|
+
* `RunAgentOptions.getRequests` hook. `model` is an executor model NAME — the
|
|
377
|
+
* same string every {@link AgentTextRequest.model} carries, resolved by the
|
|
378
|
+
* run's executors (e.g. a `defineModels` key when using
|
|
379
|
+
* `createAiSdkExecutors`) — never a model instance.
|
|
380
|
+
*/
|
|
381
|
+
interface AgentStateRequest {
|
|
382
|
+
/** Instruction for this request's model call, appended to the run's message log as a user message. */
|
|
383
|
+
prompt: string;
|
|
384
|
+
/** System prompt for this request's model call(s). */
|
|
385
|
+
system?: string;
|
|
386
|
+
/** Executor model name (resolved by the run's executors). */
|
|
387
|
+
model: string;
|
|
388
|
+
/**
|
|
389
|
+
* `'text'` (default): a `generateText` call with the message log +
|
|
390
|
+
* `prompt`; the reply is appended to the log, then the machine is advanced
|
|
391
|
+
* per {@link AgentStateRequest.onDone}. `'decision'`: no text call — a
|
|
392
|
+
* single `decide` call (log + `prompt`) chooses the event. Use for pure
|
|
393
|
+
* routing states.
|
|
394
|
+
*/
|
|
395
|
+
kind?: "text" | "decision";
|
|
396
|
+
/**
|
|
397
|
+
* What to send when this request's text call resolves — the EXPLICIT
|
|
398
|
+
* advancement contract, always an event OBJECT (the same shape
|
|
399
|
+
* `actor.send` takes; no string shorthand). A literal event sends exactly
|
|
400
|
+
* that; a function receives the text output (plus the live snapshot and
|
|
401
|
+
* message log) and returns the event to send — payload included — or
|
|
402
|
+
* `undefined` to send nothing. Omitted: a `decide` call chooses among the
|
|
403
|
+
* candidate events (requires a `decide` executor) — there is no implicit
|
|
404
|
+
* auto-send. A resolved event whose type the state does not accept throws
|
|
405
|
+
* (programmer error); one a guard rejects is simply not sent. Ignored for
|
|
406
|
+
* `kind: 'decision'` (the decide call IS the advancement).
|
|
407
|
+
*/
|
|
408
|
+
onDone?: ChosenEvent | ((args: {
|
|
409
|
+
output: unknown;
|
|
410
|
+
snapshot: AnyMachineSnapshot;
|
|
411
|
+
messages: readonly AgentMessage[];
|
|
412
|
+
}) => ChosenEvent | undefined);
|
|
413
|
+
/** Restricts this request's candidate outcome events for the `decide` fallback (default: every currently-accepted event). */
|
|
414
|
+
allowedEvents?: readonly string[];
|
|
415
|
+
/** Trace/request id; defaults to `interpret_<n>`. */
|
|
416
|
+
id?: string;
|
|
417
|
+
}
|
|
418
|
+
//#endregion
|
|
419
|
+
//#region src/run-agent.d.ts
|
|
420
|
+
/**
|
|
421
|
+
* Thrown by {@link runAgent} when resuming with a `snapshot` + `event` whose
|
|
422
|
+
* `type` the restored state cannot accept (a type-level check via
|
|
423
|
+
* {@link getAcceptedEvents}). A programmer/integration error, in the same
|
|
424
|
+
* class as runAgent's bind-time throws — it throws rather than settling an
|
|
425
|
+
* `error` result. A type-legal event a guard rejects is NOT this error (the
|
|
426
|
+
* machine simply takes no transition). Opt out with
|
|
427
|
+
* {@link RunAgentOptions.onIllegalResumeEvent} `'ignore'`.
|
|
428
|
+
*/
|
|
429
|
+
declare class AgentIllegalResumeEventError extends AgentError {
|
|
430
|
+
readonly eventType: string;
|
|
431
|
+
readonly acceptedTypes: string[];
|
|
432
|
+
constructor(eventType: string, acceptedTypes: string[]);
|
|
433
|
+
}
|
|
434
|
+
/**
|
|
435
|
+
* Thrown by {@link runAgent} when resuming from a `snapshot` whose stamped
|
|
436
|
+
* `agentMeta.version` differs from the current machine's version, under the
|
|
437
|
+
* default `onVersionMismatch: 'throw'` and with no `migrateSnapshot` hook. The
|
|
438
|
+
* structural fingerprint of the machine changed since the snapshot was
|
|
439
|
+
* persisted (a state/transition/invoke was added, removed, or retargeted), so
|
|
440
|
+
* the snapshot may no longer resume cleanly. `from` is the snapshot's version,
|
|
441
|
+
* `to` the current machine's.
|
|
442
|
+
*/
|
|
443
|
+
declare class AgentSnapshotVersionMismatchError extends AgentError {
|
|
444
|
+
readonly from: string;
|
|
445
|
+
readonly to: string;
|
|
446
|
+
readonly machineId: string;
|
|
447
|
+
constructor(from: string, to: string, machineId: string);
|
|
448
|
+
}
|
|
449
|
+
/**
|
|
450
|
+
* Thrown by {@link generateResult} when the run settles `idle` instead of
|
|
451
|
+
* `done`: the machine paused for external input. Carries the idle `snapshot`
|
|
452
|
+
* and `acceptedTypes` (the event types that could resume it, via
|
|
453
|
+
* {@link getAcceptedEvents}). Use {@link runAgent} directly when idle is an
|
|
454
|
+
* expected outcome you handle.
|
|
455
|
+
*/
|
|
456
|
+
declare class AgentIdleError extends AgentError {
|
|
457
|
+
readonly snapshot: AnyMachineSnapshot;
|
|
458
|
+
readonly acceptedTypes: string[];
|
|
459
|
+
constructor(snapshot: AnyMachineSnapshot, acceptedTypes: string[]);
|
|
460
|
+
}
|
|
461
|
+
/** Handler for `agent.userInput` invokes passed as {@link RunAgentOptions.userInput}. Resolves to what the human typed. */
|
|
462
|
+
interface AgentUserInputExecutor {
|
|
463
|
+
(input: AgentUserInput): PromiseLike<string>;
|
|
464
|
+
}
|
|
465
|
+
/**
|
|
466
|
+
* The run's machine identity, stamped onto every settled snapshot's `agentMeta`.
|
|
467
|
+
* `machineId` is the machine's `id`; `version` is
|
|
468
|
+
* {@link RunAgentOptions.machineVersion} or the
|
|
469
|
+
* {@link getMachineStructuralHash} of the machine. Trace events and the
|
|
470
|
+
* `onMessage` info arg carry the same identity flattened, as
|
|
471
|
+
* `machineId`/`machineVersion`.
|
|
472
|
+
*/
|
|
473
|
+
interface AgentRunMeta {
|
|
474
|
+
machineId: string;
|
|
475
|
+
version: string;
|
|
476
|
+
}
|
|
477
|
+
/**
|
|
478
|
+
* Second argument passed to {@link RunAgentOptions.onMessage}: the run's
|
|
479
|
+
* identity, carried alongside each live message. Not stamped onto the message
|
|
480
|
+
* itself (messages stay clean model input).
|
|
481
|
+
*/
|
|
482
|
+
interface AgentMessageInfo {
|
|
483
|
+
runId: string;
|
|
484
|
+
machineId: string;
|
|
485
|
+
/** {@link RunAgentOptions.machineVersion}, else the machine's own `version`, else its structural hash. */
|
|
486
|
+
machineVersion: string;
|
|
487
|
+
}
|
|
488
|
+
/**
|
|
489
|
+
* The version of the {@link AgentTraceEvent} envelope every trace event carries
|
|
490
|
+
* as `schemaVersion`. Bumped only on a breaking change to the envelope or any
|
|
491
|
+
* payload shape, so a consumer can gate on it. Emitted identically by
|
|
492
|
+
* {@link runAgent}, {@link provideExecutors}' `onTrace`, and
|
|
493
|
+
* {@link traceTransitions}.
|
|
494
|
+
*/
|
|
495
|
+
declare const AGENT_TRACE_SCHEMA_VERSION = 1;
|
|
496
|
+
type AgentTraceEvent<TMachine extends AnyStateMachine = AnyStateMachine> = {
|
|
497
|
+
/** The {@link AGENT_TRACE_SCHEMA_VERSION} the event was produced with. */schemaVersion: typeof AGENT_TRACE_SCHEMA_VERSION;
|
|
498
|
+
runId: string;
|
|
499
|
+
seq: number;
|
|
500
|
+
timestamp: string;
|
|
501
|
+
machineId: string; /** {@link RunAgentOptions.machineVersion}, else the machine's own `version`, else its structural hash. */
|
|
502
|
+
machineVersion: string;
|
|
503
|
+
} & ({
|
|
504
|
+
type: "run.start";
|
|
505
|
+
input?: InputFrom<TMachine>;
|
|
506
|
+
snapshot?: Snapshot<unknown>;
|
|
507
|
+
event?: EventFromLogic<TMachine>;
|
|
508
|
+
} | {
|
|
509
|
+
type: "request.start";
|
|
510
|
+
request: AgentStepRequest;
|
|
511
|
+
} | {
|
|
512
|
+
type: "request.end";
|
|
513
|
+
request: AgentStepRequest;
|
|
514
|
+
output: unknown;
|
|
515
|
+
raw: unknown;
|
|
516
|
+
/** The model's reasoning, lifted off the raw executor result when the
|
|
517
|
+
* request opted into the structured-output envelope's `reasoning` field.
|
|
518
|
+
* Present only when the executor surfaced a string `reasoning`. */
|
|
519
|
+
reasoning?: string;
|
|
520
|
+
/** This call's token usage, lifted off the raw executor result's `usage`.
|
|
521
|
+
* Present only when the executor reported it. The run-level total is
|
|
522
|
+
* {@link RunAgentResult.usage}. */
|
|
523
|
+
usage?: AgentCallUsage;
|
|
524
|
+
} | {
|
|
525
|
+
type: "request.error";
|
|
526
|
+
request: AgentStepRequest;
|
|
527
|
+
error: unknown;
|
|
528
|
+
} | {
|
|
529
|
+
type: "stream.chunk";
|
|
530
|
+
request: AgentRequest;
|
|
531
|
+
chunk: string;
|
|
532
|
+
} | {
|
|
533
|
+
type: "machine.transition";
|
|
534
|
+
snapshot: SnapshotFrom<TMachine>;
|
|
535
|
+
event: EventFromLogic<TMachine>; /** Durable replay-entry id when this transition corresponds to one. */
|
|
536
|
+
eventId?: string;
|
|
537
|
+
} | {
|
|
538
|
+
type: "emit";
|
|
539
|
+
event: EmittedFrom<TMachine>;
|
|
540
|
+
} | {
|
|
541
|
+
/** A reserved `@agent.usage` event the run declined to deliver. The
|
|
542
|
+
* tokens still fold into {@link RunAgentResult.usage}; only the machine
|
|
543
|
+
* event is dropped. */
|
|
544
|
+
type: "usage.dropped";
|
|
545
|
+
event: AgentUsageEvent; /** `'settled'`: the call settled after the run's cycle had resolved. */
|
|
546
|
+
reason: "settled";
|
|
547
|
+
} | ({
|
|
548
|
+
type: "run.end";
|
|
549
|
+
status: "done";
|
|
550
|
+
output: OutputFrom<TMachine>;
|
|
551
|
+
snapshot: SnapshotFrom<TMachine>;
|
|
552
|
+
} | {
|
|
553
|
+
type: "run.end";
|
|
554
|
+
status: "idle";
|
|
555
|
+
snapshot: SnapshotFrom<TMachine>;
|
|
556
|
+
pendingUserInputs?: PendingUserInput[];
|
|
557
|
+
persistedSnapshot?: Snapshot<unknown>;
|
|
558
|
+
} | {
|
|
559
|
+
type: "run.end";
|
|
560
|
+
status: "error";
|
|
561
|
+
cause: RunAgentErrorCause;
|
|
562
|
+
error: unknown;
|
|
563
|
+
snapshot: SnapshotFrom<TMachine>;
|
|
564
|
+
}));
|
|
565
|
+
/**
|
|
566
|
+
* The JSON-safe projection of an {@link AgentTraceEvent} produced by
|
|
567
|
+
* {@link serializeTraceEvent}: the envelope fields are unchanged, and every
|
|
568
|
+
* payload field that can hold a live object (snapshots, machine events, request
|
|
569
|
+
* objects, raw SDK results, errors) is narrowed to a {@link JsonValue}. Safe to
|
|
570
|
+
* hand straight to `JSON.stringify` for a JSONL trace file.
|
|
571
|
+
*/
|
|
572
|
+
type JsonSerializableTraceEvent = {
|
|
573
|
+
schemaVersion: typeof AGENT_TRACE_SCHEMA_VERSION;
|
|
574
|
+
runId: string;
|
|
575
|
+
seq: number;
|
|
576
|
+
timestamp: string;
|
|
577
|
+
machineId: string;
|
|
578
|
+
machineVersion: string;
|
|
579
|
+
} & ({
|
|
580
|
+
type: "run.start";
|
|
581
|
+
input?: JsonValue;
|
|
582
|
+
snapshot?: JsonValue;
|
|
583
|
+
event?: JsonValue;
|
|
584
|
+
} | {
|
|
585
|
+
type: "request.start";
|
|
586
|
+
request: JsonValue;
|
|
587
|
+
} | {
|
|
588
|
+
type: "request.end";
|
|
589
|
+
request: JsonValue;
|
|
590
|
+
output: JsonValue; /** Present only when `includeRaw` was set; the raw executor result, sanitized. */
|
|
591
|
+
raw?: JsonValue;
|
|
592
|
+
reasoning?: string; /** Present only when the executor reported it; plain numbers, passed through as-is. */
|
|
593
|
+
usage?: JsonValue;
|
|
594
|
+
} | {
|
|
595
|
+
type: "request.error";
|
|
596
|
+
request: JsonValue;
|
|
597
|
+
error: JsonValue;
|
|
598
|
+
} | {
|
|
599
|
+
type: "stream.chunk";
|
|
600
|
+
request: JsonValue;
|
|
601
|
+
chunk: string;
|
|
602
|
+
} | {
|
|
603
|
+
type: "machine.transition";
|
|
604
|
+
snapshot: JsonValue;
|
|
605
|
+
event: JsonValue;
|
|
606
|
+
eventId?: string;
|
|
607
|
+
} | {
|
|
608
|
+
type: "emit";
|
|
609
|
+
event: JsonValue;
|
|
610
|
+
} | {
|
|
611
|
+
type: "usage.dropped";
|
|
612
|
+
event: JsonValue;
|
|
613
|
+
reason: "settled";
|
|
614
|
+
} | {
|
|
615
|
+
type: "run.end";
|
|
616
|
+
status: "done";
|
|
617
|
+
output: JsonValue;
|
|
618
|
+
snapshot: JsonValue;
|
|
619
|
+
} | {
|
|
620
|
+
type: "run.end";
|
|
621
|
+
status: "idle";
|
|
622
|
+
snapshot: JsonValue;
|
|
623
|
+
pendingUserInputs?: JsonValue;
|
|
624
|
+
persistedSnapshot?: JsonValue;
|
|
625
|
+
} | {
|
|
626
|
+
type: "run.end";
|
|
627
|
+
status: "error";
|
|
628
|
+
cause: RunAgentErrorCause;
|
|
629
|
+
error: JsonValue;
|
|
630
|
+
snapshot: JsonValue;
|
|
631
|
+
});
|
|
632
|
+
/**
|
|
633
|
+
* Projects an {@link AgentTraceEvent} into a guaranteed JSON-safe envelope —
|
|
634
|
+
* the form the trace stream is actually sold for (one `JSON.stringify` per line
|
|
635
|
+
* in a JSONL file). Live values are sanitized rather than trusted:
|
|
636
|
+
*
|
|
637
|
+
* - Snapshots (`run.start`, `machine.transition`, `run.end`) go through the
|
|
638
|
+
* same JSON round-trip as {@link persistSnapshot}, so what lands on disk is
|
|
639
|
+
* what a resume would see.
|
|
640
|
+
* - `request.end`'s `raw` (a provider SDK object, frequently cyclic) is DROPPED
|
|
641
|
+
* unless `includeRaw` is set, in which case it is sanitized like everything
|
|
642
|
+
* else.
|
|
643
|
+
* - Non-serializable values anywhere (functions, symbols, `undefined`, cyclic
|
|
644
|
+
* back-references) are dropped; `Error`s become `{ name, message, stack?,
|
|
645
|
+
* code? }` instead of `{}`. Nothing throws.
|
|
646
|
+
*
|
|
647
|
+
* @example
|
|
648
|
+
* ```ts
|
|
649
|
+
* await appendFile('trace.jsonl', JSON.stringify(serializeTraceEvent(event)) + '\n');
|
|
650
|
+
* ```
|
|
651
|
+
*/
|
|
652
|
+
declare function serializeTraceEvent(event: AgentTraceEvent, options?: {
|
|
653
|
+
includeRaw?: boolean;
|
|
654
|
+
}): JsonSerializableTraceEvent;
|
|
655
|
+
/**
|
|
656
|
+
* Options for {@link runAgent}.
|
|
657
|
+
*
|
|
658
|
+
* Host executors are passed as a single {@link AgentRequestExecutors}-shaped
|
|
659
|
+
* set under `executors` (the same shape the step path takes). Each executor
|
|
660
|
+
* kind is required only if the machine actually reaches a request of that kind
|
|
661
|
+
* — checked at bind time, before any actor runs. The whole `executors` field is
|
|
662
|
+
* optional: a machine whose agent sources all carry their own executor
|
|
663
|
+
* (`.withExecutor(...)`) needs none.
|
|
664
|
+
*/
|
|
665
|
+
interface RunAgentOptions<TMachine extends AnyStateMachine> {
|
|
666
|
+
/**
|
|
667
|
+
* The host executor set backing the machine's agent actors — build it with
|
|
668
|
+
* `createAiSdkExecutors({ models })` from '@statelyai/agent/ai-sdk', or supply
|
|
669
|
+
* `{ generateText?, streamText?, decide? }` by hand. Every slot is optional
|
|
670
|
+
* here (unlike the step path's {@link AgentRequestExecutors}): each kind is
|
|
671
|
+
* bind-time-checked only when the machine actually reaches a request of that
|
|
672
|
+
* kind, so e.g. a stream-only machine may pass `{ streamText }` alone.
|
|
673
|
+
*/
|
|
674
|
+
executors?: Partial<AgentRequestExecutors>;
|
|
675
|
+
/** Machine input, passed straight to `createActor(machine, { input })`. Omit when resuming via `snapshot`. */
|
|
676
|
+
input?: InputFrom<TMachine>;
|
|
677
|
+
/** A previously-settled run's `result.snapshot`, to resume from instead of starting fresh. Pair with `event` to deliver the event that unblocks the resumed idle state. */
|
|
678
|
+
snapshot?: Snapshot<unknown>;
|
|
679
|
+
/** An event to send immediately after starting/resuming the actor (e.g. the human's answer to an idle-state prompt). */
|
|
680
|
+
event?: EventFromLogic<TMachine>;
|
|
681
|
+
/**
|
|
682
|
+
* A prior `runAgent` result's replayable `events`, copied as the prefix of
|
|
683
|
+
* this result's event log. Pass this alongside `snapshot` + `event` when
|
|
684
|
+
* resuming so the next result retains the complete, replayable history;
|
|
685
|
+
* with a `snapshot` these events are history only (`snapshot` is the live
|
|
686
|
+
* resume source).
|
|
687
|
+
*
|
|
688
|
+
* **Events-only resume:** with NO `snapshot` and a self-contained log (a
|
|
689
|
+
* reserved `@agent.init` first entry — every log started by `runAgent` from
|
|
690
|
+
* scratch has one), the resume snapshot is derived by replaying the log:
|
|
691
|
+
* recorded model/tool results are reused, never re-executed, and a request
|
|
692
|
+
* that was still in flight when the log ended re-executes idempotently on
|
|
693
|
+
* restore. This is the crash-recovery path: persist entries via `onEvent`
|
|
694
|
+
* (or an event-log store) and resume from the log alone.
|
|
695
|
+
*/
|
|
696
|
+
events?: readonly AgentLogEntry[];
|
|
697
|
+
/**
|
|
698
|
+
* How to handle a resume `event` the restored state cannot accept (a
|
|
699
|
+
* type-level check via {@link getAcceptedEvents}, only applied when resuming
|
|
700
|
+
* from a `snapshot`). `'throw'` (default) throws {@link AgentIllegalResumeEventError}
|
|
701
|
+
* before delivering the event; `'ignore'` restores the older silent behavior
|
|
702
|
+
* (the event is sent and the machine drops it). A type-legal event a guard
|
|
703
|
+
* rejects is never an illegal resume event.
|
|
704
|
+
*/
|
|
705
|
+
onIllegalResumeEvent?: "throw" | "ignore";
|
|
706
|
+
/**
|
|
707
|
+
* The version stamped onto every settled snapshot's `agentMeta` and compared
|
|
708
|
+
* against an incoming snapshot's stamp on resume. Defaults to the machine's
|
|
709
|
+
* own `version` (XState's `createMachine({ version })` prop) when set, else
|
|
710
|
+
* {@link getMachineStructuralHash} of the machine (a structural fingerprint
|
|
711
|
+
* that changes on any edit). Set `version` on the machine — or this option —
|
|
712
|
+
* to control migration boundaries yourself.
|
|
713
|
+
*/
|
|
714
|
+
machineVersion?: string;
|
|
715
|
+
/**
|
|
716
|
+
* How to handle a resume `snapshot` whose stamped `agentMeta.version` differs
|
|
717
|
+
* from the current machine's version. `'throw'` (default) throws
|
|
718
|
+
* {@link AgentSnapshotVersionMismatchError} with `from`/`to`; `'warn'`
|
|
719
|
+
* `console.warn`s once and proceeds; `'ignore'` proceeds silently. Ignored
|
|
720
|
+
* when {@link migrateSnapshot} is provided (that runs instead), and never
|
|
721
|
+
* triggers for an unstamped snapshot (no `agentMeta`).
|
|
722
|
+
*/
|
|
723
|
+
onVersionMismatch?: "throw" | "warn" | "ignore";
|
|
724
|
+
/**
|
|
725
|
+
* Called instead of {@link onVersionMismatch} when a resume snapshot's
|
|
726
|
+
* version mismatches the current machine's: receives the incoming snapshot
|
|
727
|
+
* and `{ from, to }`, and its return value is used as the snapshot to resume
|
|
728
|
+
* from. A throw propagates.
|
|
729
|
+
*/
|
|
730
|
+
migrateSnapshot?: (snapshot: Snapshot<unknown>, info: {
|
|
731
|
+
from: string;
|
|
732
|
+
to: string;
|
|
733
|
+
}) => Snapshot<unknown>;
|
|
734
|
+
/** Actor source implementations, merged onto the machine before binding — sugar for `machine.provide({ actors })` ahead of the run. */
|
|
735
|
+
actors?: Record<string, AnyActorLogic>;
|
|
736
|
+
/**
|
|
737
|
+
* Optional human-input handler for `agent.userInput` invokes (CLI prompt,
|
|
738
|
+
* web form, Slack, …). With a handler, input is gathered inline without
|
|
739
|
+
* settling. Without one, an `agent.userInput` invoke becomes a *pending
|
|
740
|
+
* placeholder*: it waits indefinitely, does not block idle detection, and
|
|
741
|
+
* the run settles `{ status: 'idle', pendingUserInputs, persistedSnapshot }`
|
|
742
|
+
* once no other work is in flight — resume by passing `persistedSnapshot`
|
|
743
|
+
* back as `snapshot` together with a `userInput` handler that answers it.
|
|
744
|
+
*/
|
|
745
|
+
userInput?: AgentUserInputExecutor;
|
|
746
|
+
/**
|
|
747
|
+
* Host override for detecting a snapshot that is an INTENTIONAL wait for an
|
|
748
|
+
* external event — the deterministic replacement for the timing heuristic
|
|
749
|
+
* runAgent uses to settle idle. Resolution order: this option (host override)
|
|
750
|
+
* → the machine-carried predicate declared via `setupAgent({ isSuspended })`
|
|
751
|
+
* → the timing heuristic (when neither is present). When the resolved
|
|
752
|
+
* predicate returns true and nothing is in flight (no live requests/plans/
|
|
753
|
+
* invokes; the `agent.userInput` placeholder exemption still applies), runAgent
|
|
754
|
+
* settles idle immediately, without the `setTimeout` heuristic. It does NOT
|
|
755
|
+
* force-settle while agent work is in flight, and whole-machine idle semantics
|
|
756
|
+
* are unchanged; a machine with no predicate falls back to the heuristic
|
|
757
|
+
* exactly as before (with a one-time dev warning suggesting a predicate).
|
|
758
|
+
* Declare your own signal, e.g. `(s) => s.hasTag('awaiting-review')`.
|
|
759
|
+
*/
|
|
760
|
+
isSuspended?: (snapshot: AnyMachineSnapshot) => boolean;
|
|
761
|
+
/**
|
|
762
|
+
* The override to runAgent's DEFAULT contract. By default agent work is
|
|
763
|
+
* whatever the machine *invokes* (`agent.generateText`, TextLogic,
|
|
764
|
+
* `agent.decide`, …). With `getRequests`, whenever the machine would
|
|
765
|
+
* otherwise settle idle, this hook reads the snapshot and returns the model
|
|
766
|
+
* request(s) to run instead — prompts from state `description`s, `meta`,
|
|
767
|
+
* tags, a lookup table keyed by state value, wherever you keep them. Return
|
|
768
|
+
* nothing to settle idle (human-wait states).
|
|
769
|
+
*
|
|
770
|
+
* There is no blessed source for the prompts — this is a recipe seam.
|
|
771
|
+
* Prompts-in-descriptions, copy-paste and adapt:
|
|
772
|
+
*
|
|
773
|
+
* ```ts
|
|
774
|
+
* getRequests: (snapshot) =>
|
|
775
|
+
* snapshot._nodes
|
|
776
|
+
* .filter((node) => node.description && !node.tags.includes('waiting'))
|
|
777
|
+
* .map((node) => ({
|
|
778
|
+
* model: 'writer',
|
|
779
|
+
* prompt: node.description!,
|
|
780
|
+
* kind: node.tags.includes('decision') ? 'decision' : 'text',
|
|
781
|
+
* // single-outcome states advance deterministically; else `decide`
|
|
782
|
+
* onDone: node.ownEvents.length === 1 ? { type: node.ownEvents[0] } : undefined,
|
|
783
|
+
* allowedEvents: node.ownEvents,
|
|
784
|
+
* })),
|
|
785
|
+
* ```
|
|
786
|
+
*
|
|
787
|
+
* Each request runs per {@link AgentStateRequest.kind}, appends to the
|
|
788
|
+
* run's message log (see {@link RunAgentOptions.messages}), and advances
|
|
789
|
+
* the machine per {@link AgentStateRequest.onDone} — explicitly named/
|
|
790
|
+
* computed event, or a `decide` call when omitted — always gated by
|
|
791
|
+
* `snapshot.can`. Multiple requests run concurrently (parallel regions —
|
|
792
|
+
* scope each with `allowedEvents`, e.g. the node's `ownEvents`). A pass
|
|
793
|
+
* that sends no event settles idle. Every model call counts against
|
|
794
|
+
* `maxModelCalls`.
|
|
795
|
+
*/
|
|
796
|
+
getRequests?: (snapshot: SnapshotFrom<TMachine>, agentContext: {
|
|
797
|
+
messages: readonly AgentMessage[];
|
|
798
|
+
}) => AgentStateRequest | readonly AgentStateRequest[] | undefined;
|
|
799
|
+
/**
|
|
800
|
+
* Adds to the run's aggregated message log (the working memory
|
|
801
|
+
* `getRequests` requests read and append to). The log starts as the resume
|
|
802
|
+
* `snapshot`'s stamped `messages` (else `[]`); an ARRAY here is APPENDED to
|
|
803
|
+
* that history — the safe default for folding in a user reply on resume,
|
|
804
|
+
* never silently erasing prior conversation. Pass a FUNCTION
|
|
805
|
+
* `(prior) => AgentMessage[]` to take full control (replace, filter,
|
|
806
|
+
* compact). The final log is stamped onto every settled result's
|
|
807
|
+
* `snapshot.messages` (like `agentMeta`), so persist/resume round-trips it
|
|
808
|
+
* with no extra wiring — read it with `getAgentMessages(snapshot)`.
|
|
809
|
+
*/
|
|
810
|
+
messages?: AgentMessage[] | ((prior: AgentMessage[]) => AgentMessage[]);
|
|
811
|
+
/** Fires for each streamed chunk of a `mode: 'stream'` text request, alongside the {@link AgentRequest} that produced it (parallel states can interleave multiple streams). Purely observational. */
|
|
812
|
+
onChunk?: (chunk: string, info: {
|
|
813
|
+
request: AgentRequest;
|
|
814
|
+
}) => void;
|
|
815
|
+
/** Fires once per resolved text/decision request with its normalized output and the raw executor result (tool calls, usage, …) — the seam for tracing/observability and event-sourced replay logging. */
|
|
816
|
+
onResult?: (request: AgentStepRequest, result: {
|
|
817
|
+
output: unknown;
|
|
818
|
+
raw: unknown;
|
|
819
|
+
}) => void;
|
|
820
|
+
/**
|
|
821
|
+
* Fires as each new replayable external input is appended to this run's
|
|
822
|
+
* event log. A fresh run begins with `@agent.init`; raised and other internal
|
|
823
|
+
* events are excluded. History supplied through {@link events} is not
|
|
824
|
+
* re-emitted. Purely observational, like {@link onTransition}.
|
|
825
|
+
*/
|
|
826
|
+
onEvent?: (entry: AgentLogEntry) => void;
|
|
827
|
+
/** Fires a single ordered stream of run/request/chunk/transition/emit/end events. Intended for eval traces, JSONL logs, and adapter-owned telemetry/exporters. */
|
|
828
|
+
onTrace?: (event: AgentTraceEvent<TMachine>) => void;
|
|
829
|
+
/**
|
|
830
|
+
* Fires on every machine transition (snapshot + causing event). Pure
|
|
831
|
+
* observation — progress UIs, logging, tracing. Cannot send events.
|
|
832
|
+
*/
|
|
833
|
+
onTransition?: (snapshot: SnapshotFrom<TMachine>, event: EventFromLogic<TMachine>) => void;
|
|
834
|
+
/**
|
|
835
|
+
* Fires for each message appended to the run's aggregated log (see
|
|
836
|
+
* {@link RunAgentOptions.messages}) the moment a `getRequests` request
|
|
837
|
+
* appends it — the live view of the log a caller otherwise only reads off
|
|
838
|
+
* the settled snapshot via `getAgentMessages`. Purely observational, like
|
|
839
|
+
* {@link onTransition}. Never fires for the seeded history, and never fires
|
|
840
|
+
* on a default invoke-driven run (nothing appends there).
|
|
841
|
+
*/
|
|
842
|
+
onMessage?: (message: AgentMessage, info: AgentMessageInfo) => void;
|
|
843
|
+
/**
|
|
844
|
+
* Handlers for events the machine emits (`enq.emit(...)`), keyed by emitted
|
|
845
|
+
* event type — `'*'` catches all. Typed from the machine's `emitted`
|
|
846
|
+
* schemas (`setupAgent({ emitted: { ... } })`). Purely observational, like
|
|
847
|
+
* {@link onTransition}: the machine narrates progress on its own vocabulary
|
|
848
|
+
* (not xstate internals) and the host renders it — a progress UI, an SSE
|
|
849
|
+
* stream, a log line.
|
|
850
|
+
*/
|
|
851
|
+
on?: { [TType in EmittedFrom<TMachine>["type"] | "*"]?: (emitted: EmittedFrom<TMachine> & (TType extends "*" ? unknown : {
|
|
852
|
+
type: TType;
|
|
853
|
+
})) => void };
|
|
854
|
+
/**
|
|
855
|
+
* Raw xstate inspection passthrough: fires for every inspection event in
|
|
856
|
+
* the whole actor system — root machine, invoked child machines, spawned
|
|
857
|
+
* actors — each carrying its `actorRef` (`event.actorRef.id`/`.src`). This
|
|
858
|
+
* is the system-wide seam {@link onTransition} (root transitions only)
|
|
859
|
+
* cannot give you: filter `event.type === '@xstate.transition'` and read
|
|
860
|
+
* `event.actorRef` to attribute a child machine's states to the child.
|
|
861
|
+
* Purely observational, like the other callbacks. Unlike them it also
|
|
862
|
+
* fires during the final settle (a child's last transition and stop events
|
|
863
|
+
* arrive while the run is tearing down).
|
|
864
|
+
*
|
|
865
|
+
* Accepts a function or an observer (`{ next }`), matching `createActor`'s
|
|
866
|
+
* `inspect` option, so `@statelyai/sdk`'s `inspector.inspect` plugs in
|
|
867
|
+
* directly.
|
|
868
|
+
*/
|
|
869
|
+
inspect?: ((inspectionEvent: InspectionEvent) => void) | {
|
|
870
|
+
next?: (inspectionEvent: InspectionEvent) => void;
|
|
871
|
+
};
|
|
872
|
+
/** Caps the number of model/decision calls this run may make (each retry of a decision counts separately); exceeding it settles `{ status: 'error', cause: 'max-model-calls' }`. Default 100. */
|
|
873
|
+
maxModelCalls?: number;
|
|
874
|
+
/** Aborts the run; settles `{ status: 'error', cause: 'aborted' }` with `signal.reason` as the error. */
|
|
875
|
+
signal?: AbortSignal;
|
|
876
|
+
}
|
|
877
|
+
/**
|
|
878
|
+
* The outcome of a {@link runAgent} call — always exactly one of three
|
|
879
|
+
* variants, never a throw for a waiting or failed machine (programmer
|
|
880
|
+
* errors like a missing executor still throw, at bind time before any actor
|
|
881
|
+
* runs). `done`: a final state was reached (`output` is the machine's
|
|
882
|
+
* `OutputFrom`). `idle`: the run settled with no in-flight work — resume by
|
|
883
|
+
* calling `runAgent` again with `{ snapshot, event }`. `error`: a run-level
|
|
884
|
+
* failure, discriminated by `cause` (`'aborted'`, `'max-model-calls'`,
|
|
885
|
+
* `'decision-exhausted'`, `'machine'` for any other machine error state, or
|
|
886
|
+
* `'stopped'` for an external stop — see {@link RunAgentErrorCause}). Every
|
|
887
|
+
* variant carries the final `snapshot` plus a replayable `events` array. The
|
|
888
|
+
* underlying actor is stopped on every settle path — there is no live actor to
|
|
889
|
+
* resume; resume is always by snapshot.
|
|
890
|
+
*/
|
|
891
|
+
/** A pending unhandled `agent.userInput` invoke surfaced on an idle settle — `id` is the invoke's id, `input` its resolved invoke input (prompt, metadata). Answer it by resuming with a `userInput` handler. */
|
|
892
|
+
interface PendingUserInput {
|
|
893
|
+
id: string;
|
|
894
|
+
input: AgentUserInput | undefined;
|
|
895
|
+
}
|
|
896
|
+
type RunAgentOutcome<TMachine extends AnyStateMachine> = {
|
|
897
|
+
status: "done";
|
|
898
|
+
output: OutputFrom<TMachine>;
|
|
899
|
+
snapshot: SnapshotFrom<TMachine>;
|
|
900
|
+
} | {
|
|
901
|
+
status: "idle";
|
|
902
|
+
snapshot: SnapshotFrom<TMachine>; /** Present when the machine is waiting on unhandled `agent.userInput` invokes: one entry per pending invoke. */
|
|
903
|
+
pendingUserInputs?: PendingUserInput[];
|
|
904
|
+
/**
|
|
905
|
+
* Present alongside `pendingUserInputs`: the JSON-serializable persisted
|
|
906
|
+
* snapshot (in-flight children included). Persist THIS one and resume
|
|
907
|
+
* with `runAgent(machine, { snapshot: persistedSnapshot, userInput })` —
|
|
908
|
+
* the live `snapshot` above cannot round-trip active children.
|
|
909
|
+
*/
|
|
910
|
+
persistedSnapshot?: Snapshot<unknown>;
|
|
911
|
+
} | {
|
|
912
|
+
status: "error";
|
|
913
|
+
cause: RunAgentErrorCause;
|
|
914
|
+
error: unknown;
|
|
915
|
+
snapshot: SnapshotFrom<TMachine>;
|
|
916
|
+
};
|
|
917
|
+
type RunAgentResult<TMachine extends AnyStateMachine> = RunAgentOutcome<TMachine> & {
|
|
918
|
+
/**
|
|
919
|
+
* Versioned, JSON-safe envelopes around replayable external inputs observed
|
|
920
|
+
* through this run: machine input, effect completions/failures, user events,
|
|
921
|
+
* and timer firings. Raised/internal events are excluded because replay
|
|
922
|
+
* re-derives them. Each entry carries timestamp, machine identity/version,
|
|
923
|
+
* and strict replay hashes.
|
|
924
|
+
*
|
|
925
|
+
* A fresh run starts with `@agent.init`. When resuming from a snapshot, pass
|
|
926
|
+
* the preceding result's `events` through {@link RunAgentOptions.events} to
|
|
927
|
+
* retain a self-contained history.
|
|
928
|
+
*/
|
|
929
|
+
events: AgentLogEntry[];
|
|
930
|
+
/**
|
|
931
|
+
* Aggregated model-call usage for THIS run — `modelCalls` plus the token
|
|
932
|
+
* fields every executor reported (see {@link AgentUsage} for the
|
|
933
|
+
* partial-sum rule). Present on all three variants: an `idle` or `error`
|
|
934
|
+
* result accounts for the calls made before the run settled.
|
|
935
|
+
*
|
|
936
|
+
* A resumed run counts only its own calls, not the history behind
|
|
937
|
+
* `snapshot`/`events`.
|
|
938
|
+
*/
|
|
939
|
+
usage: AgentUsage;
|
|
940
|
+
};
|
|
941
|
+
/**
|
|
942
|
+
* Discriminates a {@link RunAgentResult} `error`:
|
|
943
|
+
* - `'aborted'` — the run's `signal` fired.
|
|
944
|
+
* - `'max-model-calls'` — the `maxModelCalls` budget was exceeded.
|
|
945
|
+
* - `'decision-exhausted'` — the machine reached an error state whose error is
|
|
946
|
+
* (or wraps) a {@link AgentDecisionExhaustedError} that no `onError` handled.
|
|
947
|
+
* - `'machine'` — any other machine error state.
|
|
948
|
+
* - `'stopped'` — the actor was stopped externally (`status === 'stopped'`).
|
|
949
|
+
*/
|
|
950
|
+
type RunAgentErrorCause = "aborted" | "max-model-calls" | "decision-exhausted" | "machine" | "stopped";
|
|
951
|
+
/**
|
|
952
|
+
* Runs an agent machine to completion or idle: a `createActor` host that
|
|
953
|
+
* binds `options`' host executors onto the machine's `agent.*`/`TextLogic`/
|
|
954
|
+
* `DecisionLogic` actor sources, starts (or resumes) the actor, and drives
|
|
955
|
+
* it until it settles — {@link RunAgentResult} `done | idle | error`. Unlike
|
|
956
|
+
* the step helpers ({@link initialAgentStep} etc — a pure
|
|
957
|
+
* transition-at-a-time path for durable hosts), `runAgent` owns a live actor
|
|
958
|
+
* internally; there is no continuation callback, so **idle always settles**
|
|
959
|
+
* and the caller resumes explicitly by passing the settled `{ snapshot,
|
|
960
|
+
* event }` back in. The actor is stopped on every settle path (`done`,
|
|
961
|
+
* `idle`, and `error` alike) — resume is always by snapshot, never by
|
|
962
|
+
* holding a reference to a live actor.
|
|
963
|
+
*
|
|
964
|
+
* Binding happens **before** the actor starts: every invoke the machine
|
|
965
|
+
* could reach is walked and checked against the effective actor sources
|
|
966
|
+
* (`options.actors` merged onto the machine), so a missing
|
|
967
|
+
* `streamText`/`decide` executor or any other unbound actor source throws
|
|
968
|
+
* immediately — a bind-time error, not a mid-run failure. The one exception
|
|
969
|
+
* is `agent.userInput`: unhandled, it binds as a pending placeholder that
|
|
970
|
+
* settles the run idle (with `pendingUserInputs`) instead of erroring.
|
|
971
|
+
*
|
|
972
|
+
* @example
|
|
973
|
+
* ```ts
|
|
974
|
+
* const executors = createAiSdkExecutors({ models });
|
|
975
|
+
* let r = await runAgent(machine, { input, executors });
|
|
976
|
+
* while (r.status === 'idle') {
|
|
977
|
+
* const event = await promptUser(getAcceptedEvents(r.snapshot));
|
|
978
|
+
* r = await runAgent(machine, { snapshot: r.snapshot, event, executors });
|
|
979
|
+
* }
|
|
980
|
+
* if (r.status !== 'done') throw new Error(`Run did not complete: ${r.status}`);
|
|
981
|
+
* console.log(r.output);
|
|
982
|
+
* ```
|
|
983
|
+
*
|
|
984
|
+
* The `executors`' `generateText`/`streamText` accept the raw Vercel AI SDK
|
|
985
|
+
* functions directly (`executors: { generateText, streamText }` with them
|
|
986
|
+
* imported from `ai`) — their `{ text }`/`{ textStream }` results are unwrapped
|
|
987
|
+
* natively. `decide` cannot be a raw AI SDK function: the tool-per-event mapping
|
|
988
|
+
* lives in an adapter — use `createAiSdkExecutors` from '@statelyai/agent/ai-sdk'.
|
|
989
|
+
*/
|
|
990
|
+
declare function runAgent<TMachine extends AnyStateMachine>(machine: TMachine, options: RunAgentOptions<TMachine>): Promise<RunAgentResult<TMachine>>;
|
|
991
|
+
/**
|
|
992
|
+
* A long-lived agent session returned by {@link createAgentActor}: the same
|
|
993
|
+
* engine as {@link runAgent} (executor binding at any depth, the replayable
|
|
994
|
+
* event log, budgets, traces), but the actor stays alive across idle settles.
|
|
995
|
+
*
|
|
996
|
+
* One **cycle** runs from start (or the event that re-opened the session) to
|
|
997
|
+
* the next quiescence. `settled()` resolves with the current cycle's
|
|
998
|
+
* {@link RunAgentResult}; after an `idle` settle, sending the actor an event
|
|
999
|
+
* re-opens the cycle and the next `settled()` call tracks it. The event log
|
|
1000
|
+
* spans the whole session — every turn appends to one replayable history.
|
|
1001
|
+
* `done`, `error`, and external stop are final: the actor stops and every
|
|
1002
|
+
* later `settled()` resolves with that final result.
|
|
1003
|
+
*/
|
|
1004
|
+
interface AgentActorSession<TMachine extends AnyStateMachine> {
|
|
1005
|
+
/** The live bound actor. Drive it directly: `session.actor.send(event)`. */
|
|
1006
|
+
actor: ReturnType<typeof createActor<TMachine>>;
|
|
1007
|
+
/** The session's replayable event log (live; grows across cycles). */
|
|
1008
|
+
readonly events: readonly AgentLogEntry[];
|
|
1009
|
+
/** Cumulative session usage (all cycles). */
|
|
1010
|
+
usage(): AgentUsage;
|
|
1011
|
+
/** Resolves with the current cycle's settled result (`done | idle | error`). */
|
|
1012
|
+
settled(): Promise<RunAgentResult<TMachine>>;
|
|
1013
|
+
/** Stops the actor. A not-yet-settled cycle settles `error`/`stopped`. */
|
|
1014
|
+
stop(): void;
|
|
1015
|
+
}
|
|
1016
|
+
/**
|
|
1017
|
+
* Session mode: {@link runAgent}'s engine with a long-lived actor. Use it when
|
|
1018
|
+
* the agent is a *session* fed by external events (chat turns, device or
|
|
1019
|
+
* timer events, a socket) rather than a one-shot job — you keep the log,
|
|
1020
|
+
* budget, traces, and idle semantics that bare `provideExecutors` +
|
|
1021
|
+
* `createActor` would forfeit.
|
|
1022
|
+
*
|
|
1023
|
+
* ```ts
|
|
1024
|
+
* const session = createAgentActor(machine, { input, executors });
|
|
1025
|
+
* let result = await session.settled(); // first quiescence
|
|
1026
|
+
* while (result.status === "idle") {
|
|
1027
|
+
* session.actor.send(await nextUserEvent(result.snapshot));
|
|
1028
|
+
* result = await session.settled(); // next quiescence, same log
|
|
1029
|
+
* }
|
|
1030
|
+
* session.stop();
|
|
1031
|
+
* ```
|
|
1032
|
+
*
|
|
1033
|
+
* Accepts the same options as {@link runAgent} (including `snapshot`/`events`
|
|
1034
|
+
* resume). Not yet supported in session mode: `getRequests` re-interpretation
|
|
1035
|
+
* across cycles behaves per-cycle exactly as in `runAgent`.
|
|
1036
|
+
*/
|
|
1037
|
+
declare function createAgentActor<TMachine extends AnyStateMachine>(machine: TMachine, options: RunAgentOptions<TMachine>): AgentActorSession<TMachine>;
|
|
1038
|
+
/**
|
|
1039
|
+
* The resolved value of {@link generateResult}: the `done`-narrowed
|
|
1040
|
+
* {@link RunAgentResult} — `output` plus run metadata (`snapshot`, replayable
|
|
1041
|
+
* `events`, aggregated `usage`), mirroring how the AI SDK's `generateText`
|
|
1042
|
+
* resolves `text` alongside its call metadata.
|
|
1043
|
+
*/
|
|
1044
|
+
type GenerateResult<TMachine extends AnyStateMachine> = Extract<RunAgentResult<TMachine>, {
|
|
1045
|
+
status: "done";
|
|
1046
|
+
}>;
|
|
1047
|
+
/**
|
|
1048
|
+
* Runs an agent machine to a **final state**, for run-to-done flows where an
|
|
1049
|
+
* idle pause is unexpected. Wraps {@link runAgent}:
|
|
1050
|
+
*
|
|
1051
|
+
* - `done` → resolves with the done result: `result.output` (the machine's
|
|
1052
|
+
* `OutputFrom`) plus metadata — `result.snapshot`, the replayable
|
|
1053
|
+
* `result.events`, and the aggregated `result.usage` — the same shape
|
|
1054
|
+
* `generateText` users expect (`text` + call metadata).
|
|
1055
|
+
* - `idle` → throws {@link AgentIdleError} carrying the idle snapshot and the
|
|
1056
|
+
* event types that could resume it.
|
|
1057
|
+
* - `error` → throws `result.error` when it is an `Error`; otherwise wraps it
|
|
1058
|
+
* in an `Error` whose `.cause` is the {@link RunAgentErrorCause} and whose
|
|
1059
|
+
* `.error` is the raw thrown value.
|
|
1060
|
+
*
|
|
1061
|
+
* Use {@link runAgent} directly when idle is an expected outcome you handle
|
|
1062
|
+
* (human-in-the-loop, resumable flows); use `generateResult` when the
|
|
1063
|
+
* machine is meant to run straight through to a final state.
|
|
1064
|
+
*/
|
|
1065
|
+
declare function generateResult<TMachine extends AnyStateMachine>(machine: TMachine, options: RunAgentOptions<TMachine>): Promise<GenerateResult<TMachine>>;
|
|
1066
|
+
/**
|
|
1067
|
+
* The actor handed to an {@link inspectTransitions} handler: an
|
|
1068
|
+
* {@link AnyActorRef} widened with the runtime `id`/`src` used to attribute a
|
|
1069
|
+
* transition to the root machine or a specific invoked child (xstate's static
|
|
1070
|
+
* `ActorRef` type omits them, but they are always present at runtime).
|
|
1071
|
+
*/
|
|
1072
|
+
type InspectedActorRef = AnyActorRef & {
|
|
1073
|
+
id: string;
|
|
1074
|
+
src?: string | AnyActorLogic;
|
|
1075
|
+
};
|
|
1076
|
+
/**
|
|
1077
|
+
* Wraps a `(snapshot, actorRef) => void` handler into a function usable as
|
|
1078
|
+
* {@link RunAgentOptions.inspect}: it filters the raw inspection stream to
|
|
1079
|
+
* `@xstate.transition` events and hands the handler the typed
|
|
1080
|
+
* {@link AnyMachineSnapshot} and the {@link InspectedActorRef} that
|
|
1081
|
+
* transitioned. Attribute a child actor via `actorRef.id`/`actorRef.src`. Saves
|
|
1082
|
+
* the manual `event.type === '@xstate.transition'` filtering and the snapshot/
|
|
1083
|
+
* actorRef casts.
|
|
1084
|
+
*/
|
|
1085
|
+
declare function inspectTransitions(handler: (snapshot: AnyMachineSnapshot, actorRef: InspectedActorRef) => void): (inspectionEvent: InspectionEvent) => void;
|
|
1086
|
+
/**
|
|
1087
|
+
* An xstate `inspect` handler that emits `machine.transition` trace events onto
|
|
1088
|
+
* `onTrace`, sharing the SAME versioned envelope and per-root-actor `seq`
|
|
1089
|
+
* registry as {@link provideExecutors}' `onTrace`. Pair the two on one actor to
|
|
1090
|
+
* get a single ordered trace stream (request + transition events) for the
|
|
1091
|
+
* uncontrolled path:
|
|
1092
|
+
*
|
|
1093
|
+
* ```ts
|
|
1094
|
+
* const bound = provideExecutors(machine, executors, { onTrace });
|
|
1095
|
+
* const actor = createActor(bound, { inspect: traceTransitions(onTrace) });
|
|
1096
|
+
* ```
|
|
1097
|
+
*
|
|
1098
|
+
* Only ROOT-actor transitions are traced (matching `runAgent`'s
|
|
1099
|
+
* `machine.transition`); child-actor transitions are ignored. Attribute the
|
|
1100
|
+
* event via its envelope `runId`.
|
|
1101
|
+
*
|
|
1102
|
+
* By design this path has NO `run.start`/`run.end` events: `createActor` has no
|
|
1103
|
+
* run boundary the way `runAgent` does, so the stream starts at the actor's
|
|
1104
|
+
* first transition. It also does NOT emit `emit` trace events: in this xstate
|
|
1105
|
+
* build emitted events are delivered through `actor.on(...)`, not the inspection
|
|
1106
|
+
* protocol, so they are not observable from an `inspect` handler — subscribe
|
|
1107
|
+
* with `actor.on('*', ...)` if you need them.
|
|
1108
|
+
*/
|
|
1109
|
+
declare function traceTransitions<TMachine extends AnyStateMachine = AnyStateMachine>(onTrace: (event: AgentTraceEvent<TMachine>) => void): (inspectionEvent: InspectionEvent) => void;
|
|
1110
|
+
//#endregion
|
|
1111
|
+
export { AgentReplayDivergenceError as A, getCallUsage as B, AgentStateRequest as C, AgentEffectDiff as D, AgentEffect as E, ReplayOptions as F, AgentRequest as G, replay as H, ReplayResult as I, AgentStepRequest as K, createReplayEntry as L, AgentUsageEvent as M, CreateReplayEntryOptions as N, AgentEventLogDiff as O, GetAgentEffectsOptions as P, diffEventLogs as R, traceTransitions as S, AGENT_USAGE_EVENT_TYPE as T, verifyReplay as U, initEntry as V, AgentPlanRequest as W, createAgentActor as _, AgentMessageInfo as a, runAgent as b, AgentTraceEvent as c, InspectedActorRef as d, JsonSerializableTraceEvent as f, RunAgentResult as g, RunAgentOptions as h, AgentIllegalResumeEventError as i, AgentReplayMachineMismatchError as j, AgentLogPatchOperation as k, AgentUserInputExecutor as l, RunAgentErrorCause as m, AgentActorSession as n, AgentRunMeta as o, PendingUserInput as p, executeAgentRequest as q, AgentIdleError as r, AgentSnapshotVersionMismatchError as s, AGENT_TRACE_SCHEMA_VERSION as t, GenerateResult as u, generateResult as v, AGENT_INIT_EVENT_TYPE as w, serializeTraceEvent as x, inspectTransitions as y, getAgentEffects as z };
|