@statelyai/agent 2.0.0-alpha.10 → 2.0.0-alpha.11
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/adapter.cjs +15 -0
- package/dist/adapter.d.cts +4 -0
- package/dist/adapter.d.mts +4 -0
- package/dist/adapter.mjs +2 -0
- package/dist/ai-sdk.cjs +66 -102
- package/dist/ai-sdk.d.cts +5 -115
- package/dist/ai-sdk.d.mts +5 -115
- package/dist/ai-sdk.mjs +64 -91
- package/dist/decision-C3k4ve51.mjs +227 -0
- package/dist/decision-D8wJrM8W.cjs +286 -0
- package/dist/{decision-b-lkcs4L.cjs → events-CRQj3VtP.cjs} +10 -295
- package/dist/{decision-CQdrKc8k.mjs → events-JiVPYrct.mjs} +10 -229
- package/dist/index.cjs +2521 -52
- package/dist/index.d.cts +1029 -9
- package/dist/index.d.mts +1029 -9
- package/dist/index.mjs +2493 -4
- package/dist/openai-compat.cjs +23 -33
- package/dist/openai-compat.d.cts +3 -42
- package/dist/openai-compat.d.mts +3 -42
- package/dist/openai-compat.mjs +20 -24
- package/dist/steps-BALp1eZo.d.mts +198 -0
- package/dist/steps-CVe54GPP.cjs +420 -0
- package/dist/steps-CkyyyuHd.mjs +379 -0
- package/dist/steps-MjnQI4aB.d.cts +198 -0
- package/dist/steps.cjs +12 -0
- package/dist/steps.d.cts +3 -0
- package/dist/steps.d.mts +3 -0
- package/dist/steps.mjs +3 -0
- package/dist/{text-logic-C7WJpCIc.d.mts → text-logic-CaKqgX4Y.d.mts} +8 -8
- package/dist/{text-logic-CZjyACzQ.d.cts → text-logic-Ckhr2kKC.d.cts} +8 -8
- package/package.json +27 -4
- package/readme.md +18 -8
- package/schemas/agent-workflow.json +4 -5
- package/dist/cli.cjs +0 -64
- package/dist/cli.d.cts +0 -1
- package/dist/cli.d.mts +0 -1
- package/dist/cli.mjs +0 -65
- package/dist/run-agent-BFMkuI1F.cjs +0 -1599
- package/dist/run-agent-BVMd--1l.d.cts +0 -1103
- package/dist/run-agent-BoAOq_0Z.mjs +0 -1540
- package/dist/run-agent-DzYJb3CK.d.mts +0 -1103
- package/dist/src-D-77Ha5p.cjs +0 -1087
- package/dist/src-DUeIFjv-.mjs +0 -1016
- /package/dist/{utils-Dri7aeEG.d.cts → utils-BYqT_Dyv.d.cts} +0 -0
- /package/dist/{utils-Y6GDRGGE.d.mts → utils-Do5wIJrh.d.mts} +0 -0
|
@@ -4,8 +4,6 @@ import { AnyMachineSnapshot, AsyncActorLogic, EventObject, LogicActorLogic, Mach
|
|
|
4
4
|
//#region src/events.d.ts
|
|
5
5
|
/** The invoke `src` of an {@link AgentRequest}/{@link AgentDecisionRequest} — a plain string, widened so literal `src` values still narrow in editor hints. */
|
|
6
6
|
type AgentRequestSource = string & {};
|
|
7
|
-
/** Default prefix for the synthetic tool name generated per candidate event (e.g. `send_event_ASK`). Override per-request with {@link AgentEventToolNameResolver}. */
|
|
8
|
-
declare const EVENT_TOOL_PREFIX: "send_event_";
|
|
9
7
|
/** Customizes the tool name generated for a candidate event; see {@link AgentRequestOptions.eventToolName}. */
|
|
10
8
|
type AgentEventToolNameResolver = (args: {
|
|
11
9
|
eventType: string;
|
|
@@ -648,13 +646,15 @@ type AgentRequestExecutor<TResult extends AgentRequestExecutorResult = AgentRequ
|
|
|
648
646
|
/**
|
|
649
647
|
* The full set of host executors a machine's agent actors are resolved
|
|
650
648
|
* with — passed to `runAgent`, `executeAgentRequest`, and
|
|
651
|
-
* `TextLogic.execute`.
|
|
652
|
-
*
|
|
653
|
-
*
|
|
654
|
-
* machine actually needs
|
|
649
|
+
* `TextLogic.execute`. Every slot is optional: `generateText` is needed only
|
|
650
|
+
* if the machine has a `mode: 'generate'` text request, `streamText` only for
|
|
651
|
+
* a `mode: 'stream'` request, and `decide` only for a decision/plan — omitting
|
|
652
|
+
* a slot the machine actually needs is a clear bind-time error (see `runAgent`
|
|
653
|
+
* and `provideExecutors`). Adapter result sets (`AiSdkExecutors`,
|
|
654
|
+
* `OpenAiCompatExecutors`) re-require all three.
|
|
655
655
|
*/
|
|
656
656
|
interface AgentRequestExecutors<TGenerateResult extends AgentRequestExecutorResult = AgentRequestExecutorResult, TStreamResult extends AgentRequestExecutorResult = AgentRequestExecutorResult> {
|
|
657
|
-
generateText
|
|
657
|
+
generateText?: AgentRequestExecutor<TGenerateResult>;
|
|
658
658
|
streamText?: AgentRequestExecutor<TStreamResult>;
|
|
659
659
|
decide?: AgentDecisionExecutor;
|
|
660
660
|
}
|
|
@@ -707,4 +707,4 @@ declare function buildEnvelopeSchema(inner: StandardSchemaV1, options?: {
|
|
|
707
707
|
*/
|
|
708
708
|
declare function parseStructuredEnvelope(request: Pick<AgentTextRequest, "outputSchema" | "reasoning">, value: unknown): StructuredOutputEnvelope;
|
|
709
709
|
//#endregion
|
|
710
|
-
export { AgentDecisionInput as A,
|
|
710
|
+
export { AgentDecisionInput as A, ResolveDecisionOptions as B, createTextLogic as C, parseOutput as D, parseModelRef as E, DecisionExhaustedError as F, AgentRequestOptions as G, resolveDecision as H, DecisionLogic as I, matchesEventPattern as J, AgentRequestSource as K, DecisionLogicConfig as L, AgentPlanInput as M, AgentPlanOutput as N, parseStructuredEnvelope as O, DecisionAttempt as P, PLAN_DONE_EVENT_TYPE as R, buildEnvelopeSchema as S, isStructuredOutputSchema as T, AgentEventDescriptor as U, renderDecisionAttempts as V, AgentEventToolNameResolver as W, parseAgentEvent as Y, TextLogicExecuteArgs as _, AgentRequestExecutorInfo as a, TextLogicOutput as b, AgentRequestMode as c, AiSdkShapedStreamResult as d, AiSdkShapedTextResult as f, TextLogicConfig as g, TextLogic as h, AgentRequestExecutor as i, AgentDecisionRequest as j, AgentDecisionExecutor as k, AgentTextRequest as l, StructuredOutputEnvelope as m, AgentModelRef as n, AgentRequestExecutorResult as o, BuiltinAgentActors as p, getAcceptedEvents as q, AgentOutputMode as r, AgentRequestExecutors as s, AgentModelMap as t, AgentUserInput as u, TextLogicExecutor as v, getAgentOutputMode as w, bindRequestExecutor as x, TextLogicInput as y, PlanLogic as z };
|
package/package.json
CHANGED
|
@@ -1,14 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@statelyai/agent",
|
|
3
|
-
"version": "2.0.0-alpha.
|
|
3
|
+
"version": "2.0.0-alpha.11",
|
|
4
4
|
"description": "State-machine authoring layer for AI agents",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.cjs",
|
|
7
7
|
"module": "dist/index.mjs",
|
|
8
8
|
"types": "dist/index.d.mts",
|
|
9
|
-
"bin": {
|
|
10
|
-
"statelyai-agent": "dist/cli.mjs"
|
|
11
|
-
},
|
|
12
9
|
"exports": {
|
|
13
10
|
".": {
|
|
14
11
|
"import": {
|
|
@@ -40,6 +37,26 @@
|
|
|
40
37
|
"default": "./dist/openai-compat.cjs"
|
|
41
38
|
}
|
|
42
39
|
},
|
|
40
|
+
"./steps": {
|
|
41
|
+
"import": {
|
|
42
|
+
"types": "./dist/steps.d.mts",
|
|
43
|
+
"default": "./dist/steps.mjs"
|
|
44
|
+
},
|
|
45
|
+
"require": {
|
|
46
|
+
"types": "./dist/steps.d.cts",
|
|
47
|
+
"default": "./dist/steps.cjs"
|
|
48
|
+
}
|
|
49
|
+
},
|
|
50
|
+
"./adapter": {
|
|
51
|
+
"import": {
|
|
52
|
+
"types": "./dist/adapter.d.mts",
|
|
53
|
+
"default": "./dist/adapter.mjs"
|
|
54
|
+
},
|
|
55
|
+
"require": {
|
|
56
|
+
"types": "./dist/adapter.d.cts",
|
|
57
|
+
"default": "./dist/adapter.cjs"
|
|
58
|
+
}
|
|
59
|
+
},
|
|
43
60
|
"./zod": {
|
|
44
61
|
"import": {
|
|
45
62
|
"types": "./dist/zod.d.mts",
|
|
@@ -83,15 +100,20 @@
|
|
|
83
100
|
"@cloudflare/workers-types": "^4.20260702.1",
|
|
84
101
|
"@inquirer/prompts": "^8.5.2",
|
|
85
102
|
"@statelyai/inspect": "^0.7.2",
|
|
103
|
+
"@types/express": "^5.0.6",
|
|
86
104
|
"@types/node": "^20.16.10",
|
|
105
|
+
"@types/react": "^19.2.17",
|
|
87
106
|
"agents": "0.11.5",
|
|
88
107
|
"ai": "^6.0.67",
|
|
89
108
|
"ajv": "^8.20.0",
|
|
90
109
|
"dotenv": "^16.4.5",
|
|
110
|
+
"express": "^5.2.1",
|
|
111
|
+
"hono": "^4.12.30",
|
|
91
112
|
"knip": "6.24.0",
|
|
92
113
|
"openai": "^6.45.0",
|
|
93
114
|
"oxfmt": "0.57.0",
|
|
94
115
|
"oxlint": "1.72.0",
|
|
116
|
+
"react": "^19.2.7",
|
|
95
117
|
"tsdown": "^0.21.7",
|
|
96
118
|
"tsx": "^4.21.0",
|
|
97
119
|
"typescript": "^5.6.2",
|
|
@@ -126,6 +148,7 @@
|
|
|
126
148
|
"format:check": "oxfmt --check src examples",
|
|
127
149
|
"knip": "knip",
|
|
128
150
|
"check": "pnpm run typecheck && pnpm run lint && pnpm run format:check && pnpm run knip",
|
|
151
|
+
"check:dts": "tsc -p fixtures/dts-consumer/tsconfig.json",
|
|
129
152
|
"test": "vitest",
|
|
130
153
|
"test:ci": "vitest --run",
|
|
131
154
|
"changeset": "changeset",
|
package/readme.md
CHANGED
|
@@ -2,25 +2,31 @@
|
|
|
2
2
|
|
|
3
3
|
**The logic layer for AI agents.**
|
|
4
4
|
|
|
5
|
-
Build agents as state machines
|
|
5
|
+
Build agents as state machines to control exactly what the agent can do. The machine owns control flow; the model only ever picks a legal event. Testing, inspection, and visualization fall out for free.
|
|
6
6
|
|
|
7
7
|
Stately Agent adds model requests and decisions to XState. The state machine defines what the agent can do. Your application chooses the model, runs the requests, and stores the state.
|
|
8
8
|
|
|
9
|
-
Any agent workflow or loop can be modeled as a state machine. Model calls and tools run as effects inside it. The model proposes an event. The machine decides whether it is allowed and what happens next.
|
|
9
|
+
Any agent workflow or loop can be modeled as a state machine. Model calls and tools run as effects inside it. The model proposes an event. The machine decides whether it is allowed and what happens next. See [how this compares to LangGraph and hand-rolling a loop](docs/comparison.md).
|
|
10
10
|
|
|
11
11
|
Stately Agent 2 is in alpha. APIs may change before the stable release.
|
|
12
12
|
|
|
13
13
|
[Documentation](https://stately.ai/docs/agents) · [Examples](examples/README.md) · [XState](https://github.com/statelyai/xstate)
|
|
14
14
|
|
|
15
|
+
## Three ways to start
|
|
16
|
+
|
|
17
|
+
- **Author a new agent.** Build a machine from states, decisions, and typed requests; run it locally with `runAgent`, test it with no API key, then eject to any framework or runtime with zero machine changes. See the [Quickstart](docs/quickstart.md) and [Eject to your stack](docs/eject.md).
|
|
18
|
+
- **Retrofit an existing agent.** Turn a `while` loop into a machine: your SDK calls, tools, and retry code become the executors; the machine replaces only the control flow. See [Migrating from a loop](docs/from-a-loop.md).
|
|
19
|
+
- **Copy a known pattern.** ReAct, reflection, plan-and-execute, RAG, supervisor, and more, each a single runnable file you lift in 60 seconds. See [Agent patterns](docs/patterns.md).
|
|
20
|
+
|
|
15
21
|
## Install
|
|
16
22
|
|
|
17
23
|
<!-- install command matching the package prerelease channel and package.json peers -->
|
|
18
24
|
|
|
19
25
|
```sh
|
|
20
|
-
pnpm add @statelyai/agent@alpha xstate@alpha zod ai @ai-sdk/openai
|
|
26
|
+
pnpm add @statelyai/agent@alpha xstate@alpha zod ai@^6 @ai-sdk/openai@^3
|
|
21
27
|
```
|
|
22
28
|
|
|
23
|
-
Node 22.18 or newer is required.
|
|
29
|
+
Node 22.18 or newer is required. The package is ESM-only; the library targets XState v6 alpha and stays compatible with XState v5. Provider packages must match your `ai` major: `@ai-sdk/openai@^3` pairs with `ai@^6` (a bare `@ai-sdk/openai` resolves to `@latest`, which can mismatch the `ai` peer).
|
|
24
30
|
|
|
25
31
|
## Quick start
|
|
26
32
|
|
|
@@ -30,15 +36,15 @@ This agent reviews refund requests. The model may propose an automatic refund, b
|
|
|
30
36
|
|
|
31
37
|
```ts
|
|
32
38
|
import { openai } from "@ai-sdk/openai";
|
|
33
|
-
import {
|
|
34
|
-
import {
|
|
39
|
+
import { runAgent, setupAgent } from "@statelyai/agent";
|
|
40
|
+
import { createAiSdkExecutors, defineModels } from "@statelyai/agent/ai-sdk";
|
|
35
41
|
import { z } from "zod";
|
|
36
42
|
|
|
37
43
|
const models = defineModels({
|
|
38
44
|
fast: openai("gpt-5.4-mini"),
|
|
39
45
|
});
|
|
40
46
|
|
|
41
|
-
const
|
|
47
|
+
const agentSetup = setupAgent({
|
|
42
48
|
models,
|
|
43
49
|
context: z.object({
|
|
44
50
|
request: z.string(),
|
|
@@ -57,7 +63,7 @@ const agent = setupAgent({
|
|
|
57
63
|
},
|
|
58
64
|
});
|
|
59
65
|
|
|
60
|
-
const refundMachine =
|
|
66
|
+
const refundMachine = agentSetup.createMachine({
|
|
61
67
|
context: ({ input }) => input,
|
|
62
68
|
initial: "deciding",
|
|
63
69
|
states: {
|
|
@@ -92,6 +98,7 @@ const result = await runAgent(refundMachine, {
|
|
|
92
98
|
request: "I was charged twice for the same order.",
|
|
93
99
|
amount: 75,
|
|
94
100
|
},
|
|
101
|
+
executors: createAiSdkExecutors({ models }),
|
|
95
102
|
});
|
|
96
103
|
|
|
97
104
|
if (result.status === "done") {
|
|
@@ -145,3 +152,6 @@ See [all examples](examples/README.md).
|
|
|
145
152
|
- [Human in the loop](docs/human-in-the-loop.md)
|
|
146
153
|
- [Testing and verification](docs/verify.md)
|
|
147
154
|
- [Running on different hosts](docs/hosts.md)
|
|
155
|
+
- [Eject to your stack](docs/eject.md)
|
|
156
|
+
- [Agent patterns](docs/patterns.md)
|
|
157
|
+
- [Migrating from a loop](docs/from-a-loop.md)
|
|
@@ -6,6 +6,10 @@
|
|
|
6
6
|
"type": "object",
|
|
7
7
|
"required": ["initial", "states"],
|
|
8
8
|
"properties": {
|
|
9
|
+
"$schema": {
|
|
10
|
+
"description": "JSON Schema reference an editor attaches to the config file. Ignored by the lowering.",
|
|
11
|
+
"type": "string"
|
|
12
|
+
},
|
|
9
13
|
"key": {
|
|
10
14
|
"description": "Stable workflow key used by tools, storage, and visual editors.",
|
|
11
15
|
"type": "string",
|
|
@@ -23,11 +27,6 @@
|
|
|
23
27
|
"description": {
|
|
24
28
|
"type": "string"
|
|
25
29
|
},
|
|
26
|
-
"queryLanguage": {
|
|
27
|
-
"description": "Expression language used inside {{ }} expressions. The built-in setupAgent.fromConfig lowering currently supports simple dot-path expressions over input, context, and event.",
|
|
28
|
-
"type": "string",
|
|
29
|
-
"default": "path"
|
|
30
|
-
},
|
|
31
30
|
"schemas": {
|
|
32
31
|
"$ref": "#/$defs/AgentSchemas"
|
|
33
32
|
},
|
package/dist/cli.cjs
DELETED
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
const require_run_agent = require("./run-agent-BFMkuI1F.cjs");
|
|
3
|
-
const require_src = require("./src-D-77Ha5p.cjs");
|
|
4
|
-
let node_fs = require("node:fs");
|
|
5
|
-
//#region src/cli.ts
|
|
6
|
-
/**
|
|
7
|
-
* `statelyai-agent lint <workflow.json>` — keyless static verification for an
|
|
8
|
-
* agent machine authored as data (an {@link AgentWorkflowConfig} JSON file).
|
|
9
|
-
*
|
|
10
|
-
* The library bundles no JSON Schema engine, so the CLI lints STRUCTURE ONLY:
|
|
11
|
-
* it compiles the config with a permissive pass-through schema compiler (each
|
|
12
|
-
* JSON Schema is kept as-is for structural checks, validation is a no-op) and
|
|
13
|
-
* runs {@link lintAgentMachine}. Exits `1` on any error-severity finding.
|
|
14
|
-
*
|
|
15
|
-
* For full schema-aware linting, import the API and compile with a real engine:
|
|
16
|
-
* `lintAgentMachine(setupAgent.fromConfig(config, { compileSchema }))`.
|
|
17
|
-
*
|
|
18
|
-
* @module
|
|
19
|
-
*/
|
|
20
|
-
function stubCompileSchema(jsonSchema) {
|
|
21
|
-
return { "~standard": {
|
|
22
|
-
version: 1,
|
|
23
|
-
vendor: "statelyai-agent-cli",
|
|
24
|
-
validate: (value) => ({ value }),
|
|
25
|
-
jsonSchema: { input: () => jsonSchema }
|
|
26
|
-
} };
|
|
27
|
-
}
|
|
28
|
-
function printUsage() {
|
|
29
|
-
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");
|
|
30
|
-
}
|
|
31
|
-
function main(argv) {
|
|
32
|
-
const args = argv.slice(2);
|
|
33
|
-
const command = args[0];
|
|
34
|
-
const file = args.find((arg, index) => index > 0 && !arg.startsWith("-"));
|
|
35
|
-
if (command !== "lint" || !file) {
|
|
36
|
-
printUsage();
|
|
37
|
-
return 2;
|
|
38
|
-
}
|
|
39
|
-
let config;
|
|
40
|
-
try {
|
|
41
|
-
config = JSON.parse((0, node_fs.readFileSync)(file, "utf8"));
|
|
42
|
-
} catch (error) {
|
|
43
|
-
process.stderr.write(`statelyai-agent: could not read/parse '${file}': ${error instanceof Error ? error.message : String(error)}\n`);
|
|
44
|
-
return 2;
|
|
45
|
-
}
|
|
46
|
-
let machine;
|
|
47
|
-
try {
|
|
48
|
-
machine = require_run_agent.setupAgent.fromConfig(config, { compileSchema: stubCompileSchema });
|
|
49
|
-
} catch (error) {
|
|
50
|
-
process.stderr.write(`statelyai-agent: '${file}' is not a valid agent-machine config: ${error instanceof Error ? error.message : String(error)}\n`);
|
|
51
|
-
return 2;
|
|
52
|
-
}
|
|
53
|
-
const diagnostics = require_src.lintAgentMachine(machine);
|
|
54
|
-
const errors = diagnostics.filter((d) => d.severity === "error");
|
|
55
|
-
const warnings = diagnostics.filter((d) => d.severity === "warning");
|
|
56
|
-
for (const d of diagnostics) {
|
|
57
|
-
const label = d.severity === "error" ? "error" : "warn ";
|
|
58
|
-
process.stdout.write(` ${label} ${d.code} ${d.path}\n ${d.message}\n`);
|
|
59
|
-
}
|
|
60
|
-
process.stdout.write(`\n${file}: ${errors.length} error(s), ${warnings.length} warning(s) (structure-only; schemas not compiled).\n`);
|
|
61
|
-
return errors.length > 0 ? 1 : 0;
|
|
62
|
-
}
|
|
63
|
-
process.exit(main(process.argv));
|
|
64
|
-
//#endregion
|
package/dist/cli.d.cts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { };
|
package/dist/cli.d.mts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { };
|
package/dist/cli.mjs
DELETED
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
import { c as setupAgent } from "./run-agent-BoAOq_0Z.mjs";
|
|
3
|
-
import { a as lintAgentMachine } from "./src-DUeIFjv-.mjs";
|
|
4
|
-
import { readFileSync } from "node:fs";
|
|
5
|
-
//#region src/cli.ts
|
|
6
|
-
/**
|
|
7
|
-
* `statelyai-agent lint <workflow.json>` — keyless static verification for an
|
|
8
|
-
* agent machine authored as data (an {@link AgentWorkflowConfig} JSON file).
|
|
9
|
-
*
|
|
10
|
-
* The library bundles no JSON Schema engine, so the CLI lints STRUCTURE ONLY:
|
|
11
|
-
* it compiles the config with a permissive pass-through schema compiler (each
|
|
12
|
-
* JSON Schema is kept as-is for structural checks, validation is a no-op) and
|
|
13
|
-
* runs {@link lintAgentMachine}. Exits `1` on any error-severity finding.
|
|
14
|
-
*
|
|
15
|
-
* For full schema-aware linting, import the API and compile with a real engine:
|
|
16
|
-
* `lintAgentMachine(setupAgent.fromConfig(config, { compileSchema }))`.
|
|
17
|
-
*
|
|
18
|
-
* @module
|
|
19
|
-
*/
|
|
20
|
-
function stubCompileSchema(jsonSchema) {
|
|
21
|
-
return { "~standard": {
|
|
22
|
-
version: 1,
|
|
23
|
-
vendor: "statelyai-agent-cli",
|
|
24
|
-
validate: (value) => ({ value }),
|
|
25
|
-
jsonSchema: { input: () => jsonSchema }
|
|
26
|
-
} };
|
|
27
|
-
}
|
|
28
|
-
function printUsage() {
|
|
29
|
-
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");
|
|
30
|
-
}
|
|
31
|
-
function main(argv) {
|
|
32
|
-
const args = argv.slice(2);
|
|
33
|
-
const command = args[0];
|
|
34
|
-
const file = args.find((arg, index) => index > 0 && !arg.startsWith("-"));
|
|
35
|
-
if (command !== "lint" || !file) {
|
|
36
|
-
printUsage();
|
|
37
|
-
return 2;
|
|
38
|
-
}
|
|
39
|
-
let config;
|
|
40
|
-
try {
|
|
41
|
-
config = JSON.parse(readFileSync(file, "utf8"));
|
|
42
|
-
} catch (error) {
|
|
43
|
-
process.stderr.write(`statelyai-agent: could not read/parse '${file}': ${error instanceof Error ? error.message : String(error)}\n`);
|
|
44
|
-
return 2;
|
|
45
|
-
}
|
|
46
|
-
let machine;
|
|
47
|
-
try {
|
|
48
|
-
machine = setupAgent.fromConfig(config, { compileSchema: stubCompileSchema });
|
|
49
|
-
} catch (error) {
|
|
50
|
-
process.stderr.write(`statelyai-agent: '${file}' is not a valid agent-machine config: ${error instanceof Error ? error.message : String(error)}\n`);
|
|
51
|
-
return 2;
|
|
52
|
-
}
|
|
53
|
-
const diagnostics = lintAgentMachine(machine);
|
|
54
|
-
const errors = diagnostics.filter((d) => d.severity === "error");
|
|
55
|
-
const warnings = diagnostics.filter((d) => d.severity === "warning");
|
|
56
|
-
for (const d of diagnostics) {
|
|
57
|
-
const label = d.severity === "error" ? "error" : "warn ";
|
|
58
|
-
process.stdout.write(` ${label} ${d.code} ${d.path}\n ${d.message}\n`);
|
|
59
|
-
}
|
|
60
|
-
process.stdout.write(`\n${file}: ${errors.length} error(s), ${warnings.length} warning(s) (structure-only; schemas not compiled).\n`);
|
|
61
|
-
return errors.length > 0 ? 1 : 0;
|
|
62
|
-
}
|
|
63
|
-
process.exit(main(process.argv));
|
|
64
|
-
//#endregion
|
|
65
|
-
export {};
|