@statelyai/agent 2.0.0-alpha.21 → 2.0.0-alpha.23

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 (48) hide show
  1. package/dist/ai-sdk.cjs +53 -25
  2. package/dist/ai-sdk.d.cts +20 -12
  3. package/dist/ai-sdk.d.mts +20 -12
  4. package/dist/ai-sdk.mjs +53 -25
  5. package/dist/{decision-JWx6n3xR.mjs → decision-BBZ2jMO1.mjs} +542 -84
  6. package/dist/{decision-BnTCsuJv.cjs → decision-Cv6SfNWl.cjs} +629 -99
  7. package/dist/index.cjs +2225 -1032
  8. package/dist/index.d.cts +415 -276
  9. package/dist/index.d.mts +415 -276
  10. package/dist/index.mjs +2163 -983
  11. package/dist/machines.cjs +30 -2
  12. package/dist/machines.d.cts +151 -54
  13. package/dist/machines.d.mts +151 -54
  14. package/dist/machines.mjs +30 -2
  15. package/dist/openai.cjs +447 -0
  16. package/dist/openai.d.cts +177 -0
  17. package/dist/openai.d.mts +177 -0
  18. package/dist/openai.mjs +437 -0
  19. package/dist/otel.cjs +3 -6
  20. package/dist/otel.d.cts +1 -1
  21. package/dist/otel.d.mts +1 -1
  22. package/dist/otel.mjs +3 -6
  23. package/dist/run-agent-Ck7Sa3Tb.d.mts +968 -0
  24. package/dist/run-agent-DWqA8KiI.d.cts +968 -0
  25. package/dist/setup-agent-CeO2fARv.mjs +639 -0
  26. package/dist/setup-agent-Dl2VELLi.cjs +663 -0
  27. package/dist/{text-logic-Mmbgb2jy.d.cts → text-logic-C7bSnH_B.d.cts} +238 -44
  28. package/dist/{text-logic-BR5twXCv.d.mts → text-logic-DJBK3LbG.d.mts} +238 -44
  29. package/dist/{types-DSdj2tGs.d.cts → types-CjHk5OdH.d.cts} +4 -19
  30. package/dist/{types-CvWRGFxP.d.mts → types-DWA6X9R-.d.mts} +4 -19
  31. package/package.json +17 -21
  32. package/readme.md +32 -17
  33. package/dist/errors-BQRk9eiZ.d.cts +0 -19
  34. package/dist/errors-C9rxnWbX.d.mts +0 -19
  35. package/dist/errors-CeSXQx0v.mjs +0 -23
  36. package/dist/errors-DUBBzRLP.cjs +0 -28
  37. package/dist/event-log-store-Bz7HDBkE.d.cts +0 -145
  38. package/dist/event-log-store-DmIDosD6.mjs +0 -427
  39. package/dist/event-log-store-a_TKy1gk.cjs +0 -468
  40. package/dist/event-log-store-hrA1vqtN.d.mts +0 -145
  41. package/dist/run-agent-DBNI8ETM.d.mts +0 -1098
  42. package/dist/run-agent-Do094mGu.d.cts +0 -1098
  43. package/dist/setup-agent-91FSuZbB.cjs +0 -1641
  44. package/dist/setup-agent-DqqdcdNh.mjs +0 -1521
  45. package/dist/sqlite.cjs +0 -129
  46. package/dist/sqlite.d.cts +0 -57
  47. package/dist/sqlite.d.mts +0 -57
  48. package/dist/sqlite.mjs +0 -127
@@ -1,8 +1,71 @@
1
- import { a as AgentToolChoice, c as AgentTools, d as ChosenEvent, g as InferOutput, l as AllowedEvents, n as AgentMessage, v as StandardSchemaV1 } from "./types-DSdj2tGs.cjs";
2
- import { t as AgentError } from "./errors-BQRk9eiZ.cjs";
3
- import { AnyMachineSnapshot, AsyncActorLogic, EventObject, MachineSnapshot } from "xstate";
1
+ import { _ as StandardSchemaV1, c as AllowedEvents, h as InferOutput, i as AgentToolChoice, n as AgentMessage, s as AgentTools, u as ChosenEvent } from "./types-CjHk5OdH.cjs";
2
+ import { AnyMachineSnapshot, AnyStateMachine, AsyncActorLogic, EventFromLogic, EventObject, MachineSnapshot } from "xstate";
4
3
 
4
+ //#region src/errors.d.ts
5
+ /**
6
+ * Base class for every error this package throws. Carries a stable, kebab-case
7
+ * `code` so hosts can branch on the failure without `instanceof` (useful across
8
+ * bundle/realm boundaries and after serialization).
9
+ *
10
+ * @example
11
+ * ```ts
12
+ * catch (error) {
13
+ * if (error instanceof AgentError && error.code === 'agent-idle') { ... }
14
+ * }
15
+ * ```
16
+ */
17
+ declare class AgentError extends Error {
18
+ readonly code: string;
19
+ constructor(code: string, message: string, options?: ErrorOptions);
20
+ }
21
+ /**
22
+ * A model call ran out of output tokens before it produced anything usable.
23
+ * Core never throws this: it is the adapter's signal that a `'length'` finish
24
+ * reason left nothing to return — a structured request whose envelope never
25
+ * closed, say. A text request that WAS cut off still returns its text, with
26
+ * `finishReason: 'length'`.
27
+ *
28
+ * The code is `'truncated'`, so an invoke's `onError` can branch on it without
29
+ * `instanceof`:
30
+ *
31
+ * @example
32
+ * ```ts
33
+ * onError: [
34
+ * { guard: ({ event }) => event.error.code === 'truncated', target: 'retryShorter' },
35
+ * { target: 'failed' },
36
+ * ]
37
+ * ```
38
+ */
39
+ declare class AgentTruncatedError extends AgentError {
40
+ /** The request that was cut off — `AgentTextRequest.name`. */
41
+ readonly requestName: string;
42
+ /** The durable invoke id of the request, when the host knows it. */
43
+ readonly requestId?: string;
44
+ /** Whatever the model did produce before it hit the limit, if anything. */
45
+ readonly partialOutput?: unknown;
46
+ constructor(message: string, options: {
47
+ requestName: string;
48
+ requestId?: string;
49
+ partialOutput?: unknown;
50
+ cause?: unknown;
51
+ });
52
+ }
53
+ //#endregion
5
54
  //#region src/events.d.ts
55
+ /**
56
+ * Thrown by {@link parseAgentEvent} (and {@link eventFromInteraction}) when a
57
+ * wire payload is not a usable event: it is not an object with a string
58
+ * `type`, it names a reserved `@agent.*` type, or its fields fail the schema
59
+ * the machine registered for that type. A host turns it into a 400.
60
+ *
61
+ * Not handling an event is NOT this error — a state machine ignores events it
62
+ * has no transition for, so an event the current state does not handle parses
63
+ * fine and settles the run with `result.ignored` set.
64
+ */
65
+ declare class AgentInvalidEventPayloadError extends AgentError {
66
+ readonly eventType: string;
67
+ constructor(eventType: string, detail: string);
68
+ }
6
69
  /** The invoke `src` of an {@link AgentRequest}/{@link AgentDecisionRequest} — a plain string, widened so literal `src` values still narrow in editor hints. */
7
70
  type AgentRequestSource = string & {};
8
71
  /** Customizes the tool name generated for a candidate event; see {@link AgentRequestOptions.eventToolName}. */
@@ -33,30 +96,32 @@ interface AgentRequestOptions {
33
96
  }
34
97
  /** Recovers a machine's event union from its snapshot type, so {@link parseAgentEvent} returns the machine-typed event without a downstream cast. @internal */
35
98
  type EventFromSnapshot<TSnapshot> = TSnapshot extends MachineSnapshot<any, infer TEvent, any, any, any, any, any, any> ? TEvent : EventObject;
99
+ /** The machine event union {@link parseAgentEvent} returns, from a machine or from a snapshot of one. @internal */
100
+ type ParsedAgentEvent<TSource> = TSource extends AnyStateMachine ? EventFromLogic<TSource> : EventFromSnapshot<TSource>;
36
101
  /**
37
- * Runtime-validates a dynamically-built `{ type, ...payload }` event against a
38
- * snapshot's currently-accepted events (via {@link getAcceptedEvents}) and,
39
- * when one is registered, the event type's payload schema — returning the
40
- * event typed as the machine's event union (recovered from the snapshot type)
41
- * so it can be sent to `runAgent({ event })` / `actor.send(...)` without an
42
- * `as never` cast. For generic, meta-driven hosts that assemble events from
43
- * user input or a wire message.
102
+ * Parses a wire payload (a request body, a socket frame) into an
103
+ * event typed as the machine's event union, so it can go straight to
104
+ * `runAgent({ event })` / `actor.send(...)` without a cast. Pass the machine
105
+ * itself, or any snapshot of it.
106
+ *
107
+ * It checks exactly what a schema can check: the payload is an object with a
108
+ * string `type`, that type is not one of the library-reserved `@agent.*` types,
109
+ * and — when the machine registered a schema for it — the fields satisfy that
110
+ * schema (defaults filled, transforms applied). Anything else throws
111
+ * {@link AgentInvalidEventPayloadError}, which a host answers with a 400.
44
112
  *
45
- * Throws a descriptive error when `event.type` is not currently accepted
46
- * (listing the accepted types) or when its payload fails the registered schema.
47
- * Pass event payload schemas via `options.events`/`options.schemas` (the same
48
- * shape {@link getAcceptedEvents} takes) — the accepted TYPES always come from
49
- * the live snapshot; the schemas only add payload validation.
113
+ * It deliberately does NOT check whether the current state handles the event.
114
+ * State machines ignore events they have no transition for; that is normal
115
+ * behavior, not a validation failure. Send the parsed event and read
116
+ * `result.ignored` if the host wants to tell the client nothing happened.
50
117
  *
51
118
  * @example
52
119
  * ```ts
53
- * const event = parseAgentEvent(result.snapshot, rawEvent, { events: schemas.events });
54
- * result = await runAgent(machine, { snapshot: result.snapshot, event, executors });
120
+ * const event = parseAgentEvent(machine, await request.json());
121
+ * const result = await runAgent(machine, { store, threadId, event, executors });
55
122
  * ```
56
123
  */
57
- declare function parseAgentEvent<TSnapshot extends AnyMachineSnapshot>(snapshot: TSnapshot, event: {
58
- type: string;
59
- } & Record<string, unknown>, options?: Pick<AgentRequestOptions, "events" | "schemas" | "eventToolName">): EventFromSnapshot<TSnapshot>;
124
+ declare function parseAgentEvent<TSource extends AnyStateMachine | AnyMachineSnapshot>(source: TSource, payload: unknown, options?: Pick<AgentRequestOptions, "events" | "schemas">): ParsedAgentEvent<TSource>;
60
125
  /**
61
126
  * Lists the events a snapshot can currently accept, as {@link AgentEventDescriptor}s
62
127
  * a model can be offered (via `resolveDecision`/an adapter's tool-per-event
@@ -85,10 +150,13 @@ declare function getAcceptedEvents(snapshot: AnyMachineSnapshot, options?: Pick<
85
150
  * See {@link AgentDecisionRequest} for the request shape this lowers to.
86
151
  */
87
152
  interface AgentDecisionInput<TEvent extends string = string, TMetadata = Record<string, unknown>, TModel extends string = string> {
153
+ /** Semantic request identity. Defaults to the invoke occurrence id. */
154
+ name?: string;
88
155
  model: TModel;
89
156
  system?: string;
90
157
  prompt?: string;
91
- messages?: AgentMessage[];
158
+ /** Framework-native messages, passed through without conversion. */
159
+ messages?: any[];
92
160
  allowedEvents?: AllowedEvents<TEvent>;
93
161
  maxRetries?: number;
94
162
  temperature?: number;
@@ -107,13 +175,16 @@ interface AgentDecisionInput<TEvent extends string = string, TMetadata = Record<
107
175
  * {@link AllowedEvents}) and `maxRetries` for {@link resolveDecision}.
108
176
  */
109
177
  interface DecisionLogicConfig<TInputSchema extends StandardSchemaV1 = StandardSchemaV1, TEvent extends string = string, TMetadata extends Record<string, unknown> = Record<string, unknown>, TModel extends string = string> {
178
+ /** Semantic request identity. Defaults to the invoke occurrence id. */
179
+ name?: ResolveTextLogicValue<string | undefined, InferOutput<TInputSchema>>;
110
180
  schemas?: {
111
181
  input: TInputSchema;
112
182
  };
113
183
  model: ResolveTextLogicValue<TModel, InferOutput<TInputSchema>>;
114
184
  system?: ResolveTextLogicValue<string | undefined, InferOutput<TInputSchema>>;
115
185
  prompt?: ResolveTextLogicValue<string | undefined, InferOutput<TInputSchema>>;
116
- messages?: ResolveTextLogicValue<AgentMessage[] | undefined, InferOutput<TInputSchema>>;
186
+ /** Framework-native messages, passed through without conversion. */
187
+ messages?: ResolveTextLogicValue<any[] | undefined, InferOutput<TInputSchema>>;
117
188
  allowedEvents?: AllowedEvents<TEvent, InferOutput<TInputSchema>>;
118
189
  maxRetries?: number;
119
190
  temperature?: ResolveTextLogicValue<number | undefined, InferOutput<TInputSchema>>;
@@ -124,6 +195,49 @@ interface DecisionLogicConfig<TInputSchema extends StandardSchemaV1 = StandardSc
124
195
  stopSequences?: ResolveTextLogicValue<string[] | undefined, InferOutput<TInputSchema>>;
125
196
  metadata?: ResolveTextLogicValue<TMetadata | undefined, InferOutput<TInputSchema>>;
126
197
  }
198
+ /**
199
+ * Actor logic for a decision: an async effect that resolves to exactly one
200
+ * currently-legal {@link ChosenEvent} (never a plain value). Under `runAgent`
201
+ * the chosen event is delivered to the invoking actor automatically — the
202
+ * transition it triggers usually exits the invoking state and ends the invoke.
203
+ * Built by {@link createDecisionLogic}. Register it under `actors:` to reuse/export/
204
+ * test it standalone; for a state-local, zero-config decision, use the
205
+ * `agent.decide` builtin invoke instead.
206
+ */
207
+ interface DecisionLogic<TInputSchema extends StandardSchemaV1 = StandardSchemaV1, TMetadata extends Record<string, unknown> = Record<string, unknown>> extends AsyncActorLogic<ChosenEvent, InferOutput<TInputSchema>> {
208
+ readonly kind: "statelyai.decisionLogic";
209
+ readonly maxRetries: number;
210
+ request(input: InferOutput<TInputSchema>): AgentDecisionRequest;
211
+ withExecutor(execute: AgentDecisionExecutor): DecisionLogic<TInputSchema, TMetadata>;
212
+ }
213
+ /**
214
+ * Creates reusable, standalone {@link DecisionLogic}: an actor that, when
215
+ * run, resolves to exactly one currently-legal {@link ChosenEvent} by
216
+ * calling the host `decide` executor (passed here as `execute`, or supplied
217
+ * later via {@link DecisionLogic.withExecutor}, `machine.provide(...)`, or
218
+ * `runAgent`'s `decide` option). Register the result under `actors:` and
219
+ * invoke it by name; for a one-off, state-local decision, prefer the
220
+ * `agent.decide` builtin invoke instead — it needs no separate declaration
221
+ * and types `allowedEvents` against the machine's own event schemas.
222
+ *
223
+ * @example
224
+ * ```ts
225
+ * import { createDecisionLogic } from '@statelyai/agent';
226
+ * import { z } from 'zod';
227
+ *
228
+ * export const chooseMove = createDecisionLogic({
229
+ * schemas: { input: z.object({ playerHp: z.number(), enemyHp: z.number() }) },
230
+ * model: 'openai/gpt-5.4-mini',
231
+ * system: 'You are playing a turn-based game. Choose exactly one legal move.',
232
+ * prompt: ({ input }) => `Player HP: ${input.playerHp}\nEnemy HP: ${input.enemyHp}`,
233
+ * allowedEvents: ({ input }) =>
234
+ * input.playerHp <= 6
235
+ * ? ['ATTACK', 'DEFEND', 'HEAL', 'FLEE']
236
+ * : ['ATTACK', 'DEFEND', 'FLEE'],
237
+ * });
238
+ * ```
239
+ */
240
+ declare function createDecisionLogic<TInputSchema extends StandardSchemaV1, TEvent extends string = string, TMetadata extends Record<string, unknown> = Record<string, unknown>, TModel extends string = string>(config: DecisionLogicConfig<TInputSchema, TEvent, TMetadata, TModel>, execute?: AgentDecisionExecutor): DecisionLogic<TInputSchema, TMetadata>;
127
241
  /**
128
242
  * A decision request: resolves to exactly one currently-legal event. See
129
243
  * `resolveDecision`.
@@ -132,10 +246,15 @@ interface AgentDecisionRequest {
132
246
  kind: "decision";
133
247
  /** Durable invoke id. */
134
248
  id: string;
249
+ /** Semantic request identity; defaults to {@link id}. */
250
+ name?: string;
251
+ /** The schema-validated invoke input that produced this request. */
252
+ input?: unknown;
135
253
  model: string;
136
254
  system?: string;
137
255
  prompt?: string;
138
- messages?: AgentMessage[];
256
+ /** Framework-native messages, passed through without conversion. */
257
+ messages?: any[];
139
258
  /** Candidate events: declared `allowedEvents` ∩ snapshot-legal events. */
140
259
  events: AgentEventDescriptor[];
141
260
  /**
@@ -151,13 +270,6 @@ interface AgentDecisionRequest {
151
270
  seed?: number;
152
271
  stopSequences?: string[];
153
272
  metadata?: Record<string, unknown>;
154
- /**
155
- * Abort signal for the underlying model call, threaded through by
156
- * {@link resolveDecision} from its `options.signal` so a `decide` executor
157
- * can cancel the in-flight request (symmetric with the text executors'
158
- * `info.signal`). Runtime-only — never serialized into a provider request.
159
- */
160
- signal?: AbortSignal;
161
273
  /**
162
274
  * The `runAgent` run this decision belongs to (`run_<n>`, matching trace
163
275
  * events), injected by runAgent like `signal` (symmetric with the text
@@ -168,6 +280,42 @@ interface AgentDecisionRequest {
168
280
  */
169
281
  runId?: string;
170
282
  }
283
+ /**
284
+ * Options for {@link createDecisionRequest}. Everything except `model` and
285
+ * `events` is optional; `events` also accepts bare event types.
286
+ */
287
+ interface CreateDecisionRequestOptions extends Omit<AgentDecisionRequest, "kind" | "id" | "events" | "attempts"> {
288
+ /** Durable invoke id. Defaults to `name`, then `'decision'`. */
289
+ id?: string;
290
+ /** Candidate events: descriptors (from `getAcceptedEvents`) or bare types. */
291
+ events: readonly (string | AgentEventDescriptor)[];
292
+ /** Prior failed attempts. Defaults to `[]` (a first attempt). */
293
+ attempts?: DecisionAttempt[];
294
+ }
295
+ /**
296
+ * Builds an {@link AgentDecisionRequest} for {@link resolveDecision}, filling
297
+ * in the fields a hand-written literal has to restate every time: `kind`, an
298
+ * `id`, an empty `attempts` list, and each candidate event's `toolName`.
299
+ *
300
+ * @example
301
+ * ```ts
302
+ * const chosen = await resolveDecision(
303
+ * createDecisionRequest({
304
+ * name: 'judge',
305
+ * model: 'reviewer',
306
+ * prompt: `Judge this draft.\n\n${snapshot.context.draft}`,
307
+ * events: getAcceptedEvents(snapshot),
308
+ * }),
309
+ * { decide },
310
+ * { canTake: (event) => snapshot.can(event) },
311
+ * );
312
+ * ```
313
+ */
314
+ declare function createDecisionRequest(options: CreateDecisionRequestOptions): AgentDecisionRequest;
315
+ /** Decision request after core has resolved its semantic identity. */
316
+ type AgentExecutorDecisionRequest = AgentDecisionRequest & {
317
+ name: string;
318
+ };
171
319
  /**
172
320
  * A single failed decision attempt, recorded by {@link resolveDecision} and
173
321
  * fed back to the executor on the next attempt via
@@ -224,7 +372,7 @@ declare function renderDecisionAttempts(request: Pick<AgentDecisionRequest, "eve
224
372
  * report this attempt's tokens there and `runAgent` folds them into the run's
225
373
  * aggregated {@link AgentUsage}.
226
374
  */
227
- type AgentDecisionExecutor = (request: AgentDecisionRequest, info?: AgentRequestExecutorInfo) => PromiseLike<{
375
+ type AgentDecisionExecutor = (request: AgentExecutorDecisionRequest, info?: AgentRequestExecutorInfo) => PromiseLike<{
228
376
  event: ChosenEvent;
229
377
  reason?: string; /** This attempt's token usage, aggregated into the run result's {@link AgentUsage}. */
230
378
  usage?: AgentCallUsage;
@@ -294,7 +442,7 @@ type AgentModelMap = Record<string, unknown>;
294
442
  * autocomplete. Refs are opaque routing keys — the host/executor (or the AI SDK
295
443
  * adapter's models map / `resolveModel`) resolves them to a real model.
296
444
  */
297
- type AgentModelRef<TModels extends AgentModelMap = {}> = [keyof TModels] extends [never] ? string : (keyof TModels & string) | (string & {});
445
+ type AgentModelRef<TModels extends AgentModelMap = {}> = [keyof TModels] extends [never] ? string : keyof TModels & string;
298
446
  /**
299
447
  * Splits a portable `"provider/model-id"` model ref (the convention JSON
300
448
  * workflows and registry-less hosts use, e.g. `"openai/gpt-5.4-mini"`) into
@@ -318,7 +466,7 @@ declare function parseModelRef(modelRef: string): {
318
466
  * `createAiSdkExecutors`) map this shape onto their provider's call
319
467
  * settings.
320
468
  */
321
- interface AgentTextRequest<TMetadata = Record<string, unknown>> {
469
+ interface AgentTextRequest<TMetadata = Record<string, unknown>, TMessage = any> {
322
470
  /**
323
471
  * The registered name of the request that produced this call — the
324
472
  * `setupAgent({ requests })` key (also set by `setupAgent.fromConfig`), or
@@ -328,10 +476,12 @@ interface AgentTextRequest<TMetadata = Record<string, unknown>> {
328
476
  * the caller sets it on the inline input.
329
477
  */
330
478
  name?: string;
479
+ /** The schema-validated invoke input that produced this request. */
480
+ input?: unknown;
331
481
  model: string;
332
482
  system?: string;
333
483
  prompt?: string;
334
- messages?: AgentMessage[];
484
+ messages?: TMessage[];
335
485
  /** Host/model tools that are always available to this text call. */
336
486
  tools?: AgentTools;
337
487
  toolChoice?: AgentToolChoice;
@@ -381,7 +531,7 @@ interface AgentTextRequest<TMetadata = Record<string, unknown>> {
381
531
  /**
382
532
  * Aggregated model-call usage for ONE `runAgent` call — the run-level total
383
533
  * attached to every settled {@link RunAgentResult} (and therefore to
384
- * `generateResult`'s `{ output, snapshot, events, usage }`).
534
+ * `runAgent`'s `{ output, snapshot, persist, usage }`).
385
535
  *
386
536
  * - `modelCalls` counts every model/decision call this run made (each decision
387
537
  * retry counts separately) — the same seam `maxModelCalls` budgets. Always a
@@ -406,6 +556,29 @@ interface AgentUsage {
406
556
  }
407
557
  /** One model call's reported usage — {@link AgentUsage} without the run-level `modelCalls` count. What an executor puts on its result's `usage` field. */
408
558
  type AgentCallUsage = Omit<AgentUsage, "modelCalls">;
559
+ /**
560
+ * Why a model call stopped, normalized across providers:
561
+ *
562
+ * - `'stop'` — the model finished on its own.
563
+ * - `'length'` — the output token limit cut it off.
564
+ * - `'tool-calls'` — it stopped to call tools.
565
+ * - `'content-filter'` — a safety filter stopped it.
566
+ * - `'other'` — anything else, including a provider error the adapter mapped.
567
+ *
568
+ * Adapters set it on their executor result; `runAgent` copies it onto the
569
+ * `request.end` trace event. A provider's own string stays on the result's
570
+ * `raw`.
571
+ */
572
+ type AgentFinishReason = "stop" | "length" | "tool-calls" | "content-filter" | "other";
573
+ /**
574
+ * Reads a settled call's {@link AgentFinishReason} off a RAW executor result's
575
+ * `finishReason` field — the finish-reason sibling of {@link getCallUsage},
576
+ * applied by `runAgent` before it puts the reason on the `request.end` trace.
577
+ * A provider's `'error'` normalizes to `'other'`; anything else the union does
578
+ * not name (an un-normalized provider string, a missing field) returns
579
+ * `undefined`.
580
+ */
581
+ declare function getCallFinishReason(raw: unknown): AgentFinishReason | undefined;
409
582
  /**
410
583
  * Reads a settled call's per-call {@link AgentCallUsage} off a RAW executor
411
584
  * result's `usage` field, keeping only finite numbers — the same normalization
@@ -479,7 +652,8 @@ interface TextLogicConfig<TInputSchema extends StandardSchemaV1 = StandardSchema
479
652
  model: ResolveTextLogicValue<TModel, InferOutput<TInputSchema>>;
480
653
  system?: ResolveTextLogicValue<string | undefined, InferOutput<TInputSchema>>;
481
654
  prompt?: ResolveTextLogicValue<string | undefined, InferOutput<TInputSchema>>;
482
- messages?: ResolveTextLogicValue<AgentMessage[] | undefined, InferOutput<TInputSchema>>;
655
+ /** Framework-native messages, passed through without conversion. */
656
+ messages?: ResolveTextLogicValue<any[] | undefined, InferOutput<TInputSchema>>;
483
657
  tools?: ResolveTextLogicValue<AgentTools | undefined, InferOutput<TInputSchema>>;
484
658
  toolChoice?: ResolveTextLogicValue<AgentToolChoice | undefined, InferOutput<TInputSchema>>;
485
659
  /** Opt into the structured-output envelope's `reasoning` field (see {@link AgentTextRequest.includeReasoning}). */
@@ -575,9 +749,11 @@ declare function bindRequestExecutor<TInputSchema extends StandardSchemaV1, TOut
575
749
  * {@link AgentUsage}. Optional — an executor that reports nothing still counts
576
750
  * toward `modelCalls`.
577
751
  */
578
- type AgentRequestExecutorResult<TOutput = unknown> = {
579
- output: TOutput; /** This call's token usage, aggregated into the run result's {@link AgentUsage}. */
580
- usage?: AgentCallUsage;
752
+ type AgentRequestExecutorResult<TOutput = unknown, TMessage = unknown> = {
753
+ output: TOutput; /** Framework-native response messages, preserved without normalization. */
754
+ messages?: TMessage[]; /** This call's token usage, aggregated into the run result's {@link AgentUsage}. */
755
+ usage?: AgentCallUsage; /** Why this call stopped, normalized (see {@link AgentFinishReason}). Surfaced on the `request.end` trace event. */
756
+ finishReason?: AgentFinishReason;
581
757
  [key: string]: unknown;
582
758
  };
583
759
  /**
@@ -602,6 +778,24 @@ interface AgentRequestExecutorInfo {
602
778
  * call has no invoking actor.
603
779
  */
604
780
  requestId?: string;
781
+ /**
782
+ * A per-call idempotency key, `${executionId}:${requestId}#${n}` — the event
783
+ * log's lineage id plus the occurrence of this call at this invoke site.
784
+ * IDENTICAL across a crash re-execution: a run resumed from a log whose last
785
+ * call was still in flight re-issues that call under the same key, so an
786
+ * executor-level cache (or a provider's own idempotency header) can return
787
+ * the first attempt's result instead of paying for it twice. A decision
788
+ * retry appends its attempt ordinal (`${executionId}:${requestId}#${n}.${a}`,
789
+ * `a` being the number of prior failed attempts), so a retry never collides
790
+ * with the rejected attempt it is replacing.
791
+ *
792
+ * It identifies the CALL SITE, not the request: a fork inherits its parent's
793
+ * lineage id, so cache on `callKey` together with a fingerprint of the
794
+ * request and reuse a cached result only when the request also matches.
795
+ *
796
+ * Undefined off the `runAgent` path, and for a log with no `executionId`.
797
+ */
798
+ callKey?: string;
605
799
  }
606
800
  /**
607
801
  * A raw Vercel AI SDK `generateText` result shape: resolves `{ text }` (a
@@ -651,15 +845,15 @@ type AiSdkShapedStreamResult = {
651
845
  * - `prompt`/`messages` are mutually exclusive, matching `ai`'s `Prompt`
652
846
  * union (core always sets exactly one).
653
847
  * - `tools`, `toolChoice`, and `messages` are widened to `any` — their
654
- * portable shapes ({@link AgentTools}, {@link AgentToolChoice},
655
- * {@link AgentMessage}) are structural supersets of `ai`'s branded types
656
- * and would otherwise fail the contravariant check.
848
+ * framework-native shapes may be branded and would otherwise fail the
849
+ * contravariant check.
657
850
  *
658
851
  * Hand-written executors that want the precise shapes can annotate their
659
852
  * parameter as `AgentTextRequest & { tools: AgentTools }` — that wider
660
853
  * parameter type keeps the executor assignable.
661
854
  */
662
- type AgentExecutorTextRequest<TMetadata = Record<string, unknown>> = Omit<AgentTextRequest<TMetadata>, "prompt" | "messages" | "tools" | "toolChoice"> & {
855
+ type AgentExecutorTextRequest<TMetadata = Record<string, unknown>> = Omit<AgentTextRequest<TMetadata>, "name" | "prompt" | "messages" | "tools" | "toolChoice"> & {
856
+ /** Semantic request identity; always resolved before an executor is called. */name: string;
663
857
  tools: any;
664
858
  toolChoice?: any;
665
859
  } & ({
@@ -744,4 +938,4 @@ declare function buildEnvelopeSchema(inner: StandardSchemaV1, options?: {
744
938
  */
745
939
  declare function parseStructuredEnvelope(request: Pick<AgentTextRequest, "outputSchema" | "includeReasoning">, value: unknown): StructuredOutputEnvelope;
746
940
  //#endregion
747
- export { AgentDecisionExecutor as A, AgentEventToolNameResolver as B, buildEnvelopeSchema as C, parseModelRef as D, getCallUsage as E, DecisionLogicConfig as F, parseAgentEvent as G, AgentRequestSource as H, ResolveDecisionOptions as I, renderDecisionAttempts as L, AgentDecisionInput as M, AgentDecisionRequest as N, parseOutput as O, DecisionAttempt as P, resolveDecision as R, bindRequestExecutor as S, getAgentOutputMode as T, AgentSchemas as U, AgentRequestOptions as V, getAcceptedEvents as W, StructuredOutputEnvelope as _, AgentOutputMode as a, TextLogicExecuteArgs as b, AgentRequestExecutorResult as c, AgentTextRequest as d, AgentUsage as f, BuiltinAgentActors as g, AiSdkShapedTextResult as h, AgentModelRef as i, AgentDecisionExhaustedError as j, parseStructuredEnvelope as k, AgentRequestExecutors as l, AiSdkShapedStreamResult as m, AgentExecutorTextRequest as n, AgentRequestExecutor as o, AgentUserInput as p, AgentModelMap as r, AgentRequestExecutorInfo as s, AgentCallUsage as t, AgentRequestMode as u, TextLogic as v, createTextLogic as w, TextLogicExecutor as x, TextLogicConfig as y, AgentEventDescriptor as z };
941
+ export { getAcceptedEvents as $, parseOutput as A, DecisionLogicConfig as B, bindRequestExecutor as C, getCallFinishReason as D, getAgentOutputMode as E, AgentDecisionRequest as F, resolveDecision as G, createDecisionLogic as H, AgentExecutorDecisionRequest as I, AgentInvalidEventPayloadError as J, AgentEventDescriptor as K, CreateDecisionRequestOptions as L, AgentDecisionExecutor as M, AgentDecisionExhaustedError as N, getCallUsage as O, AgentDecisionInput as P, EventFromSnapshot as Q, DecisionAttempt as R, TextLogicExecutor as S, createTextLogic as T, createDecisionRequest as U, ResolveDecisionOptions as V, renderDecisionAttempts as W, AgentRequestSource as X, AgentRequestOptions as Y, AgentSchemas as Z, BuiltinAgentActors as _, AgentModelRef as a, TextLogicConfig as b, AgentRequestExecutorInfo as c, AgentRequestMode as d, parseAgentEvent as et, AgentTextRequest as f, AiSdkShapedTextResult as g, AiSdkShapedStreamResult as h, AgentModelMap as i, parseStructuredEnvelope as j, parseModelRef as k, AgentRequestExecutorResult as l, AgentUserInput as m, AgentExecutorTextRequest as n, AgentTruncatedError as nt, AgentOutputMode as o, AgentUsage as p, AgentEventToolNameResolver as q, AgentFinishReason as r, AgentRequestExecutor as s, AgentCallUsage as t, AgentError as tt, AgentRequestExecutors as u, StructuredOutputEnvelope as v, buildEnvelopeSchema as w, TextLogicExecuteArgs as x, TextLogic as y, DecisionLogic as z };