@statelyai/agent 1.1.6 → 2.0.0-alpha.6

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 (84) hide show
  1. package/LICENSE +21 -0
  2. package/dist/ai-sdk.cjs +249 -0
  3. package/dist/ai-sdk.d.cts +168 -0
  4. package/dist/ai-sdk.d.mts +168 -0
  5. package/dist/ai-sdk.mjs +241 -0
  6. package/dist/cli.cjs +63 -0
  7. package/dist/cli.d.cts +1 -0
  8. package/dist/cli.d.mts +1 -0
  9. package/dist/cli.mjs +64 -0
  10. package/dist/decision-CX3YdwrO.cjs +1239 -0
  11. package/dist/decision-D1654JdD.mjs +940 -0
  12. package/dist/index.cjs +54 -0
  13. package/dist/index.d.cts +1217 -0
  14. package/dist/index.d.mts +1194 -405
  15. package/dist/index.mjs +3 -588
  16. package/dist/openai-compat.cjs +319 -0
  17. package/dist/openai-compat.d.cts +98 -0
  18. package/dist/openai-compat.d.mts +98 -0
  19. package/dist/openai-compat.mjs +312 -0
  20. package/dist/src-CEa947Dm.mjs +2449 -0
  21. package/dist/src-wBfi-kTA.cjs +2568 -0
  22. package/dist/text-logic-1ZQkO3zr.d.cts +682 -0
  23. package/dist/text-logic-2EMJIS-n.d.mts +682 -0
  24. package/dist/types-BHjeDdch.d.cts +208 -0
  25. package/dist/types-Cq1YlAQ6.d.mts +208 -0
  26. package/dist/utils-CWUCa3pF.d.mts +108 -0
  27. package/dist/utils-lK1wnL2i.d.cts +108 -0
  28. package/dist/zod.cjs +31 -0
  29. package/dist/zod.d.cts +30 -0
  30. package/dist/zod.d.mts +30 -0
  31. package/dist/zod.mjs +30 -0
  32. package/package.json +109 -28
  33. package/readme.md +144 -6
  34. package/schemas/agent-workflow.json +527 -0
  35. package/.changeset/README.md +0 -8
  36. package/.changeset/config.json +0 -11
  37. package/.env.template +0 -3
  38. package/.github/actions/ci-setup/action.yml +0 -24
  39. package/.github/workflows/release.yml +0 -46
  40. package/.vscode/launch.json +0 -28
  41. package/CHANGELOG.md +0 -222
  42. package/dist/index.d.ts +0 -428
  43. package/dist/index.js +0 -621
  44. package/examples/chatbot.ts +0 -71
  45. package/examples/cot.ts +0 -89
  46. package/examples/email.ts +0 -118
  47. package/examples/example.ts +0 -81
  48. package/examples/goal.ts +0 -94
  49. package/examples/helpers/helpers.ts +0 -17
  50. package/examples/helpers/loader.ts +0 -32
  51. package/examples/helpers/runner.ts +0 -27
  52. package/examples/joke.ts +0 -225
  53. package/examples/multi.ts +0 -103
  54. package/examples/newspaper.ts +0 -324
  55. package/examples/number.ts +0 -102
  56. package/examples/raffle.ts +0 -105
  57. package/examples/sandbox.ts +0 -28
  58. package/examples/simple.ts +0 -39
  59. package/examples/support.ts +0 -147
  60. package/examples/ticTacToe.ts +0 -224
  61. package/examples/todo.ts +0 -137
  62. package/examples/tutor.ts +0 -100
  63. package/examples/verify.ts +0 -120
  64. package/examples/weather.ts +0 -178
  65. package/examples/wiki.ts +0 -30
  66. package/examples/word.ts +0 -171
  67. package/src/adapters/vercel.ts +0 -7
  68. package/src/agent-experimental.ts +0 -221
  69. package/src/agent.test.ts +0 -506
  70. package/src/agent.ts +0 -300
  71. package/src/decision.test.ts +0 -179
  72. package/src/decision.ts +0 -84
  73. package/src/index.ts +0 -4
  74. package/src/memory.ts +0 -25
  75. package/src/planners/shortestPathPlanner.ts +0 -22
  76. package/src/planners/simplePlanner.ts +0 -139
  77. package/src/schemas.ts +0 -11
  78. package/src/strategies/chain-of-note.ts +0 -155
  79. package/src/templates/defaultText.ts +0 -18
  80. package/src/text.ts +0 -241
  81. package/src/types.ts +0 -499
  82. package/src/utils.ts +0 -72
  83. package/tsconfig.json +0 -109
  84. package/vitest.config.ts +0 -9
@@ -0,0 +1,241 @@
1
+ import { G as isStandardSchema, T as getAgentOutputMode, l as renderDecisionAttempts, x as buildEnvelopeSchema } from "./decision-D1654JdD.mjs";
2
+ import { Output, generateText, stepCountIs, streamText, tool } from "ai";
3
+ //#region src/ai-sdk/index.ts
4
+ /**
5
+ * Maps an {@link AgentTools} map onto AI SDK `tool()` definitions. A tool that
6
+ * already carries its own Standard Schema `inputSchema` — an AI SDK
7
+ * `tool({...})`, or any equivalent descriptor — is passed through **unchanged**,
8
+ * so the SDK applies its own validation, calls `execute(input, options)`, and
9
+ * every extra property (`providerOptions`, `toModelOutput`, …) survives. A bare
10
+ * `AgentToolExecute` function becomes a tool with an unconstrained input schema;
11
+ * a minimal descriptor with no readable schema is converted with a permissive
12
+ * fallback. Used internally by {@link toAiSdkCallSettings}; exported for callers
13
+ * building AI SDK calls by hand outside `createAiSdkExecutors`.
14
+ */
15
+ function toAiSdkTools(tools) {
16
+ const entries = [];
17
+ for (const [name, descriptor] of Object.entries(tools)) {
18
+ if (!descriptor) continue;
19
+ if (typeof descriptor === "function") {
20
+ entries.push([name, tool({
21
+ inputSchema: unknownSchema,
22
+ execute: (input) => descriptor(input)
23
+ })]);
24
+ continue;
25
+ }
26
+ if (isStandardSchema(descriptor.inputSchema)) {
27
+ entries.push([name, descriptor]);
28
+ continue;
29
+ }
30
+ const inputSchema = descriptor.inputSchema ?? descriptor.schemas?.input;
31
+ const toolOptions = {
32
+ description: descriptor.description,
33
+ inputSchema: inputSchema ? inputSchema : unknownSchema
34
+ };
35
+ if (descriptor.execute) {
36
+ entries.push([name, tool({
37
+ ...toolOptions,
38
+ execute: (input) => descriptor.execute?.(input)
39
+ })]);
40
+ continue;
41
+ }
42
+ entries.push([name, tool(toolOptions)]);
43
+ }
44
+ return Object.fromEntries(entries);
45
+ }
46
+ function maxStepsSetting(request) {
47
+ return typeof request.metadata?.maxSteps === "number" ? { stopWhen: stepCountIs(request.metadata.maxSteps) } : {};
48
+ }
49
+ const unknownSchema = { "~standard": {
50
+ version: 1,
51
+ vendor: "statelyai-agent",
52
+ validate: (value) => ({ value }),
53
+ jsonSchema: { input: () => ({}) }
54
+ } };
55
+ /**
56
+ * Identity helper for a `models` map whose value is exported. Returns the map
57
+ * unchanged, but types it as {@link AiSdkModelMap}`<keyof T & string>` — a
58
+ * portable, nameable type — so an exported `const models = defineModels({...})`
59
+ * needs no `Record<'a' | 'b', LanguageModel>` annotation and never triggers
60
+ * TS2742 ("inferred type cannot be named without a reference to …"). The exact
61
+ * ref keys survive, so `createAiSdkExecutors({ models })` and
62
+ * `setupAgent({ models })` still infer/autocomplete them.
63
+ *
64
+ * @example
65
+ * ```ts
66
+ * export const models = defineModels({
67
+ * quick: openai('gpt-5.4-mini'),
68
+ * deep: openai('gpt-5.4'),
69
+ * });
70
+ * // typeof models === AiSdkModelMap<'quick' | 'deep'>
71
+ * ```
72
+ */
73
+ function defineModels(models) {
74
+ return models;
75
+ }
76
+ function resolveAiSdkModel(options, modelRef) {
77
+ if (options.resolveModel) return options.resolveModel(modelRef);
78
+ const models = options.models;
79
+ if (!models) throw new Error(`createAiSdkExecutors: no model resolver configured for '${modelRef}'.`);
80
+ const model = models[modelRef];
81
+ if (!model) throw new Error(`createAiSdkExecutors: unknown model '${modelRef}'.`);
82
+ return model;
83
+ }
84
+ /**
85
+ * AI SDK request-mapping settings shared by `generateText`/`streamText`.
86
+ * `AgentTextRequest.messages` (`AgentMessage[]`) and AI SDK's `ModelMessage[]`
87
+ * are structurally compatible by design (§1 of docs/p0-design.md) — the cast
88
+ * below is a typed identity mapping, not a semantic conversion.
89
+ */
90
+ function toAiSdkCallSettings(request) {
91
+ const messages = request.messages;
92
+ return {
93
+ system: request.system,
94
+ ...messages ? { messages } : { prompt: request.prompt ?? "" },
95
+ temperature: request.temperature,
96
+ maxOutputTokens: request.maxOutputTokens,
97
+ topP: request.topP,
98
+ topK: request.topK,
99
+ seed: request.seed,
100
+ stopSequences: request.stopSequences,
101
+ tools: request.tools ? toAiSdkTools(request.tools) : void 0,
102
+ toolChoice: toAiSdkToolChoice(request.toolChoice)
103
+ };
104
+ }
105
+ /** Maps an {@link AgentToolChoice} to AI SDK's tool-choice shape — `{ type: 'tool'; name }` becomes `{ type: 'tool'; toolName }`; `'auto'`/`'none'`/`'required'`/`undefined` pass through unchanged. */
106
+ function toAiSdkToolChoice(toolChoice) {
107
+ return typeof toolChoice === "object" ? {
108
+ type: "tool",
109
+ toolName: toolChoice.name
110
+ } : toolChoice;
111
+ }
112
+ /** `true` when the request should use AI SDK structured `Output.object`. */
113
+ function isStructuredOutputRequest(request) {
114
+ return getAgentOutputMode(request.outputSchema) === "structured";
115
+ }
116
+ /**
117
+ * The canonical Vercel AI SDK adapter: builds the `{ generateText, streamText,
118
+ * decide }` executor set consumed by `runAgent`/`executeAgentRequest`. `ai`
119
+ * must not become a dependency of core `src/` files — this subpath is the one
120
+ * place it's imported, and callers must supply their own model resolver so no
121
+ * concrete provider package (e.g. `@ai-sdk/openai`) becomes a dependency here
122
+ * either.
123
+ *
124
+ * @example
125
+ * ```ts
126
+ * const executors = createAiSdkExecutors({ models: { quick: openai('gpt-5.4-mini') } });
127
+ * const result = await runAgent(machine, { input, executors });
128
+ * ```
129
+ */
130
+ function createAiSdkExecutors(options) {
131
+ const generateText$1 = async (request, info) => {
132
+ const common = {
133
+ model: resolveAiSdkModel(options, request.model),
134
+ abortSignal: info?.signal,
135
+ ...toAiSdkCallSettings(request),
136
+ ...maxStepsSetting(request)
137
+ };
138
+ if (isStructuredOutputRequest(request)) {
139
+ const envelope = buildEnvelopeSchema(request.outputSchema, { reasoning: request.reasoning });
140
+ const result = await generateText({
141
+ ...common,
142
+ output: Output.object({ schema: envelope })
143
+ });
144
+ const { result: output, reasoning } = result.output;
145
+ return {
146
+ output,
147
+ ...reasoning !== void 0 ? { reasoning } : {},
148
+ usage: result.usage,
149
+ finishReason: result.finishReason,
150
+ toolCalls: result.toolCalls,
151
+ toolResults: result.toolResults
152
+ };
153
+ }
154
+ const result = await generateText(common);
155
+ return {
156
+ output: result.text,
157
+ usage: result.usage,
158
+ finishReason: result.finishReason,
159
+ toolCalls: result.toolCalls,
160
+ toolResults: result.toolResults
161
+ };
162
+ };
163
+ const streamText$1 = async (request, info) => {
164
+ const result = streamText({
165
+ model: resolveAiSdkModel(options, request.model),
166
+ abortSignal: info?.signal,
167
+ ...toAiSdkCallSettings(request),
168
+ ...maxStepsSetting(request)
169
+ });
170
+ for await (const chunk of result.textStream) info?.onChunk?.(chunk);
171
+ return {
172
+ output: await result.text,
173
+ usage: await result.usage,
174
+ finishReason: await result.finishReason
175
+ };
176
+ };
177
+ const decide = async (request) => {
178
+ const model = resolveAiSdkModel(options, request.model);
179
+ const tools = toAiSdkEventTools(request.events);
180
+ const messages = toDecisionMessages(request);
181
+ const result = await generateText({
182
+ model,
183
+ abortSignal: request.signal,
184
+ system: request.system,
185
+ ...messages ? { messages } : { prompt: request.prompt ?? "" },
186
+ tools,
187
+ toolChoice: "required",
188
+ stopWhen: stepCountIs(1),
189
+ temperature: request.temperature,
190
+ maxOutputTokens: request.maxOutputTokens,
191
+ topP: request.topP,
192
+ topK: request.topK,
193
+ seed: request.seed,
194
+ stopSequences: request.stopSequences
195
+ });
196
+ const toolCall = result.toolCalls[0];
197
+ if (!toolCall) throw new Error("createAiSdkExecutors: decide — model did not call an event tool.");
198
+ const chosenEvent = request.events.find((event) => event.toolName === toolCall.toolName);
199
+ if (!chosenEvent) throw new Error(`createAiSdkExecutors: decide — model called unknown tool '${toolCall.toolName}'.`);
200
+ return {
201
+ event: {
202
+ ...toolCall.input && typeof toolCall.input === "object" ? toolCall.input : {},
203
+ type: chosenEvent.type
204
+ },
205
+ usage: result.usage,
206
+ finishReason: result.finishReason
207
+ };
208
+ };
209
+ return {
210
+ generateText: generateText$1,
211
+ streamText: streamText$1,
212
+ decide
213
+ };
214
+ }
215
+ /** One AI SDK `tool()` per candidate event — the "tool-per-event +
216
+ * toolChoice: 'required'" recipe from docs/p0-design.md §2.6. */
217
+ function toAiSdkEventTools(events) {
218
+ return Object.fromEntries(events.map((event) => [event.toolName, tool({
219
+ description: `Choose the '${event.type}' move.`,
220
+ inputSchema: event.inputSchema ? event.inputSchema : unknownSchema
221
+ })]));
222
+ }
223
+ /**
224
+ * Messages for a decision request, with prior failed `attempts` (§2.6)
225
+ * rendered as appended user messages (via core's {@link renderDecisionAttempts})
226
+ * so retries converge. Core never rewrites prompts — this is adapter business.
227
+ */
228
+ function toDecisionMessages(request) {
229
+ if (!request.messages && request.attempts.length === 0) return;
230
+ const messages = [...request.messages ?? (request.prompt !== void 0 ? [{
231
+ role: "user",
232
+ content: request.prompt
233
+ }] : [])];
234
+ for (const attempt of renderDecisionAttempts(request)) messages.push({
235
+ role: "user",
236
+ content: attempt.content
237
+ });
238
+ return messages;
239
+ }
240
+ //#endregion
241
+ export { createAiSdkExecutors, defineModels, isStructuredOutputRequest, toAiSdkCallSettings, toAiSdkEventTools, toAiSdkToolChoice, toAiSdkTools, toDecisionMessages };
package/dist/cli.cjs ADDED
@@ -0,0 +1,63 @@
1
+ #!/usr/bin/env node
2
+ const require_src = require("./src-wBfi-kTA.cjs");
3
+ let node_fs = require("node:fs");
4
+ //#region src/cli.ts
5
+ /**
6
+ * `statelyai-agent lint <workflow.json>` — keyless static verification for an
7
+ * agent machine authored as data (an {@link AgentWorkflowConfig} JSON file).
8
+ *
9
+ * The library bundles no JSON Schema engine, so the CLI lints STRUCTURE ONLY:
10
+ * it compiles the config with a permissive pass-through schema compiler (each
11
+ * JSON Schema is kept as-is for structural checks, validation is a no-op) and
12
+ * runs {@link lintAgentMachine}. Exits `1` on any error-severity finding.
13
+ *
14
+ * For full schema-aware linting, import the API and compile with a real engine:
15
+ * `lintAgentMachine(setupAgent.fromConfig(config, { compileSchema }))`.
16
+ *
17
+ * @module
18
+ */
19
+ function stubCompileSchema(jsonSchema) {
20
+ return { "~standard": {
21
+ version: 1,
22
+ vendor: "statelyai-agent-cli",
23
+ validate: (value) => ({ value }),
24
+ jsonSchema: { input: () => jsonSchema }
25
+ } };
26
+ }
27
+ function printUsage() {
28
+ process.stderr.write("Usage: statelyai-agent lint <workflow.json> [--no-schemas]\n\n Statically verifies an agent-machine JSON config (structure-only).\n Exits 1 on any error-severity finding.\n");
29
+ }
30
+ function main(argv) {
31
+ const args = argv.slice(2);
32
+ const command = args[0];
33
+ const file = args.find((arg, index) => index > 0 && !arg.startsWith("-"));
34
+ if (command !== "lint" || !file) {
35
+ printUsage();
36
+ return 2;
37
+ }
38
+ let config;
39
+ try {
40
+ config = JSON.parse((0, node_fs.readFileSync)(file, "utf8"));
41
+ } catch (error) {
42
+ process.stderr.write(`statelyai-agent: could not read/parse '${file}': ${error instanceof Error ? error.message : String(error)}\n`);
43
+ return 2;
44
+ }
45
+ let machine;
46
+ try {
47
+ machine = require_src.setupAgent.fromConfig(config, { compileSchema: stubCompileSchema });
48
+ } catch (error) {
49
+ process.stderr.write(`statelyai-agent: '${file}' is not a valid agent-machine config: ${error instanceof Error ? error.message : String(error)}\n`);
50
+ return 2;
51
+ }
52
+ const diagnostics = require_src.lintAgentMachine(machine);
53
+ const errors = diagnostics.filter((d) => d.severity === "error");
54
+ const warnings = diagnostics.filter((d) => d.severity === "warning");
55
+ for (const d of diagnostics) {
56
+ const label = d.severity === "error" ? "error" : "warn ";
57
+ process.stdout.write(` ${label} ${d.code} ${d.path}\n ${d.message}\n`);
58
+ }
59
+ process.stdout.write(`\n${file}: ${errors.length} error(s), ${warnings.length} warning(s) (structure-only; schemas not compiled).\n`);
60
+ return errors.length > 0 ? 1 : 0;
61
+ }
62
+ process.exit(main(process.argv));
63
+ //#endregion
package/dist/cli.d.cts ADDED
@@ -0,0 +1 @@
1
+ export { };
package/dist/cli.d.mts ADDED
@@ -0,0 +1 @@
1
+ export { };
package/dist/cli.mjs ADDED
@@ -0,0 +1,64 @@
1
+ #!/usr/bin/env node
2
+ import { r as lintAgentMachine, v as setupAgent } from "./src-CEa947Dm.mjs";
3
+ import { readFileSync } from "node:fs";
4
+ //#region src/cli.ts
5
+ /**
6
+ * `statelyai-agent lint <workflow.json>` — keyless static verification for an
7
+ * agent machine authored as data (an {@link AgentWorkflowConfig} JSON file).
8
+ *
9
+ * The library bundles no JSON Schema engine, so the CLI lints STRUCTURE ONLY:
10
+ * it compiles the config with a permissive pass-through schema compiler (each
11
+ * JSON Schema is kept as-is for structural checks, validation is a no-op) and
12
+ * runs {@link lintAgentMachine}. Exits `1` on any error-severity finding.
13
+ *
14
+ * For full schema-aware linting, import the API and compile with a real engine:
15
+ * `lintAgentMachine(setupAgent.fromConfig(config, { compileSchema }))`.
16
+ *
17
+ * @module
18
+ */
19
+ function stubCompileSchema(jsonSchema) {
20
+ return { "~standard": {
21
+ version: 1,
22
+ vendor: "statelyai-agent-cli",
23
+ validate: (value) => ({ value }),
24
+ jsonSchema: { input: () => jsonSchema }
25
+ } };
26
+ }
27
+ function printUsage() {
28
+ process.stderr.write("Usage: statelyai-agent lint <workflow.json> [--no-schemas]\n\n Statically verifies an agent-machine JSON config (structure-only).\n Exits 1 on any error-severity finding.\n");
29
+ }
30
+ function main(argv) {
31
+ const args = argv.slice(2);
32
+ const command = args[0];
33
+ const file = args.find((arg, index) => index > 0 && !arg.startsWith("-"));
34
+ if (command !== "lint" || !file) {
35
+ printUsage();
36
+ return 2;
37
+ }
38
+ let config;
39
+ try {
40
+ config = JSON.parse(readFileSync(file, "utf8"));
41
+ } catch (error) {
42
+ process.stderr.write(`statelyai-agent: could not read/parse '${file}': ${error instanceof Error ? error.message : String(error)}\n`);
43
+ return 2;
44
+ }
45
+ let machine;
46
+ try {
47
+ machine = setupAgent.fromConfig(config, { compileSchema: stubCompileSchema });
48
+ } catch (error) {
49
+ process.stderr.write(`statelyai-agent: '${file}' is not a valid agent-machine config: ${error instanceof Error ? error.message : String(error)}\n`);
50
+ return 2;
51
+ }
52
+ const diagnostics = lintAgentMachine(machine);
53
+ const errors = diagnostics.filter((d) => d.severity === "error");
54
+ const warnings = diagnostics.filter((d) => d.severity === "warning");
55
+ for (const d of diagnostics) {
56
+ const label = d.severity === "error" ? "error" : "warn ";
57
+ process.stdout.write(` ${label} ${d.code} ${d.path}\n ${d.message}\n`);
58
+ }
59
+ process.stdout.write(`\n${file}: ${errors.length} error(s), ${warnings.length} warning(s) (structure-only; schemas not compiled).\n`);
60
+ return errors.length > 0 ? 1 : 0;
61
+ }
62
+ process.exit(main(process.argv));
63
+ //#endregion
64
+ export {};