@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.
- package/dist/ai-sdk.cjs +149 -26
- package/dist/ai-sdk.d.cts +57 -34
- package/dist/ai-sdk.d.mts +57 -34
- package/dist/ai-sdk.mjs +147 -23
- package/dist/{decision-RQ0iv0oZ.mjs → decision-Bl_rKQnU.mjs} +73 -7
- package/dist/{decision-CmM8-HHz.cjs → decision-oevZnkBe.cjs} +112 -29
- package/dist/{text-logic-f5F5sCdc.cjs → event-log-Dtb16p1p.cjs} +813 -6
- package/dist/{text-logic-CIqHAmBi.mjs → event-log-GPZO9p7_.mjs} +679 -3
- package/dist/{event-log-store-BIPOz-di.d.mts → event-log-store-CN9ygggF.d.cts} +90 -5
- package/dist/{event-log-store-2xzFmgr2.d.cts → event-log-store-DS836wch.d.mts} +90 -5
- package/dist/event-log-store-bCdskPNS.cjs +95 -0
- package/dist/event-log-store-yalq8C77.mjs +84 -0
- package/dist/index.cjs +571 -58
- package/dist/index.d.cts +104 -510
- package/dist/index.d.mts +104 -510
- package/dist/index.mjs +542 -32
- package/dist/log.cjs +77 -20
- package/dist/log.d.cts +5 -5
- package/dist/log.d.mts +5 -5
- package/dist/log.mjs +58 -3
- package/dist/machines.cjs +1 -1
- package/dist/machines.d.cts +15 -15
- package/dist/machines.d.mts +15 -15
- package/dist/machines.mjs +1 -1
- package/dist/model-source-C7FFP2Sj.mjs +39 -0
- package/dist/model-source-DjJPjGSP.cjs +44 -0
- package/dist/openai.cjs +10 -10
- package/dist/openai.d.cts +27 -25
- package/dist/openai.d.mts +27 -25
- package/dist/openai.mjs +2 -2
- package/dist/otel.cjs +5 -4
- package/dist/otel.d.cts +5 -7
- package/dist/otel.d.mts +5 -7
- package/dist/otel.mjs +5 -3
- package/dist/{run-agent-COXXc0RW.d.mts → run-agent-C9ubX8Tx.d.cts} +87 -30
- package/dist/{run-agent-xNTxpt82.mjs → run-agent-CuQT1xSS.mjs} +170 -42
- package/dist/{run-agent-ByO-Bxyd.d.cts → run-agent-CxSyZmIE.d.mts} +87 -30
- package/dist/{run-agent-Dmf8GV2d.cjs → run-agent-cToZ3K42.cjs} +219 -86
- package/dist/{setup-agent-DV4cTou-.cjs → setup-agent-DTF3NQg3.cjs} +31 -20
- package/dist/setup-agent-DlbgwsIJ.d.cts +577 -0
- package/dist/{setup-agent-BuanDXeh.mjs → setup-agent-DniLvDu7.mjs} +15 -9
- package/dist/setup-agent-tsc3vm5I.d.mts +577 -0
- package/dist/tanstack-ai.cjs +627 -0
- package/dist/tanstack-ai.d.cts +204 -0
- package/dist/tanstack-ai.d.mts +204 -0
- package/dist/tanstack-ai.mjs +618 -0
- package/dist/testing.cjs +98 -985
- package/dist/testing.d.cts +51 -347
- package/dist/testing.d.mts +51 -347
- package/dist/testing.mjs +86 -973
- package/dist/{text-logic-IjfYy9DP.d.cts → text-logic-9fv1i9aK.d.cts} +50 -10
- package/dist/{text-logic-D-czVPYp.d.mts → text-logic-BDbGjYMh.d.mts} +50 -10
- package/dist/{types-BgNbNKnJ.d.mts → types-Dp5_Ru4R.d.cts} +2 -2
- package/dist/{types-hR5f5YXa.d.cts → types-Dp5_Ru4R.d.mts} +2 -2
- package/dist/usage-D8UphgEA.d.mts +17 -0
- package/dist/usage-R1NTmLxY.d.cts +17 -0
- package/dist/{utils-_q7F-AZu.d.mts → utils-BnXdWih3.d.mts} +1 -2
- package/dist/{utils-o4YRdHJX.d.cts → utils-ebVpCYoF.d.cts} +1 -2
- package/dist/validate.cjs +239 -8
- package/dist/validate.d.cts +110 -3
- package/dist/validate.d.mts +110 -3
- package/dist/validate.mjs +238 -7
- package/dist/verify-B5qGC5WN.mjs +1181 -0
- package/dist/verify-CBuYIpsa.d.mts +414 -0
- package/dist/verify-Cqghu4gz.cjs +1222 -0
- package/dist/verify-DYH_2VzU.d.cts +414 -0
- package/package.json +44 -31
- package/readme.md +38 -26
- package/skills/generate-machine/SKILL.md +140 -66
- package/skills/improve-machine/SKILL.md +190 -0
- package/skills/improve-machine/reference.md +96 -0
- package/dist/event-log-store-2pAFiWuc.mjs +0 -576
- package/dist/event-log-store-C-COhIXP.cjs +0 -702
- package/dist/usage-BdEjFuIi.mjs +0 -5
- 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-
|
|
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;
|
|
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;
|
|
741
|
-
|
|
742
|
-
|
|
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. */
|
|
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,
|
|
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-
|
|
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;
|
|
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;
|
|
741
|
-
|
|
742
|
-
|
|
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. */
|
|
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,
|
|
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-
|
|
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-
|
|
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/
|
|
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
|
-
|
|
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;
|