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

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.
@@ -1,6 +1,6 @@
1
1
  import { T as WithAgentInputSchema, c as AgentTools, d as ChosenEvent, h as InferInput, n as AgentMessage, v as StandardSchemaV1 } from "./types-CvWRGFxP.mjs";
2
2
  import { t as AgentError } from "./errors-C9rxnWbX.mjs";
3
- import { H as AgentRequestSource, N as AgentDecisionRequest, V as AgentRequestOptions, d as AgentTextRequest, f as AgentUsage, l as AgentRequestExecutors, p as AgentUserInput, t as AgentCallUsage, u as AgentRequestMode, z as AgentEventDescriptor } from "./text-logic-BR5twXCv.mjs";
3
+ import { N as AgentDecisionRequest, U as AgentRequestOptions, V as AgentEventDescriptor, W as AgentRequestSource, d as AgentTextRequest, f as AgentUsage, l as AgentRequestExecutors, p as AgentUserInput, t as AgentCallUsage, u as AgentRequestMode } from "./text-logic-DhfFWzu9.mjs";
4
4
  import { i as AgentLogEntry, o as JsonValue } from "./event-log-store-hrA1vqtN.mjs";
5
5
  import { AnyActorLogic, AnyActorRef, AnyMachineSnapshot, AnyStateMachine, AsyncActorLogic, EmittedFrom, EventFromLogic, EventObject, ExecutableActionObject, InputFrom, InspectionEvent, OutputFrom, Snapshot, SnapshotFrom, createActor } from "xstate";
6
6
 
@@ -1,6 +1,6 @@
1
1
  import { T as WithAgentInputSchema, c as AgentTools, d as ChosenEvent, h as InferInput, n as AgentMessage, v as StandardSchemaV1 } from "./types-DSdj2tGs.cjs";
2
2
  import { t as AgentError } from "./errors-BQRk9eiZ.cjs";
3
- import { H as AgentRequestSource, N as AgentDecisionRequest, V as AgentRequestOptions, d as AgentTextRequest, f as AgentUsage, l as AgentRequestExecutors, p as AgentUserInput, t as AgentCallUsage, u as AgentRequestMode, z as AgentEventDescriptor } from "./text-logic-Mmbgb2jy.cjs";
3
+ import { N as AgentDecisionRequest, U as AgentRequestOptions, V as AgentEventDescriptor, W as AgentRequestSource, d as AgentTextRequest, f as AgentUsage, l as AgentRequestExecutors, p as AgentUserInput, t as AgentCallUsage, u as AgentRequestMode } from "./text-logic-BaxPrcLk.cjs";
4
4
  import { i as AgentLogEntry, o as JsonValue } from "./event-log-store-Bz7HDBkE.cjs";
5
5
  import { AnyActorLogic, AnyActorRef, AnyMachineSnapshot, AnyStateMachine, AsyncActorLogic, EmittedFrom, EventFromLogic, EventObject, ExecutableActionObject, InputFrom, InspectionEvent, OutputFrom, Snapshot, SnapshotFrom, createActor } from "xstate";
6
6
 
@@ -1,5 +1,5 @@
1
1
  const require_errors = require("./errors-DUBBzRLP.cjs");
2
- const require_decision = require("./decision-BnTCsuJv.cjs");
2
+ const require_decision = require("./decision-1o45_ZrS.cjs");
3
3
  const require_event_log_store = require("./event-log-store-a_TKy1gk.cjs");
4
4
  require("./validate.cjs");
5
5
  let xstate = require("xstate");
@@ -37,22 +37,88 @@ const KNOWN_PART_TYPES = new Set([
37
37
  "tool-call",
38
38
  "tool-result"
39
39
  ]);
40
+ const USER_PART_TYPES = new Set([
41
+ "text",
42
+ "image",
43
+ "file"
44
+ ]);
45
+ const ASSISTANT_PART_TYPES = new Set([
46
+ "text",
47
+ "file",
48
+ "tool-call",
49
+ "tool-result"
50
+ ]);
51
+ const TOOL_PART_TYPES = new Set(["tool-result"]);
52
+ const TOOL_RESULT_CONTENT_PART_TYPES = new Set(["text", "image"]);
40
53
  function isKnownPart(part) {
41
- return !!part && typeof part === "object" && KNOWN_PART_TYPES.has(part.type);
54
+ const type = part && typeof part === "object" ? part.type : void 0;
55
+ return typeof type === "string" && KNOWN_PART_TYPES.has(type);
42
56
  }
43
- function validatePartsArray(content) {
44
- if (!Array.isArray(content)) return "Expected content to be a string or an array of parts";
45
- for (const part of content) if (!isKnownPart(part)) {
57
+ function requireString(part, type, field) {
58
+ return typeof part[field] === "string" ? void 0 : `${type} part requires a string "${field}"`;
59
+ }
60
+ function isMediaData(value) {
61
+ return typeof value === "string" || value instanceof Uint8Array || value instanceof ArrayBuffer || value instanceof URL;
62
+ }
63
+ function requireMediaData(part, type, field) {
64
+ return isMediaData(part[field]) ? void 0 : `${type} part requires "${field}" to be a string, Uint8Array, ArrayBuffer, or URL`;
65
+ }
66
+ const TOOL_RESULT_OUTPUT_TYPES = new Set([
67
+ "text",
68
+ "json",
69
+ "error-text",
70
+ "error-json",
71
+ "content"
72
+ ]);
73
+ function validateToolResultOutput(output) {
74
+ if (!output || typeof output !== "object" || Array.isArray(output)) return "tool-result part requires an \"output\" object";
75
+ const record = output;
76
+ const outputType = record.type;
77
+ if (typeof outputType !== "string" || !TOOL_RESULT_OUTPUT_TYPES.has(outputType)) return `Unknown tool-result output type: ${JSON.stringify(outputType)}`;
78
+ if (outputType === "text" || outputType === "error-text") {
79
+ if (typeof record.value !== "string") return `tool-result output of type "${outputType}" requires a string "value"`;
80
+ return;
81
+ }
82
+ if (outputType === "content") {
83
+ if (!Array.isArray(record.value)) return "tool-result output of type \"content\" requires an array \"value\"";
84
+ for (const contentPart of record.value) {
85
+ const error = validatePart(contentPart, TOOL_RESULT_CONTENT_PART_TYPES, "tool-result output content");
86
+ if (error) return error;
87
+ }
88
+ return;
89
+ }
90
+ return record.value !== void 0 ? void 0 : `tool-result output of type "${outputType}" requires a "value"`;
91
+ }
92
+ function validatePart(part, allowedTypes, location) {
93
+ if (!isKnownPart(part)) {
46
94
  const type = part && typeof part === "object" ? part.type : void 0;
47
95
  return `Unknown message part type: ${JSON.stringify(type)}`;
48
96
  }
97
+ if (!allowedTypes.has(part.type)) return `${location} does not allow "${part.type}" parts`;
98
+ const record = part;
99
+ switch (record.type) {
100
+ case "text": return requireString(record, "text", "text");
101
+ case "image": return requireMediaData(record, "image", "image");
102
+ case "file": return requireMediaData(record, "file", "data") ?? requireString(record, "file", "mediaType");
103
+ 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");
104
+ case "tool-result": return requireString(record, "tool-result", "toolCallId") ?? requireString(record, "tool-result", "toolName") ?? validateToolResultOutput(record.output);
105
+ default: return;
106
+ }
107
+ }
108
+ function validatePartsArray(content, allowedTypes, location) {
109
+ if (!Array.isArray(content)) return "Expected content to be a string or an array of parts";
110
+ for (const part of content) {
111
+ const error = validatePart(part, allowedTypes, location);
112
+ if (error) return error;
113
+ }
49
114
  }
50
115
  /**
51
116
  * A {@link StandardSchemaV1} validating an `AgentMessage[]` context field —
52
117
  * checks that every message has a known `role` (`system`/`user`/`assistant`/
53
118
  * `tool`) and that `content` is either a string (where the role allows it) or
54
- * an array of parts with a known `type`. Use it directly as a context
55
- * schema's `messages` field when authoring with `createAgentSchemas`.
119
+ * an array of role-appropriate parts whose required fields and media payloads
120
+ * have the right runtime types (extra fields are allowed). Use it directly as
121
+ * a context schema's `messages` field when authoring with `createAgentSchemas`.
56
122
  */
57
123
  const messagesSchema = { "~standard": {
58
124
  version: 1,
@@ -69,12 +135,12 @@ const messagesSchema = { "~standard": {
69
135
  continue;
70
136
  }
71
137
  if (role === "tool") {
72
- const error = validatePartsArray(content) ?? (content.some((part) => part.type !== "tool-result") ? "tool message content must contain only tool-result parts" : void 0);
138
+ const error = validatePartsArray(content, TOOL_PART_TYPES, "tool message content");
73
139
  if (error) return { issues: [{ message: error }] };
74
140
  continue;
75
141
  }
76
142
  if (typeof content === "string") continue;
77
- const error = validatePartsArray(content);
143
+ const error = validatePartsArray(content, role === "user" ? USER_PART_TYPES : ASSISTANT_PART_TYPES, `${role} message content`);
78
144
  if (error) return { issues: [{ message: error }] };
79
145
  }
80
146
  return { value };
@@ -1,5 +1,5 @@
1
1
  import { t as AgentError } from "./errors-CeSXQx0v.mjs";
2
- import { D as agentExecutionOptions, E as userInputActor, F as missingActor, G as resolveMachineVersion, L as djb2Hex, N as machineIdlePredicates, P as machineStaticTransitionTargets, Y as validateSchemaSync, _ as createTextLogic, g as builtinTextActors, j as getRegisteredAgentExecutionOptions, l as DECIDE_ACTOR, n as createDecideActor, o as getAcceptedEvents, p as USER_INPUT_ACTOR, r as isDecisionLogic, v as executeAgentTextRequest, x as isTextLogic } from "./decision-JWx6n3xR.mjs";
2
+ import { D as userInputActor, F as machineStaticTransitionTargets, I as missingActor, K as resolveMachineVersion, M as getRegisteredAgentExecutionOptions, O as agentExecutionOptions, P as machineIdlePredicates, R as djb2Hex, S as isTextLogic, X as validateSchemaSync, _ as builtinTextActors, i as isDecisionLogic, m as USER_INPUT_ACTOR, n as createDecideActor, s as getAcceptedEvents, u as DECIDE_ACTOR, v as createTextLogic, y as executeAgentTextRequest } from "./decision-DxSTqzgZ.mjs";
3
3
  import { a as assertJsonSerializable, i as assertAgentLogEntry } from "./event-log-store-DmIDosD6.mjs";
4
4
  import { createMachineFromConfig, initialTransition, setup, transition } from "xstate";
5
5
  //#region src/messages.ts
@@ -36,22 +36,88 @@ const KNOWN_PART_TYPES = new Set([
36
36
  "tool-call",
37
37
  "tool-result"
38
38
  ]);
39
+ const USER_PART_TYPES = new Set([
40
+ "text",
41
+ "image",
42
+ "file"
43
+ ]);
44
+ const ASSISTANT_PART_TYPES = new Set([
45
+ "text",
46
+ "file",
47
+ "tool-call",
48
+ "tool-result"
49
+ ]);
50
+ const TOOL_PART_TYPES = new Set(["tool-result"]);
51
+ const TOOL_RESULT_CONTENT_PART_TYPES = new Set(["text", "image"]);
39
52
  function isKnownPart(part) {
40
- return !!part && typeof part === "object" && KNOWN_PART_TYPES.has(part.type);
53
+ const type = part && typeof part === "object" ? part.type : void 0;
54
+ return typeof type === "string" && KNOWN_PART_TYPES.has(type);
41
55
  }
42
- function validatePartsArray(content) {
43
- if (!Array.isArray(content)) return "Expected content to be a string or an array of parts";
44
- for (const part of content) if (!isKnownPart(part)) {
56
+ function requireString(part, type, field) {
57
+ return typeof part[field] === "string" ? void 0 : `${type} part requires a string "${field}"`;
58
+ }
59
+ function isMediaData(value) {
60
+ return typeof value === "string" || value instanceof Uint8Array || value instanceof ArrayBuffer || value instanceof URL;
61
+ }
62
+ function requireMediaData(part, type, field) {
63
+ return isMediaData(part[field]) ? void 0 : `${type} part requires "${field}" to be a string, Uint8Array, ArrayBuffer, or URL`;
64
+ }
65
+ const TOOL_RESULT_OUTPUT_TYPES = new Set([
66
+ "text",
67
+ "json",
68
+ "error-text",
69
+ "error-json",
70
+ "content"
71
+ ]);
72
+ function validateToolResultOutput(output) {
73
+ if (!output || typeof output !== "object" || Array.isArray(output)) return "tool-result part requires an \"output\" object";
74
+ const record = output;
75
+ const outputType = record.type;
76
+ if (typeof outputType !== "string" || !TOOL_RESULT_OUTPUT_TYPES.has(outputType)) return `Unknown tool-result output type: ${JSON.stringify(outputType)}`;
77
+ if (outputType === "text" || outputType === "error-text") {
78
+ if (typeof record.value !== "string") return `tool-result output of type "${outputType}" requires a string "value"`;
79
+ return;
80
+ }
81
+ if (outputType === "content") {
82
+ if (!Array.isArray(record.value)) return "tool-result output of type \"content\" requires an array \"value\"";
83
+ for (const contentPart of record.value) {
84
+ const error = validatePart(contentPart, TOOL_RESULT_CONTENT_PART_TYPES, "tool-result output content");
85
+ if (error) return error;
86
+ }
87
+ return;
88
+ }
89
+ return record.value !== void 0 ? void 0 : `tool-result output of type "${outputType}" requires a "value"`;
90
+ }
91
+ function validatePart(part, allowedTypes, location) {
92
+ if (!isKnownPart(part)) {
45
93
  const type = part && typeof part === "object" ? part.type : void 0;
46
94
  return `Unknown message part type: ${JSON.stringify(type)}`;
47
95
  }
96
+ if (!allowedTypes.has(part.type)) return `${location} does not allow "${part.type}" parts`;
97
+ const record = part;
98
+ switch (record.type) {
99
+ case "text": return requireString(record, "text", "text");
100
+ case "image": return requireMediaData(record, "image", "image");
101
+ case "file": return requireMediaData(record, "file", "data") ?? requireString(record, "file", "mediaType");
102
+ 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");
103
+ case "tool-result": return requireString(record, "tool-result", "toolCallId") ?? requireString(record, "tool-result", "toolName") ?? validateToolResultOutput(record.output);
104
+ default: return;
105
+ }
106
+ }
107
+ function validatePartsArray(content, allowedTypes, location) {
108
+ if (!Array.isArray(content)) return "Expected content to be a string or an array of parts";
109
+ for (const part of content) {
110
+ const error = validatePart(part, allowedTypes, location);
111
+ if (error) return error;
112
+ }
48
113
  }
49
114
  /**
50
115
  * A {@link StandardSchemaV1} validating an `AgentMessage[]` context field —
51
116
  * checks that every message has a known `role` (`system`/`user`/`assistant`/
52
117
  * `tool`) and that `content` is either a string (where the role allows it) or
53
- * an array of parts with a known `type`. Use it directly as a context
54
- * schema's `messages` field when authoring with `createAgentSchemas`.
118
+ * an array of role-appropriate parts whose required fields and media payloads
119
+ * have the right runtime types (extra fields are allowed). Use it directly as
120
+ * a context schema's `messages` field when authoring with `createAgentSchemas`.
55
121
  */
56
122
  const messagesSchema = { "~standard": {
57
123
  version: 1,
@@ -68,12 +134,12 @@ const messagesSchema = { "~standard": {
68
134
  continue;
69
135
  }
70
136
  if (role === "tool") {
71
- const error = validatePartsArray(content) ?? (content.some((part) => part.type !== "tool-result") ? "tool message content must contain only tool-result parts" : void 0);
137
+ const error = validatePartsArray(content, TOOL_PART_TYPES, "tool message content");
72
138
  if (error) return { issues: [{ message: error }] };
73
139
  continue;
74
140
  }
75
141
  if (typeof content === "string") continue;
76
- const error = validatePartsArray(content);
142
+ const error = validatePartsArray(content, role === "user" ? USER_PART_TYPES : ASSISTANT_PART_TYPES, `${role} message content`);
77
143
  if (error) return { issues: [{ message: error }] };
78
144
  }
79
145
  return { value };
@@ -124,6 +124,49 @@ interface DecisionLogicConfig<TInputSchema extends StandardSchemaV1 = StandardSc
124
124
  stopSequences?: ResolveTextLogicValue<string[] | undefined, InferOutput<TInputSchema>>;
125
125
  metadata?: ResolveTextLogicValue<TMetadata | undefined, InferOutput<TInputSchema>>;
126
126
  }
127
+ /**
128
+ * Actor logic for a decision: an async effect that resolves to exactly one
129
+ * currently-legal {@link ChosenEvent} (never a plain value). Under `runAgent`
130
+ * the chosen event is delivered to the invoking actor automatically — the
131
+ * transition it triggers usually exits the invoking state and ends the invoke.
132
+ * Built by {@link createDecisionLogic}. Register it under `actors:` to reuse/export/
133
+ * test it standalone; for a state-local, zero-config decision, use the
134
+ * `agent.decide` builtin invoke instead.
135
+ */
136
+ interface DecisionLogic<TInputSchema extends StandardSchemaV1 = StandardSchemaV1, TMetadata extends Record<string, unknown> = Record<string, unknown>> extends AsyncActorLogic<ChosenEvent, InferOutput<TInputSchema>> {
137
+ readonly kind: "statelyai.decisionLogic";
138
+ readonly maxRetries: number;
139
+ request(input: InferOutput<TInputSchema>): AgentDecisionRequest;
140
+ withExecutor(execute: AgentDecisionExecutor): DecisionLogic<TInputSchema, TMetadata>;
141
+ }
142
+ /**
143
+ * Creates reusable, standalone {@link DecisionLogic}: an actor that, when
144
+ * run, resolves to exactly one currently-legal {@link ChosenEvent} by
145
+ * calling the host `decide` executor (passed here as `execute`, or supplied
146
+ * later via {@link DecisionLogic.withExecutor}, `machine.provide(...)`, or
147
+ * `runAgent`'s `decide` option). Register the result under `actors:` and
148
+ * invoke it by name; for a one-off, state-local decision, prefer the
149
+ * `agent.decide` builtin invoke instead — it needs no separate declaration
150
+ * and types `allowedEvents` against the machine's own event schemas.
151
+ *
152
+ * @example
153
+ * ```ts
154
+ * import { createDecisionLogic } from '@statelyai/agent';
155
+ * import { z } from 'zod';
156
+ *
157
+ * export const chooseMove = createDecisionLogic({
158
+ * schemas: { input: z.object({ playerHp: z.number(), enemyHp: z.number() }) },
159
+ * model: 'openai/gpt-5.4-mini',
160
+ * system: 'You are playing a turn-based game. Choose exactly one legal move.',
161
+ * prompt: ({ input }) => `Player HP: ${input.playerHp}\nEnemy HP: ${input.enemyHp}`,
162
+ * allowedEvents: ({ input }) =>
163
+ * input.playerHp <= 6
164
+ * ? ['ATTACK', 'DEFEND', 'HEAL', 'FLEE']
165
+ * : ['ATTACK', 'DEFEND', 'FLEE'],
166
+ * });
167
+ * ```
168
+ */
169
+ declare function createDecisionLogic<TInputSchema extends StandardSchemaV1, TEvent extends string = string, TMetadata extends Record<string, unknown> = Record<string, unknown>, TModel extends string = string>(config: DecisionLogicConfig<TInputSchema, TEvent, TMetadata, TModel>, execute?: AgentDecisionExecutor): DecisionLogic<TInputSchema, TMetadata>;
127
170
  /**
128
171
  * A decision request: resolves to exactly one currently-legal event. See
129
172
  * `resolveDecision`.
@@ -744,4 +787,4 @@ declare function buildEnvelopeSchema(inner: StandardSchemaV1, options?: {
744
787
  */
745
788
  declare function parseStructuredEnvelope(request: Pick<AgentTextRequest, "outputSchema" | "includeReasoning">, value: unknown): StructuredOutputEnvelope;
746
789
  //#endregion
747
- export { AgentDecisionExecutor as A, AgentEventToolNameResolver as B, buildEnvelopeSchema as C, parseModelRef as D, getCallUsage as E, DecisionLogicConfig as F, parseAgentEvent as G, AgentRequestSource as H, ResolveDecisionOptions as I, renderDecisionAttempts as L, AgentDecisionInput as M, AgentDecisionRequest as N, parseOutput as O, DecisionAttempt as P, resolveDecision as R, bindRequestExecutor as S, getAgentOutputMode as T, AgentSchemas as U, AgentRequestOptions as V, getAcceptedEvents as W, StructuredOutputEnvelope as _, AgentOutputMode as a, TextLogicExecuteArgs as b, AgentRequestExecutorResult as c, AgentTextRequest as d, AgentUsage as f, BuiltinAgentActors as g, AiSdkShapedTextResult as h, AgentModelRef as i, AgentDecisionExhaustedError as j, parseStructuredEnvelope as k, AgentRequestExecutors as l, AiSdkShapedStreamResult as m, AgentExecutorTextRequest as n, AgentRequestExecutor as o, AgentUserInput as p, AgentModelMap as r, AgentRequestExecutorInfo as s, AgentCallUsage as t, AgentRequestMode as u, TextLogic as v, createTextLogic as w, TextLogicExecutor as x, TextLogicConfig as y, AgentEventDescriptor as z };
790
+ export { AgentDecisionExecutor as A, resolveDecision as B, buildEnvelopeSchema as C, parseModelRef as D, getCallUsage as E, DecisionLogic as F, AgentSchemas as G, AgentEventToolNameResolver as H, DecisionLogicConfig as I, getAcceptedEvents as K, ResolveDecisionOptions as L, AgentDecisionInput as M, AgentDecisionRequest as N, parseOutput as O, DecisionAttempt as P, createDecisionLogic as R, bindRequestExecutor as S, getAgentOutputMode as T, AgentRequestOptions as U, AgentEventDescriptor as V, AgentRequestSource as W, StructuredOutputEnvelope as _, AgentOutputMode as a, TextLogicExecuteArgs as b, AgentRequestExecutorResult as c, AgentTextRequest as d, AgentUsage as f, BuiltinAgentActors as g, AiSdkShapedTextResult as h, AgentModelRef as i, AgentDecisionExhaustedError as j, parseStructuredEnvelope as k, AgentRequestExecutors as l, AiSdkShapedStreamResult as m, AgentExecutorTextRequest as n, AgentRequestExecutor as o, AgentUserInput as p, parseAgentEvent as q, AgentModelMap as r, AgentRequestExecutorInfo as s, AgentCallUsage as t, AgentRequestMode as u, TextLogic as v, createTextLogic as w, TextLogicExecutor as x, TextLogicConfig as y, renderDecisionAttempts as z };
@@ -124,6 +124,49 @@ interface DecisionLogicConfig<TInputSchema extends StandardSchemaV1 = StandardSc
124
124
  stopSequences?: ResolveTextLogicValue<string[] | undefined, InferOutput<TInputSchema>>;
125
125
  metadata?: ResolveTextLogicValue<TMetadata | undefined, InferOutput<TInputSchema>>;
126
126
  }
127
+ /**
128
+ * Actor logic for a decision: an async effect that resolves to exactly one
129
+ * currently-legal {@link ChosenEvent} (never a plain value). Under `runAgent`
130
+ * the chosen event is delivered to the invoking actor automatically — the
131
+ * transition it triggers usually exits the invoking state and ends the invoke.
132
+ * Built by {@link createDecisionLogic}. Register it under `actors:` to reuse/export/
133
+ * test it standalone; for a state-local, zero-config decision, use the
134
+ * `agent.decide` builtin invoke instead.
135
+ */
136
+ interface DecisionLogic<TInputSchema extends StandardSchemaV1 = StandardSchemaV1, TMetadata extends Record<string, unknown> = Record<string, unknown>> extends AsyncActorLogic<ChosenEvent, InferOutput<TInputSchema>> {
137
+ readonly kind: "statelyai.decisionLogic";
138
+ readonly maxRetries: number;
139
+ request(input: InferOutput<TInputSchema>): AgentDecisionRequest;
140
+ withExecutor(execute: AgentDecisionExecutor): DecisionLogic<TInputSchema, TMetadata>;
141
+ }
142
+ /**
143
+ * Creates reusable, standalone {@link DecisionLogic}: an actor that, when
144
+ * run, resolves to exactly one currently-legal {@link ChosenEvent} by
145
+ * calling the host `decide` executor (passed here as `execute`, or supplied
146
+ * later via {@link DecisionLogic.withExecutor}, `machine.provide(...)`, or
147
+ * `runAgent`'s `decide` option). Register the result under `actors:` and
148
+ * invoke it by name; for a one-off, state-local decision, prefer the
149
+ * `agent.decide` builtin invoke instead — it needs no separate declaration
150
+ * and types `allowedEvents` against the machine's own event schemas.
151
+ *
152
+ * @example
153
+ * ```ts
154
+ * import { createDecisionLogic } from '@statelyai/agent';
155
+ * import { z } from 'zod';
156
+ *
157
+ * export const chooseMove = createDecisionLogic({
158
+ * schemas: { input: z.object({ playerHp: z.number(), enemyHp: z.number() }) },
159
+ * model: 'openai/gpt-5.4-mini',
160
+ * system: 'You are playing a turn-based game. Choose exactly one legal move.',
161
+ * prompt: ({ input }) => `Player HP: ${input.playerHp}\nEnemy HP: ${input.enemyHp}`,
162
+ * allowedEvents: ({ input }) =>
163
+ * input.playerHp <= 6
164
+ * ? ['ATTACK', 'DEFEND', 'HEAL', 'FLEE']
165
+ * : ['ATTACK', 'DEFEND', 'FLEE'],
166
+ * });
167
+ * ```
168
+ */
169
+ declare function createDecisionLogic<TInputSchema extends StandardSchemaV1, TEvent extends string = string, TMetadata extends Record<string, unknown> = Record<string, unknown>, TModel extends string = string>(config: DecisionLogicConfig<TInputSchema, TEvent, TMetadata, TModel>, execute?: AgentDecisionExecutor): DecisionLogic<TInputSchema, TMetadata>;
127
170
  /**
128
171
  * A decision request: resolves to exactly one currently-legal event. See
129
172
  * `resolveDecision`.
@@ -744,4 +787,4 @@ declare function buildEnvelopeSchema(inner: StandardSchemaV1, options?: {
744
787
  */
745
788
  declare function parseStructuredEnvelope(request: Pick<AgentTextRequest, "outputSchema" | "includeReasoning">, value: unknown): StructuredOutputEnvelope;
746
789
  //#endregion
747
- export { AgentDecisionExecutor as A, AgentEventToolNameResolver as B, buildEnvelopeSchema as C, parseModelRef as D, getCallUsage as E, DecisionLogicConfig as F, parseAgentEvent as G, AgentRequestSource as H, ResolveDecisionOptions as I, renderDecisionAttempts as L, AgentDecisionInput as M, AgentDecisionRequest as N, parseOutput as O, DecisionAttempt as P, resolveDecision as R, bindRequestExecutor as S, getAgentOutputMode as T, AgentSchemas as U, AgentRequestOptions as V, getAcceptedEvents as W, StructuredOutputEnvelope as _, AgentOutputMode as a, TextLogicExecuteArgs as b, AgentRequestExecutorResult as c, AgentTextRequest as d, AgentUsage as f, BuiltinAgentActors as g, AiSdkShapedTextResult as h, AgentModelRef as i, AgentDecisionExhaustedError as j, parseStructuredEnvelope as k, AgentRequestExecutors as l, AiSdkShapedStreamResult as m, AgentExecutorTextRequest as n, AgentRequestExecutor as o, AgentUserInput as p, AgentModelMap as r, AgentRequestExecutorInfo as s, AgentCallUsage as t, AgentRequestMode as u, TextLogic as v, createTextLogic as w, TextLogicExecutor as x, TextLogicConfig as y, AgentEventDescriptor as z };
790
+ export { AgentDecisionExecutor as A, resolveDecision as B, buildEnvelopeSchema as C, parseModelRef as D, getCallUsage as E, DecisionLogic as F, AgentSchemas as G, AgentEventToolNameResolver as H, DecisionLogicConfig as I, getAcceptedEvents as K, ResolveDecisionOptions as L, AgentDecisionInput as M, AgentDecisionRequest as N, parseOutput as O, DecisionAttempt as P, createDecisionLogic as R, bindRequestExecutor as S, getAgentOutputMode as T, AgentRequestOptions as U, AgentEventDescriptor as V, AgentRequestSource as W, StructuredOutputEnvelope as _, AgentOutputMode as a, TextLogicExecuteArgs as b, AgentRequestExecutorResult as c, AgentTextRequest as d, AgentUsage as f, BuiltinAgentActors as g, AiSdkShapedTextResult as h, AgentModelRef as i, AgentDecisionExhaustedError as j, parseStructuredEnvelope as k, AgentRequestExecutors as l, AiSdkShapedStreamResult as m, AgentExecutorTextRequest as n, AgentRequestExecutor as o, AgentUserInput as p, parseAgentEvent as q, AgentModelMap as r, AgentRequestExecutorInfo as s, AgentCallUsage as t, AgentRequestMode as u, TextLogic as v, createTextLogic as w, TextLogicExecutor as x, TextLogicConfig as y, renderDecisionAttempts as z };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@statelyai/agent",
3
- "version": "2.0.0-alpha.21",
3
+ "version": "2.0.0-alpha.22",
4
4
  "description": "Make invalid agent actions impossible. Agent logic as state machines: deterministic, inspectable, resumable, runs anywhere.",
5
5
  "keywords": [
6
6
  "agent",