@statelyai/agent 1.1.6 → 2.0.0-alpha.5

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.
Files changed (84) hide show
  1. package/LICENSE +21 -0
  2. package/dist/ai-sdk.cjs +249 -0
  3. package/dist/ai-sdk.d.cts +168 -0
  4. package/dist/ai-sdk.d.mts +168 -0
  5. package/dist/ai-sdk.mjs +241 -0
  6. package/dist/cli.cjs +63 -0
  7. package/dist/cli.d.cts +1 -0
  8. package/dist/cli.d.mts +1 -0
  9. package/dist/cli.mjs +64 -0
  10. package/dist/decision-FTmbqSEe.mjs +938 -0
  11. package/dist/decision-pC-bY2DE.cjs +1231 -0
  12. package/dist/index.cjs +54 -0
  13. package/dist/index.d.cts +1217 -0
  14. package/dist/index.d.mts +1194 -405
  15. package/dist/index.mjs +3 -588
  16. package/dist/openai-compat.cjs +319 -0
  17. package/dist/openai-compat.d.cts +98 -0
  18. package/dist/openai-compat.d.mts +98 -0
  19. package/dist/openai-compat.mjs +312 -0
  20. package/dist/src-CjpHDU8F.mjs +2445 -0
  21. package/dist/src-DcRsWPfV.cjs +2564 -0
  22. package/dist/text-logic-1ZQkO3zr.d.cts +682 -0
  23. package/dist/text-logic-2EMJIS-n.d.mts +682 -0
  24. package/dist/types-BHjeDdch.d.cts +208 -0
  25. package/dist/types-Cq1YlAQ6.d.mts +208 -0
  26. package/dist/utils-CWUCa3pF.d.mts +108 -0
  27. package/dist/utils-lK1wnL2i.d.cts +108 -0
  28. package/dist/zod.cjs +31 -0
  29. package/dist/zod.d.cts +30 -0
  30. package/dist/zod.d.mts +30 -0
  31. package/dist/zod.mjs +30 -0
  32. package/package.json +109 -28
  33. package/readme.md +144 -6
  34. package/schemas/agent-workflow.json +527 -0
  35. package/.changeset/README.md +0 -8
  36. package/.changeset/config.json +0 -11
  37. package/.env.template +0 -3
  38. package/.github/actions/ci-setup/action.yml +0 -24
  39. package/.github/workflows/release.yml +0 -46
  40. package/.vscode/launch.json +0 -28
  41. package/CHANGELOG.md +0 -222
  42. package/dist/index.d.ts +0 -428
  43. package/dist/index.js +0 -621
  44. package/examples/chatbot.ts +0 -71
  45. package/examples/cot.ts +0 -89
  46. package/examples/email.ts +0 -118
  47. package/examples/example.ts +0 -81
  48. package/examples/goal.ts +0 -94
  49. package/examples/helpers/helpers.ts +0 -17
  50. package/examples/helpers/loader.ts +0 -32
  51. package/examples/helpers/runner.ts +0 -27
  52. package/examples/joke.ts +0 -225
  53. package/examples/multi.ts +0 -103
  54. package/examples/newspaper.ts +0 -324
  55. package/examples/number.ts +0 -102
  56. package/examples/raffle.ts +0 -105
  57. package/examples/sandbox.ts +0 -28
  58. package/examples/simple.ts +0 -39
  59. package/examples/support.ts +0 -147
  60. package/examples/ticTacToe.ts +0 -224
  61. package/examples/todo.ts +0 -137
  62. package/examples/tutor.ts +0 -100
  63. package/examples/verify.ts +0 -120
  64. package/examples/weather.ts +0 -178
  65. package/examples/wiki.ts +0 -30
  66. package/examples/word.ts +0 -171
  67. package/src/adapters/vercel.ts +0 -7
  68. package/src/agent-experimental.ts +0 -221
  69. package/src/agent.test.ts +0 -506
  70. package/src/agent.ts +0 -300
  71. package/src/decision.test.ts +0 -179
  72. package/src/decision.ts +0 -84
  73. package/src/index.ts +0 -4
  74. package/src/memory.ts +0 -25
  75. package/src/planners/shortestPathPlanner.ts +0 -22
  76. package/src/planners/simplePlanner.ts +0 -139
  77. package/src/schemas.ts +0 -11
  78. package/src/strategies/chain-of-note.ts +0 -155
  79. package/src/templates/defaultText.ts +0 -18
  80. package/src/text.ts +0 -241
  81. package/src/types.ts +0 -499
  82. package/src/utils.ts +0 -72
  83. package/tsconfig.json +0 -109
  84. package/vitest.config.ts +0 -9
@@ -0,0 +1,682 @@
1
+ import { b as StandardSchemaV1, c as AgentTools, f as ChosenEvent, i as AgentToolChoice, t as AgentMessage, u as AllowedEvents, v as InferOutput } from "./types-BHjeDdch.cjs";
2
+ import { AnyMachineSnapshot, AsyncActorLogic, EventObject, LogicActorLogic, MachineSnapshot } from "xstate";
3
+
4
+ //#region src/events.d.ts
5
+ /** The invoke `src` of an {@link AgentRequest}/{@link AgentDecisionRequest} — a plain string, widened so literal `src` values still narrow in editor hints. */
6
+ type AgentRequestSource = string & {};
7
+ /** Default prefix for the synthetic tool name generated per candidate event (e.g. `send_event_ASK`). Override per-request with {@link AgentEventToolNameResolver}. */
8
+ declare const EVENT_TOOL_PREFIX: "send_event_";
9
+ /** Customizes the tool name generated for a candidate event; see {@link AgentRequestOptions.eventToolName}. */
10
+ type AgentEventToolNameResolver = (args: {
11
+ eventType: string;
12
+ defaultToolName: string;
13
+ }) => string;
14
+ /**
15
+ * True when an event type matches an `allowedEvents` entry: an exact type,
16
+ * `'*'` (every event), or a `'prefix.*'` wildcard matching any deeper
17
+ * segment (`'todo.*'` matches `'todo.add'` and `'todo.list.clear'`, not
18
+ * `'todo'` itself — mirroring xstate's partial wildcard events).
19
+ */
20
+ declare function matchesEventPattern(eventType: string, pattern: string): boolean;
21
+ /** One candidate event a decision (or {@link getAcceptedEvents} caller) may choose: its type, the synthetic tool name a model can call to pick it, and its payload schema if one is registered. */
22
+ interface AgentEventDescriptor {
23
+ type: string;
24
+ toolName: string;
25
+ inputSchema?: StandardSchemaV1;
26
+ }
27
+ /** Registered event payload schemas, as attached to a machine by `setupAgent`/`createAgentSchemas`. */
28
+ interface AgentSchemas {
29
+ events?: Record<string, StandardSchemaV1>;
30
+ }
31
+ /** Shared options threaded through step discovery ({@link getAgentRequests}/{@link getAcceptedEvents}) — snapshot for event legality, event schemas for payload validation/tool schemas, and registered actor source logics. */
32
+ interface AgentRequestOptions {
33
+ snapshot?: AnyMachineSnapshot;
34
+ events?: Record<string, StandardSchemaV1>;
35
+ schemas?: AgentSchemas;
36
+ actorSources?: Record<string, unknown>;
37
+ /** Customize machine-event tool names. Defaults to send_event_<TYPE>. */
38
+ eventToolName?: AgentEventToolNameResolver;
39
+ }
40
+ /**
41
+ * Lists the events a snapshot can currently accept, as {@link AgentEventDescriptor}s
42
+ * a model can be offered (via `resolveDecision`/an adapter's tool-per-event
43
+ * mapping). **Filters by event TYPE only** — it does not evaluate guards, so
44
+ * a type-legal-but-guard-rejected event can still appear here. Guard
45
+ * legality is checked separately, at decision-resolution time, via
46
+ * `snapshot.can(event)` (the `canTake` option of {@link resolveDecision} /
47
+ * {@link ResolveDecisionOptions}). Pass `eventTypes` to further narrow to a
48
+ * declared `allowedEvents` set — entries may be exact types or wildcard
49
+ * patterns (`'*'`, `'todo.*'`; see {@link matchesEventPattern}).
50
+ */
51
+ /** Recovers a machine's event union from its snapshot type, so {@link parseAgentEvent} returns the machine-typed event without a downstream cast. @internal */
52
+ type EventFromSnapshot<TSnapshot> = TSnapshot extends MachineSnapshot<any, infer TEvent, any, any, any, any, any, any> ? TEvent : EventObject;
53
+ /**
54
+ * Runtime-validates a dynamically-built `{ type, ...payload }` event against a
55
+ * snapshot's currently-accepted events (via {@link getAcceptedEvents}) and,
56
+ * when one is registered, the event type's payload schema — returning the
57
+ * event typed as the machine's event union (recovered from the snapshot type)
58
+ * so it can be sent to `runAgent({ event })` / `actor.send(...)` without an
59
+ * `as never` cast. For generic, meta-driven hosts that assemble events from
60
+ * user input or a wire message.
61
+ *
62
+ * Throws a descriptive error when `event.type` is not currently accepted
63
+ * (listing the accepted types) or when its payload fails the registered schema.
64
+ * Pass event payload schemas via `options.events`/`options.schemas` (the same
65
+ * shape {@link getAcceptedEvents} takes) — the accepted TYPES always come from
66
+ * the live snapshot; the schemas only add payload validation.
67
+ *
68
+ * @example
69
+ * ```ts
70
+ * const event = parseAgentEvent(result.snapshot, rawEvent, { events: schemas.events });
71
+ * result = await runAgent(machine, { snapshot: result.snapshot, event, executors });
72
+ * ```
73
+ */
74
+ declare function parseAgentEvent<TSnapshot extends AnyMachineSnapshot>(snapshot: TSnapshot, event: {
75
+ type: string;
76
+ } & Record<string, unknown>, options?: Pick<AgentRequestOptions, "events" | "schemas" | "eventToolName">): EventFromSnapshot<TSnapshot>;
77
+ declare function getAcceptedEvents(snapshot: AnyMachineSnapshot, options?: Pick<AgentRequestOptions, "events" | "schemas" | "eventToolName"> & {
78
+ eventTypes?: readonly string[];
79
+ }): AgentEventDescriptor[];
80
+ //#endregion
81
+ //#region src/decision.d.ts
82
+ /**
83
+ * Inline input for the `agent.decide` builtin actor — the zero-config
84
+ * counterpart to {@link createDecisionLogic}, invoked directly from a
85
+ * state's `invoke.input` (typed against the machine's own event schemas).
86
+ * See {@link AgentDecisionRequest} for the request shape this lowers to.
87
+ */
88
+ interface AgentDecisionInput<TEvent extends string = string, TMetadata = Record<string, unknown>, TModel extends string = string> {
89
+ model: TModel;
90
+ system?: string;
91
+ prompt?: string;
92
+ messages?: AgentMessage[];
93
+ allowedEvents?: AllowedEvents<TEvent>;
94
+ maxRetries?: number;
95
+ temperature?: number;
96
+ maxOutputTokens?: number;
97
+ topP?: number;
98
+ topK?: number;
99
+ seed?: number;
100
+ stopSequences?: string[];
101
+ metadata?: TMetadata;
102
+ }
103
+ /**
104
+ * Inline input for the `agent.plan` builtin actor — a multi-event decision.
105
+ * Where `agent.decide` picks exactly one currently-legal event, `agent.plan`
106
+ * applies an ordered sequence of them: each step re-reads the live snapshot,
107
+ * asks the `decide` executor for one legal event (same validation and
108
+ * `rejected-by-guard` retry loop as a decision), sends it to the machine,
109
+ * and repeats until a `stopOn` event is chosen, `maxSteps` is reached, no
110
+ * legal candidate remains, or an applied event exits the invoking state
111
+ * (which cancels the invoke — the machine simply moves on).
112
+ *
113
+ * Requires a snapshot-aware host: {@link runAgent}, or the step path (where an
114
+ * `agent.plan` invoke re-surfaces as a `kind: 'plan'` request that
115
+ * `resolveAgentRequests` drives one step per call).
116
+ */
117
+ interface AgentPlanInput<TEvent extends string = string, TMetadata = Record<string, unknown>, TModel extends string = string> extends AgentDecisionInput<TEvent, TMetadata, TModel> {
118
+ /** Maximum events applied in one plan. Default 8. */
119
+ maxSteps?: number;
120
+ /**
121
+ * Machine events that end the plan once chosen: the event is still
122
+ * validated and sent, then the loop stops. Usually unnecessary — every
123
+ * plan step already offers the built-in {@link PLAN_DONE_EVENT_TYPE}
124
+ * "done" option, which ends the plan without touching the machine.
125
+ * Declare `stopOn` only for "send this real event AND stop" semantics.
126
+ */
127
+ stopOn?: readonly TEvent[];
128
+ }
129
+ /**
130
+ * Reserved event type the `agent.plan` builtin adds to every step's
131
+ * candidates as the explicit "no further action needed" move. Choosing it
132
+ * ends the plan (`stopped: 'done'`); it is never sent to the machine, so
133
+ * machines need no no-op sentinel event of their own.
134
+ */
135
+ declare const PLAN_DONE_EVENT_TYPE: "agent.plan.done";
136
+ /** What an `agent.plan` invoke resolves with (its `onDone` output). */
137
+ interface AgentPlanOutput {
138
+ /** The events applied, in order (possibly empty). */
139
+ steps: ChosenEvent[];
140
+ /** Why the loop ended. */
141
+ stopped: "done" | "stop-event" | "max-steps" | "no-legal-events";
142
+ }
143
+ /**
144
+ * The in-progress state of a plan, held in the `agent.plan` invoke child's own
145
+ * `createLogic` snapshot `context`. Because a `createLogic` snapshot serializes
146
+ * (and restores) by identity, this lands at
147
+ * `children.<planId>.snapshot.context` in a machine's persisted snapshot for
148
+ * free — so a step-path host that persists after every event resumes a plan
149
+ * mid-flight without a bespoke carrier.
150
+ */
151
+ interface PlanLedgerContext {
152
+ /** The events applied so far in this plan, in order (the trail). */
153
+ applied: ChosenEvent[];
154
+ /** How many more events the plan may apply (`maxSteps - applied.length`). */
155
+ stepsRemaining: number;
156
+ /** Set once the plan terminates; `null` while in flight. */
157
+ stopped: AgentPlanOutput["stopped"] | null;
158
+ }
159
+ /**
160
+ * The two ledger events that drive a {@link PlanLedgerContext} forward:
161
+ * `plan.applied` appends one event to the trail and decrements the budget;
162
+ * `plan.ended` records the stop reason and completes the ledger (its snapshot
163
+ * goes `done` with the {@link AgentPlanOutput}).
164
+ */
165
+ type PlanLedgerEvent = {
166
+ type: "plan.applied";
167
+ event: ChosenEvent;
168
+ } | {
169
+ type: "plan.ended";
170
+ stopped: AgentPlanOutput["stopped"];
171
+ };
172
+ /**
173
+ * Actor logic for the `agent.plan` builtin: a stateful, transition-based
174
+ * ledger. Its snapshot `context` ({@link PlanLedgerContext}) IS the plan's
175
+ * in-progress state — the applied trail plus remaining budget — advanced one
176
+ * {@link PlanLedgerEvent} at a time. On the step path the invoke child runs this
177
+ * logic directly (so its context persists at `children.<id>.snapshot.context`);
178
+ * runAgent swaps in an async implementation that drives the SAME ledger via the
179
+ * shared {@link initialPlanLedger}/{@link advancePlanLedger} drivers.
180
+ */
181
+ interface PlanLogic<TInputSchema extends StandardSchemaV1 = StandardSchemaV1<AgentPlanInput>> extends LogicActorLogic<PlanLedgerContext, AgentPlanOutput, PlanLedgerEvent, InferOutput<TInputSchema>> {
182
+ readonly kind: "statelyai.planLogic";
183
+ readonly maxRetries: number;
184
+ /** Builds the per-step base {@link AgentDecisionRequest} (id/events filled in per step). */
185
+ request(input: InferOutput<TInputSchema>): AgentDecisionRequest;
186
+ /** @internal Resolves declared `allowedEvents` (undefined = all currently legal). */
187
+ allowedEventTypes(input: InferOutput<TInputSchema>): readonly string[] | undefined;
188
+ }
189
+ /**
190
+ * Config for {@link createDecisionLogic}: how to build an
191
+ * {@link AgentDecisionRequest} from typed input. Each field mirrors
192
+ * {@link TextLogicConfig} (static value or a `({ input }) => value`
193
+ * resolver), plus `allowedEvents` to narrow the candidate event set (see
194
+ * {@link AllowedEvents}) and `maxRetries` for {@link resolveDecision}.
195
+ */
196
+ interface DecisionLogicConfig<TInputSchema extends StandardSchemaV1 = StandardSchemaV1, TEvent extends string = string, TMetadata extends Record<string, unknown> = Record<string, unknown>, TModel extends string = string> {
197
+ schemas?: {
198
+ input: TInputSchema;
199
+ };
200
+ model: ResolveTextLogicValue<TModel, InferOutput<TInputSchema>>;
201
+ system?: ResolveTextLogicValue<string | undefined, InferOutput<TInputSchema>>;
202
+ prompt?: ResolveTextLogicValue<string | undefined, InferOutput<TInputSchema>>;
203
+ messages?: ResolveTextLogicValue<AgentMessage[] | undefined, InferOutput<TInputSchema>>;
204
+ allowedEvents?: AllowedEvents<TEvent, InferOutput<TInputSchema>>;
205
+ maxRetries?: number;
206
+ temperature?: ResolveTextLogicValue<number | undefined, InferOutput<TInputSchema>>;
207
+ maxOutputTokens?: ResolveTextLogicValue<number | undefined, InferOutput<TInputSchema>>;
208
+ topP?: ResolveTextLogicValue<number | undefined, InferOutput<TInputSchema>>;
209
+ topK?: ResolveTextLogicValue<number | undefined, InferOutput<TInputSchema>>;
210
+ seed?: ResolveTextLogicValue<number | undefined, InferOutput<TInputSchema>>;
211
+ stopSequences?: ResolveTextLogicValue<string[] | undefined, InferOutput<TInputSchema>>;
212
+ metadata?: ResolveTextLogicValue<TMetadata | undefined, InferOutput<TInputSchema>>;
213
+ }
214
+ /**
215
+ * Actor logic for a decision: an async effect that resolves to exactly one
216
+ * currently-legal {@link ChosenEvent} (never a plain value). Under `runAgent`
217
+ * the chosen event is delivered to the invoking actor automatically — the
218
+ * transition it triggers usually exits the invoking state and ends the invoke.
219
+ * Built by {@link createDecisionLogic}. Register it under `actorSources:` to reuse/export/
220
+ * test it standalone; for a state-local, zero-config decision, use the
221
+ * `agent.decide` builtin invoke instead.
222
+ */
223
+ interface DecisionLogic<TInputSchema extends StandardSchemaV1 = StandardSchemaV1, TMetadata extends Record<string, unknown> = Record<string, unknown>> extends AsyncActorLogic<ChosenEvent, InferOutput<TInputSchema>> {
224
+ readonly kind: "statelyai.decisionLogic";
225
+ readonly maxRetries: number;
226
+ request(input: InferOutput<TInputSchema>): AgentDecisionRequest;
227
+ withExecutor(execute: AgentDecisionExecutor): DecisionLogic<TInputSchema, TMetadata>;
228
+ }
229
+ /**
230
+ * A decision request: resolves to exactly one currently-legal event. See
231
+ * `resolveDecision`.
232
+ */
233
+ interface AgentDecisionRequest {
234
+ kind: "decision";
235
+ /** Durable invoke id. */
236
+ id: string;
237
+ model: string;
238
+ system?: string;
239
+ prompt?: string;
240
+ messages?: AgentMessage[];
241
+ /** Candidate events: declared `allowedEvents` ∩ snapshot-legal events. */
242
+ events: AgentEventDescriptor[];
243
+ /**
244
+ * Prior failed attempts for THIS decision. Empty on the first attempt.
245
+ * Adapters render these into the provider request so retries converge.
246
+ * Core never rewrites prompts/messages — attempts are data on the request.
247
+ */
248
+ attempts: DecisionAttempt[];
249
+ temperature?: number;
250
+ maxOutputTokens?: number;
251
+ topP?: number;
252
+ topK?: number;
253
+ seed?: number;
254
+ stopSequences?: string[];
255
+ metadata?: Record<string, unknown>;
256
+ /**
257
+ * Abort signal for the underlying model call, threaded through by
258
+ * {@link resolveDecision} from its `options.signal` so a `decide` executor
259
+ * can cancel the in-flight request (symmetric with the text executors'
260
+ * `info.signal`). Runtime-only — never serialized into a provider request.
261
+ */
262
+ signal?: AbortSignal;
263
+ }
264
+ /**
265
+ * A single failed decision attempt, recorded by {@link resolveDecision} and
266
+ * fed back to the executor on the next attempt via
267
+ * `request.attempts`. `failure` names which of the three checks rejected the
268
+ * choice: `'unknown-event'` (not among the candidate `events`),
269
+ * `'invalid-payload'` (failed the event's schema), or `'rejected-by-guard'`
270
+ * (failed the `canTake` check — type/payload were legal, but the machine's
271
+ * guard rejected it at apply time).
272
+ */
273
+ interface DecisionAttempt {
274
+ event?: ChosenEvent;
275
+ failure: "unknown-event" | "invalid-payload" | "rejected-by-guard";
276
+ reason: string;
277
+ }
278
+ /**
279
+ * Thrown by {@link resolveDecision} when every attempt (up to
280
+ * `maxRetries + 1` of them) fails one of the three checks recorded in
281
+ * {@link DecisionAttempt.failure}. Carries the full `attempts` list for
282
+ * diagnostics; a machine typically routes this via the decision invoke's
283
+ * `onError`.
284
+ */
285
+ declare class DecisionExhaustedError extends Error {
286
+ attempts: DecisionAttempt[];
287
+ constructor(attempts: DecisionAttempt[]);
288
+ }
289
+ /**
290
+ * Renders a decision request's prior failed `attempts` into feedback messages
291
+ * a host appends to the model call so retries converge — the transport-agnostic
292
+ * "your last choice failed because X, choose again from Y" logic every adapter
293
+ * and raw-SDK host repeats. Returns one `user`-role {@link AgentMessage} per
294
+ * attempt (empty when there are none); adapters map each onto their wire
295
+ * message shape (`attempt.content` is always a string). Core never rewrites the
296
+ * request itself — this only turns the recorded attempts into messages.
297
+ *
298
+ * @example
299
+ * ```ts
300
+ * const messages = [...baseMessages, ...renderDecisionAttempts(request)];
301
+ * ```
302
+ */
303
+ declare function renderDecisionAttempts(request: Pick<AgentDecisionRequest, "events" | "attempts">): AgentMessage[];
304
+ /**
305
+ * Host implementation of "make the model choose one of `request.events`."
306
+ * Third executor slot on {@link AgentRequestExecutors}, symmetric with
307
+ * `generateText`/`streamText` — how the model is coerced into choosing
308
+ * (tool-per-event + forced tool choice, structured output, …) is entirely
309
+ * adapter business; core only validates and retries the returned choice (see
310
+ * {@link resolveDecision}). The optional `reason` is carried through to
311
+ * `onResult`/event-sourcing but never affects validation. Like text
312
+ * executors' `{ output, ...extras }` envelope, any extra keys (usage, finish
313
+ * reason, …) flow untouched to `onResult`'s `raw`.
314
+ */
315
+ type AgentDecisionExecutor = (request: AgentDecisionRequest) => PromiseLike<{
316
+ event: ChosenEvent;
317
+ reason?: string;
318
+ [key: string]: unknown;
319
+ }>;
320
+ /**
321
+ * Options for {@link resolveDecision}. The `TEvent` parameter (the machine's
322
+ * event union, defaulting to the loose {@link ChosenEvent}) types both
323
+ * `canTake`'s argument and {@link resolveDecision}'s return — pass it (or let
324
+ * it infer from `canTake`) to get a machine-typed chosen event out without a
325
+ * downstream cast.
326
+ */
327
+ interface ResolveDecisionOptions<TEvent extends ChosenEvent = ChosenEvent> {
328
+ /** Retries after a failed attempt. Default `2`, so up to 3 attempts total. */
329
+ maxRetries?: number;
330
+ /** Checked before each attempt; aborting rejects the pending decision. */
331
+ signal?: AbortSignal;
332
+ /**
333
+ * Guard-legality check (mode 3), typically `(e) => snapshot.can(e)`. A
334
+ * type-and-payload-valid event that this rejects records a
335
+ * `'rejected-by-guard'` attempt and retries. Omit to skip guard checking
336
+ * (type + payload validation only — e.g. under bare `createActor`, where
337
+ * no snapshot is reachable). Typing its argument as the machine's event
338
+ * union (e.g. `(e: GameEvent) => snapshot.can(e)`) makes
339
+ * {@link resolveDecision} return that union.
340
+ */
341
+ canTake?: (event: TEvent) => boolean;
342
+ }
343
+ /**
344
+ * Validation + retry core for decisions. No provider mechanics — the
345
+ * `executor` is responsible for making the model choose an event; this
346
+ * function only validates the choice and retries on failure, up to
347
+ * `options.maxRetries` (default 2, i.e. up to 3 attempts total).
348
+ *
349
+ * Each attempt is checked in order and can fail one of three ways (recorded
350
+ * as a {@link DecisionAttempt}): `'unknown-event'` (the chosen `type` is not
351
+ * among `request.events`), `'invalid-payload'` (the payload fails that
352
+ * event's schema), or `'rejected-by-guard'` (passes both checks but
353
+ * `options.canTake` returns `false` — a type/payload-legal event the
354
+ * machine's guard rejects right now; omit `canTake` to skip this check).
355
+ * Every prior failed attempt for this call is fed back to the executor on
356
+ * the next attempt via `request.attempts`, so an adapter can render "your
357
+ * last choice failed because X — try again" into the next model call; core
358
+ * never rewrites the request itself. Exhausting all attempts throws
359
+ * {@link DecisionExhaustedError} with the full attempts list.
360
+ *
361
+ * @example
362
+ * ```ts
363
+ * const event = await resolveDecision(request, decide, {
364
+ * canTake: (e) => snapshot.can(e),
365
+ * });
366
+ * ```
367
+ */
368
+ declare function resolveDecision<TEvent extends ChosenEvent = ChosenEvent>(request: AgentDecisionRequest, executor: AgentDecisionExecutor, options?: ResolveDecisionOptions<TEvent>): Promise<TEvent>;
369
+ //#endregion
370
+ //#region src/text-logic.d.ts
371
+ declare const USER_INPUT_ACTOR: "agent.userInput";
372
+ declare const GENERATE_TEXT_ACTOR: "agent.generateText";
373
+ declare const STREAM_TEXT_ACTOR: "agent.streamText";
374
+ declare const DECIDE_ACTOR: "agent.decide";
375
+ declare const PLAN_ACTOR: "agent.plan";
376
+ /** Whether a text request should be resolved with `generateText` (one-shot) or `streamText` (chunked, via `onChunk`). */
377
+ type AgentRequestMode = "generate" | "stream";
378
+ /** A `setupAgent({ models })` model registry, mapping short model refs to provider-specific model values. */
379
+ type AgentModelMap = Record<string, unknown>;
380
+ /**
381
+ * A model reference: any string is legal, but a registered `models` map's keys
382
+ * autocomplete. Refs are opaque routing keys — the host/executor (or the AI SDK
383
+ * adapter's models map / `resolveModel`) resolves them to a real model.
384
+ */
385
+ type AgentModelRef<TModels extends AgentModelMap = {}> = [keyof TModels] extends [never] ? string : (keyof TModels & string) | (string & {});
386
+ /**
387
+ * Portable, provider-agnostic input a text request passes to a host
388
+ * executor (`generateText`/`streamText` on {@link AgentRequestExecutors}).
389
+ * Built by {@link TextLogic.request} / `DecisionLogic.request` from a
390
+ * `TextLogicConfig`/`DecisionLogicConfig`; adapters (e.g.
391
+ * `createAiSdkExecutors`) map this shape onto their provider's call
392
+ * settings.
393
+ */
394
+ interface AgentTextRequest<TMetadata = Record<string, unknown>> {
395
+ /**
396
+ * The registered name of the request that produced this call — the
397
+ * `setupAgent({ requests })` key (also set by `setupAgent.fromConfig`), or
398
+ * `TextLogicConfig.name` for standalone `createTextLogic` actors. Hosts and
399
+ * test mocks can route on it instead of sniffing `system`/`prompt` text.
400
+ * Absent for ad-hoc `agent.generateText`/`agent.streamText` invokes unless
401
+ * the caller sets it on the inline input.
402
+ */
403
+ name?: string;
404
+ model: string;
405
+ system?: string;
406
+ prompt?: string;
407
+ messages?: AgentMessage[];
408
+ /** Host/model tools that are always available to this text call. */
409
+ tools?: AgentTools;
410
+ toolChoice?: AgentToolChoice;
411
+ outputSchema?: StandardSchemaV1;
412
+ /**
413
+ * Opt-in reasoning for a structured-output request: when `true`, adapters add
414
+ * an optional string `reasoning` property (listed BEFORE `result`) to the
415
+ * structured-output envelope schema, nudging the model to reason before
416
+ * committing to the result. The reasoning is surfaced on the executor's raw
417
+ * result (never in machine context/output). Ignored for text-mode requests.
418
+ */
419
+ reasoning?: boolean;
420
+ temperature?: number;
421
+ /**
422
+ * Maximum number of output tokens to generate. Named `maxOutputTokens` (not
423
+ * `maxTokens`) so an `AgentTextRequest` is spread-compatible with the Vercel
424
+ * AI SDK's `generateText`/`streamText` options.
425
+ */
426
+ maxOutputTokens?: number;
427
+ topP?: number;
428
+ topK?: number;
429
+ seed?: number;
430
+ stopSequences?: string[];
431
+ /**
432
+ * Host-owned per-call options. Use this for provider/runtime details such
433
+ * as Cloudflare bindings, tracing IDs, SDK provider options, or transport
434
+ * hints. The machine carries it; the host decides what it means — e.g.
435
+ * the AI SDK adapter (`createAiSdkExecutors`) reads `metadata.maxSteps` to
436
+ * bound its multi-step tool-call loop for that request.
437
+ */
438
+ metadata?: TMetadata;
439
+ }
440
+ /** Inline input for the `agent.userInput` builtin actor — a human-input request (CLI prompt, form, chat reply, …). See {@link RunAgentOptions.userInput}. */
441
+ interface AgentUserInput<TMetadata = Record<string, unknown>> {
442
+ prompt?: string;
443
+ schema?: StandardSchemaV1;
444
+ metadata?: TMetadata;
445
+ }
446
+ /** The five `agent.*` builtin actor logics every setupAgent-built machine registers. @internal */
447
+ type BuiltinAgentActors<TEvent extends string = string, TModel extends string = string> = {
448
+ [GENERATE_TEXT_ACTOR]: AsyncActorLogic<unknown, AgentTextRequest>;
449
+ [STREAM_TEXT_ACTOR]: AsyncActorLogic<unknown, AgentTextRequest>;
450
+ [USER_INPUT_ACTOR]: AsyncActorLogic<unknown, AgentUserInput>;
451
+ [DECIDE_ACTOR]: AsyncActorLogic<ChosenEvent, AgentDecisionInput<TEvent, Record<string, unknown>, TModel>>;
452
+ [PLAN_ACTOR]: PlanLogic<StandardSchemaV1<AgentPlanInput<TEvent, Record<string, unknown>, TModel>>>;
453
+ };
454
+ /**
455
+ * Validates a raw model/executor output against `schema`, returning the
456
+ * parsed value. Thin wrapper over {@link validateSchemaSync} for parsing a
457
+ * text request's structured output outside of `TextLogic.execute`/
458
+ * `executeAgentRequest` (e.g. a custom host loop).
459
+ */
460
+ declare function parseOutput<TSchema extends StandardSchemaV1>(schema: TSchema, output: unknown): InferOutput<TSchema>;
461
+ /** A TextLogicConfig/DecisionLogicConfig field value: either static, or a `({ input }) => value` resolver. @internal */
462
+ type ResolveTextLogicValue<TValue, TInput> = TValue | ((args: {
463
+ input: TInput;
464
+ }) => TValue);
465
+ /**
466
+ * Config for {@link createTextLogic}: how to build an
467
+ * {@link AgentTextRequest} from typed input, plus the input/output schemas
468
+ * that validate it. Each request-shaping field (`model`, `system`, `prompt`,
469
+ * …) is either a static value or a `({ input }) => value` resolver.
470
+ */
471
+ interface TextLogicConfig<TInputSchema extends StandardSchemaV1, TOutputSchema extends StandardSchemaV1, TMetadata = Record<string, unknown>, TModel extends string = string> {
472
+ mode?: AgentRequestMode;
473
+ /** Stamped onto every lowered request as {@link AgentTextRequest.name}. `setupAgent({ requests })` sets this to the request's key. */
474
+ name?: ResolveTextLogicValue<string | undefined, InferOutput<TInputSchema>>;
475
+ schemas: {
476
+ input: TInputSchema;
477
+ output: TOutputSchema;
478
+ };
479
+ model: ResolveTextLogicValue<TModel, InferOutput<TInputSchema>>;
480
+ system?: ResolveTextLogicValue<string | undefined, InferOutput<TInputSchema>>;
481
+ prompt?: ResolveTextLogicValue<string | undefined, InferOutput<TInputSchema>>;
482
+ messages?: ResolveTextLogicValue<AgentMessage[] | undefined, InferOutput<TInputSchema>>;
483
+ tools?: ResolveTextLogicValue<AgentTools | undefined, InferOutput<TInputSchema>>;
484
+ toolChoice?: ResolveTextLogicValue<AgentToolChoice | undefined, InferOutput<TInputSchema>>;
485
+ /** Opt into the structured-output envelope's `reasoning` field (see {@link AgentTextRequest.reasoning}). */
486
+ reasoning?: ResolveTextLogicValue<boolean | undefined, InferOutput<TInputSchema>>;
487
+ temperature?: ResolveTextLogicValue<number | undefined, InferOutput<TInputSchema>>;
488
+ maxOutputTokens?: ResolveTextLogicValue<number | undefined, InferOutput<TInputSchema>>;
489
+ topP?: ResolveTextLogicValue<number | undefined, InferOutput<TInputSchema>>;
490
+ topK?: ResolveTextLogicValue<number | undefined, InferOutput<TInputSchema>>;
491
+ seed?: ResolveTextLogicValue<number | undefined, InferOutput<TInputSchema>>;
492
+ stopSequences?: ResolveTextLogicValue<string[] | undefined, InferOutput<TInputSchema>>;
493
+ metadata?: ResolveTextLogicValue<TMetadata | undefined, InferOutput<TInputSchema>>;
494
+ }
495
+ /** Arguments passed to a {@link TextLogicExecutor}: the typed input, the lowered {@link AgentTextRequest}, and the actor's own `signal`/`system`/`self`/`emit`. */
496
+ interface TextLogicExecuteArgs<TInput, TMetadata = Record<string, unknown>> {
497
+ input: TInput;
498
+ request: AgentTextRequest<TMetadata>;
499
+ signal: AbortSignal;
500
+ system: unknown;
501
+ self: unknown;
502
+ emit: (emitted: EventObject) => void;
503
+ }
504
+ /** Host implementation bound to a specific {@link TextLogic} via `withExecutor`/`createTextLogic`'s second argument — resolves one text request to an `{ output }` envelope typed from the logic's output schema (`{ output: T }`). Passthrough fields (usage, raw, …) are allowed alongside `output`. */
505
+ type TextLogicExecutor<TInputSchema extends StandardSchemaV1, TOutputSchema extends StandardSchemaV1, TMetadata = unknown> = (args: TextLogicExecuteArgs<InferOutput<TInputSchema>, TMetadata>) => PromiseLike<AgentRequestExecutorResult<InferOutput<TOutputSchema>>> | AgentRequestExecutorResult<InferOutput<TOutputSchema>>;
506
+ /**
507
+ * Actor logic for a text request: an async effect that resolves typed input
508
+ * to typed, schema-validated output via a model call. Built by
509
+ * {@link createTextLogic}; register under `actorSources:` and invoke by name, or
510
+ * bind an executor later with `withExecutor`. The `agent.generateText`/
511
+ * `agent.streamText` builtins and `setupAgent({ requests })` entries are
512
+ * both `TextLogic` under the hood.
513
+ */
514
+ interface TextLogic<TInputSchema extends StandardSchemaV1 = StandardSchemaV1, TOutputSchema extends StandardSchemaV1 = StandardSchemaV1, TMetadata = Record<string, unknown>> extends AsyncActorLogic<InferOutput<TOutputSchema>, InferOutput<TInputSchema>> {
515
+ readonly kind: "statelyai.textLogic";
516
+ readonly mode: AgentRequestMode;
517
+ readonly schemas: {
518
+ readonly input: TInputSchema;
519
+ readonly output: TOutputSchema;
520
+ };
521
+ request(input: InferOutput<TInputSchema>): AgentTextRequest<TMetadata>;
522
+ execute(input: InferOutput<TInputSchema>, executors: AgentRequestExecutors): Promise<InferOutput<TOutputSchema>>;
523
+ withExecutor(execute: TextLogicExecutor<TInputSchema, TOutputSchema, TMetadata>): TextLogic<TInputSchema, TOutputSchema, TMetadata>;
524
+ }
525
+ /** Extracts a {@link TextLogic}'s validated input type. */
526
+ type TextLogicInput<TLogic extends TextLogic> = TLogic extends TextLogic<infer TInputSchema, StandardSchemaV1, infer _TMetadata> ? InferOutput<TInputSchema> : never;
527
+ /** Extracts a {@link TextLogic}'s validated output type. */
528
+ type TextLogicOutput<TLogic extends TextLogic> = TLogic extends TextLogic<StandardSchemaV1, infer TOutputSchema, infer _TMetadata> ? InferOutput<TOutputSchema> : never;
529
+ /**
530
+ * Creates reusable, standalone {@link TextLogic}: an actor that, when run,
531
+ * resolves typed input to typed output via a model call. Register the
532
+ * result under `actorSources:` and invoke it by name (equivalent to what
533
+ * `setupAgent({ requests })` builds internally for each request entry). Pass
534
+ * `execute` here, or bind it later with `.withExecutor(...)`, a runtime
535
+ * adapter's `machine.provide(...)`, or `runAgent`'s `generateText`/
536
+ * `streamText` options.
537
+ *
538
+ * @example
539
+ * ```ts
540
+ * export const tellJoke = createTextLogic({
541
+ * mode: 'stream',
542
+ * schemas: { input: z.object({ topic: z.string() }), output: z.string() },
543
+ * model: 'openai/gpt-5.4-mini',
544
+ * system: 'You tell short, punchy jokes.',
545
+ * prompt: ({ input }) => `Tell a joke about ${input.topic}.`,
546
+ * });
547
+ * ```
548
+ */
549
+ declare function createTextLogic<TInputSchema extends StandardSchemaV1, TOutputSchema extends StandardSchemaV1, TMetadata = Record<string, unknown>, TModel extends string = string>(config: TextLogicConfig<TInputSchema, TOutputSchema, TMetadata, TModel>, execute?: TextLogicExecutor<TInputSchema, TOutputSchema, TMetadata>): TextLogic<TInputSchema, TOutputSchema, TMetadata>;
550
+ /**
551
+ * Binds a child machine's {@link TextLogic} to a raw
552
+ * {@link AgentRequestExecutor} (the `generateText`/`streamText` shape hosts
553
+ * implement). Encapsulates the `withExecutor` idiom child agents repeat:
554
+ * default the request's `tools` to `{}`, forward the actor `signal`, call the
555
+ * executor, and return its `{ output }` envelope. Use this to share ONE
556
+ * executor across a parent and its nested children.
557
+ *
558
+ * @example
559
+ * ```ts
560
+ * childMachine.provide({
561
+ * actorSources: {
562
+ * researchTopic: bindRequestExecutor(setup.requests.researchTopic, generateText),
563
+ * },
564
+ * });
565
+ * ```
566
+ */
567
+ declare function bindRequestExecutor<TInputSchema extends StandardSchemaV1, TOutputSchema extends StandardSchemaV1, TMetadata>(logic: TextLogic<TInputSchema, TOutputSchema, TMetadata>, executor: AgentRequestExecutor): TextLogic<TInputSchema, TOutputSchema, TMetadata>;
568
+ /**
569
+ * The envelope an {@link AgentRequestExecutor} must return: `{ output }` where
570
+ * `output` is the request's value (a text string or a structured object).
571
+ * Passthrough fields (usage, toolCalls, finishReason, raw, …) are allowed
572
+ * alongside `output` and preserved on the raw result. {@link normalizeGeneratorResult}
573
+ * unwraps `output`; a non-envelope return is a runtime error.
574
+ */
575
+ type AgentRequestExecutorResult<TOutput = unknown> = {
576
+ output: TOutput;
577
+ [key: string]: unknown;
578
+ };
579
+ /**
580
+ * Optional second argument passed to executors by `runAgent`. The step path
581
+ * (`executeAgentRequest`) never passes this — chunk streaming only exists on
582
+ * the live path, where `onChunk` (§3.1) needs a way to reach the executor.
583
+ */
584
+ interface AgentRequestExecutorInfo {
585
+ onChunk?: (chunk: string) => void;
586
+ signal?: AbortSignal;
587
+ }
588
+ /**
589
+ * A raw Vercel AI SDK `generateText` result shape: resolves `{ text }` (a
590
+ * string or a promise of one) instead of the `{ output }`
591
+ * {@link AgentRequestExecutorResult} envelope. Admitted directly as an executor
592
+ * return type so `ai`'s `generateText` passes to `runAgent`/executors without a
593
+ * cast — {@link normalizeGeneratorResult} unwraps `text` at runtime (text-only;
594
+ * structured output is best-effort JSON parsing against the request's
595
+ * `outputSchema`). Extra fields (`content`, `usage`, …) are ignored.
596
+ */
597
+ type AiSdkShapedTextResult = {
598
+ text: string | PromiseLike<string>;
599
+ [key: string]: unknown;
600
+ };
601
+ /**
602
+ * A raw Vercel AI SDK `streamText` result shape: exposes a `textStream` async
603
+ * iterable of string chunks (and, optionally, a `text` promise for the final
604
+ * text) instead of the `{ output }` {@link AgentRequestExecutorResult} envelope.
605
+ * Admitted directly as an executor return type so `ai`'s `streamText` passes to
606
+ * `runAgent`/executors without a cast — {@link normalizeGeneratorResult}
607
+ * iterates `textStream`, forwarding chunks, then resolves the final text
608
+ * (text-only; structured output is best-effort). Extra fields are ignored.
609
+ */
610
+ type AiSdkShapedStreamResult = {
611
+ textStream: AsyncIterable<string>;
612
+ text?: PromiseLike<string>;
613
+ [key: string]: unknown;
614
+ };
615
+ /**
616
+ * Host implementation of one text call (`generateText` or `streamText`) —
617
+ * resolves a lowered {@link AgentTextRequest} to an `{ output }` envelope (see
618
+ * {@link AgentRequestExecutorResult}), unwrapped by
619
+ * {@link normalizeGeneratorResult}. The return type is widened to also admit the
620
+ * raw Vercel AI SDK shapes ({@link AiSdkShapedTextResult} /
621
+ * {@link AiSdkShapedStreamResult}) so `ai`'s own `generateText`/`streamText`
622
+ * pass through without a cast; `normalizeGeneratorResult` checks for `{ output }`
623
+ * first, then falls back to those shapes at runtime.
624
+ */
625
+ type AgentRequestExecutor<TResult extends AgentRequestExecutorResult = AgentRequestExecutorResult> = (request: AgentTextRequest & {
626
+ tools: AgentTools;
627
+ }, info?: AgentRequestExecutorInfo) => PromiseLike<TResult | AiSdkShapedTextResult | AiSdkShapedStreamResult> | TResult | AiSdkShapedTextResult | AiSdkShapedStreamResult;
628
+ /**
629
+ * The full set of host executors a machine's agent actors are resolved
630
+ * with — passed to `runAgent`, `executeAgentRequest`, and
631
+ * `TextLogic.execute`. `generateText` is required; `streamText` is only
632
+ * needed if the machine has a `mode: 'stream'` text request, and `decide`
633
+ * only if it uses a decision — omitting either is a bind-time error when the
634
+ * machine actually needs it (see `runAgent`).
635
+ */
636
+ interface AgentRequestExecutors<TGenerateResult extends AgentRequestExecutorResult = AgentRequestExecutorResult, TStreamResult extends AgentRequestExecutorResult = AgentRequestExecutorResult> {
637
+ generateText: AgentRequestExecutor<TGenerateResult>;
638
+ streamText?: AgentRequestExecutor<TStreamResult>;
639
+ decide?: AgentDecisionExecutor;
640
+ }
641
+ /** Whether a text request's output is a validated structured object (`'structured'`) or plain text (`'text'`) — derived from the output schema's JSON Schema `type`. */
642
+ type AgentOutputMode = "structured" | "text";
643
+ /**
644
+ * Classifies a text request's output schema as `'structured'` (its JSON
645
+ * Schema is `type: 'object'`, `type: 'array'`, or a top-level union/
646
+ * composition — `anyOf`/`oneOf`/`allOf`, which a bare `z.union`/
647
+ * `z.discriminatedUnion` emits with no top-level `type`) or `'text'`
648
+ * (anything else, including no schema). Reads the schema's
649
+ * `~standard.jsonSchema.input()` extension — schemas without it are treated
650
+ * as `'text'`.
651
+ */
652
+ declare function getAgentOutputMode(schema?: StandardSchemaV1): AgentOutputMode;
653
+ /** True when {@link getAgentOutputMode} classifies `schema` as `'structured'`. */
654
+ declare function isStructuredOutputSchema(schema?: StandardSchemaV1): boolean;
655
+ /** The unwrapped shape a {@link buildEnvelopeSchema} validate returns: the inner
656
+ * `result` value plus, when opted in and present, the model's `reasoning`. */
657
+ interface StructuredOutputEnvelope {
658
+ result: unknown;
659
+ reasoning?: string;
660
+ }
661
+ /**
662
+ * Builds the uniform structured-output envelope schema every structured request
663
+ * is sent to the provider as: a root object `{ result: <inner> }`, plus — when
664
+ * `options.reasoning` is `true` — an optional string `reasoning` property listed
665
+ * BEFORE `result` (property order nudges the model to reason first). This is THE
666
+ * wire contract for structured output: a root object is universally accepted as
667
+ * a provider response schema, unlike a bare union/array root that many providers
668
+ * reject.
669
+ *
670
+ * The returned {@link StandardSchemaV1} validates the `{ reasoning?, result }`
671
+ * envelope (unwrapping `result` through the original schema, capturing a string
672
+ * `reasoning` when present) and exposes the enveloped JSON Schema. Adapters read
673
+ * `.result` off the provider output before the machine validates it — so this is
674
+ * transparent: user-facing output types stay the declared (un-enveloped) schema,
675
+ * and `reasoning` is surfaced only on the raw executor result, never in machine
676
+ * context/output.
677
+ */
678
+ declare function buildEnvelopeSchema(inner: StandardSchemaV1, options?: {
679
+ reasoning?: boolean;
680
+ }): StandardSchemaV1<StructuredOutputEnvelope>;
681
+ //#endregion
682
+ export { AgentPlanInput as A, AgentEventDescriptor as B, createTextLogic as C, AgentDecisionExecutor as D, parseOutput as E, DecisionLogicConfig as F, getAcceptedEvents as G, AgentRequestOptions as H, PLAN_DONE_EVENT_TYPE as I, matchesEventPattern as K, ResolveDecisionOptions as L, DecisionAttempt as M, DecisionExhaustedError as N, AgentDecisionInput as O, DecisionLogic as P, renderDecisionAttempts as R, buildEnvelopeSchema as S, isStructuredOutputSchema as T, AgentRequestSource as U, AgentEventToolNameResolver as V, EVENT_TOOL_PREFIX as W, TextLogicExecuteArgs as _, AgentRequestExecutorInfo as a, TextLogicOutput as b, AgentRequestMode as c, AiSdkShapedStreamResult as d, AiSdkShapedTextResult as f, TextLogicConfig as g, TextLogic as h, AgentRequestExecutor as i, AgentPlanOutput as j, AgentDecisionRequest as k, AgentTextRequest as l, StructuredOutputEnvelope as m, AgentModelRef as n, AgentRequestExecutorResult as o, BuiltinAgentActors as p, parseAgentEvent as q, AgentOutputMode as r, AgentRequestExecutors as s, AgentModelMap as t, AgentUserInput as u, TextLogicExecutor as v, getAgentOutputMode as w, bindRequestExecutor as x, TextLogicInput as y, resolveDecision as z };