@statelyai/agent 2.0.0-alpha.10 → 2.0.0-alpha.12

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 (62) hide show
  1. package/dist/ai-sdk.cjs +62 -99
  2. package/dist/ai-sdk.d.cts +10 -117
  3. package/dist/ai-sdk.d.mts +10 -117
  4. package/dist/ai-sdk.mjs +63 -91
  5. package/dist/{decision-CQdrKc8k.mjs → decision-BezSD_YC.mjs} +120 -32
  6. package/dist/{decision-b-lkcs4L.cjs → decision-dWGhBh0P.cjs} +141 -53
  7. package/dist/errors-BQRk9eiZ.d.cts +19 -0
  8. package/dist/errors-C9rxnWbX.d.mts +19 -0
  9. package/dist/errors-CeSXQx0v.mjs +23 -0
  10. package/dist/errors-DUBBzRLP.cjs +28 -0
  11. package/dist/event-log-store-CNT_7F0V.cjs +452 -0
  12. package/dist/event-log-store-CriMgX1D.d.mts +144 -0
  13. package/dist/event-log-store-D7pWtIhb.mjs +411 -0
  14. package/dist/event-log-store-Ruq18mGp.d.cts +144 -0
  15. package/dist/index.cjs +2844 -30
  16. package/dist/index.d.cts +1005 -12
  17. package/dist/index.d.mts +1005 -12
  18. package/dist/index.mjs +2799 -4
  19. package/dist/machines.cjs +752 -0
  20. package/dist/machines.d.cts +372 -0
  21. package/dist/machines.d.mts +372 -0
  22. package/dist/machines.mjs +741 -0
  23. package/dist/otel.cjs +268 -0
  24. package/dist/otel.d.cts +67 -0
  25. package/dist/otel.d.mts +67 -0
  26. package/dist/otel.mjs +267 -0
  27. package/dist/run-agent-B1nBa7aV.d.mts +1111 -0
  28. package/dist/run-agent-qkg0evvW.d.cts +1111 -0
  29. package/dist/setup-agent-DAZZSjDS.mjs +1711 -0
  30. package/dist/setup-agent-DP95MFrI.cjs +1836 -0
  31. package/dist/sqlite.cjs +135 -0
  32. package/dist/sqlite.d.cts +57 -0
  33. package/dist/sqlite.d.mts +57 -0
  34. package/dist/sqlite.mjs +133 -0
  35. package/dist/{text-logic-C7WJpCIc.d.mts → text-logic-CorGzucG.d.cts} +110 -66
  36. package/dist/{text-logic-CZjyACzQ.d.cts → text-logic-DjR5PUVz.d.mts} +110 -66
  37. package/dist/{types-C9QiMjre.d.cts → types-QbEfCVny.d.cts} +1 -1
  38. package/dist/{types-qm00QF91.d.mts → types-_FXoFBGO.d.mts} +1 -1
  39. package/package.json +55 -27
  40. package/readme.md +40 -9
  41. package/schemas/agent-workflow.json +44 -26
  42. package/skills/generate-machine/SKILL.md +267 -0
  43. package/dist/cli.cjs +0 -64
  44. package/dist/cli.d.cts +0 -1
  45. package/dist/cli.d.mts +0 -1
  46. package/dist/cli.mjs +0 -65
  47. package/dist/openai-compat.cjs +0 -319
  48. package/dist/openai-compat.d.cts +0 -98
  49. package/dist/openai-compat.d.mts +0 -98
  50. package/dist/openai-compat.mjs +0 -312
  51. package/dist/run-agent-BFMkuI1F.cjs +0 -1599
  52. package/dist/run-agent-BVMd--1l.d.cts +0 -1103
  53. package/dist/run-agent-BoAOq_0Z.mjs +0 -1540
  54. package/dist/run-agent-DzYJb3CK.d.mts +0 -1103
  55. package/dist/src-D-77Ha5p.cjs +0 -1087
  56. package/dist/src-DUeIFjv-.mjs +0 -1016
  57. package/dist/utils-Dri7aeEG.d.cts +0 -108
  58. package/dist/utils-Y6GDRGGE.d.mts +0 -108
  59. package/dist/zod.cjs +0 -31
  60. package/dist/zod.d.cts +0 -30
  61. package/dist/zod.d.mts +0 -30
  62. package/dist/zod.mjs +0 -30
@@ -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
  },
@@ -46,6 +45,17 @@
46
45
  },
47
46
  "default": {}
48
47
  },
48
+ "actors": {
49
+ "description": "Placeholder actor sources declared by key. JSON wires no execution; provide the logic via machine.provide({ actors }) after setupAgent.fromConfig(...).",
50
+ "type": "object",
51
+ "propertyNames": {
52
+ "$ref": "#/$defs/Identifier"
53
+ },
54
+ "additionalProperties": {
55
+ "$ref": "#/$defs/Actor"
56
+ },
57
+ "default": {}
58
+ },
49
59
  "initial": {
50
60
  "description": "Initial child state key.",
51
61
  "type": "string"
@@ -234,6 +244,7 @@
234
244
  }
235
245
  },
236
246
  "toolChoice": {
247
+ "description": "Passed to the provider as-is; unlike other request fields it is NOT template-evaluated, so {{ }} expressions are not allowed here.",
237
248
  "anyOf": [
238
249
  {
239
250
  "type": "string",
@@ -251,10 +262,13 @@
251
262
  }
252
263
  },
253
264
  "additionalProperties": false
254
- },
255
- { "$ref": "#/$defs/ExpressionString" }
265
+ }
256
266
  ]
257
267
  },
268
+ "reasoning": {
269
+ "description": "Opt into the structured-output envelope's `reasoning` field.",
270
+ "type": "boolean"
271
+ },
258
272
  "temperature": {
259
273
  "$ref": "#/$defs/ExpressionValue"
260
274
  },
@@ -302,7 +316,8 @@
302
316
  "$ref": "#/$defs/ExpressionValue"
303
317
  }
304
318
  },
305
- "Tool": {
319
+ "Actor": {
320
+ "description": "A placeholder actor source: schemas describe it for authors/editors; the implementation is provided by the host.",
306
321
  "type": "object",
307
322
  "properties": {
308
323
  "description": {
@@ -315,6 +330,21 @@
315
330
  "$ref": "#/$defs/JsonSchema"
316
331
  }
317
332
  },
333
+ "additionalProperties": false
334
+ },
335
+ "Tool": {
336
+ "type": "object",
337
+ "properties": {
338
+ "description": {
339
+ "type": "string"
340
+ },
341
+ "inputSchema": {
342
+ "$ref": "#/$defs/JsonSchema"
343
+ },
344
+ "outputSchema": {
345
+ "$ref": "#/$defs/JsonSchema"
346
+ }
347
+ },
318
348
  "additionalProperties": {
319
349
  "$ref": "#/$defs/JsonValue"
320
350
  }
@@ -396,7 +426,8 @@
396
426
  "$ref": "#/$defs/ExpressionValue"
397
427
  },
398
428
  "meta": {
399
- "$ref": "#/$defs/ExpressionObject"
429
+ "description": "Static state metadata, passed through verbatim. Not template-evaluated.",
430
+ "$ref": "#/$defs/JsonObject"
400
431
  }
401
432
  },
402
433
  "additionalProperties": false
@@ -421,9 +452,6 @@
421
452
  },
422
453
  "onError": {
423
454
  "$ref": "#/$defs/TransitionOrArray"
424
- },
425
- "meta": {
426
- "$ref": "#/$defs/ExpressionObject"
427
455
  }
428
456
  },
429
457
  "additionalProperties": false
@@ -454,21 +482,10 @@
454
482
  ]
455
483
  },
456
484
  "guard": {
485
+ "description": "Either a whole-string {{ }} expression evaluated as truthy/falsy, or a named guard reference resolved against the `guards` passed to setupAgent.fromConfig(config, { guards }). Object guards ({ type, params }) are rejected by the lowering.",
457
486
  "anyOf": [
458
487
  { "$ref": "#/$defs/ExpressionString" },
459
- {
460
- "type": "object",
461
- "required": ["type"],
462
- "properties": {
463
- "type": {
464
- "type": "string"
465
- },
466
- "params": {
467
- "$ref": "#/$defs/ExpressionValue"
468
- }
469
- },
470
- "additionalProperties": false
471
- }
488
+ { "$ref": "#/$defs/Identifier" }
472
489
  ]
473
490
  },
474
491
  "assign": {
@@ -485,7 +502,8 @@
485
502
  "type": "boolean"
486
503
  },
487
504
  "meta": {
488
- "$ref": "#/$defs/ExpressionObject"
505
+ "description": "Static transition metadata, passed through verbatim. Not template-evaluated.",
506
+ "$ref": "#/$defs/JsonObject"
489
507
  }
490
508
  },
491
509
  "additionalProperties": false
@@ -0,0 +1,267 @@
1
+ ---
2
+ name: generate-machine
3
+ description: Author a @statelyai/agent workflow as JSON and check it before it runs. Use when asked to generate or author an agent machine, create a workflow config, write an AgentWorkflowConfig, or produce an LLM-authored state machine for an agent — and when a generated config fails Ajv validation or agent lint and needs repair.
4
+ ---
5
+
6
+ # Generate an agent machine
7
+
8
+ An agent machine is data. You author a JSON `AgentWorkflowConfig`, then run it through gates that all work with no API key: Ajv → `fromConfig` → lint → simulate. Do not hand back a config that has not passed all four.
9
+
10
+ ```
11
+ author → validate (Ajv 2020) → lower (fromConfig) → lint (assertAgentMachine) → simulate → hand back
12
+ ```
13
+
14
+ ## 1. Read the schema
15
+
16
+ The config shape is fixed by a shipped JSON Schema. Read it first; it is the contract.
17
+
18
+ - Consuming the package: `node_modules/@statelyai/agent/agent-workflow.json` (importable as `@statelyai/agent/agent-workflow.json`)
19
+ - In the `statelyai/agent` repo: `schemas/agent-workflow.json`
20
+
21
+ ## 2. Author the config
22
+
23
+ Rules the runtime enforces. Each one maps to a build error or a lint diagnostic:
24
+
25
+ - Every value is a JSON literal or a whole-string `"{{ }}"` expression reading a dot path on `input`, `context`, or `event`. No JavaScript.
26
+ - Guard expressions are truthy-only: no comparisons, operators, or negation.
27
+ - A model call is either a named `requests` entry invoked with `src: "<requestName>"`, or an inline invoke with `src: "agent.decide"` plus an `allowedEvents` list.
28
+ - A state invoking `agent.decide` MUST handle every allowed event in its `on`.
29
+ - An `agent.decide` invoke has no `onDone` (a decision produces no output). Use `onError` for the retries-exhausted path.
30
+ - A request invoke reads its result via `onDone.assign` from `"{{ event.output.<field> }}"`.
31
+ - Every path must reach a `"type": "final"` state, and each final state needs an `output` when `schemas.output` is declared.
32
+ - Do not invent guard or action names. Only `"{{ }}"` guards, `assign`, and `emit` exist unless the host tells you which named guards/actions it implements.
33
+ - Model refs are strings (`"openai/gpt-5.4-mini"`); the host resolves them.
34
+
35
+ Reference config — decision, text request, idle human step, one final state:
36
+
37
+ ```json
38
+ {
39
+ "id": "support-ticket",
40
+ "schemas": {
41
+ "input": {
42
+ "type": "object",
43
+ "properties": { "ticket": { "type": "string" } },
44
+ "required": ["ticket"]
45
+ },
46
+ "context": {
47
+ "type": "object",
48
+ "properties": {
49
+ "ticket": { "type": "string" },
50
+ "reply": { "type": "string" },
51
+ "resolution": { "type": "string" }
52
+ },
53
+ "required": ["ticket"]
54
+ },
55
+ "events": {
56
+ "ESCALATE": {
57
+ "type": "object",
58
+ "properties": { "reason": { "type": "string" } },
59
+ "required": ["reason"]
60
+ },
61
+ "REPLY": { "type": "object", "properties": {} },
62
+ "APPROVE": { "type": "object", "properties": {} },
63
+ "REJECT": { "type": "object", "properties": {} }
64
+ },
65
+ "output": {
66
+ "type": "object",
67
+ "properties": { "resolution": { "type": "string" }, "reply": { "type": "string" } },
68
+ "required": ["resolution"]
69
+ }
70
+ },
71
+ "context": { "ticket": "{{ input.ticket }}" },
72
+ "requests": {
73
+ "draftReply": {
74
+ "model": "openai/gpt-5.4-mini",
75
+ "system": "Draft a short, courteous support reply.",
76
+ "prompt": "{{ context.ticket }}",
77
+ "input": {
78
+ "type": "object",
79
+ "properties": { "ticket": { "type": "string" } },
80
+ "required": ["ticket"]
81
+ },
82
+ "output": {
83
+ "type": "object",
84
+ "properties": { "reply": { "type": "string" } },
85
+ "required": ["reply"]
86
+ }
87
+ }
88
+ },
89
+ "initial": "triaging",
90
+ "states": {
91
+ "triaging": {
92
+ "invoke": {
93
+ "id": "triageDecision",
94
+ "src": "agent.decide",
95
+ "input": {
96
+ "model": "openai/gpt-5.4-mini",
97
+ "system": "Decide whether this ticket needs escalation or a drafted reply.",
98
+ "prompt": "{{ context.ticket }}",
99
+ "allowedEvents": ["ESCALATE", "REPLY"],
100
+ "maxRetries": 2
101
+ },
102
+ "onError": { "target": "resolved", "assign": { "resolution": "escalated" } }
103
+ },
104
+ "on": {
105
+ "ESCALATE": { "target": "resolved", "assign": { "resolution": "escalated" } },
106
+ "REPLY": { "target": "drafting" }
107
+ }
108
+ },
109
+ "drafting": {
110
+ "invoke": {
111
+ "id": "draft",
112
+ "src": "draftReply",
113
+ "input": { "ticket": "{{ context.ticket }}" },
114
+ "onDone": {
115
+ "target": "awaitingApproval",
116
+ "assign": { "reply": "{{ event.output.reply }}" }
117
+ }
118
+ }
119
+ },
120
+ "awaitingApproval": {
121
+ "description": "Idle: nothing to do until a human approves or rejects the draft.",
122
+ "on": {
123
+ "APPROVE": { "target": "resolved", "assign": { "resolution": "replied" } },
124
+ "REJECT": { "target": "resolved", "assign": { "resolution": "escalated" } }
125
+ }
126
+ },
127
+ "resolved": {
128
+ "type": "final",
129
+ "output": { "resolution": "{{ context.resolution }}", "reply": "{{ context.reply }}" }
130
+ }
131
+ }
132
+ }
133
+ ```
134
+
135
+ ## 3. Validate with Ajv 2020
136
+
137
+ The workflow schema is draft 2020-12, so it needs Ajv's 2020 build. Run this before anything else touches the config.
138
+
139
+ ```ts
140
+ import Ajv2020 from "ajv/dist/2020.js";
141
+ import workflowSchema from "@statelyai/agent/agent-workflow.json";
142
+ import type { AgentWorkflowConfig } from "@statelyai/agent";
143
+
144
+ const validateWorkflow = new Ajv2020({ strict: false }).compile(workflowSchema);
145
+
146
+ function validateGeneratedConfig(candidate: unknown): AgentWorkflowConfig {
147
+ if (validateWorkflow(candidate)) return candidate as AgentWorkflowConfig;
148
+ throw new Error(
149
+ (validateWorkflow.errors ?? [])
150
+ .map((error) => `${error.instancePath || "(root)"} ${error.message}`)
151
+ .join("\n"),
152
+ );
153
+ }
154
+ ```
155
+
156
+ Ajv errors carry `instancePath`, so a repair prompt can name the exact bad field.
157
+
158
+ ## 4. Lower with `fromConfig`
159
+
160
+ `fromConfig` needs a `compileSchema` that turns the JSON Schemas _inside_ the config into Standard Schema validators. Two engines, two jobs: the 2020 build above checks the config document; this one compiles the per-field schemas. The library bundles no JSON Schema engine, by design.
161
+
162
+ ```ts
163
+ import Ajv from "ajv";
164
+ import { setupAgent, type SchemaCompiler, type StandardSchemaV1 } from "@statelyai/agent";
165
+
166
+ const ajv = new Ajv({ strict: false });
167
+
168
+ export const ajvCompileSchema: SchemaCompiler = (jsonSchema, name): StandardSchemaV1 => {
169
+ const validate = ajv.compile(jsonSchema);
170
+ return {
171
+ "~standard": {
172
+ version: 1,
173
+ vendor: "ajv",
174
+ validate: (value) =>
175
+ validate(value)
176
+ ? { value }
177
+ : {
178
+ issues: (validate.errors ?? []).map((e) => ({
179
+ message: `${name}${e.instancePath} ${e.message}`,
180
+ })),
181
+ },
182
+ // Expose the source JSON Schema so lint's serializability checks can read the shape.
183
+ jsonSchema: { input: () => jsonSchema },
184
+ },
185
+ };
186
+ };
187
+
188
+ const { machine, schemas } = setupAgent.fromConfig(config, { compileSchema: ajvCompileSchema });
189
+ ```
190
+
191
+ Lowering is itself a gate: it throws on an unresolved named guard/action and on an `onDone` attached to an `agent.decide` invoke.
192
+
193
+ ## 5. Lint
194
+
195
+ ```ts
196
+ import { assertAgentMachine, lintAgentMachine } from "@statelyai/agent";
197
+
198
+ const diagnostics = lintAgentMachine(machine);
199
+ assertAgentMachine(machine); // throws AgentLintError on error-severity findings
200
+ ```
201
+
202
+ Every check applies to config-built machines, reachability included — the lowering keeps the config's transition targets, so `unreachable-state` and `missing-final` read the real graph. Do not disable checks.
203
+
204
+ The one that bites most often is `decide-without-events`: an `allowedEvents` list with no matching `on` transitions produces a decision the machine can never deliver.
205
+
206
+ ## 6. Simulate a dry run
207
+
208
+ Lint is structural. A dry run proves a path actually settles. No API key needed.
209
+
210
+ ```ts
211
+ import { simulateAgent } from "@statelyai/agent";
212
+
213
+ const dryRun = await simulateAgent(machine, {
214
+ input: { ticket: "" },
215
+ script: {
216
+ decisions: { "agent.decide": [{ type: "REPLY" }] },
217
+ text: { draftReply: [{ reply: "" }] },
218
+ },
219
+ });
220
+ // dryRun.status: 'done' | 'idle' | 'exhausted'
221
+ ```
222
+
223
+ Derive the script from the config rather than guessing: take the first entry of each decision's `allowedEvents`, and stub each request's output from its declared `output` schema (`""` for string, `0` for number, `[]` for array, recurse on `properties`).
224
+
225
+ - `'exhausted'` → the machine loops. Reject it.
226
+ - `'idle'` → it stopped at a human step. Expected when the config has one.
227
+ - To cover every branch instead of one path, use `explorePaths` / `canReach`.
228
+
229
+ ## 7. Repair loop
230
+
231
+ Every gate throws with a message naming the offending field, state, or path. Feed that message back verbatim and regenerate:
232
+
233
+ ```ts
234
+ for (let attempt = 0; attempt < 3; attempt++) {
235
+ try {
236
+ return buildAndVet(await author({ system, prompt }));
237
+ } catch (error) {
238
+ prompt = `${originalTask}\n\nYour previous config was rejected:\n${(error as Error).message}\nReturn a corrected config.`;
239
+ }
240
+ }
241
+ ```
242
+
243
+ Keep the cap at ~3. A config that fails three schema-shaped repairs is usually asking for something the data form cannot express — author it in TypeScript with `setupAgent` instead.
244
+
245
+ ## 8. Hand back
246
+
247
+ Deliver the config JSON plus how to run it:
248
+
249
+ ```ts
250
+ import { runAgent } from "@statelyai/agent";
251
+ import { createAiSdkExecutors } from "@statelyai/agent/ai-sdk";
252
+
253
+ const result = await runAgent(machine, {
254
+ input: { ticket: "Export downloads a 0-byte CSV on Safari." },
255
+ executors: createAiSdkExecutors({ resolveModel }),
256
+ });
257
+ ```
258
+
259
+ Say which gates passed, list any warning-severity lint diagnostics, and report the dry-run status. Model refs are strings, so the host supplies `resolveModel`.
260
+
261
+ ## Known limits
262
+
263
+ - **Named guards and actions are host-resolved.** A config carries no functions. `guard: "isReady"` only works if the host passes an `isReady` implementation to `fromConfig`; an unresolved name is a build-time throw. Either list the host's names in the prompt or forbid named guards/actions entirely.
264
+ - **Expressions are dot-path templates only.** `"{{ context.a.b }}"` — no comparisons, no arithmetic, no method calls, no partial interpolation inside a larger string.
265
+ - **Ajv validity is not semantic validity.** A config can validate and still invoke a request that does not exist or route to a state that solves nothing. That is what lint and simulate are for.
266
+ - **A dry run covers one path.** Use `explorePaths` when the branch structure matters.
267
+ - **Model refs and tool names are unchecked strings.** They resolve at run time, in the host.
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 {};