@statelyai/agent 2.0.0-alpha.28 → 2.0.0-alpha.29

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 (75) hide show
  1. package/dist/ai-sdk.cjs +149 -26
  2. package/dist/ai-sdk.d.cts +57 -34
  3. package/dist/ai-sdk.d.mts +57 -34
  4. package/dist/ai-sdk.mjs +147 -23
  5. package/dist/{decision-RQ0iv0oZ.mjs → decision-Bl_rKQnU.mjs} +73 -7
  6. package/dist/{decision-CmM8-HHz.cjs → decision-oevZnkBe.cjs} +112 -29
  7. package/dist/{text-logic-f5F5sCdc.cjs → event-log-Dtb16p1p.cjs} +813 -6
  8. package/dist/{text-logic-CIqHAmBi.mjs → event-log-GPZO9p7_.mjs} +679 -3
  9. package/dist/{event-log-store-BIPOz-di.d.mts → event-log-store-CN9ygggF.d.cts} +90 -5
  10. package/dist/{event-log-store-2xzFmgr2.d.cts → event-log-store-DS836wch.d.mts} +90 -5
  11. package/dist/event-log-store-bCdskPNS.cjs +95 -0
  12. package/dist/event-log-store-yalq8C77.mjs +84 -0
  13. package/dist/index.cjs +571 -58
  14. package/dist/index.d.cts +104 -510
  15. package/dist/index.d.mts +104 -510
  16. package/dist/index.mjs +542 -32
  17. package/dist/log.cjs +77 -20
  18. package/dist/log.d.cts +5 -5
  19. package/dist/log.d.mts +5 -5
  20. package/dist/log.mjs +58 -3
  21. package/dist/machines.cjs +1 -1
  22. package/dist/machines.d.cts +15 -15
  23. package/dist/machines.d.mts +15 -15
  24. package/dist/machines.mjs +1 -1
  25. package/dist/model-source-C7FFP2Sj.mjs +39 -0
  26. package/dist/model-source-DjJPjGSP.cjs +44 -0
  27. package/dist/openai.cjs +10 -10
  28. package/dist/openai.d.cts +27 -25
  29. package/dist/openai.d.mts +27 -25
  30. package/dist/openai.mjs +2 -2
  31. package/dist/otel.cjs +5 -4
  32. package/dist/otel.d.cts +5 -7
  33. package/dist/otel.d.mts +5 -7
  34. package/dist/otel.mjs +5 -3
  35. package/dist/{run-agent-COXXc0RW.d.mts → run-agent-C9ubX8Tx.d.cts} +87 -30
  36. package/dist/{run-agent-xNTxpt82.mjs → run-agent-CuQT1xSS.mjs} +170 -42
  37. package/dist/{run-agent-ByO-Bxyd.d.cts → run-agent-CxSyZmIE.d.mts} +87 -30
  38. package/dist/{run-agent-Dmf8GV2d.cjs → run-agent-cToZ3K42.cjs} +219 -86
  39. package/dist/{setup-agent-DV4cTou-.cjs → setup-agent-DTF3NQg3.cjs} +31 -20
  40. package/dist/setup-agent-DlbgwsIJ.d.cts +577 -0
  41. package/dist/{setup-agent-BuanDXeh.mjs → setup-agent-DniLvDu7.mjs} +15 -9
  42. package/dist/setup-agent-tsc3vm5I.d.mts +577 -0
  43. package/dist/tanstack-ai.cjs +627 -0
  44. package/dist/tanstack-ai.d.cts +204 -0
  45. package/dist/tanstack-ai.d.mts +204 -0
  46. package/dist/tanstack-ai.mjs +618 -0
  47. package/dist/testing.cjs +98 -985
  48. package/dist/testing.d.cts +51 -347
  49. package/dist/testing.d.mts +51 -347
  50. package/dist/testing.mjs +86 -973
  51. package/dist/{text-logic-IjfYy9DP.d.cts → text-logic-9fv1i9aK.d.cts} +50 -10
  52. package/dist/{text-logic-D-czVPYp.d.mts → text-logic-BDbGjYMh.d.mts} +50 -10
  53. package/dist/{types-BgNbNKnJ.d.mts → types-Dp5_Ru4R.d.cts} +2 -2
  54. package/dist/{types-hR5f5YXa.d.cts → types-Dp5_Ru4R.d.mts} +2 -2
  55. package/dist/usage-D8UphgEA.d.mts +17 -0
  56. package/dist/usage-R1NTmLxY.d.cts +17 -0
  57. package/dist/{utils-_q7F-AZu.d.mts → utils-BnXdWih3.d.mts} +1 -2
  58. package/dist/{utils-o4YRdHJX.d.cts → utils-ebVpCYoF.d.cts} +1 -2
  59. package/dist/validate.cjs +239 -8
  60. package/dist/validate.d.cts +110 -3
  61. package/dist/validate.d.mts +110 -3
  62. package/dist/validate.mjs +238 -7
  63. package/dist/verify-B5qGC5WN.mjs +1181 -0
  64. package/dist/verify-CBuYIpsa.d.mts +414 -0
  65. package/dist/verify-Cqghu4gz.cjs +1222 -0
  66. package/dist/verify-DYH_2VzU.d.cts +414 -0
  67. package/package.json +44 -31
  68. package/readme.md +38 -26
  69. package/skills/generate-machine/SKILL.md +140 -66
  70. package/skills/improve-machine/SKILL.md +190 -0
  71. package/skills/improve-machine/reference.md +96 -0
  72. package/dist/event-log-store-2pAFiWuc.mjs +0 -576
  73. package/dist/event-log-store-C-COhIXP.cjs +0 -702
  74. package/dist/usage-BdEjFuIi.mjs +0 -5
  75. package/dist/usage-efOQPdf_.cjs +0 -10
@@ -1,6 +1,5 @@
1
- import { _ as StandardSchemaV1, c as AllowedEvents, h as InferOutput, i as AgentToolChoice, n as AgentMessage, s as AgentTools, u as ChosenEvent } from "./types-hR5f5YXa.cjs";
1
+ import { _ as StandardSchemaV1, c as AllowedEvents, h as InferOutput, i as AgentToolChoice, n as AgentMessage, s as AgentTools, u as ChosenEvent } from "./types-Dp5_Ru4R.cjs";
2
2
  import { AnyMachineSnapshot, AnyStateMachine, AsyncActorLogic, EventFromLogic, EventObject, MachineSnapshot } from "xstate";
3
-
4
3
  //#region src/errors.d.ts
5
4
  /**
6
5
  * Base class for every error this package throws. Carries a stable, kebab-case
@@ -152,6 +151,14 @@ interface AgentDecisionInput<TEvent extends string = string, TMetadata = Record<
152
151
  /** Framework-native messages, passed through without conversion. */
153
152
  messages?: any[];
154
153
  allowedEvents?: AllowedEvents<TEvent>;
154
+ /**
155
+ * Concrete payloads per event type, without `type`. When given, the
156
+ * decision is a closed choice: the request carries one
157
+ * {@link AgentDecisionOption} per payload whose event the snapshot accepts,
158
+ * and the decider picks one instead of writing a payload. Event types in
159
+ * `allowedEvents` with no entry here are offered as `{ type }`.
160
+ */
161
+ payloads?: Partial<Record<TEvent, Record<string, unknown>[]>>;
155
162
  maxRetries?: number;
156
163
  temperature?: number;
157
164
  maxOutputTokens?: number;
@@ -251,6 +258,21 @@ interface AgentDecisionRequest {
251
258
  messages?: any[];
252
259
  /** Candidate events: declared `allowedEvents` ∩ snapshot-legal events. */
253
260
  events: AgentEventDescriptor[];
261
+ /**
262
+ * Concrete choices, present when the host enumerated payloads
263
+ * (`payloads` on the decide input, or `decideNext`). A snapshot-aware host
264
+ * keeps only options the snapshot accepts. An executor that sees options
265
+ * should choose one of them; a chosen event matching no option is
266
+ * rejected and retried like a guard rejection.
267
+ */
268
+ options?: AgentDecisionOption[];
269
+ /**
270
+ * Candidate events the snapshot rejected when the options were built:
271
+ * enumerated like `options`, but `snapshot.can(event)` was false. Never
272
+ * offered; executors ignore it. Set by `decideNext` and by the runtime's
273
+ * closed choices, so a `request.start` trace shows what the guards blocked.
274
+ */
275
+ withheld?: ChosenEvent[];
254
276
  /**
255
277
  * Prior failed attempts for THIS decision. Empty on the first attempt.
256
278
  * Adapters render these into the provider request so retries converge.
@@ -264,6 +286,11 @@ interface AgentDecisionRequest {
264
286
  seed?: number;
265
287
  stopSequences?: string[];
266
288
  metadata?: Record<string, unknown>;
289
+ /**
290
+ * Per-invoke retry budget lowered from `agent.decide` inline input. Hosts
291
+ * prefer it over the logic's configured `maxRetries` when set.
292
+ */
293
+ maxRetries?: number;
267
294
  /**
268
295
  * The run this decision belongs to (`run_<n>`, matching trace
269
296
  * events), injected by the runtime like `signal` (symmetric with the text
@@ -310,6 +337,12 @@ declare function createDecisionRequest(options: CreateDecisionRequestOptions): A
310
337
  type AgentExecutorDecisionRequest = AgentDecisionRequest & {
311
338
  name: string;
312
339
  };
340
+ /** One concrete event a decider may choose, with an optional description for the model. */
341
+ interface AgentDecisionOption {
342
+ event: ChosenEvent;
343
+ /** What choosing this does, in words; lookahead text when the host computed it. */
344
+ description?: string;
345
+ }
313
346
  /**
314
347
  * A single failed decision attempt, recorded by {@link resolveDecision} and
315
348
  * fed back to the executor on the next attempt via
@@ -317,7 +350,7 @@ type AgentExecutorDecisionRequest = AgentDecisionRequest & {
317
350
  * choice: `'unknown-event'` (not among the candidate `events`),
318
351
  * `'invalid-payload'` (failed the event's schema), or `'rejected-by-guard'`
319
352
  * (failed the `canTake` check — type/payload were legal, but the machine's
320
- * guard rejected it at apply time).
353
+ * guard rejected it at apply time — or matched none of `request.options`).
321
354
  */
322
355
  interface DecisionAttempt {
323
356
  event?: ChosenEvent;
@@ -349,7 +382,7 @@ declare class AgentDecisionExhaustedError extends AgentError {
349
382
  * const messages = [...baseMessages, ...renderDecisionAttempts(request)];
350
383
  * ```
351
384
  */
352
- declare function renderDecisionAttempts(request: Pick<AgentDecisionRequest, "events" | "attempts">): AgentMessage[];
385
+ declare function renderDecisionAttempts(request: Pick<AgentDecisionRequest, "events" | "attempts" | "options">): AgentMessage[];
353
386
  /**
354
387
  * Host implementation of "make the model choose one of `request.events`."
355
388
  * Third executor slot on {@link AgentRequestExecutors}, symmetric with
@@ -368,7 +401,8 @@ declare function renderDecisionAttempts(request: Pick<AgentDecisionRequest, "eve
368
401
  */
369
402
  type AgentDecisionExecutor = (request: AgentExecutorDecisionRequest, info?: AgentRequestExecutorInfo) => PromiseLike<{
370
403
  event: ChosenEvent;
371
- reason?: string; /** This attempt's token usage, aggregated into the run result's {@link AgentUsage}. */
404
+ reason?: string;
405
+ /** This attempt's token usage, aggregated into the run result's {@link AgentUsage}. */
372
406
  usage?: AgentCallUsage;
373
407
  [key: string]: unknown;
374
408
  }>;
@@ -407,6 +441,8 @@ interface ResolveDecisionOptions<TEvent extends ChosenEvent = ChosenEvent> {
407
441
  * event's schema), or `'rejected-by-guard'` (passes both checks but
408
442
  * `options.canTake` returns `false` — a type/payload-legal event the
409
443
  * machine's guard rejects right now; omit `canTake` to skip this check).
444
+ * When the request carries `options`, a choice matching none of them (type and
445
+ * payload, deep-equal) also fails as `'rejected-by-guard'`.
410
446
  * Every prior failed attempt for this call is fed back to the executor on
411
447
  * the next attempt via `request.attempts`, so an adapter can render "your
412
448
  * last choice failed because X — try again" into the next model call; core
@@ -737,9 +773,12 @@ declare function bindRequestExecutor<TInputSchema extends StandardSchemaV1, TOut
737
773
  * toward `modelCalls`.
738
774
  */
739
775
  type AgentRequestExecutorResult<TOutput = unknown, TMessage = unknown> = {
740
- result: TOutput; /** The provider's response messages for this call (the assistant turn, tool calls and results). */
741
- messages?: TMessage[]; /** This call's token usage, aggregated into the run result's {@link AgentUsage}. */
742
- usage?: AgentCallUsage; /** Why this call stopped, normalized (see {@link AgentFinishReason}). Surfaced on the `request.end` trace event. */
776
+ result: TOutput;
777
+ /** The provider's response messages for this call (the assistant turn, tool calls and results). */
778
+ messages?: TMessage[];
779
+ /** This call's token usage, aggregated into the run result's {@link AgentUsage}. */
780
+ usage?: AgentCallUsage;
781
+ /** Why this call stopped, normalized (see {@link AgentFinishReason}). Surfaced on the `request.end` trace event. */
743
782
  finishReason?: AgentFinishReason;
744
783
  [key: string]: unknown;
745
784
  };
@@ -789,7 +828,8 @@ interface AgentRequestExecutorInfo {
789
828
  * `tools` merged in. Exactly one of `prompt`/`messages` is set.
790
829
  */
791
830
  type AgentExecutorTextRequest<TMetadata = Record<string, unknown>> = Omit<AgentTextRequest<TMetadata>, "name" | "tools"> & {
792
- /** Semantic request identity; always resolved before an executor is called. */name: string;
831
+ /** Semantic request identity; always resolved before an executor is called. */
832
+ name: string;
793
833
  tools: AgentTools;
794
834
  };
795
835
  /**
@@ -861,4 +901,4 @@ declare function providerOutputSchema(inner: StandardSchemaV1, options?: {
861
901
  */
862
902
  declare function parseProviderOutput(request: Pick<AgentTextRequest, "outputSchema" | "includeReasoning">, value: unknown): ProviderStructuredOutput;
863
903
  //#endregion
864
- export { AgentDecisionExhaustedError as A, createDecisionRequest as B, getAgentOutputMode as C, parseProviderOutput as D, parseOutput as E, DecisionAttempt as F, AgentRequestOptions as G, resolveDecision as H, DecisionLogic as I, EventFromSnapshot as J, AgentRequestSource as K, DecisionLogicConfig as L, AgentDecisionRequest as M, AgentExecutorDecisionRequest as N, providerOutputSchema as O, CreateDecisionRequestOptions as P, AgentTruncatedError as Q, ResolveDecisionOptions as R, createTextLogic as S, getCallUsage as T, AgentEventDescriptor as U, renderDecisionAttempts as V, AgentInvalidEventPayloadError as W, parseAgentEvent as X, getAcceptedEvents as Y, AgentError as Z, TextLogic as _, AgentModelRef as a, TextLogicExecutor as b, AgentRequestExecutorInfo as c, AgentRequestMode as d, AgentTextRequest as f, ProviderStructuredOutput as g, BuiltinAgentActors as h, AgentModelMap as i, AgentDecisionInput as j, AgentDecisionExecutor as k, AgentRequestExecutorResult as l, AgentUsage as m, AgentExecutorTextRequest as n, AgentOutputMode as o, AgentTextResult as p, AgentSchemas as q, AgentFinishReason as r, AgentRequestExecutor as s, AgentCallUsage as t, AgentRequestExecutors as u, TextLogicConfig as v, getCallFinishReason as w, bindRequestExecutor as x, TextLogicExecuteArgs as y, createDecisionLogic as z };
904
+ export { AgentTruncatedError as $, AgentDecisionExhaustedError as A, createDecisionLogic as B, getAgentOutputMode as C, parseProviderOutput as D, parseOutput as E, CreateDecisionRequestOptions as F, AgentInvalidEventPayloadError as G, renderDecisionAttempts as H, DecisionAttempt as I, AgentSchemas as J, AgentRequestOptions as K, DecisionLogic as L, AgentDecisionOption as M, AgentDecisionRequest as N, providerOutputSchema as O, AgentExecutorDecisionRequest as P, AgentError as Q, DecisionLogicConfig as R, createTextLogic as S, getCallUsage as T, resolveDecision as U, createDecisionRequest as V, AgentEventDescriptor as W, getAcceptedEvents as X, EventFromSnapshot as Y, parseAgentEvent as Z, TextLogic as _, AgentModelRef as a, TextLogicExecutor as b, AgentRequestExecutorInfo as c, AgentRequestMode as d, AgentTextRequest as f, ProviderStructuredOutput as g, BuiltinAgentActors as h, AgentModelMap as i, AgentDecisionInput as j, AgentDecisionExecutor as k, AgentRequestExecutorResult as l, AgentUsage as m, AgentExecutorTextRequest as n, AgentOutputMode as o, AgentTextResult as p, AgentRequestSource as q, AgentFinishReason as r, AgentRequestExecutor as s, AgentCallUsage as t, AgentRequestExecutors as u, TextLogicConfig as v, getCallFinishReason as w, bindRequestExecutor as x, TextLogicExecuteArgs as y, ResolveDecisionOptions as z };
@@ -1,6 +1,5 @@
1
- import { _ as StandardSchemaV1, c as AllowedEvents, h as InferOutput, i as AgentToolChoice, n as AgentMessage, s as AgentTools, u as ChosenEvent } from "./types-BgNbNKnJ.mjs";
1
+ import { _ as StandardSchemaV1, c as AllowedEvents, h as InferOutput, i as AgentToolChoice, n as AgentMessage, s as AgentTools, u as ChosenEvent } from "./types-Dp5_Ru4R.mjs";
2
2
  import { AnyMachineSnapshot, AnyStateMachine, AsyncActorLogic, EventFromLogic, EventObject, MachineSnapshot } from "xstate";
3
-
4
3
  //#region src/errors.d.ts
5
4
  /**
6
5
  * Base class for every error this package throws. Carries a stable, kebab-case
@@ -152,6 +151,14 @@ interface AgentDecisionInput<TEvent extends string = string, TMetadata = Record<
152
151
  /** Framework-native messages, passed through without conversion. */
153
152
  messages?: any[];
154
153
  allowedEvents?: AllowedEvents<TEvent>;
154
+ /**
155
+ * Concrete payloads per event type, without `type`. When given, the
156
+ * decision is a closed choice: the request carries one
157
+ * {@link AgentDecisionOption} per payload whose event the snapshot accepts,
158
+ * and the decider picks one instead of writing a payload. Event types in
159
+ * `allowedEvents` with no entry here are offered as `{ type }`.
160
+ */
161
+ payloads?: Partial<Record<TEvent, Record<string, unknown>[]>>;
155
162
  maxRetries?: number;
156
163
  temperature?: number;
157
164
  maxOutputTokens?: number;
@@ -251,6 +258,21 @@ interface AgentDecisionRequest {
251
258
  messages?: any[];
252
259
  /** Candidate events: declared `allowedEvents` ∩ snapshot-legal events. */
253
260
  events: AgentEventDescriptor[];
261
+ /**
262
+ * Concrete choices, present when the host enumerated payloads
263
+ * (`payloads` on the decide input, or `decideNext`). A snapshot-aware host
264
+ * keeps only options the snapshot accepts. An executor that sees options
265
+ * should choose one of them; a chosen event matching no option is
266
+ * rejected and retried like a guard rejection.
267
+ */
268
+ options?: AgentDecisionOption[];
269
+ /**
270
+ * Candidate events the snapshot rejected when the options were built:
271
+ * enumerated like `options`, but `snapshot.can(event)` was false. Never
272
+ * offered; executors ignore it. Set by `decideNext` and by the runtime's
273
+ * closed choices, so a `request.start` trace shows what the guards blocked.
274
+ */
275
+ withheld?: ChosenEvent[];
254
276
  /**
255
277
  * Prior failed attempts for THIS decision. Empty on the first attempt.
256
278
  * Adapters render these into the provider request so retries converge.
@@ -264,6 +286,11 @@ interface AgentDecisionRequest {
264
286
  seed?: number;
265
287
  stopSequences?: string[];
266
288
  metadata?: Record<string, unknown>;
289
+ /**
290
+ * Per-invoke retry budget lowered from `agent.decide` inline input. Hosts
291
+ * prefer it over the logic's configured `maxRetries` when set.
292
+ */
293
+ maxRetries?: number;
267
294
  /**
268
295
  * The run this decision belongs to (`run_<n>`, matching trace
269
296
  * events), injected by the runtime like `signal` (symmetric with the text
@@ -310,6 +337,12 @@ declare function createDecisionRequest(options: CreateDecisionRequestOptions): A
310
337
  type AgentExecutorDecisionRequest = AgentDecisionRequest & {
311
338
  name: string;
312
339
  };
340
+ /** One concrete event a decider may choose, with an optional description for the model. */
341
+ interface AgentDecisionOption {
342
+ event: ChosenEvent;
343
+ /** What choosing this does, in words; lookahead text when the host computed it. */
344
+ description?: string;
345
+ }
313
346
  /**
314
347
  * A single failed decision attempt, recorded by {@link resolveDecision} and
315
348
  * fed back to the executor on the next attempt via
@@ -317,7 +350,7 @@ type AgentExecutorDecisionRequest = AgentDecisionRequest & {
317
350
  * choice: `'unknown-event'` (not among the candidate `events`),
318
351
  * `'invalid-payload'` (failed the event's schema), or `'rejected-by-guard'`
319
352
  * (failed the `canTake` check — type/payload were legal, but the machine's
320
- * guard rejected it at apply time).
353
+ * guard rejected it at apply time — or matched none of `request.options`).
321
354
  */
322
355
  interface DecisionAttempt {
323
356
  event?: ChosenEvent;
@@ -349,7 +382,7 @@ declare class AgentDecisionExhaustedError extends AgentError {
349
382
  * const messages = [...baseMessages, ...renderDecisionAttempts(request)];
350
383
  * ```
351
384
  */
352
- declare function renderDecisionAttempts(request: Pick<AgentDecisionRequest, "events" | "attempts">): AgentMessage[];
385
+ declare function renderDecisionAttempts(request: Pick<AgentDecisionRequest, "events" | "attempts" | "options">): AgentMessage[];
353
386
  /**
354
387
  * Host implementation of "make the model choose one of `request.events`."
355
388
  * Third executor slot on {@link AgentRequestExecutors}, symmetric with
@@ -368,7 +401,8 @@ declare function renderDecisionAttempts(request: Pick<AgentDecisionRequest, "eve
368
401
  */
369
402
  type AgentDecisionExecutor = (request: AgentExecutorDecisionRequest, info?: AgentRequestExecutorInfo) => PromiseLike<{
370
403
  event: ChosenEvent;
371
- reason?: string; /** This attempt's token usage, aggregated into the run result's {@link AgentUsage}. */
404
+ reason?: string;
405
+ /** This attempt's token usage, aggregated into the run result's {@link AgentUsage}. */
372
406
  usage?: AgentCallUsage;
373
407
  [key: string]: unknown;
374
408
  }>;
@@ -407,6 +441,8 @@ interface ResolveDecisionOptions<TEvent extends ChosenEvent = ChosenEvent> {
407
441
  * event's schema), or `'rejected-by-guard'` (passes both checks but
408
442
  * `options.canTake` returns `false` — a type/payload-legal event the
409
443
  * machine's guard rejects right now; omit `canTake` to skip this check).
444
+ * When the request carries `options`, a choice matching none of them (type and
445
+ * payload, deep-equal) also fails as `'rejected-by-guard'`.
410
446
  * Every prior failed attempt for this call is fed back to the executor on
411
447
  * the next attempt via `request.attempts`, so an adapter can render "your
412
448
  * last choice failed because X — try again" into the next model call; core
@@ -737,9 +773,12 @@ declare function bindRequestExecutor<TInputSchema extends StandardSchemaV1, TOut
737
773
  * toward `modelCalls`.
738
774
  */
739
775
  type AgentRequestExecutorResult<TOutput = unknown, TMessage = unknown> = {
740
- result: TOutput; /** The provider's response messages for this call (the assistant turn, tool calls and results). */
741
- messages?: TMessage[]; /** This call's token usage, aggregated into the run result's {@link AgentUsage}. */
742
- usage?: AgentCallUsage; /** Why this call stopped, normalized (see {@link AgentFinishReason}). Surfaced on the `request.end` trace event. */
776
+ result: TOutput;
777
+ /** The provider's response messages for this call (the assistant turn, tool calls and results). */
778
+ messages?: TMessage[];
779
+ /** This call's token usage, aggregated into the run result's {@link AgentUsage}. */
780
+ usage?: AgentCallUsage;
781
+ /** Why this call stopped, normalized (see {@link AgentFinishReason}). Surfaced on the `request.end` trace event. */
743
782
  finishReason?: AgentFinishReason;
744
783
  [key: string]: unknown;
745
784
  };
@@ -789,7 +828,8 @@ interface AgentRequestExecutorInfo {
789
828
  * `tools` merged in. Exactly one of `prompt`/`messages` is set.
790
829
  */
791
830
  type AgentExecutorTextRequest<TMetadata = Record<string, unknown>> = Omit<AgentTextRequest<TMetadata>, "name" | "tools"> & {
792
- /** Semantic request identity; always resolved before an executor is called. */name: string;
831
+ /** Semantic request identity; always resolved before an executor is called. */
832
+ name: string;
793
833
  tools: AgentTools;
794
834
  };
795
835
  /**
@@ -861,4 +901,4 @@ declare function providerOutputSchema(inner: StandardSchemaV1, options?: {
861
901
  */
862
902
  declare function parseProviderOutput(request: Pick<AgentTextRequest, "outputSchema" | "includeReasoning">, value: unknown): ProviderStructuredOutput;
863
903
  //#endregion
864
- export { AgentDecisionExhaustedError as A, createDecisionRequest as B, getAgentOutputMode as C, parseProviderOutput as D, parseOutput as E, DecisionAttempt as F, AgentRequestOptions as G, resolveDecision as H, DecisionLogic as I, EventFromSnapshot as J, AgentRequestSource as K, DecisionLogicConfig as L, AgentDecisionRequest as M, AgentExecutorDecisionRequest as N, providerOutputSchema as O, CreateDecisionRequestOptions as P, AgentTruncatedError as Q, ResolveDecisionOptions as R, createTextLogic as S, getCallUsage as T, AgentEventDescriptor as U, renderDecisionAttempts as V, AgentInvalidEventPayloadError as W, parseAgentEvent as X, getAcceptedEvents as Y, AgentError as Z, TextLogic as _, AgentModelRef as a, TextLogicExecutor as b, AgentRequestExecutorInfo as c, AgentRequestMode as d, AgentTextRequest as f, ProviderStructuredOutput as g, BuiltinAgentActors as h, AgentModelMap as i, AgentDecisionInput as j, AgentDecisionExecutor as k, AgentRequestExecutorResult as l, AgentUsage as m, AgentExecutorTextRequest as n, AgentOutputMode as o, AgentTextResult as p, AgentSchemas as q, AgentFinishReason as r, AgentRequestExecutor as s, AgentCallUsage as t, AgentRequestExecutors as u, TextLogicConfig as v, getCallFinishReason as w, bindRequestExecutor as x, TextLogicExecuteArgs as y, createDecisionLogic as z };
904
+ export { AgentTruncatedError as $, AgentDecisionExhaustedError as A, createDecisionLogic as B, getAgentOutputMode as C, parseProviderOutput as D, parseOutput as E, CreateDecisionRequestOptions as F, AgentInvalidEventPayloadError as G, renderDecisionAttempts as H, DecisionAttempt as I, AgentSchemas as J, AgentRequestOptions as K, DecisionLogic as L, AgentDecisionOption as M, AgentDecisionRequest as N, providerOutputSchema as O, AgentExecutorDecisionRequest as P, AgentError as Q, DecisionLogicConfig as R, createTextLogic as S, getCallUsage as T, resolveDecision as U, createDecisionRequest as V, AgentEventDescriptor as W, getAcceptedEvents as X, EventFromSnapshot as Y, parseAgentEvent as Z, TextLogic as _, AgentModelRef as a, TextLogicExecutor as b, AgentRequestExecutorInfo as c, AgentRequestMode as d, AgentTextRequest as f, ProviderStructuredOutput as g, BuiltinAgentActors as h, AgentModelMap as i, AgentDecisionInput as j, AgentDecisionExecutor as k, AgentRequestExecutorResult as l, AgentUsage as m, AgentExecutorTextRequest as n, AgentOutputMode as o, AgentTextResult as p, AgentRequestSource as q, AgentFinishReason as r, AgentRequestExecutor as s, AgentCallUsage as t, AgentRequestExecutors as u, TextLogicConfig as v, getCallFinishReason as w, bindRequestExecutor as x, TextLogicExecuteArgs as y, ResolveDecisionOptions as z };
@@ -61,7 +61,7 @@ type AgentEventSchemaInput = StandardSchemaV1 | Record<string, never>;
61
61
  /** An event schema map as authored: payload schemas and/or `{}` payload-less shorthands, keyed by event type. */
62
62
  type AgentEventSchemaInputMap = Record<string, AgentEventSchemaInput>;
63
63
  /** Resolves an authored event schema map's `{}` shorthands to real (empty-payload) schemas — the type-level counterpart of the runtime normalization in `createAgentSchemas`. */
64
- type NormalizedEventSchemas<T extends AgentEventSchemaInputMap> = { [K in keyof T]: T[K] extends StandardSchemaV1 ? T[K] : StandardSchemaV1<{}> };
64
+ type NormalizedEventSchemas<T extends AgentEventSchemaInputMap> = { [K in keyof T]: T[K] extends StandardSchemaV1 ? T[K] : StandardSchemaV1<{}>; };
65
65
  /**
66
66
  * The discriminated event union derived from a machine's event schema map
67
67
  * (e.g. `{ ASK: z.object({ question: z.string() }) }` → `{ type: 'ASK';
@@ -71,7 +71,7 @@ type NormalizedEventSchemas<T extends AgentEventSchemaInputMap> = { [K in keyof
71
71
  */
72
72
  type EventUnion<T extends AgentEventSchemaInputMap> = { [K in keyof T & string]: {
73
73
  type: K;
74
- } & (T[K] extends StandardSchemaV1 ? EventPayload<InferOutput<T[K]>> : unknown) }[keyof T & string];
74
+ } & (T[K] extends StandardSchemaV1 ? EventPayload<InferOutput<T[K]>> : unknown); }[keyof T & string];
75
75
  /** Raw binary or string content for an {@link ImagePart}/{@link FilePart}. */
76
76
  type DataContent = string | Uint8Array | ArrayBuffer;
77
77
  /** Provider-specific passthrough options, keyed by provider name (e.g. `{ anthropic: { cacheControl: ... } }`). */
@@ -61,7 +61,7 @@ type AgentEventSchemaInput = StandardSchemaV1 | Record<string, never>;
61
61
  /** An event schema map as authored: payload schemas and/or `{}` payload-less shorthands, keyed by event type. */
62
62
  type AgentEventSchemaInputMap = Record<string, AgentEventSchemaInput>;
63
63
  /** Resolves an authored event schema map's `{}` shorthands to real (empty-payload) schemas — the type-level counterpart of the runtime normalization in `createAgentSchemas`. */
64
- type NormalizedEventSchemas<T extends AgentEventSchemaInputMap> = { [K in keyof T]: T[K] extends StandardSchemaV1 ? T[K] : StandardSchemaV1<{}> };
64
+ type NormalizedEventSchemas<T extends AgentEventSchemaInputMap> = { [K in keyof T]: T[K] extends StandardSchemaV1 ? T[K] : StandardSchemaV1<{}>; };
65
65
  /**
66
66
  * The discriminated event union derived from a machine's event schema map
67
67
  * (e.g. `{ ASK: z.object({ question: z.string() }) }` → `{ type: 'ASK';
@@ -71,7 +71,7 @@ type NormalizedEventSchemas<T extends AgentEventSchemaInputMap> = { [K in keyof
71
71
  */
72
72
  type EventUnion<T extends AgentEventSchemaInputMap> = { [K in keyof T & string]: {
73
73
  type: K;
74
- } & (T[K] extends StandardSchemaV1 ? EventPayload<InferOutput<T[K]>> : unknown) }[keyof T & string];
74
+ } & (T[K] extends StandardSchemaV1 ? EventPayload<InferOutput<T[K]>> : unknown); }[keyof T & string];
75
75
  /** Raw binary or string content for an {@link ImagePart}/{@link FilePart}. */
76
76
  type DataContent = string | Uint8Array | ArrayBuffer;
77
77
  /** Provider-specific passthrough options, keyed by provider name (e.g. `{ anthropic: { cacheControl: ... } }`). */
@@ -0,0 +1,17 @@
1
+ import { t as AgentCallUsage } from "./text-logic-BDbGjYMh.mjs";
2
+ import { EventObject } from "xstate";
3
+ //#region src/usage.d.ts
4
+ /** Reserved event delivered after a model call reports token usage. */
5
+ declare const AGENT_USAGE_EVENT_TYPE: "@agent.usage";
6
+ /** Machine-owned usage signal. Handle it with an ordinary XState transition. */
7
+ interface AgentUsageEvent extends EventObject {
8
+ type: typeof AGENT_USAGE_EVENT_TYPE;
9
+ usage: AgentCallUsage;
10
+ kind?: "text" | "decision";
11
+ id?: string;
12
+ src?: string;
13
+ model?: string;
14
+ name?: string;
15
+ }
16
+ //#endregion
17
+ export { AgentUsageEvent as n, AGENT_USAGE_EVENT_TYPE as t };
@@ -0,0 +1,17 @@
1
+ import { t as AgentCallUsage } from "./text-logic-9fv1i9aK.cjs";
2
+ import { EventObject } from "xstate";
3
+ //#region src/usage.d.ts
4
+ /** Reserved event delivered after a model call reports token usage. */
5
+ declare const AGENT_USAGE_EVENT_TYPE: "@agent.usage";
6
+ /** Machine-owned usage signal. Handle it with an ordinary XState transition. */
7
+ interface AgentUsageEvent extends EventObject {
8
+ type: typeof AGENT_USAGE_EVENT_TYPE;
9
+ usage: AgentCallUsage;
10
+ kind?: "text" | "decision";
11
+ id?: string;
12
+ src?: string;
13
+ model?: string;
14
+ name?: string;
15
+ }
16
+ //#endregion
17
+ export { AgentUsageEvent as n, AGENT_USAGE_EVENT_TYPE as t };
@@ -1,6 +1,5 @@
1
- import { C as UserMessage, S as ToolResultPart, _ as StandardSchemaV1, b as ToolCallPart, f as FilePart, l as AssistantMessage, n as AgentMessage, p as ImagePart, v as SystemMessage, x as ToolMessage, y as TextPart } from "./types-BgNbNKnJ.mjs";
1
+ import { C as UserMessage, S as ToolResultPart, _ as StandardSchemaV1, b as ToolCallPart, f as FilePart, l as AssistantMessage, n as AgentMessage, p as ImagePart, v as SystemMessage, x as ToolMessage, y as TextPart } from "./types-Dp5_Ru4R.mjs";
2
2
  import { AnyMachineSnapshot, AnyStateMachine, StateValue } from "xstate";
3
-
4
3
  //#region src/utils.d.ts
5
4
  /** Returns the human-readable text carried by a message, ignoring non-text parts. */
6
5
  declare function getMessageText(message: AgentMessage): string;
@@ -1,6 +1,5 @@
1
- import { C as UserMessage, S as ToolResultPart, _ as StandardSchemaV1, b as ToolCallPart, f as FilePart, l as AssistantMessage, n as AgentMessage, p as ImagePart, v as SystemMessage, x as ToolMessage, y as TextPart } from "./types-hR5f5YXa.cjs";
1
+ import { C as UserMessage, S as ToolResultPart, _ as StandardSchemaV1, b as ToolCallPart, f as FilePart, l as AssistantMessage, n as AgentMessage, p as ImagePart, v as SystemMessage, x as ToolMessage, y as TextPart } from "./types-Dp5_Ru4R.cjs";
2
2
  import { AnyMachineSnapshot, AnyStateMachine, StateValue } from "xstate";
3
-
4
3
  //#region src/utils.d.ts
5
4
  /** Returns the human-readable text carried by a message, ignoring non-text parts. */
6
5
  declare function getMessageText(message: AgentMessage): string;
package/dist/validate.cjs CHANGED
@@ -16,11 +16,14 @@ var __copyProps = (to, from, except, desc) => {
16
16
  }
17
17
  return to;
18
18
  };
19
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
19
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule || !__hasOwnProp.call(mod, "default") ? __defProp(target, "default", {
20
20
  value: mod,
21
21
  enumerable: true
22
22
  }) : target, mod));
23
23
  //#endregion
24
+ const require_event_log = require("./event-log-Dtb16p1p.cjs");
25
+ const require_setup_agent = require("./setup-agent-DTF3NQg3.cjs");
26
+ const require_verify = require("./verify-Cqghu4gz.cjs");
24
27
  let ajv_dist_2020_js = require("ajv/dist/2020.js");
25
28
  ajv_dist_2020_js = __toESM(ajv_dist_2020_js, 1);
26
29
  //#region schemas/agent-workflow.json
@@ -383,13 +386,10 @@ var agent_workflow_default = {
383
386
  }
384
387
  };
385
388
  //#endregion
386
- //#region src/validate/index.ts
389
+ //#region src/validate/validate-config.ts
387
390
  /**
388
- * Schema validation for agent workflow configs.
389
- *
390
- * Lives behind the `@statelyai/agent/validate` subpath so the core package
391
- * stays dependency-free. This module imports `ajv`, which is declared as an
392
- * optional peer dependency.
391
+ * Schema validation for agent workflow configs. Imports `ajv`, an optional
392
+ * peer dependency of the package.
393
393
  */
394
394
  let compiledWorkflowValidator;
395
395
  function getWorkflowValidator() {
@@ -424,5 +424,236 @@ function validateAgentConfig(config) {
424
424
  };
425
425
  }
426
426
  //#endregion
427
- exports.__toESM = __toESM;
427
+ //#region src/validate/verify-config.ts
428
+ const BUILTIN_SRCS = [
429
+ require_event_log.DECIDE_ACTOR,
430
+ require_event_log.GENERATE_TEXT_ACTOR,
431
+ require_event_log.STREAM_TEXT_ACTOR
432
+ ];
433
+ const MAX_DETAIL_LINES = 10;
434
+ /**
435
+ * Runs every pre-run gate on a model-authored workflow config and stops at
436
+ * the first failure. Never throws on a bad config: each failure becomes a gate
437
+ * record whose `detail` is a repair prompt.
438
+ *
439
+ * - `validate`: the config's shape, against the shipped JSON Schema.
440
+ * - `vocabulary`: names the config references, against `allow`.
441
+ * - `lower`: `setupAgent.fromConfig` (unresolved guards/actions, bad targets).
442
+ * - `lint`: `lintAgentMachine` (errors fail; warnings fail with `lint.warnings`).
443
+ * - `explore`: `explorePaths` from each `explore.inputs` entry; every terminal
444
+ * must be one of `explore.terminals`, no cap (`maxPaths`, `maxNodes`) may cut
445
+ * it short, every event's payloads must be tried (`unexpandedEvents`), and
446
+ * every reached text request or invoke needs an `explore.outputs` entry.
447
+ *
448
+ * @example
449
+ * ```ts
450
+ * const result = await verifyAgentConfig(candidate, { compileSchema, allow: { events: ["APPROVE", "DENY"] } });
451
+ * const failed = result.gates.find((gate) => !gate.ok);
452
+ * if (failed) feedback.push(`gate '${failed.name}' failed: ${failed.detail}`);
453
+ * ```
454
+ */
455
+ async function verifyAgentConfig(config, options) {
456
+ const gates = [];
457
+ const record = (name, problems, notes = []) => {
458
+ const lines = problems.length ? problems : notes;
459
+ gates.push({
460
+ name,
461
+ ok: problems.length === 0,
462
+ ...lines.length ? { detail: formatDetail(lines) } : {}
463
+ });
464
+ return problems.length === 0;
465
+ };
466
+ const fail = (extra = {}) => ({
467
+ ok: false,
468
+ gates,
469
+ ...extra
470
+ });
471
+ if (!record("validate", validateAgentConfig(config).errors.map((error) => `${error.path} ${error.message}`))) return fail();
472
+ const typed = config;
473
+ if (options.allow && !record("vocabulary", checkVocabulary(typed, options.allow))) return fail({ config: typed });
474
+ let machine;
475
+ try {
476
+ machine = require_setup_agent.setupAgentFromConfig(typed, {
477
+ compileSchema: options.compileSchema,
478
+ ...options.guards ? { guards: options.guards } : {},
479
+ ...options.actions ? { actions: options.actions } : {}
480
+ }).machine;
481
+ if (options.actors) machine = machine.provide({ actors: options.actors });
482
+ } catch (error) {
483
+ record("lower", [errorMessage(error)]);
484
+ return fail({ config: typed });
485
+ }
486
+ record("lower", []);
487
+ const diagnostics = require_verify.lintAgentMachine(machine).map((d) => ({
488
+ failing: d.severity === "error" || options.lint?.warnings === true,
489
+ line: `${d.severity} ${d.code} at '${d.path}': ${d.message}`
490
+ }));
491
+ if (!record("lint", diagnostics.filter((d) => d.failing).map((d) => d.line), diagnostics.map((d) => d.line))) return fail({
492
+ config: typed,
493
+ machine
494
+ });
495
+ if (options.explore && !record("explore", await checkExplore(machine, options.explore))) return fail({
496
+ config: typed,
497
+ machine
498
+ });
499
+ return {
500
+ ok: true,
501
+ gates,
502
+ config: typed,
503
+ machine
504
+ };
505
+ }
506
+ /** A config's `T | T[]` field as a list of objects. */
507
+ const nodes = (value) => (value === void 0 ? [] : Array.isArray(value) ? value : [value]).filter((node) => !!node && typeof node === "object");
508
+ const hasTemplate = (value) => typeof value === "string" && value.includes("{{");
509
+ const list = (names) => names.length ? names.join(", ") : "(none)";
510
+ /** Every state in the config, depth-first, with its dotted path. */
511
+ function walkStates(states, prefix = "") {
512
+ if (!states || typeof states !== "object") return [];
513
+ return Object.entries(states).flatMap(([key, state]) => {
514
+ const path = prefix ? `${prefix}.${key}` : key;
515
+ return [{
516
+ path,
517
+ state
518
+ }, ...walkStates(state?.states, path)];
519
+ });
520
+ }
521
+ /** Every transition on a state: `on`, `after`, `always`, `choice`, `onDone`, and invoke done/error. */
522
+ function transitionsOf(state) {
523
+ return [
524
+ ...Object.values(state.on ?? {}).flatMap(nodes),
525
+ ...Object.values(state.after ?? {}).flatMap(nodes),
526
+ ...nodes(state.always),
527
+ ...nodes(state.choice),
528
+ ...nodes(state.onDone),
529
+ ...nodes(state.invoke).flatMap((invoke) => [...nodes(invoke.onDone), ...nodes(invoke.onError)])
530
+ ];
531
+ }
532
+ /**
533
+ * Paths of raw xstate expression slots (`{ "@expr": ... }`, `{ "@code": ... }`).
534
+ * xstate evaluates such an object whole, ignoring its literal siblings, so a
535
+ * slot would hide the model ref or `allowedEvents` the checks below read.
536
+ */
537
+ function rawExpressionPaths(value, path) {
538
+ if (Array.isArray(value)) return value.flatMap((item, index) => rawExpressionPaths(item, `${path}[${index}]`));
539
+ if (!value || typeof value !== "object") return [];
540
+ const node = value;
541
+ if (typeof node["@expr"] === "string" || typeof node["@code"] === "string") return [path];
542
+ return Object.entries(node).flatMap(([key, item]) => rawExpressionPaths(item, path ? `${path}.${key}` : key));
543
+ }
544
+ function checkVocabulary(config, allow) {
545
+ const problems = rawExpressionPaths(config, "").map((path) => `${path || "(root)"} uses a raw '@expr' slot, which the vocabulary cannot check; write {{ }} templates instead`);
546
+ const checkModel = (where, model) => {
547
+ if (!allow.models) return;
548
+ if (typeof model !== "string" || hasTemplate(model)) problems.push(`${where} needs a literal string model ref; allowed: ${list(allow.models)}`);
549
+ else if (!allow.models.includes(model)) problems.push(`${where} uses model '${model}'; allowed: ${list(allow.models)}`);
550
+ };
551
+ for (const [kind, declared, allowed] of [[
552
+ "request",
553
+ config.requests,
554
+ allow.requests
555
+ ], [
556
+ "actor",
557
+ config.actors,
558
+ allow.actors
559
+ ]]) {
560
+ if (!allowed) continue;
561
+ for (const key of Object.keys(declared ?? {})) if (!allowed.includes(key)) problems.push(`${kind} '${key}' is not in the vocabulary; allowed: ${list(allowed)}`);
562
+ }
563
+ for (const [key, request] of Object.entries(config.requests ?? {})) checkModel(`request '${key}'`, request.model);
564
+ const srcs = allow.actors ? [
565
+ ...BUILTIN_SRCS,
566
+ ...allow.actors,
567
+ ...allow.requests ?? Object.keys(config.requests ?? {})
568
+ ] : void 0;
569
+ for (const { path, state } of walkStates(config.states)) {
570
+ for (const invoke of nodes(state.invoke)) {
571
+ const src = String(invoke.src);
572
+ if (srcs && !srcs.includes(src)) {
573
+ problems.push(`state '${path}' invokes unknown src '${src}'; allowed: ${list(srcs)}`);
574
+ continue;
575
+ }
576
+ if (!BUILTIN_SRCS.includes(src)) continue;
577
+ const input = invoke.input;
578
+ if ((allow.models || src === "agent.decide" && allow.events) && !isPlainObject(input)) {
579
+ problems.push(`state '${path}': '${src}' input must be a literal object`);
580
+ continue;
581
+ }
582
+ checkModel(`state '${path}': '${src}'`, input?.model);
583
+ if (src !== "agent.decide" || !allow.events) continue;
584
+ const allowedEvents = input.allowedEvents;
585
+ if (!Array.isArray(allowedEvents) || allowedEvents.length === 0) {
586
+ problems.push(`state '${path}': agent.decide needs a literal, non-empty allowedEvents list; allowed: ${list(allow.events)}`);
587
+ continue;
588
+ }
589
+ for (const type of allowedEvents) if (typeof type !== "string" || !allow.events.includes(type)) problems.push(`state '${path}': agent.decide allowedEvents entry '${String(type)}' is not allowed; allowed: ${list(allow.events)}`);
590
+ }
591
+ const actionsAt = [["entry", state.entry], ["exit", state.exit]];
592
+ for (const transition of transitionsOf(state)) {
593
+ const guard = transition.guard;
594
+ if (allow.guards && typeof guard === "string" && !hasTemplate(guard) && !allow.guards.includes(guard)) problems.push(`state '${path}' uses unknown named guard '${guard}'; allowed: ${list(allow.guards)}`);
595
+ actionsAt.push(["a transition", transition.actions]);
596
+ }
597
+ if (!allow.actions) continue;
598
+ for (const [where, actions] of actionsAt) for (const action of nodes(actions)) if (typeof action.type === "string" && !allow.actions.includes(action.type)) problems.push(`state '${path}' ${where} uses unknown named action '${action.type}'; allowed: ${list(allow.actions)}`);
599
+ }
600
+ return problems;
601
+ }
602
+ const isPlainObject = (value) => !!value && typeof value === "object" && !Array.isArray(value);
603
+ async function checkExplore(machine, options) {
604
+ const { inputs, terminals = ["done"], ...rest } = options;
605
+ if (inputs.length === 0) return ["explore.inputs is empty, so no path was explored; give at least one input"];
606
+ const allowed = terminals;
607
+ const maxDepth = options.maxDepth ?? 8;
608
+ const problems = /* @__PURE__ */ new Set();
609
+ for (const [index, input] of inputs.entries()) {
610
+ const at = inputs.length > 1 ? `input ${index}: ` : "";
611
+ let report;
612
+ try {
613
+ report = await require_verify.explorePaths(machine, {
614
+ ...rest,
615
+ input
616
+ });
617
+ } catch (error) {
618
+ problems.add(`${at}exploration threw: ${errorMessage(error)}`);
619
+ continue;
620
+ }
621
+ for (const terminal of report.terminals) {
622
+ if (allowed.includes(terminal.status)) continue;
623
+ const trail = `path [${terminal.path.map((event) => event.type).join(", ")}]`;
624
+ const state = JSON.stringify(terminal.state);
625
+ switch (terminal.status) {
626
+ case "max-depth":
627
+ problems.add(`${at}${trail} hit maxDepth ${maxDepth} in state ${state} without ending; the workflow may loop`);
628
+ break;
629
+ case "needs-output":
630
+ problems.add(`${at}${trail} reached '${terminal.missingSrc}' in state ${state}, which has no output to explore with; add an explore.outputs entry for it`);
631
+ break;
632
+ case "error":
633
+ problems.add(`${at}${trail} errored in state ${state} with no onError: ${errorMessage(terminal.error)}`);
634
+ break;
635
+ default: problems.add(`${at}${trail} ends '${terminal.status}' in state ${state}; every path must end ${allowed.map((t) => `'${t}'`).join(" or ")}`);
636
+ }
637
+ }
638
+ if (report.hitPathCap) problems.add(`${at}a cap (maxPaths ${options.maxPaths ?? 200} or maxNodes ${options.maxNodes ?? 1e5}) cut exploration short; the workflow branches too much to verify`);
639
+ if (report.unexpandedEvents.length > 0) problems.add(`${at}explore did not try every payload of: ${report.unexpandedEvents.join(", ")}; add explore.payloads entries for them`);
640
+ }
641
+ return [...problems];
642
+ }
643
+ function formatDetail(lines) {
644
+ const shown = lines.slice(0, MAX_DETAIL_LINES);
645
+ const hidden = lines.length - shown.length;
646
+ return [...shown, ...hidden > 0 ? [`(${hidden} more)`] : []].join("\n");
647
+ }
648
+ function errorMessage(error) {
649
+ if (error instanceof Error) return error.message;
650
+ if (typeof error === "string") return error;
651
+ try {
652
+ return JSON.stringify(error);
653
+ } catch {
654
+ return String(error);
655
+ }
656
+ }
657
+ //#endregion
428
658
  exports.validateAgentConfig = validateAgentConfig;
659
+ exports.verifyAgentConfig = verifyAgentConfig;