@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,6 +1,238 @@
1
- import { t as AgentError } from "./errors-CeSXQx0v.mjs";
2
1
  import { createAsyncLogic, getNextTransitions } from "xstate";
2
+ //#region src/errors.ts
3
+ /**
4
+ * Base class for every error this package throws. Carries a stable, kebab-case
5
+ * `code` so hosts can branch on the failure without `instanceof` (useful across
6
+ * bundle/realm boundaries and after serialization).
7
+ *
8
+ * @example
9
+ * ```ts
10
+ * catch (error) {
11
+ * if (error instanceof AgentError && error.code === 'agent-idle') { ... }
12
+ * }
13
+ * ```
14
+ */
15
+ var AgentError = class extends Error {
16
+ code;
17
+ constructor(code, message, options) {
18
+ super(message, options);
19
+ this.name = "AgentError";
20
+ this.code = code;
21
+ }
22
+ };
23
+ /**
24
+ * A model call ran out of output tokens before it produced anything usable.
25
+ * Core never throws this: it is the adapter's signal that a `'length'` finish
26
+ * reason left nothing to return — a structured request whose envelope never
27
+ * closed, say. A text request that WAS cut off still returns its text, with
28
+ * `finishReason: 'length'`.
29
+ *
30
+ * The code is `'truncated'`, so an invoke's `onError` can branch on it without
31
+ * `instanceof`:
32
+ *
33
+ * @example
34
+ * ```ts
35
+ * onError: [
36
+ * { guard: ({ event }) => event.error.code === 'truncated', target: 'retryShorter' },
37
+ * { target: 'failed' },
38
+ * ]
39
+ * ```
40
+ */
41
+ var AgentTruncatedError = class extends AgentError {
42
+ /** The request that was cut off — `AgentTextRequest.name`. */
43
+ requestName;
44
+ /** The durable invoke id of the request, when the host knows it. */
45
+ requestId;
46
+ /** Whatever the model did produce before it hit the limit, if anything. */
47
+ partialOutput;
48
+ constructor(message, options) {
49
+ super("truncated", message, { cause: options.cause });
50
+ this.name = "AgentTruncatedError";
51
+ this.requestName = options.requestName;
52
+ if (options.requestId !== void 0) this.requestId = options.requestId;
53
+ if (options.partialOutput !== void 0) this.partialOutput = options.partialOutput;
54
+ }
55
+ };
56
+ //#endregion
57
+ //#region src/messages.ts
58
+ /** Ordinary machine event emitted after a request returns framework-native messages. */
59
+ const AGENT_MESSAGES_EVENT_TYPE = "agent.messages";
60
+ /** Runtime schema for the framework-neutral `agent.messages` envelope. */
61
+ const agentMessagesEventSchema = { "~standard": {
62
+ version: 1,
63
+ vendor: "statelyai-agent",
64
+ validate(value) {
65
+ if (!value || typeof value !== "object") return { issues: [{ message: "Expected an 'agent.messages' payload object" }] };
66
+ const event = value;
67
+ const issues = [];
68
+ if (typeof event.request !== "string") issues.push({
69
+ message: "Expected a string",
70
+ path: ["request"]
71
+ });
72
+ if (typeof event.actorId !== "string") issues.push({
73
+ message: "Expected a string",
74
+ path: ["actorId"]
75
+ });
76
+ if (!Array.isArray(event.messages)) issues.push({
77
+ message: "Expected an array",
78
+ path: ["messages"]
79
+ });
80
+ return issues.length > 0 ? { issues } : { value: event };
81
+ }
82
+ } };
83
+ function appendMessages(options) {
84
+ const key = options?.key ?? "messages";
85
+ return (({ context, event }) => {
86
+ const current = context[key];
87
+ const messages = event.messages;
88
+ return { context: { [key]: [...Array.isArray(current) ? current : [], ...messages ?? []] } };
89
+ });
90
+ }
91
+ const KNOWN_PART_TYPES = new Set([
92
+ "text",
93
+ "image",
94
+ "file",
95
+ "tool-call",
96
+ "tool-result"
97
+ ]);
98
+ const USER_PART_TYPES = new Set([
99
+ "text",
100
+ "image",
101
+ "file"
102
+ ]);
103
+ const ASSISTANT_PART_TYPES = new Set([
104
+ "text",
105
+ "file",
106
+ "tool-call",
107
+ "tool-result"
108
+ ]);
109
+ const TOOL_PART_TYPES = new Set(["tool-result"]);
110
+ const TOOL_RESULT_CONTENT_PART_TYPES = new Set(["text", "image"]);
111
+ function isKnownPart(part) {
112
+ const type = part && typeof part === "object" ? part.type : void 0;
113
+ return typeof type === "string" && KNOWN_PART_TYPES.has(type);
114
+ }
115
+ function requireString(part, type, field) {
116
+ return typeof part[field] === "string" ? void 0 : `${type} part requires a string "${field}"`;
117
+ }
118
+ function isMediaData(value) {
119
+ return typeof value === "string" || value instanceof Uint8Array || value instanceof ArrayBuffer || value instanceof URL;
120
+ }
121
+ function requireMediaData(part, type, field) {
122
+ return isMediaData(part[field]) ? void 0 : `${type} part requires "${field}" to be a string, Uint8Array, ArrayBuffer, or URL`;
123
+ }
124
+ const TOOL_RESULT_OUTPUT_TYPES = new Set([
125
+ "text",
126
+ "json",
127
+ "error-text",
128
+ "error-json",
129
+ "content"
130
+ ]);
131
+ function validateToolResultOutput(output) {
132
+ if (!output || typeof output !== "object" || Array.isArray(output)) return "tool-result part requires an \"output\" object";
133
+ const record = output;
134
+ const outputType = record.type;
135
+ if (typeof outputType !== "string" || !TOOL_RESULT_OUTPUT_TYPES.has(outputType)) return `Unknown tool-result output type: ${JSON.stringify(outputType)}`;
136
+ if (outputType === "text" || outputType === "error-text") {
137
+ if (typeof record.value !== "string") return `tool-result output of type "${outputType}" requires a string "value"`;
138
+ return;
139
+ }
140
+ if (outputType === "content") {
141
+ if (!Array.isArray(record.value)) return "tool-result output of type \"content\" requires an array \"value\"";
142
+ for (const contentPart of record.value) {
143
+ const error = validatePart(contentPart, TOOL_RESULT_CONTENT_PART_TYPES, "tool-result output content");
144
+ if (error) return error;
145
+ }
146
+ return;
147
+ }
148
+ return record.value !== void 0 ? void 0 : `tool-result output of type "${outputType}" requires a "value"`;
149
+ }
150
+ function validatePart(part, allowedTypes, location) {
151
+ if (!isKnownPart(part)) {
152
+ const type = part && typeof part === "object" ? part.type : void 0;
153
+ return `Unknown message part type: ${JSON.stringify(type)}`;
154
+ }
155
+ if (!allowedTypes.has(part.type)) return `${location} does not allow "${part.type}" parts`;
156
+ const record = part;
157
+ switch (record.type) {
158
+ case "text": return requireString(record, "text", "text");
159
+ case "image": return requireMediaData(record, "image", "image");
160
+ case "file": return requireMediaData(record, "file", "data") ?? requireString(record, "file", "mediaType");
161
+ case "tool-call": return requireString(record, "tool-call", "toolCallId") ?? requireString(record, "tool-call", "toolName") ?? ("input" in record ? void 0 : "tool-call part requires an \"input\" value");
162
+ case "tool-result": return requireString(record, "tool-result", "toolCallId") ?? requireString(record, "tool-result", "toolName") ?? validateToolResultOutput(record.output);
163
+ default: return;
164
+ }
165
+ }
166
+ function validatePartsArray(content, allowedTypes, location) {
167
+ if (!Array.isArray(content)) return "Expected content to be a string or an array of parts";
168
+ for (const part of content) {
169
+ const error = validatePart(part, allowedTypes, location);
170
+ if (error) return error;
171
+ }
172
+ }
173
+ /**
174
+ * A {@link StandardSchemaV1} validating an `AgentMessage[]` context field —
175
+ * checks that every message has a known `role` (`system`/`user`/`assistant`/
176
+ * `tool`) and that `content` is either a string (where the role allows it) or
177
+ * an array of role-appropriate parts whose required fields and media payloads
178
+ * have the right runtime types (extra fields are allowed). Use it directly as
179
+ * a context schema's `messages` field when authoring with `createAgentSchemas`
180
+ * or `fromConfig`. A zod object cannot nest a Standard Schema, so in a zod
181
+ * context schema write `z.custom<AgentMessage[]>(isAgentMessages)`, which runs
182
+ * this same validator (see {@link isAgentMessages}).
183
+ */
184
+ const messagesSchema = { "~standard": {
185
+ version: 1,
186
+ vendor: "statelyai-agent",
187
+ validate(value) {
188
+ if (!Array.isArray(value)) return { issues: [{ message: "Expected an array of agent messages" }] };
189
+ for (const message of value) {
190
+ if (!message || typeof message !== "object") return { issues: [{ message: "Expected an array of agent messages" }] };
191
+ const role = message.role;
192
+ const content = message.content;
193
+ if (role !== "system" && role !== "user" && role !== "assistant" && role !== "tool") return { issues: [{ message: `Unknown message role: ${JSON.stringify(role)}` }] };
194
+ if (role === "system") {
195
+ if (typeof content !== "string") return { issues: [{ message: "system message content must be a string" }] };
196
+ continue;
197
+ }
198
+ if (role === "tool") {
199
+ const error = validatePartsArray(content, TOOL_PART_TYPES, "tool message content");
200
+ if (error) return { issues: [{ message: error }] };
201
+ continue;
202
+ }
203
+ if (typeof content === "string") continue;
204
+ const error = validatePartsArray(content, role === "user" ? USER_PART_TYPES : ASSISTANT_PART_TYPES, `${role} message content`);
205
+ if (error) return { issues: [{ message: error }] };
206
+ }
207
+ return { value };
208
+ }
209
+ } };
210
+ /**
211
+ * Type guard over {@link messagesSchema}: `true` when `value` is a valid
212
+ * `AgentMessage[]`. The one-liner for zod context schemas:
213
+ * `messages: z.custom<AgentMessage[]>(isAgentMessages)`.
214
+ */
215
+ function isAgentMessages(value) {
216
+ const result = messagesSchema["~standard"].validate(value);
217
+ return !(result instanceof Promise) && !("issues" in result && result.issues);
218
+ }
219
+ //#endregion
3
220
  //#region src/utils.ts
221
+ /** Returns the human-readable text carried by a message, ignoring non-text parts. */
222
+ function getMessageText(message) {
223
+ if (typeof message.content === "string") return message.content;
224
+ const text = [];
225
+ for (const part of message.content) {
226
+ if (part.type === "text") {
227
+ text.push(part.text);
228
+ continue;
229
+ }
230
+ if (part.type !== "tool-result") continue;
231
+ if (part.output.type === "text" || part.output.type === "error-text") text.push(part.output.value);
232
+ else if (part.output.type === "content") text.push(...part.output.value.flatMap((item) => item.type === "text" ? [item.text] : []));
233
+ }
234
+ return text.join("\n");
235
+ }
4
236
  /**
5
237
  * Walks a context value and returns the dot-paths of the first few values that
6
238
  * would NOT survive a JSON persist/resume round-trip (persist with XState's
@@ -68,8 +300,7 @@ function getMachineStructuralHash(machine) {
68
300
  * The version a machine is stamped with everywhere: an explicitly declared
69
301
  * `createMachine({ version })` when present, else its
70
302
  * {@link getMachineStructuralHash}. Single source of truth so `runAgent`,
71
- * `provideExecutors`/`traceTransitions` trace envelopes, and the event-log
72
- * helpers (`initEntry`, `createReplayEntry`, `replay`) never disagree.
303
+ * `provideExecutors`/`traceTransitions` trace envelopes agree.
73
304
  * @internal
74
305
  */
75
306
  function resolveMachineVersion(machine) {
@@ -174,21 +405,37 @@ function getStateMeta(snapshot) {
174
405
  return Object.assign({}, ...entries.map(([, meta]) => meta));
175
406
  }
176
407
  /**
177
- * Reads the run-owned message log off a snapshot settled by a `runAgent` call
178
- * that used `getRequests` (or `options.messages`) — the typed replacement for
179
- * the `(snapshot as { messages?: AgentMessage[] }).messages` cast. runAgent
180
- * stamps the log as a plain enumerable `messages` property (like `agentMeta`),
181
- * so it survives a JSON persist/resume round-trip; this accessor works on the
182
- * live settled snapshot and on a JSON-parsed persisted one alike. Returns `[]`
183
- * when no log was stamped (e.g. a default invoke-driven run).
408
+ * Renders a snapshot's state value as one deterministic string, so a log line,
409
+ * a progress field, or a test assertion reads the same on every run.
184
410
  *
185
- * The write path is `runAgent(..., { messages })`: an explicit seed that
186
- * overrides the resume snapshot's stamped log (fold in a user reply on
187
- * resume, or start a run with prior history).
411
+ * - An atomic state is its own name: `'writing'`.
412
+ * - A nested state joins with dots: `{ review: { editing: 'draft' } }` →
413
+ * `'review.editing.draft'`.
414
+ * - A parallel state brackets its regions, sorted by region name, so key order
415
+ * never leaks into the string: `{ p: { left: 'x', right: { a: 'b' } } }` →
416
+ * `'p:{left.x,right.a.b}'`.
417
+ *
418
+ * Prefer this over `String(snapshot.value)`, which renders every non-atomic
419
+ * value as `[object Object]`.
420
+ *
421
+ * @example
422
+ * ```ts
423
+ * onTransition: (snapshot) => console.log(getStatePath(snapshot));
424
+ * ```
188
425
  */
189
- function getAgentMessages(snapshot) {
190
- const stamped = snapshot?.messages;
191
- return Array.isArray(stamped) ? stamped : [];
426
+ function getStatePath(snapshot) {
427
+ return serializeStateValue(typeof snapshot === "object" && snapshot !== null && "value" in snapshot && ("status" in snapshot || typeof snapshot.matches === "function") ? snapshot.value : snapshot);
428
+ }
429
+ function serializeStateValue(value) {
430
+ if (typeof value === "string") return value;
431
+ const entries = Object.entries(value).map(([key, child]) => {
432
+ const rendered = serializeStateValue(child);
433
+ if (!rendered) return [key, key];
434
+ return [key, `${key}${rendered.startsWith("{") ? ":" : "."}${rendered}`];
435
+ }).sort(([a], [b]) => a < b ? -1 : a > b ? 1 : 0);
436
+ if (entries.length === 0) return "";
437
+ if (entries.length === 1) return entries[0][1];
438
+ return `{${entries.map(([, rendered]) => rendered).join(",")}}`;
192
439
  }
193
440
  /**
194
441
  * Structural guard for a {@link StandardSchemaV1}: `true` when `value` carries
@@ -239,7 +486,42 @@ function validateSchemaSync(schema, value) {
239
486
  }
240
487
  //#endregion
241
488
  //#region src/internal/registry.ts
489
+ /** Non-enumerable hook an optional adapter can attach to a model registry. */
490
+ const DEFAULT_AGENT_EXECUTORS = Symbol.for("@statelyai/agent.defaultExecutors");
491
+ /**
492
+ * Registered execution options, keyed on BOTH the machine object and its root
493
+ * `config` object. `config` is shared by reference across `machine.provide(...)`
494
+ * (unlike the machine itself), so the `config` key is what lets a machine
495
+ * rebound by `runAgent` — or by any host `.provide(...)` — still resolve the
496
+ * schemas/actors `setupAgent` registered. Always write through
497
+ * {@link setAgentExecutionOptions} and read through
498
+ * {@link getAgentExecutionOptions}.
499
+ */
242
500
  const agentExecutionOptions = /* @__PURE__ */ new WeakMap();
501
+ /** The root `config` object a machine shares with every `.provide(...)` of itself. */
502
+ function machineConfigKey(machine) {
503
+ const config = machine?.config;
504
+ return config && typeof config === "object" ? config : void 0;
505
+ }
506
+ /** Registers `options` for `machine` and for every `.provide(...)` of it. */
507
+ function setAgentExecutionOptions(machine, options) {
508
+ if (!machine || typeof machine !== "object") return;
509
+ agentExecutionOptions.set(machine, options);
510
+ const config = machineConfigKey(machine);
511
+ if (config) agentExecutionOptions.set(config, options);
512
+ }
513
+ /**
514
+ * Reads the options registered for `machine`, falling back to the root `config`
515
+ * key so a `.provide(...)`-rebound machine (e.g. the one behind a `runAgent`
516
+ * result snapshot) resolves the same pack.
517
+ */
518
+ function getAgentExecutionOptions(machine) {
519
+ if (!machine || typeof machine !== "object") return void 0;
520
+ const direct = agentExecutionOptions.get(machine);
521
+ if (direct) return direct;
522
+ const config = machineConfigKey(machine);
523
+ return config ? agentExecutionOptions.get(config) : void 0;
524
+ }
243
525
  /**
244
526
  * Machine-carried wait-state predicates, keyed on the machine's root `config`
245
527
  * object. `config` is shared by reference across `machine.provide(...)` (unlike
@@ -247,8 +529,7 @@ const agentExecutionOptions = /* @__PURE__ */ new WeakMap();
247
529
  * machine through `.provide` — which is why it is keyed on `config`, not the
248
530
  * machine. Set by `setupAgent({ isIdle })` in `createMachine` and by
249
531
  * `setupAgent.fromConfig` (its `isIdle` option or the config's
250
- * `idleTags`), read by `runAgent` (below the host `options.isIdle`
251
- * override, above the timing heuristic).
532
+ * `idleTags`), read by `runAgent` before its structural default.
252
533
  */
253
534
  const machineIdlePredicates = /* @__PURE__ */ new WeakMap();
254
535
  /** Reads the {@link machineIdlePredicates} predicate carried by `machine` (via its root `config`), if any. */
@@ -256,24 +537,6 @@ function getMachineIdlePredicate(machine) {
256
537
  const config = machine.config;
257
538
  return config ? machineIdlePredicates.get(config) : void 0;
258
539
  }
259
- /**
260
- * Lint-reachability sidecar for `fromConfig` machines.
261
- *
262
- * Static transition targets declared by the source config of a
263
- * `setupAgent.fromConfig` machine, as `dotted state path → declared target
264
- * strings` (every `on`/`always`/`after`/`onDone`/`choice` target plus each
265
- * invoke's `onDone`/`onError`). The JSON layer folds a transition that carries a
266
- * context patch into an opaque resolver function, erasing its target from
267
- * `machine.config` — so `lintAgentMachine`'s reachability walk reads the
268
- * targets from here instead. Keyed on the machine's root `config` object (like
269
- * {@link machineIdlePredicates}) so it survives `machine.provide(...)`.
270
- */
271
- const machineStaticTransitionTargets = /* @__PURE__ */ new WeakMap();
272
- /** Reads the {@link machineStaticTransitionTargets} map carried by `machine` (via its root `config`), if any. */
273
- function getMachineStaticTransitionTargets(machine) {
274
- const config = machine.config;
275
- return config ? machineStaticTransitionTargets.get(config) : void 0;
276
- }
277
540
  const unboundPlaceholderLogics = /* @__PURE__ */ new WeakSet();
278
541
  /** Text/decision logics created WITH their own executor (withExecutor or the
279
542
  * factory's second arg) — these are runnable as-is, so runAgent's bind check
@@ -291,7 +554,7 @@ function isUnboundPlaceholder(logic) {
291
554
  }
292
555
  function getRegisteredAgentExecutionOptions(machine, options) {
293
556
  return {
294
- ...agentExecutionOptions.get(machine),
557
+ ...getAgentExecutionOptions(machine),
295
558
  ...options
296
559
  };
297
560
  }
@@ -301,8 +564,6 @@ const USER_INPUT_ACTOR = "agent.userInput";
301
564
  const GENERATE_TEXT_ACTOR = "agent.generateText";
302
565
  const STREAM_TEXT_ACTOR = "agent.streamText";
303
566
  const DECIDE_ACTOR = "agent.decide";
304
- /** Synthetic `src` stamped on trace requests produced by `getRequests` state interpretation — NOT a registered actor source (nothing is invoked; the pass makes the call directly). */
305
- const INTERPRET_SOURCE = "agent.interpret";
306
567
  /**
307
568
  * Splits a portable `"provider/model-id"` model ref (the convention JSON
308
569
  * workflows and registry-less hosts use, e.g. `"openai/gpt-5.4-mini"`) into
@@ -324,6 +585,27 @@ function parseModelRef(modelRef) {
324
585
  modelId: modelRef.slice(slash + 1)
325
586
  };
326
587
  }
588
+ const AGENT_FINISH_REASONS = new Set([
589
+ "stop",
590
+ "length",
591
+ "tool-calls",
592
+ "content-filter",
593
+ "other"
594
+ ]);
595
+ /**
596
+ * Reads a settled call's {@link AgentFinishReason} off a RAW executor result's
597
+ * `finishReason` field — the finish-reason sibling of {@link getCallUsage},
598
+ * applied by `runAgent` before it puts the reason on the `request.end` trace.
599
+ * A provider's `'error'` normalizes to `'other'`; anything else the union does
600
+ * not name (an un-normalized provider string, a missing field) returns
601
+ * `undefined`.
602
+ */
603
+ function getCallFinishReason(raw) {
604
+ const value = raw?.finishReason;
605
+ if (typeof value !== "string") return;
606
+ if (value === "error") return "other";
607
+ return AGENT_FINISH_REASONS.has(value) ? value : void 0;
608
+ }
327
609
  /** The token fields {@link AgentUsage} aggregates. @internal */
328
610
  const AGENT_USAGE_TOKEN_FIELDS = [
329
611
  "inputTokens",
@@ -362,6 +644,13 @@ function getCallUsage(raw) {
362
644
  }
363
645
  return out;
364
646
  }
647
+ function textRequestSourceIssue(request) {
648
+ const hasPrompt = typeof request.prompt === "string" && request.prompt.length > 0;
649
+ const hasMessages = Array.isArray(request.messages) && request.messages.length > 0;
650
+ const label = request.name ? ` '${request.name}'` : "";
651
+ if (hasPrompt && hasMessages) return `Agent text request${label} has both a non-empty \`prompt\` and \`messages\` — provide exactly one so the model has a single input source.`;
652
+ if (!hasPrompt && !hasMessages) return `Agent text request${label} has neither a non-empty \`prompt\` nor \`messages\` — provide at least one so the model has something to respond to.`;
653
+ }
365
654
  const agentTextInputSchema = { "~standard": {
366
655
  version: 1,
367
656
  vendor: "statelyai-agent",
@@ -369,9 +658,8 @@ const agentTextInputSchema = { "~standard": {
369
658
  if (!value || typeof value !== "object") return { issues: [{ message: "Expected agent text input object" }] };
370
659
  const request = value;
371
660
  if (typeof request.model !== "string") return { issues: [{ message: "Expected agent text input with a string `model`" }] };
372
- const hasPrompt = typeof request.prompt === "string" && request.prompt.length > 0;
373
- const hasMessages = Array.isArray(request.messages) && request.messages.length > 0;
374
- if (!hasPrompt && !hasMessages) return { issues: [{ message: `Agent text request${request.name ? ` '${request.name}'` : ""} has neither a non-empty \`prompt\` nor \`messages\` — provide at least one so the model has something to respond to.` }] };
661
+ const issue = textRequestSourceIssue(request);
662
+ if (issue) return { issues: [{ message: issue }] };
375
663
  return { value: request };
376
664
  }
377
665
  } };
@@ -485,13 +773,24 @@ function createTextLogic(config, execute) {
485
773
  output: config.schemas?.output ?? stringOutputSchema
486
774
  };
487
775
  const request = (input) => {
488
- const args = { input: validateSchemaSync(schemas.input, input) };
776
+ const parsedInput = validateSchemaSync(schemas.input, input);
777
+ const args = { input: parsedInput };
778
+ const name = resolveTextLogicValue(config.name, args);
779
+ const prompt = resolveTextLogicValue(config.prompt, args);
780
+ const messages = resolveTextLogicValue(config.messages, args);
781
+ const sourceIssue = textRequestSourceIssue({
782
+ name,
783
+ prompt,
784
+ messages
785
+ });
786
+ if (sourceIssue) throw new Error(sourceIssue);
489
787
  return {
490
- name: resolveTextLogicValue(config.name, args),
788
+ name,
789
+ input: parsedInput,
491
790
  model: resolveTextLogicValue(config.model, args),
492
791
  system: resolveTextLogicValue(config.system, args),
493
- prompt: resolveTextLogicValue(config.prompt, args),
494
- messages: resolveTextLogicValue(config.messages, args),
792
+ prompt,
793
+ messages,
495
794
  tools: resolveTextLogicValue(config.tools, args),
496
795
  toolChoice: resolveTextLogicValue(config.toolChoice, args),
497
796
  outputSchema: schemas.output,
@@ -508,7 +807,7 @@ function createTextLogic(config, execute) {
508
807
  };
509
808
  const logic = createAsyncLogic({ run: async ({ input, signal, system, self }, enq) => {
510
809
  const resolvedRequest = request(input);
511
- if (!execute) throw new Error("Text logic has no host execution. Pass an executor as the second argument to createTextLogic(...), provide a runtime adapter, or extract it with getAgentEffects(..., { actors }).");
810
+ if (!execute) throw new Error("Text logic has no host execution. Pass an executor as the second argument to createTextLogic(...), provide a runtime adapter, or bind it through runAgent/provideExecutors, or execute the XState effect in your host.");
512
811
  const result = await execute({
513
812
  input,
514
813
  request: resolvedRequest,
@@ -657,11 +956,14 @@ function parseStructuredEnvelope(request, value) {
657
956
  async function executeAgentTextRequest(mode, id, input, executors, tools = {}, info) {
658
957
  const request = {
659
958
  ...input,
959
+ name: input.name ?? id,
660
960
  tools: {
661
961
  ...input.tools,
662
962
  ...tools
663
963
  }
664
964
  };
965
+ const sourceIssue = textRequestSourceIssue(request);
966
+ if (sourceIssue) throw new Error(sourceIssue);
665
967
  const executor = mode === "stream" ? executors.streamText : executors.generateText;
666
968
  if (!executor) throw new Error(`No executor provided for ${mode === "stream" ? "stream" : "generate"} request '${id}'.`);
667
969
  const raw = await executor(request, info);
@@ -731,7 +1033,31 @@ function invalidGeneratorResult(id) {
731
1033
  return /* @__PURE__ */ new Error(`Executor for '${id}' returned an invalid result: executors must return { output } (an envelope with the text string or structured object as \`output\`, plus optional passthrough fields). Raw Vercel AI SDK generateText/streamText results ({ text } or { textStream }) are also accepted.`);
732
1034
  }
733
1035
  //#endregion
1036
+ //#region src/internal/is-record.ts
1037
+ /** True for a plain object-like value (arrays excluded). @internal */
1038
+ function isRecord(value) {
1039
+ return typeof value === "object" && value !== null && !Array.isArray(value);
1040
+ }
1041
+ //#endregion
734
1042
  //#region src/events.ts
1043
+ /**
1044
+ * Thrown by {@link parseAgentEvent} (and {@link eventFromInteraction}) when a
1045
+ * wire payload is not a usable event: it is not an object with a string
1046
+ * `type`, it names a reserved `@agent.*` type, or its fields fail the schema
1047
+ * the machine registered for that type. A host turns it into a 400.
1048
+ *
1049
+ * Not handling an event is NOT this error — a state machine ignores events it
1050
+ * has no transition for, so an event the current state does not handle parses
1051
+ * fine and settles the run with `result.ignored` set.
1052
+ */
1053
+ var AgentInvalidEventPayloadError = class extends AgentError {
1054
+ eventType;
1055
+ constructor(eventType, detail) {
1056
+ super("invalid-event-payload", `Invalid event payload for '${eventType}': ${detail}`);
1057
+ this.name = "AgentInvalidEventPayloadError";
1058
+ this.eventType = eventType;
1059
+ }
1060
+ };
735
1061
  /** Default prefix for the synthetic tool name generated per candidate event (e.g. `send_event_ASK`). Override per-request with {@link AgentEventToolNameResolver}. @internal */
736
1062
  const EVENT_TOOL_PREFIX = "send_event_";
737
1063
  function hashString(value) {
@@ -768,58 +1094,61 @@ function matchesEventPattern(eventType, pattern) {
768
1094
  return eventType === pattern;
769
1095
  }
770
1096
  /**
771
- * The namespace reserved for events the library itself delivers to a machine
772
- * (`@agent.init`, `@agent.usage`). A machine may declare transitions on them,
1097
+ * Event types reserved for delivery by the library (`@agent.*` and
1098
+ * `agent.messages`). A machine may declare transitions on them,
773
1099
  * but they are never model-facing: {@link getAcceptedEvents} drops them before
774
1100
  * any `allowedEvents` matching, so they cannot be offered as a decision
775
1101
  * candidate (not even under a `'*'` wildcard) and {@link parseAgentEvent}
776
1102
  * rejects them — a model or a wire message must not be able to forge one.
777
- * Matched as a prefix rather than a list so this module stays free of an import
778
- * cycle back to `effects.ts`, where the constants live.
779
1103
  * @internal
780
1104
  */
781
1105
  const RESERVED_AGENT_EVENT_PREFIX = "@agent.";
1106
+ function isReservedAgentEvent(eventType) {
1107
+ return eventType.startsWith(RESERVED_AGENT_EVENT_PREFIX) || eventType === "agent.messages";
1108
+ }
782
1109
  /** True when an `allowedEvents` entry is a wildcard pattern rather than a concrete event type. @internal */
783
1110
  function isEventPattern(entry) {
784
1111
  return entry === "*" || entry.endsWith(".*");
785
1112
  }
786
1113
  /**
787
- * Runtime-validates a dynamically-built `{ type, ...payload }` event against a
788
- * snapshot's currently-accepted events (via {@link getAcceptedEvents}) and,
789
- * when one is registered, the event type's payload schema — returning the
790
- * event typed as the machine's event union (recovered from the snapshot type)
791
- * so it can be sent to `runAgent({ event })` / `actor.send(...)` without an
792
- * `as never` cast. For generic, meta-driven hosts that assemble events from
793
- * user input or a wire message.
1114
+ * Parses a wire payload (a request body, a socket frame) into an
1115
+ * event typed as the machine's event union, so it can go straight to
1116
+ * `runAgent({ event })` / `actor.send(...)` without a cast. Pass the machine
1117
+ * itself, or any snapshot of it.
1118
+ *
1119
+ * It checks exactly what a schema can check: the payload is an object with a
1120
+ * string `type`, that type is not one of the library-reserved `@agent.*` types,
1121
+ * and — when the machine registered a schema for it — the fields satisfy that
1122
+ * schema (defaults filled, transforms applied). Anything else throws
1123
+ * {@link AgentInvalidEventPayloadError}, which a host answers with a 400.
794
1124
  *
795
- * Throws a descriptive error when `event.type` is not currently accepted
796
- * (listing the accepted types) or when its payload fails the registered schema.
797
- * Pass event payload schemas via `options.events`/`options.schemas` (the same
798
- * shape {@link getAcceptedEvents} takes) — the accepted TYPES always come from
799
- * the live snapshot; the schemas only add payload validation.
1125
+ * It deliberately does NOT check whether the current state handles the event.
1126
+ * State machines ignore events they have no transition for; that is normal
1127
+ * behavior, not a validation failure. Send the parsed event and read
1128
+ * `result.ignored` if the host wants to tell the client nothing happened.
800
1129
  *
801
1130
  * @example
802
1131
  * ```ts
803
- * const event = parseAgentEvent(result.snapshot, rawEvent, { events: schemas.events });
804
- * result = await runAgent(machine, { snapshot: result.snapshot, event, executors });
1132
+ * const event = parseAgentEvent(machine, await request.json());
1133
+ * const result = await runAgent(machine, { store, threadId, event, executors });
805
1134
  * ```
806
1135
  */
807
- function parseAgentEvent(snapshot, event, options = {}) {
808
- const accepted = getAcceptedEvents(snapshot, options);
809
- const descriptor = accepted.find((candidate) => candidate.type === event.type);
810
- if (!descriptor) throw new Error(`parseAgentEvent: '${event.type}' is not an accepted event in the current state. Accepted: ${accepted.map((candidate) => candidate.type).join(", ") || "(none)"}.`);
811
- if (descriptor.inputSchema) {
812
- const { type, ...payload } = event;
813
- try {
814
- return {
815
- ...validateSchemaSync(descriptor.inputSchema, payload),
816
- type
817
- };
818
- } catch (error) {
819
- throw new Error(`parseAgentEvent: '${event.type}' payload failed validation: ${error instanceof Error ? error.message : String(error)}`);
820
- }
1136
+ function parseAgentEvent(source, payload, options = {}) {
1137
+ if (!isRecord(payload) || typeof payload.type !== "string") throw new AgentInvalidEventPayloadError("(unknown)", "expected an object with a string `type`.");
1138
+ const event = payload;
1139
+ if (isReservedAgentEvent(event.type)) throw new AgentInvalidEventPayloadError(event.type, "this event type is reserved for the library and cannot be sent from outside.");
1140
+ const registered = getAgentExecutionOptions(typeof source.provide === "function" ? source : source.machine)?.schemas;
1141
+ const inputSchema = (options.events ?? options.schemas?.events ?? registered?.events)?.[event.type];
1142
+ if (!inputSchema) return event;
1143
+ const { type, ...fields } = event;
1144
+ try {
1145
+ return {
1146
+ ...validateSchemaSync(inputSchema, fields),
1147
+ type
1148
+ };
1149
+ } catch (error) {
1150
+ throw new AgentInvalidEventPayloadError(event.type, error instanceof Error ? error.message : String(error));
821
1151
  }
822
- return event;
823
1152
  }
824
1153
  /**
825
1154
  * Lists the events a snapshot can currently accept, as {@link AgentEventDescriptor}s
@@ -843,7 +1172,7 @@ function getAcceptedEvents(snapshot, options = {}) {
843
1172
  const usedToolNames = /* @__PURE__ */ new Set();
844
1173
  return getNextTransitions(snapshot).flatMap((transitionDefinition) => {
845
1174
  const eventType = transitionDefinition.eventType;
846
- if (!eventType || eventType === "*" || eventType.startsWith("xstate.") || eventType.startsWith(RESERVED_AGENT_EVENT_PREFIX) || eventTypes && !eventTypes.some((pattern) => matchesEventPattern(eventType, pattern)) || seen.has(eventType)) return [];
1175
+ if (!eventType || eventType === "*" || eventType.startsWith("xstate.") || isReservedAgentEvent(eventType) || eventTypes && !eventTypes.some((pattern) => matchesEventPattern(eventType, pattern)) || seen.has(eventType)) return [];
847
1176
  seen.add(eventType);
848
1177
  const defaultToolName = sanitizeEventToolName(eventType);
849
1178
  const toolName = options.eventToolName ? options.eventToolName({
@@ -865,6 +1194,8 @@ function decideRequestFromInput(input) {
865
1194
  return {
866
1195
  kind: "decision",
867
1196
  id: "",
1197
+ name: input.name,
1198
+ input,
868
1199
  model: input.model,
869
1200
  system: input.system,
870
1201
  prompt: input.prompt,
@@ -910,11 +1241,138 @@ function resolveAllowedEventTypes(allowedEvents, input) {
910
1241
  const resolved = typeof allowedEvents === "function" ? allowedEvents({ input }) : allowedEvents;
911
1242
  return typeof resolved === "string" ? [resolved] : resolved;
912
1243
  }
1244
+ /**
1245
+ * Creates reusable, standalone {@link DecisionLogic}: an actor that, when
1246
+ * run, resolves to exactly one currently-legal {@link ChosenEvent} by
1247
+ * calling the host `decide` executor (passed here as `execute`, or supplied
1248
+ * later via {@link DecisionLogic.withExecutor}, `machine.provide(...)`, or
1249
+ * `runAgent`'s `decide` option). Register the result under `actors:` and
1250
+ * invoke it by name; for a one-off, state-local decision, prefer the
1251
+ * `agent.decide` builtin invoke instead — it needs no separate declaration
1252
+ * and types `allowedEvents` against the machine's own event schemas.
1253
+ *
1254
+ * @example
1255
+ * ```ts
1256
+ * import { createDecisionLogic } from '@statelyai/agent';
1257
+ * import { z } from 'zod';
1258
+ *
1259
+ * export const chooseMove = createDecisionLogic({
1260
+ * schemas: { input: z.object({ playerHp: z.number(), enemyHp: z.number() }) },
1261
+ * model: 'openai/gpt-5.4-mini',
1262
+ * system: 'You are playing a turn-based game. Choose exactly one legal move.',
1263
+ * prompt: ({ input }) => `Player HP: ${input.playerHp}\nEnemy HP: ${input.enemyHp}`,
1264
+ * allowedEvents: ({ input }) =>
1265
+ * input.playerHp <= 6
1266
+ * ? ['ATTACK', 'DEFEND', 'HEAL', 'FLEE']
1267
+ * : ['ATTACK', 'DEFEND', 'FLEE'],
1268
+ * });
1269
+ * ```
1270
+ */
1271
+ function createDecisionLogic(config, execute) {
1272
+ const maxRetries = config.maxRetries ?? 2;
1273
+ const request = (input) => {
1274
+ const parsedInput = config.schemas ? validateSchemaSync(config.schemas.input, input) : input;
1275
+ const args = { input: parsedInput };
1276
+ const allowedEventTypes = resolveAllowedEventTypes(config.allowedEvents, parsedInput);
1277
+ return {
1278
+ kind: "decision",
1279
+ id: "",
1280
+ name: resolveTextLogicValue(config.name, args),
1281
+ input: parsedInput,
1282
+ model: resolveTextLogicValue(config.model, args),
1283
+ system: resolveTextLogicValue(config.system, args),
1284
+ prompt: resolveTextLogicValue(config.prompt, args),
1285
+ messages: resolveTextLogicValue(config.messages, args),
1286
+ events: (allowedEventTypes ?? []).map((type) => ({
1287
+ type,
1288
+ toolName: sanitizeEventToolName(type)
1289
+ })),
1290
+ attempts: [],
1291
+ temperature: resolveTextLogicValue(config.temperature, args),
1292
+ maxOutputTokens: resolveTextLogicValue(config.maxOutputTokens, args),
1293
+ topP: resolveTextLogicValue(config.topP, args),
1294
+ topK: resolveTextLogicValue(config.topK, args),
1295
+ seed: resolveTextLogicValue(config.seed, args),
1296
+ stopSequences: resolveTextLogicValue(config.stopSequences, args),
1297
+ metadata: resolveTextLogicValue(config.metadata, args)
1298
+ };
1299
+ };
1300
+ const logic = createAsyncLogic({ run: async ({ input, signal }) => {
1301
+ if (!execute) throw new Error("Decision logic has no host execution. Pass an executor as the second argument to createDecisionLogic(...), provide a runtime adapter, or bind it through runAgent/provideExecutors, or call resolveDecision from your host.");
1302
+ const allowedEventTypes = resolveAllowedEventTypes(config.allowedEvents, input);
1303
+ if (allowedEventTypes === void 0) throw new Error("Decision logic has omitted `allowedEvents`, which means \"all currently-legal events\" — but that requires a snapshot-aware host (runAgent or the step path) to resolve. Under a bare createActor(...), declare `allowedEvents` explicitly on this logic to use it here.");
1304
+ if (allowedEventTypes.some(isEventPattern)) throw new Error("Decision logic uses wildcard `allowedEvents` patterns, which expand against the live snapshot — that requires a snapshot-aware host (runAgent or the step path). Under a bare createActor(...), list event types explicitly.");
1305
+ return resolveDecision(request(input), { decide: execute }, {
1306
+ maxRetries,
1307
+ signal
1308
+ });
1309
+ } });
1310
+ const decisionLogic = Object.assign(logic, {
1311
+ kind: "statelyai.decisionLogic",
1312
+ maxRetries,
1313
+ request,
1314
+ allowedEventTypes: (input) => resolveAllowedEventTypes(config.allowedEvents, input),
1315
+ withExecutor(nextExecute) {
1316
+ return createDecisionLogic(config, nextExecute);
1317
+ }
1318
+ });
1319
+ if (execute) executorBoundLogics.add(decisionLogic);
1320
+ return decisionLogic;
1321
+ }
913
1322
  /** Type guard: true for any actor logic built by createDecisionLogic/createDecideActor (checks the `kind` marker). @internal */
914
1323
  function isDecisionLogic(value) {
915
1324
  return !!value && typeof value === "object" && value.kind === "statelyai.decisionLogic" && typeof value.request === "function";
916
1325
  }
917
1326
  /**
1327
+ * Builds an {@link AgentDecisionRequest} for {@link resolveDecision}, filling
1328
+ * in the fields a hand-written literal has to restate every time: `kind`, an
1329
+ * `id`, an empty `attempts` list, and each candidate event's `toolName`.
1330
+ *
1331
+ * @example
1332
+ * ```ts
1333
+ * const chosen = await resolveDecision(
1334
+ * createDecisionRequest({
1335
+ * name: 'judge',
1336
+ * model: 'reviewer',
1337
+ * prompt: `Judge this draft.\n\n${snapshot.context.draft}`,
1338
+ * events: getAcceptedEvents(snapshot),
1339
+ * }),
1340
+ * { decide },
1341
+ * { canTake: (event) => snapshot.can(event) },
1342
+ * );
1343
+ * ```
1344
+ */
1345
+ function createDecisionRequest(options) {
1346
+ const { id, name, events, attempts, ...rest } = options;
1347
+ return {
1348
+ ...rest,
1349
+ kind: "decision",
1350
+ id: id ?? name ?? "decision",
1351
+ ...name === void 0 ? {} : { name },
1352
+ events: dedupeToolNames(events.map((event) => typeof event === "string" ? {
1353
+ type: event,
1354
+ toolName: sanitizeEventToolName(event)
1355
+ } : event)),
1356
+ attempts: attempts ?? []
1357
+ };
1358
+ }
1359
+ function dedupeToolNames(candidates) {
1360
+ const taken = /* @__PURE__ */ new Set();
1361
+ return candidates.map((candidate) => {
1362
+ if (candidate.toolName === void 0) return candidate;
1363
+ let toolName = candidate.toolName;
1364
+ for (let n = 2; taken.has(toolName); n++) {
1365
+ const suffix = `_${n}`;
1366
+ toolName = `${candidate.toolName.slice(0, 64 - suffix.length)}${suffix}`;
1367
+ }
1368
+ taken.add(toolName);
1369
+ return toolName === candidate.toolName ? candidate : {
1370
+ ...candidate,
1371
+ toolName
1372
+ };
1373
+ });
1374
+ }
1375
+ /**
918
1376
  * Thrown by {@link resolveDecision} when every attempt (up to
919
1377
  * `maxRetries + 1` of them) fails one of the three checks recorded in
920
1378
  * {@link DecisionAttempt.failure}. Carries the full `attempts` list for
@@ -982,8 +1440,8 @@ async function resolveDecision(request, executors, options = {}) {
982
1440
  options.signal?.throwIfAborted();
983
1441
  const result = await executor({
984
1442
  ...request,
985
- attempts: [...attempts],
986
- signal: options.signal
1443
+ name: request.name ?? (request.id || "agent.decide"),
1444
+ attempts: [...attempts]
987
1445
  }, {
988
1446
  ...options.signal !== void 0 ? { signal: options.signal } : {},
989
1447
  ...request.id ? { requestId: request.id } : {}
@@ -1029,4 +1487,4 @@ async function resolveDecision(request, executors, options = {}) {
1029
1487
  throw new AgentDecisionExhaustedError(attempts);
1030
1488
  }
1031
1489
  //#endregion
1032
- export { getMachineStaticTransitionTargets as A, getJsonSchema as B, parseModelRef as C, agentExecutionOptions as D, userInputActor as E, missingActor as F, resolveMachineVersion as G, getMachineStructuralHash as H, assistantMessage as I, userMessage as J, systemMessage as K, djb2Hex as L, isUnboundPlaceholder as M, machineIdlePredicates as N, executorBoundLogics as O, machineStaticTransitionTargets as P, findNonSerializableContextPaths as R, normalizeGeneratorResult as S, parseStructuredEnvelope as T, getStateMeta as U, getJsonSchemaSync as V, isStandardSchema as W, validateSchemaSync as Y, createTextLogic as _, resolveDecision as a, getCallUsage as b, AGENT_USAGE_TOKEN_FIELDS as c, INTERPRET_SOURCE as d, STREAM_TEXT_ACTOR as f, builtinTextActors as g, buildEnvelopeSchema as h, renderDecisionAttempts as i, getRegisteredAgentExecutionOptions as j, getMachineIdlePredicate as k, DECIDE_ACTOR as l, bindRequestExecutor as m, createDecideActor as n, getAcceptedEvents as o, USER_INPUT_ACTOR as p, toolMessage as q, isDecisionLogic as r, parseAgentEvent as s, AgentDecisionExhaustedError as t, GENERATE_TEXT_ACTOR as u, executeAgentTextRequest as v, parseOutput as w, isTextLogic as x, getAgentOutputMode as y, getAgentMessages as z };
1490
+ export { userMessage as $, userInputActor as A, assistantMessage as B, getCallFinishReason as C, parseModelRef as D, normalizeGeneratorResult as E, getRegisteredAgentExecutionOptions as F, getMachineStructuralHash as G, findNonSerializableContextPaths as H, isUnboundPlaceholder as I, getStatePath as J, getMessageText as K, machineIdlePredicates as L, executorBoundLogics as M, getAgentExecutionOptions as N, parseOutput as O, getMachineIdlePredicate as P, toolMessage as Q, missingActor as R, getAgentOutputMode as S, isTextLogic as T, getJsonSchema as U, djb2Hex as V, getJsonSchemaSync as W, resolveMachineVersion as X, isStandardSchema as Y, systemMessage as Z, bindRequestExecutor as _, isDecisionLogic as a, messagesSchema as at, createTextLogic as b, AgentInvalidEventPayloadError as c, isRecord as d, validateSchemaSync as et, AGENT_USAGE_TOKEN_FIELDS as f, USER_INPUT_ACTOR as g, STREAM_TEXT_ACTOR as h, createDecisionRequest as i, isAgentMessages as it, DEFAULT_AGENT_EXECUTORS as j, parseStructuredEnvelope as k, getAcceptedEvents as l, GENERATE_TEXT_ACTOR as m, createDecideActor as n, agentMessagesEventSchema as nt, renderDecisionAttempts as o, AgentError as ot, DECIDE_ACTOR as p, getStateMeta as q, createDecisionLogic as r, appendMessages as rt, resolveDecision as s, AgentTruncatedError as st, AgentDecisionExhaustedError as t, AGENT_MESSAGES_EVENT_TYPE as tt, parseAgentEvent as u, buildEnvelopeSchema as v, getCallUsage as w, executeAgentTextRequest as x, builtinTextActors as y, setAgentExecutionOptions as z };