ag-ui-validate 0.2.0 → 0.3.0
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/README.md +70 -10
- package/dist/{catalog-Ci9dqc1a.cjs → catalog-AB5vuZ8j.cjs} +3 -3
- package/dist/catalog-AB5vuZ8j.cjs.map +1 -0
- package/dist/{catalog-BglXBNbL.js → catalog-DqTI4VLt.js} +3 -3
- package/dist/catalog-DqTI4VLt.js.map +1 -0
- package/dist/cli.js +2 -2
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +2 -2
- package/dist/index.js +2 -2
- package/dist/report.cjs +1 -1
- package/dist/report.cjs.map +1 -1
- package/dist/report.js +1 -1
- package/dist/report.js.map +1 -1
- package/dist/{src-HmI-kxef.cjs → src-D04i3Vso.cjs} +2 -2
- package/dist/src-D04i3Vso.cjs.map +1 -0
- package/dist/{src-rGZ2G4qA.js → src-Dcuqz2QC.js} +2 -2
- package/dist/src-Dcuqz2QC.js.map +1 -0
- package/dist/transport.cjs +1 -1
- package/dist/transport.cjs.map +1 -1
- package/dist/transport.js +1 -1
- package/dist/transport.js.map +1 -1
- package/dist/vitest.js +2 -2
- package/dist/vitest.js.map +1 -1
- package/{src → js/src}/rules/catalog.ts +1 -1
- package/{src → js/src}/transport/index.ts +1 -1
- package/package.json +14 -13
- package/{src/rules → spec}/catalog.json +1 -1
- package/spec/event-categories.json +56 -0
- package/spec/fixtures/README.md +91 -0
- package/spec/fixtures/invalid/AGUI001-first-event-not-run-started/expected.json +10 -0
- package/spec/fixtures/invalid/AGUI001-first-event-not-run-started/stream.jsonl +4 -0
- package/spec/fixtures/invalid/AGUI002-duplicate-run-started/expected.json +11 -0
- package/spec/fixtures/invalid/AGUI002-duplicate-run-started/stream.jsonl +3 -0
- package/spec/fixtures/invalid/AGUI003-run-never-terminated/expected.json +10 -0
- package/spec/fixtures/invalid/AGUI003-run-never-terminated/stream.jsonl +4 -0
- package/spec/fixtures/invalid/AGUI004-event-after-terminal/expected.json +11 -0
- package/spec/fixtures/invalid/AGUI004-event-after-terminal/stream.jsonl +3 -0
- package/spec/fixtures/invalid/AGUI005-finished-and-error/expected.json +11 -0
- package/spec/fixtures/invalid/AGUI005-finished-and-error/stream.jsonl +3 -0
- package/spec/fixtures/invalid/AGUI006-step-finished-unmatched/expected.json +11 -0
- package/spec/fixtures/invalid/AGUI006-step-finished-unmatched/stream.jsonl +3 -0
- package/spec/fixtures/invalid/AGUI007-step-unterminated/expected.json +10 -0
- package/spec/fixtures/invalid/AGUI007-step-unterminated/stream.jsonl +3 -0
- package/spec/fixtures/invalid/AGUI008-unstable-run-ids/expected.json +12 -0
- package/spec/fixtures/invalid/AGUI008-unstable-run-ids/stream.jsonl +2 -0
- package/spec/fixtures/invalid/AGUI101-content-without-start/expected.json +11 -0
- package/spec/fixtures/invalid/AGUI101-content-without-start/stream.jsonl +3 -0
- package/spec/fixtures/invalid/AGUI102-end-without-start/expected.json +11 -0
- package/spec/fixtures/invalid/AGUI102-end-without-start/stream.jsonl +3 -0
- package/spec/fixtures/invalid/AGUI103-message-unterminated/expected.json +10 -0
- package/spec/fixtures/invalid/AGUI103-message-unterminated/stream.jsonl +4 -0
- package/spec/fixtures/invalid/AGUI104-duplicate-message-id/expected.json +12 -0
- package/spec/fixtures/invalid/AGUI104-duplicate-message-id/stream.jsonl +6 -0
- package/spec/fixtures/invalid/AGUI105-empty-content-delta/expected.json +12 -0
- package/spec/fixtures/invalid/AGUI105-empty-content-delta/stream.jsonl +5 -0
- package/spec/fixtures/invalid/AGUI106-interleaved-same-message-id/expected.json +12 -0
- package/spec/fixtures/invalid/AGUI106-interleaved-same-message-id/stream.jsonl +5 -0
- package/spec/fixtures/invalid/AGUI201-args-without-start/expected.json +11 -0
- package/spec/fixtures/invalid/AGUI201-args-without-start/stream.jsonl +3 -0
- package/spec/fixtures/invalid/AGUI202-end-without-start/expected.json +11 -0
- package/spec/fixtures/invalid/AGUI202-end-without-start/stream.jsonl +3 -0
- package/spec/fixtures/invalid/AGUI203-unterminated-tool-call/expected.json +10 -0
- package/spec/fixtures/invalid/AGUI203-unterminated-tool-call/stream.jsonl +4 -0
- package/spec/fixtures/invalid/AGUI204-args-not-json/expected.json +10 -0
- package/spec/fixtures/invalid/AGUI204-args-not-json/stream.jsonl +6 -0
- package/spec/fixtures/invalid/AGUI205-duplicate-tool-call-id/expected.json +12 -0
- package/spec/fixtures/invalid/AGUI205-duplicate-tool-call-id/stream.jsonl +5 -0
- package/spec/fixtures/invalid/AGUI206-result-before-end/expected.json +12 -0
- package/spec/fixtures/invalid/AGUI206-result-before-end/stream.jsonl +5 -0
- package/spec/fixtures/invalid/AGUI207-result-unknown-id/expected.json +11 -0
- package/spec/fixtures/invalid/AGUI207-result-unknown-id/stream.jsonl +3 -0
- package/spec/fixtures/invalid/AGUI208-unknown-parent-message-id/expected.json +11 -0
- package/spec/fixtures/invalid/AGUI208-unknown-parent-message-id/stream.jsonl +4 -0
- package/spec/fixtures/invalid/AGUI301-delta-before-snapshot/expected.json +10 -0
- package/spec/fixtures/invalid/AGUI301-delta-before-snapshot/stream.jsonl +3 -0
- package/spec/fixtures/invalid/AGUI302-delta-failed-to-apply/expected.json +11 -0
- package/spec/fixtures/invalid/AGUI302-delta-failed-to-apply/stream.jsonl +4 -0
- package/spec/fixtures/invalid/AGUI303-invalid-patch-document/expected.json +11 -0
- package/spec/fixtures/invalid/AGUI303-invalid-patch-document/stream.jsonl +4 -0
- package/spec/fixtures/invalid/AGUI304-midrun-snapshot-discards-deltas/expected.json +10 -0
- package/spec/fixtures/invalid/AGUI304-midrun-snapshot-discards-deltas/stream.jsonl +5 -0
- package/spec/fixtures/invalid/AGUI305-shared-state-never-established/expected.json +9 -0
- package/spec/fixtures/invalid/AGUI305-shared-state-never-established/options.json +5 -0
- package/spec/fixtures/invalid/AGUI305-shared-state-never-established/stream.jsonl +5 -0
- package/spec/fixtures/invalid/AGUI401-reasoning-content-without-start/expected.json +11 -0
- package/spec/fixtures/invalid/AGUI401-reasoning-content-without-start/stream.jsonl +3 -0
- package/spec/fixtures/invalid/AGUI402-reasoning-unterminated/expected.json +10 -0
- package/spec/fixtures/invalid/AGUI402-reasoning-unterminated/stream.jsonl +3 -0
- package/spec/fixtures/invalid/AGUI501-missing-data-prefix/expected.json +9 -0
- package/spec/fixtures/invalid/AGUI501-missing-data-prefix/scenario.json +17 -0
- package/spec/fixtures/invalid/AGUI502-payload-not-json/expected.json +10 -0
- package/spec/fixtures/invalid/AGUI502-payload-not-json/stream.jsonl +3 -0
- package/spec/fixtures/invalid/AGUI503-unknown-event-type/expected.json +10 -0
- package/spec/fixtures/invalid/AGUI503-unknown-event-type/stream.jsonl +3 -0
- package/spec/fixtures/invalid/AGUI504-schema-violation/expected.json +11 -0
- package/spec/fixtures/invalid/AGUI504-schema-violation/stream.jsonl +4 -0
- package/spec/fixtures/invalid/AGUI505-unexpected-content-type/expected.json +9 -0
- package/spec/fixtures/invalid/AGUI505-unexpected-content-type/scenario.json +25 -0
- package/spec/fixtures/invalid/AGUI506-keepalive-gap/expected.json +9 -0
- package/spec/fixtures/invalid/AGUI506-keepalive-gap/scenario.json +25 -0
- package/spec/fixtures/invalid/AGUI507-buffered-response/expected.json +9 -0
- package/spec/fixtures/invalid/AGUI507-buffered-response/scenario.json +9 -0
- package/spec/fixtures/invalid/AGUI508-connection-dropped/expected.json +17 -0
- package/spec/fixtures/invalid/AGUI508-connection-dropped/scenario.json +10 -0
- package/spec/fixtures/invalid/AGUI901-raw-wraps-typed-event/expected.json +11 -0
- package/spec/fixtures/invalid/AGUI901-raw-wraps-typed-event/stream.jsonl +3 -0
- package/spec/fixtures/invalid/AGUI902-no-timestamps/expected.json +9 -0
- package/spec/fixtures/invalid/AGUI902-no-timestamps/stream.jsonl +2 -0
- package/spec/fixtures/invalid/AGUI903-custom-name-not-namespaced/expected.json +11 -0
- package/spec/fixtures/invalid/AGUI903-custom-name-not-namespaced/stream.jsonl +3 -0
- package/spec/fixtures/valid/agentic-chat.jsonl +14 -0
- package/spec/fixtures/valid/agentic-generative-ui.jsonl +13 -0
- package/spec/fixtures/valid/backend-tool-rendering.jsonl +14 -0
- package/spec/fixtures/valid/human-in-the-loop.jsonl +13 -0
- package/spec/fixtures/valid/predictive-state-updates.expected.json +11 -0
- package/spec/fixtures/valid/predictive-state-updates.jsonl +11 -0
- package/spec/fixtures/valid/shared-state.jsonl +8 -0
- package/spec/fixtures/valid/tool-based-generative-ui.jsonl +5 -0
- package/dist/catalog-BglXBNbL.js.map +0 -1
- package/dist/catalog-Ci9dqc1a.cjs.map +0 -1
- package/dist/src-HmI-kxef.cjs.map +0 -1
- package/dist/src-rGZ2G4qA.js.map +0 -1
- /package/{src → js/src}/cli-args.ts +0 -0
- /package/{src → js/src}/cli.ts +0 -0
- /package/{src → js/src}/index.ts +0 -0
- /package/{src → js/src}/protocol/event-table.ts +0 -0
- /package/{src → js/src}/protocol/jsonpatch.ts +0 -0
- /package/{src → js/src}/report/index.ts +0 -0
- /package/{src → js/src}/report/json.ts +0 -0
- /package/{src → js/src}/report/junit.ts +0 -0
- /package/{src → js/src}/report/pretty.ts +0 -0
- /package/{src → js/src}/report/sarif.ts +0 -0
- /package/{src → js/src}/rules/checks/context.ts +0 -0
- /package/{src → js/src}/rules/checks/lifecycle.ts +0 -0
- /package/{src → js/src}/rules/checks/reasoning.ts +0 -0
- /package/{src → js/src}/rules/checks/state.ts +0 -0
- /package/{src → js/src}/rules/checks/text.ts +0 -0
- /package/{src → js/src}/rules/checks/toolcalls.ts +0 -0
- /package/{src → js/src}/rules/checks/transport.ts +0 -0
- /package/{src → js/src}/transport/ndjson.ts +0 -0
- /package/{src → js/src}/transport/sse.ts +0 -0
- /package/{src → js/src}/types.ts +0 -0
- /package/{src → js/src}/vitest/index.ts +0 -0
- /package/{src → js/src}/vitest/matcher.ts +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// ag-ui-validate/transport: SSE + NDJSON clients over the pure core.
|
|
2
2
|
// This is the I/O layer — fetch, streams, and clocks live here, never in the
|
|
3
3
|
// core. Uses only web-platform APIs (fetch, TextDecoder, AbortController) so
|
|
4
|
-
// it stays isomorphic: Node
|
|
4
|
+
// it stays isomorphic: Node 22+, browsers, Deno, Workers.
|
|
5
5
|
|
|
6
6
|
import { createValidator } from "../index.js"
|
|
7
7
|
import type { Diagnostic, Report, ValidationLayer, ValidatorOptions } from "../index.js"
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ag-ui-validate",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "Conformance validator for the AG-UI protocol. Feed it an event stream, get every violation with a rule ID, a severity, and a link to the governing spec section.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ag-ui",
|
|
@@ -23,10 +23,10 @@
|
|
|
23
23
|
"type": "module",
|
|
24
24
|
"sideEffects": [
|
|
25
25
|
"./dist/vitest.js",
|
|
26
|
-
"./src/vitest/index.ts"
|
|
26
|
+
"./js/src/vitest/index.ts"
|
|
27
27
|
],
|
|
28
28
|
"engines": {
|
|
29
|
-
"node": ">=
|
|
29
|
+
"node": ">=22"
|
|
30
30
|
},
|
|
31
31
|
"bin": {
|
|
32
32
|
"ag-ui-validate": "./dist/cli.js"
|
|
@@ -88,20 +88,21 @@
|
|
|
88
88
|
},
|
|
89
89
|
"files": [
|
|
90
90
|
"dist",
|
|
91
|
-
"src"
|
|
91
|
+
"js/src",
|
|
92
|
+
"spec"
|
|
92
93
|
],
|
|
93
94
|
"scripts": {
|
|
94
|
-
"build": "tsdown",
|
|
95
|
-
"typecheck": "tsc --noEmit -p tsconfig.src.json && tsc --noEmit",
|
|
96
|
-
"test": "vitest run",
|
|
97
|
-
"test:watch": "vitest",
|
|
98
|
-
"fixtures:build": "npm run build && node scripts/build-fixtures.mjs",
|
|
99
|
-
"protocol:derive": "node scripts/generate-event-table.mjs",
|
|
95
|
+
"build": "tsdown --config js/tsdown.config.mjs",
|
|
96
|
+
"typecheck": "tsc --noEmit -p js/tsconfig.src.json && tsc --noEmit -p js/tsconfig.json",
|
|
97
|
+
"test": "vitest run --config js/vitest.config.ts",
|
|
98
|
+
"test:watch": "vitest --config js/vitest.config.ts",
|
|
99
|
+
"fixtures:build": "npm run build && node js/scripts/build-fixtures.mjs",
|
|
100
|
+
"protocol:derive": "node js/scripts/generate-event-table.mjs",
|
|
100
101
|
"docs:generate": "node scripts/generate-rule-docs.mjs",
|
|
101
102
|
"docs:check": "node scripts/generate-rule-docs.mjs --check",
|
|
102
|
-
"demo": "node scripts/demo.mjs",
|
|
103
|
-
"fuzz": "node scripts/fuzz.mjs",
|
|
104
|
-
"e2e": "node scripts/e2e-live-server.mjs",
|
|
103
|
+
"demo": "node js/scripts/demo.mjs",
|
|
104
|
+
"fuzz": "node js/scripts/fuzz.mjs",
|
|
105
|
+
"e2e": "node js/scripts/e2e-live-server.mjs",
|
|
105
106
|
"links:check": "node scripts/check-spec-links.mjs",
|
|
106
107
|
"changeset": "changeset",
|
|
107
108
|
"version": "changeset version",
|
|
@@ -341,7 +341,7 @@
|
|
|
341
341
|
"id": "AGUI503",
|
|
342
342
|
"severity": "error",
|
|
343
343
|
"title": "Unknown event type",
|
|
344
|
-
"messageTemplate": "Unknown event type '{type}' (not in
|
|
344
|
+
"messageTemplate": "Unknown event type '{type}' (not in the installed AG-UI SDK v{sdkVersion}, and not RAW or CUSTOM)",
|
|
345
345
|
"specUrl": "https://docs.ag-ui.com/concepts/events#event-types-overview",
|
|
346
346
|
"specQuote": "Events in the protocol are categorized by their purpose.",
|
|
347
347
|
"since": "0.x",
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$comment": "Wire-type -> category/deprecation data for the canonical event table. Hand-maintained (not derivable from the SDK schemas themselves); shared by every language's event-table derivation tool so this classification is written once. Categories are display/grouping metadata only, not conformance rules — those live in catalog.json.",
|
|
3
|
+
"categories": [
|
|
4
|
+
"lifecycle",
|
|
5
|
+
"text",
|
|
6
|
+
"toolcall",
|
|
7
|
+
"state",
|
|
8
|
+
"activity",
|
|
9
|
+
"reasoning",
|
|
10
|
+
"thinking",
|
|
11
|
+
"special"
|
|
12
|
+
],
|
|
13
|
+
"eventCategory": {
|
|
14
|
+
"RUN_STARTED": "lifecycle",
|
|
15
|
+
"RUN_FINISHED": "lifecycle",
|
|
16
|
+
"RUN_ERROR": "lifecycle",
|
|
17
|
+
"STEP_STARTED": "lifecycle",
|
|
18
|
+
"STEP_FINISHED": "lifecycle",
|
|
19
|
+
"TEXT_MESSAGE_START": "text",
|
|
20
|
+
"TEXT_MESSAGE_CONTENT": "text",
|
|
21
|
+
"TEXT_MESSAGE_END": "text",
|
|
22
|
+
"TEXT_MESSAGE_CHUNK": "text",
|
|
23
|
+
"TOOL_CALL_START": "toolcall",
|
|
24
|
+
"TOOL_CALL_ARGS": "toolcall",
|
|
25
|
+
"TOOL_CALL_END": "toolcall",
|
|
26
|
+
"TOOL_CALL_CHUNK": "toolcall",
|
|
27
|
+
"TOOL_CALL_RESULT": "toolcall",
|
|
28
|
+
"STATE_SNAPSHOT": "state",
|
|
29
|
+
"STATE_DELTA": "state",
|
|
30
|
+
"MESSAGES_SNAPSHOT": "state",
|
|
31
|
+
"ACTIVITY_SNAPSHOT": "activity",
|
|
32
|
+
"ACTIVITY_DELTA": "activity",
|
|
33
|
+
"REASONING_START": "reasoning",
|
|
34
|
+
"REASONING_MESSAGE_START": "reasoning",
|
|
35
|
+
"REASONING_MESSAGE_CONTENT": "reasoning",
|
|
36
|
+
"REASONING_MESSAGE_END": "reasoning",
|
|
37
|
+
"REASONING_MESSAGE_CHUNK": "reasoning",
|
|
38
|
+
"REASONING_END": "reasoning",
|
|
39
|
+
"REASONING_ENCRYPTED_VALUE": "reasoning",
|
|
40
|
+
"THINKING_START": "thinking",
|
|
41
|
+
"THINKING_END": "thinking",
|
|
42
|
+
"THINKING_TEXT_MESSAGE_START": "thinking",
|
|
43
|
+
"THINKING_TEXT_MESSAGE_CONTENT": "thinking",
|
|
44
|
+
"THINKING_TEXT_MESSAGE_END": "thinking",
|
|
45
|
+
"RAW": "special",
|
|
46
|
+
"CUSTOM": "special"
|
|
47
|
+
},
|
|
48
|
+
"$deprecatedComment": "@deprecated markers in @ag-ui/core's type definitions, 'Will be removed in 1.0.0'. Maps a deprecated wire type to its replacement.",
|
|
49
|
+
"deprecated": {
|
|
50
|
+
"THINKING_START": "REASONING_START",
|
|
51
|
+
"THINKING_END": "REASONING_END",
|
|
52
|
+
"THINKING_TEXT_MESSAGE_START": "REASONING_MESSAGE_START",
|
|
53
|
+
"THINKING_TEXT_MESSAGE_CONTENT": "REASONING_MESSAGE_CONTENT",
|
|
54
|
+
"THINKING_TEXT_MESSAGE_END": "REASONING_MESSAGE_END"
|
|
55
|
+
}
|
|
56
|
+
}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
# AG-UI conformance fixture corpus
|
|
2
|
+
|
|
3
|
+
A language-neutral corpus for testing AG-UI protocol validators. Any
|
|
4
|
+
implementation — TypeScript, Python, Go — that consumes the shared rule
|
|
5
|
+
catalog ([`catalog.json`](../catalog.json)) can be tested
|
|
6
|
+
against these files. The corpus, not per-rule test code, is the suite: adding
|
|
7
|
+
a rule to the catalog means adding a fixture directory here.
|
|
8
|
+
|
|
9
|
+
## Layout
|
|
10
|
+
|
|
11
|
+
```
|
|
12
|
+
fixtures/
|
|
13
|
+
├── valid/ one stream per canonical AG-UI feature
|
|
14
|
+
│ ├── agentic-chat.jsonl
|
|
15
|
+
│ ├── agentic-chat.expected.json (optional; assumed [] when absent)
|
|
16
|
+
│ └── …
|
|
17
|
+
└── invalid/ one directory per rule
|
|
18
|
+
├── AGUI203-unterminated-tool-call/
|
|
19
|
+
│ ├── stream.jsonl the event stream
|
|
20
|
+
│ ├── expected.json the exact expected Diagnostic[]
|
|
21
|
+
│ └── options.json (optional) validator options for this run
|
|
22
|
+
└── AGUI506-keepalive-gap/ transport rules use a scenario instead
|
|
23
|
+
├── scenario.json an HTTP response body as timed byte chunks
|
|
24
|
+
└── expected.json
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## Running the corpus against an implementation
|
|
28
|
+
|
|
29
|
+
For every event-stream fixture (`stream.jsonl`):
|
|
30
|
+
|
|
31
|
+
1. Read the `.jsonl` file and split it into lines; drop empty lines.
|
|
32
|
+
2. Feed each remaining line to the validator **as a raw string** — do not
|
|
33
|
+
pre-parse. Malformed lines are intentional (they exercise AGUI502); a
|
|
34
|
+
conforming validator treats them as diagnostics, never exceptions.
|
|
35
|
+
3. If `options.json` exists, construct the validator with those options
|
|
36
|
+
(e.g. `{"features": ["shared-state"]}` for AGUI305).
|
|
37
|
+
4. After the last line, finalize (end-of-stream checks).
|
|
38
|
+
5. Deep-compare the accumulated diagnostics with `expected.json`. Order
|
|
39
|
+
matters: diagnostics are emitted in stream order, and end-of-stream
|
|
40
|
+
diagnostics use `eventIndex: -1`.
|
|
41
|
+
|
|
42
|
+
For every transport fixture (`scenario.json`) — these exercise the rules that
|
|
43
|
+
need a live connection (AGUI501, AGUI505–AGUI508):
|
|
44
|
+
|
|
45
|
+
1. The scenario describes an HTTP response: `contentType` and `chunks`, each
|
|
46
|
+
chunk being `{ "gapMs": n, "text": "…" }` — the raw bytes as they arrived,
|
|
47
|
+
with `gapMs` of simulated silence before the chunk.
|
|
48
|
+
2. Feed the chunk bytes through your transport layer (SSE or NDJSON per the
|
|
49
|
+
content type, sniffing when unknown) with a simulated clock that advances
|
|
50
|
+
by each `gapMs`; the keepalive window is the default 30 000 ms.
|
|
51
|
+
3. `"abnormalEof": true` means the connection errored after the last chunk
|
|
52
|
+
(as opposed to closing cleanly) — the AGUI508 condition.
|
|
53
|
+
4. Finalize and deep-compare diagnostics with `expected.json` as above.
|
|
54
|
+
|
|
55
|
+
Every `invalid/` fixture must fire its directory's namesake rule; every
|
|
56
|
+
`valid/` fixture must produce exactly its `*.expected.json` (usually nothing —
|
|
57
|
+
they are the false-positive guards). `valid/predictive-state-updates` expects
|
|
58
|
+
one `info` finding: the Dojo's real `PredictState` custom event name is
|
|
59
|
+
un-namespaced (AGUI903, see `docs/spec-questions.md` SQ-14).
|
|
60
|
+
|
|
61
|
+
## Diagnostic shape
|
|
62
|
+
|
|
63
|
+
```json
|
|
64
|
+
{
|
|
65
|
+
"rule": "AGUI203",
|
|
66
|
+
"severity": "error",
|
|
67
|
+
"message": "TOOL_CALL_START id 'call_7' never terminated",
|
|
68
|
+
"eventIndex": 3,
|
|
69
|
+
"eventType": "RUN_FINISHED",
|
|
70
|
+
"pointer": "/toolCallId",
|
|
71
|
+
"relatedEventIndex": 1,
|
|
72
|
+
"specUrl": "https://docs.ag-ui.com/concepts/events#tool-call-events"
|
|
73
|
+
}
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
`eventType`, `pointer`, and `relatedEventIndex` are optional and omitted when
|
|
77
|
+
absent. Messages come from the catalog's `messageTemplate`s, so independent
|
|
78
|
+
implementations produce identical output.
|
|
79
|
+
|
|
80
|
+
## Maintenance
|
|
81
|
+
|
|
82
|
+
Fixtures are generated by [`scripts/build-fixtures.mjs`](../../js/scripts/build-fixtures.mjs),
|
|
83
|
+
which declares each stream's *intended* rule hits independently of the
|
|
84
|
+
validator and refuses to write anything on mismatch — regeneration can never
|
|
85
|
+
silently bake an implementation bug into `expected.json`.
|
|
86
|
+
|
|
87
|
+
## Not yet covered
|
|
88
|
+
|
|
89
|
+
- **`valid/real-world/`** — captures from real frameworks (LangGraph, CrewAI,
|
|
90
|
+
Pydantic AI, Agno, Langflow `stream_protocol=agui`). Contributions welcome;
|
|
91
|
+
sanitise credentials before submitting.
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
[
|
|
2
|
+
{
|
|
3
|
+
"rule": "AGUI001",
|
|
4
|
+
"severity": "error",
|
|
5
|
+
"message": "First event of the run is TEXT_MESSAGE_START; expected RUN_STARTED",
|
|
6
|
+
"eventIndex": 0,
|
|
7
|
+
"specUrl": "https://docs.ag-ui.com/concepts/events#runstarted",
|
|
8
|
+
"eventType": "TEXT_MESSAGE_START"
|
|
9
|
+
}
|
|
10
|
+
]
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
{"type":"TEXT_MESSAGE_START","messageId":"msg_001","role":"assistant","timestamp":1755300007900}
|
|
2
|
+
{"type":"TEXT_MESSAGE_CONTENT","messageId":"msg_001","delta":"Hello without a run.","timestamp":1755300008000}
|
|
3
|
+
{"type":"TEXT_MESSAGE_END","messageId":"msg_001","timestamp":1755300008100}
|
|
4
|
+
{"type":"RUN_FINISHED","threadId":"thread_001","runId":"run_001","timestamp":1755300008200}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
[
|
|
2
|
+
{
|
|
3
|
+
"rule": "AGUI002",
|
|
4
|
+
"severity": "error",
|
|
5
|
+
"message": "Duplicate RUN_STARTED (runId 'run_002') before the active run terminated",
|
|
6
|
+
"eventIndex": 1,
|
|
7
|
+
"specUrl": "https://docs.ag-ui.com/concepts/events#lifecycle-events",
|
|
8
|
+
"eventType": "RUN_STARTED",
|
|
9
|
+
"relatedEventIndex": 0
|
|
10
|
+
}
|
|
11
|
+
]
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
{"type":"RUN_STARTED","threadId":"thread_001","runId":"run_001","timestamp":1755300008300}
|
|
2
|
+
{"type":"RUN_STARTED","threadId":"thread_001","runId":"run_002","timestamp":1755300008400}
|
|
3
|
+
{"type":"RUN_FINISHED","threadId":"thread_001","runId":"run_001","outcome":{"type":"success"},"timestamp":1755300008500}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
{"type":"RUN_STARTED","threadId":"thread_001","runId":"run_001","timestamp":1755300008600}
|
|
2
|
+
{"type":"TEXT_MESSAGE_START","messageId":"msg_001","role":"assistant","timestamp":1755300008700}
|
|
3
|
+
{"type":"TEXT_MESSAGE_CONTENT","messageId":"msg_001","delta":"This run just stops.","timestamp":1755300008800}
|
|
4
|
+
{"type":"TEXT_MESSAGE_END","messageId":"msg_001","timestamp":1755300008900}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
[
|
|
2
|
+
{
|
|
3
|
+
"rule": "AGUI004",
|
|
4
|
+
"severity": "error",
|
|
5
|
+
"message": "TEXT_MESSAGE_START follows the run's terminal RUN_FINISHED",
|
|
6
|
+
"eventIndex": 2,
|
|
7
|
+
"specUrl": "https://docs.ag-ui.com/concepts/events#lifecycle-events",
|
|
8
|
+
"eventType": "TEXT_MESSAGE_START",
|
|
9
|
+
"relatedEventIndex": 1
|
|
10
|
+
}
|
|
11
|
+
]
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
{"type":"RUN_STARTED","threadId":"thread_001","runId":"run_001","timestamp":1755300009000}
|
|
2
|
+
{"type":"RUN_FINISHED","threadId":"thread_001","runId":"run_001","outcome":{"type":"success"},"timestamp":1755300009100}
|
|
3
|
+
{"type":"TEXT_MESSAGE_START","messageId":"msg_001","role":"assistant","timestamp":1755300009200}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
[
|
|
2
|
+
{
|
|
3
|
+
"rule": "AGUI005",
|
|
4
|
+
"severity": "error",
|
|
5
|
+
"message": "RUN_ERROR emitted after the run already terminated with RUN_FINISHED",
|
|
6
|
+
"eventIndex": 2,
|
|
7
|
+
"specUrl": "https://docs.ag-ui.com/concepts/events#runfinished",
|
|
8
|
+
"eventType": "RUN_ERROR",
|
|
9
|
+
"relatedEventIndex": 1
|
|
10
|
+
}
|
|
11
|
+
]
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
{"type":"RUN_STARTED","threadId":"thread_001","runId":"run_001","timestamp":1755300009300}
|
|
2
|
+
{"type":"RUN_FINISHED","threadId":"thread_001","runId":"run_001","outcome":{"type":"success"},"timestamp":1755300009400}
|
|
3
|
+
{"type":"RUN_ERROR","message":"boom","timestamp":1755300009500}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
[
|
|
2
|
+
{
|
|
3
|
+
"rule": "AGUI006",
|
|
4
|
+
"severity": "error",
|
|
5
|
+
"message": "STEP_FINISHED 'plan' has no open STEP_STARTED",
|
|
6
|
+
"eventIndex": 1,
|
|
7
|
+
"specUrl": "https://docs.ag-ui.com/concepts/events#stepfinished",
|
|
8
|
+
"eventType": "STEP_FINISHED",
|
|
9
|
+
"pointer": "/stepName"
|
|
10
|
+
}
|
|
11
|
+
]
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
{"type":"RUN_STARTED","threadId":"thread_001","runId":"run_001","timestamp":1755300009600}
|
|
2
|
+
{"type":"STEP_FINISHED","stepName":"plan","timestamp":1755300009700}
|
|
3
|
+
{"type":"RUN_FINISHED","threadId":"thread_001","runId":"run_001","outcome":{"type":"success"},"timestamp":1755300009800}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
{"type":"RUN_STARTED","threadId":"thread_001","runId":"run_001","timestamp":1755300009900}
|
|
2
|
+
{"type":"STEP_STARTED","stepName":"plan","timestamp":1755300010000}
|
|
3
|
+
{"type":"RUN_FINISHED","threadId":"thread_001","runId":"run_001","outcome":{"type":"success"},"timestamp":1755300010100}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
[
|
|
2
|
+
{
|
|
3
|
+
"rule": "AGUI008",
|
|
4
|
+
"severity": "warning",
|
|
5
|
+
"message": "RUN_FINISHED runId 'run_999' does not match RUN_STARTED runId 'run_001'",
|
|
6
|
+
"eventIndex": 1,
|
|
7
|
+
"specUrl": "https://docs.ag-ui.com/concepts/events#runstarted",
|
|
8
|
+
"eventType": "RUN_FINISHED",
|
|
9
|
+
"pointer": "/runId",
|
|
10
|
+
"relatedEventIndex": 0
|
|
11
|
+
}
|
|
12
|
+
]
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
[
|
|
2
|
+
{
|
|
3
|
+
"rule": "AGUI101",
|
|
4
|
+
"severity": "error",
|
|
5
|
+
"message": "TEXT_MESSAGE_CONTENT for messageId 'msg_ghost' with no open TEXT_MESSAGE_START",
|
|
6
|
+
"eventIndex": 1,
|
|
7
|
+
"specUrl": "https://docs.ag-ui.com/concepts/events#text-message-events",
|
|
8
|
+
"eventType": "TEXT_MESSAGE_CONTENT",
|
|
9
|
+
"pointer": "/messageId"
|
|
10
|
+
}
|
|
11
|
+
]
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
{"type":"RUN_STARTED","threadId":"thread_001","runId":"run_001","timestamp":1755300010400}
|
|
2
|
+
{"type":"TEXT_MESSAGE_CONTENT","messageId":"msg_ghost","delta":"orphan","timestamp":1755300010500}
|
|
3
|
+
{"type":"RUN_FINISHED","threadId":"thread_001","runId":"run_001","outcome":{"type":"success"},"timestamp":1755300010600}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
[
|
|
2
|
+
{
|
|
3
|
+
"rule": "AGUI102",
|
|
4
|
+
"severity": "error",
|
|
5
|
+
"message": "TEXT_MESSAGE_END for messageId 'msg_ghost' with no open TEXT_MESSAGE_START",
|
|
6
|
+
"eventIndex": 1,
|
|
7
|
+
"specUrl": "https://docs.ag-ui.com/concepts/events#textmessageend",
|
|
8
|
+
"eventType": "TEXT_MESSAGE_END",
|
|
9
|
+
"pointer": "/messageId"
|
|
10
|
+
}
|
|
11
|
+
]
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
{"type":"RUN_STARTED","threadId":"thread_001","runId":"run_001","timestamp":1755300010700}
|
|
2
|
+
{"type":"TEXT_MESSAGE_END","messageId":"msg_ghost","timestamp":1755300010800}
|
|
3
|
+
{"type":"RUN_FINISHED","threadId":"thread_001","runId":"run_001","outcome":{"type":"success"},"timestamp":1755300010900}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
{"type":"RUN_STARTED","threadId":"thread_001","runId":"run_001","timestamp":1755300011000}
|
|
2
|
+
{"type":"TEXT_MESSAGE_START","messageId":"msg_001","role":"assistant","timestamp":1755300011100}
|
|
3
|
+
{"type":"TEXT_MESSAGE_CONTENT","messageId":"msg_001","delta":"never ends","timestamp":1755300011200}
|
|
4
|
+
{"type":"RUN_FINISHED","threadId":"thread_001","runId":"run_001","outcome":{"type":"success"},"timestamp":1755300011300}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
[
|
|
2
|
+
{
|
|
3
|
+
"rule": "AGUI104",
|
|
4
|
+
"severity": "error",
|
|
5
|
+
"message": "messageId 'msg_001' was already used by a completed message",
|
|
6
|
+
"eventIndex": 4,
|
|
7
|
+
"specUrl": "https://docs.ag-ui.com/concepts/events#textmessagestart",
|
|
8
|
+
"eventType": "TEXT_MESSAGE_START",
|
|
9
|
+
"pointer": "/messageId",
|
|
10
|
+
"relatedEventIndex": 3
|
|
11
|
+
}
|
|
12
|
+
]
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
{"type":"RUN_STARTED","threadId":"thread_001","runId":"run_001","timestamp":1755300011400}
|
|
2
|
+
{"type":"TEXT_MESSAGE_START","messageId":"msg_001","role":"assistant","timestamp":1755300011500}
|
|
3
|
+
{"type":"TEXT_MESSAGE_CONTENT","messageId":"msg_001","delta":"first use","timestamp":1755300011600}
|
|
4
|
+
{"type":"TEXT_MESSAGE_END","messageId":"msg_001","timestamp":1755300011700}
|
|
5
|
+
{"type":"TEXT_MESSAGE_START","messageId":"msg_001","role":"assistant","timestamp":1755300011800}
|
|
6
|
+
{"type":"RUN_FINISHED","threadId":"thread_001","runId":"run_001","outcome":{"type":"success"},"timestamp":1755300011900}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
[
|
|
2
|
+
{
|
|
3
|
+
"rule": "AGUI105",
|
|
4
|
+
"severity": "warning",
|
|
5
|
+
"message": "TEXT_MESSAGE_CONTENT for messageId 'msg_001' has an empty delta",
|
|
6
|
+
"eventIndex": 2,
|
|
7
|
+
"specUrl": "https://docs.ag-ui.com/concepts/events#textmessagecontent",
|
|
8
|
+
"eventType": "TEXT_MESSAGE_CONTENT",
|
|
9
|
+
"pointer": "/delta",
|
|
10
|
+
"relatedEventIndex": 1
|
|
11
|
+
}
|
|
12
|
+
]
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
{"type":"RUN_STARTED","threadId":"thread_001","runId":"run_001","timestamp":1755300012000}
|
|
2
|
+
{"type":"TEXT_MESSAGE_START","messageId":"msg_001","role":"assistant","timestamp":1755300012100}
|
|
3
|
+
{"type":"TEXT_MESSAGE_CONTENT","messageId":"msg_001","delta":"","timestamp":1755300012200}
|
|
4
|
+
{"type":"TEXT_MESSAGE_END","messageId":"msg_001","timestamp":1755300012300}
|
|
5
|
+
{"type":"RUN_FINISHED","threadId":"thread_001","runId":"run_001","outcome":{"type":"success"},"timestamp":1755300012400}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
[
|
|
2
|
+
{
|
|
3
|
+
"rule": "AGUI106",
|
|
4
|
+
"severity": "error",
|
|
5
|
+
"message": "TEXT_MESSAGE_START for messageId 'msg_001', which is already open",
|
|
6
|
+
"eventIndex": 2,
|
|
7
|
+
"specUrl": "https://docs.ag-ui.com/concepts/events#implementation-considerations",
|
|
8
|
+
"eventType": "TEXT_MESSAGE_START",
|
|
9
|
+
"pointer": "/messageId",
|
|
10
|
+
"relatedEventIndex": 1
|
|
11
|
+
}
|
|
12
|
+
]
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
{"type":"RUN_STARTED","threadId":"thread_001","runId":"run_001","timestamp":1755300012500}
|
|
2
|
+
{"type":"TEXT_MESSAGE_START","messageId":"msg_001","role":"assistant","timestamp":1755300012600}
|
|
3
|
+
{"type":"TEXT_MESSAGE_START","messageId":"msg_001","role":"assistant","timestamp":1755300012700}
|
|
4
|
+
{"type":"TEXT_MESSAGE_END","messageId":"msg_001","timestamp":1755300012800}
|
|
5
|
+
{"type":"RUN_FINISHED","threadId":"thread_001","runId":"run_001","outcome":{"type":"success"},"timestamp":1755300012900}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
[
|
|
2
|
+
{
|
|
3
|
+
"rule": "AGUI201",
|
|
4
|
+
"severity": "error",
|
|
5
|
+
"message": "TOOL_CALL_ARGS for toolCallId 'call_ghost' with no open TOOL_CALL_START",
|
|
6
|
+
"eventIndex": 1,
|
|
7
|
+
"specUrl": "https://docs.ag-ui.com/concepts/events#tool-call-events",
|
|
8
|
+
"eventType": "TOOL_CALL_ARGS",
|
|
9
|
+
"pointer": "/toolCallId"
|
|
10
|
+
}
|
|
11
|
+
]
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
{"type":"RUN_STARTED","threadId":"thread_001","runId":"run_001","timestamp":1755300013000}
|
|
2
|
+
{"type":"TOOL_CALL_ARGS","toolCallId":"call_ghost","delta":"{}","timestamp":1755300013100}
|
|
3
|
+
{"type":"RUN_FINISHED","threadId":"thread_001","runId":"run_001","outcome":{"type":"success"},"timestamp":1755300013200}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
[
|
|
2
|
+
{
|
|
3
|
+
"rule": "AGUI202",
|
|
4
|
+
"severity": "error",
|
|
5
|
+
"message": "TOOL_CALL_END for toolCallId 'call_ghost' with no open TOOL_CALL_START",
|
|
6
|
+
"eventIndex": 1,
|
|
7
|
+
"specUrl": "https://docs.ag-ui.com/concepts/events#toolcallend",
|
|
8
|
+
"eventType": "TOOL_CALL_END",
|
|
9
|
+
"pointer": "/toolCallId"
|
|
10
|
+
}
|
|
11
|
+
]
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
{"type":"RUN_STARTED","threadId":"thread_001","runId":"run_001","timestamp":1755300013300}
|
|
2
|
+
{"type":"TOOL_CALL_END","toolCallId":"call_ghost","timestamp":1755300013400}
|
|
3
|
+
{"type":"RUN_FINISHED","threadId":"thread_001","runId":"run_001","outcome":{"type":"success"},"timestamp":1755300013500}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
{"type":"RUN_STARTED","threadId":"thread_001","runId":"run_001","timestamp":1755300013600}
|
|
2
|
+
{"type":"TOOL_CALL_START","toolCallId":"call_7","toolCallName":"get_weather","timestamp":1755300013700}
|
|
3
|
+
{"type":"TOOL_CALL_ARGS","toolCallId":"call_7","delta":"{\"city\":\"Berlin\"}","timestamp":1755300013800}
|
|
4
|
+
{"type":"RUN_FINISHED","threadId":"thread_001","runId":"run_001","outcome":{"type":"success"},"timestamp":1755300013900}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
[
|
|
2
|
+
{
|
|
3
|
+
"rule": "AGUI204",
|
|
4
|
+
"severity": "error",
|
|
5
|
+
"message": "Concatenated TOOL_CALL_ARGS for toolCallId 'call_001' do not parse as JSON: Unexpected token 'o', \"{\"city\":oops}\" is not valid JSON",
|
|
6
|
+
"eventIndex": 4,
|
|
7
|
+
"specUrl": "https://docs.ag-ui.com/concepts/events#toolcallargs",
|
|
8
|
+
"relatedEventIndex": 1
|
|
9
|
+
}
|
|
10
|
+
]
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
{"type":"RUN_STARTED","threadId":"thread_001","runId":"run_001","timestamp":1755300014000}
|
|
2
|
+
{"type":"TOOL_CALL_START","toolCallId":"call_001","toolCallName":"get_weather","timestamp":1755300014100}
|
|
3
|
+
{"type":"TOOL_CALL_ARGS","toolCallId":"call_001","delta":"{\"city\":","timestamp":1755300014200}
|
|
4
|
+
{"type":"TOOL_CALL_ARGS","toolCallId":"call_001","delta":"oops}","timestamp":1755300014300}
|
|
5
|
+
{"type":"TOOL_CALL_END","toolCallId":"call_001","timestamp":1755300014400}
|
|
6
|
+
{"type":"RUN_FINISHED","threadId":"thread_001","runId":"run_001","outcome":{"type":"success"},"timestamp":1755300014500}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
[
|
|
2
|
+
{
|
|
3
|
+
"rule": "AGUI205",
|
|
4
|
+
"severity": "error",
|
|
5
|
+
"message": "toolCallId 'call_001' was already used by a completed tool call",
|
|
6
|
+
"eventIndex": 3,
|
|
7
|
+
"specUrl": "https://docs.ag-ui.com/concepts/events#toolcallstart",
|
|
8
|
+
"eventType": "TOOL_CALL_START",
|
|
9
|
+
"pointer": "/toolCallId",
|
|
10
|
+
"relatedEventIndex": 2
|
|
11
|
+
}
|
|
12
|
+
]
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
{"type":"RUN_STARTED","threadId":"thread_001","runId":"run_001","timestamp":1755300014600}
|
|
2
|
+
{"type":"TOOL_CALL_START","toolCallId":"call_001","toolCallName":"get_weather","timestamp":1755300014700}
|
|
3
|
+
{"type":"TOOL_CALL_END","toolCallId":"call_001","timestamp":1755300014800}
|
|
4
|
+
{"type":"TOOL_CALL_START","toolCallId":"call_001","toolCallName":"get_weather","timestamp":1755300014900}
|
|
5
|
+
{"type":"RUN_FINISHED","threadId":"thread_001","runId":"run_001","outcome":{"type":"success"},"timestamp":1755300015000}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
[
|
|
2
|
+
{
|
|
3
|
+
"rule": "AGUI206",
|
|
4
|
+
"severity": "warning",
|
|
5
|
+
"message": "TOOL_CALL_RESULT for toolCallId 'call_001' arrived while the call is still open",
|
|
6
|
+
"eventIndex": 2,
|
|
7
|
+
"specUrl": "https://docs.ag-ui.com/concepts/events#toolcallresult",
|
|
8
|
+
"eventType": "TOOL_CALL_RESULT",
|
|
9
|
+
"pointer": "/toolCallId",
|
|
10
|
+
"relatedEventIndex": 1
|
|
11
|
+
}
|
|
12
|
+
]
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
{"type":"RUN_STARTED","threadId":"thread_001","runId":"run_001","timestamp":1755300015100}
|
|
2
|
+
{"type":"TOOL_CALL_START","toolCallId":"call_001","toolCallName":"get_weather","timestamp":1755300015200}
|
|
3
|
+
{"type":"TOOL_CALL_RESULT","messageId":"msg_001","toolCallId":"call_001","content":"early","timestamp":1755300015300}
|
|
4
|
+
{"type":"TOOL_CALL_END","toolCallId":"call_001","timestamp":1755300015400}
|
|
5
|
+
{"type":"RUN_FINISHED","threadId":"thread_001","runId":"run_001","outcome":{"type":"success"},"timestamp":1755300015500}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
[
|
|
2
|
+
{
|
|
3
|
+
"rule": "AGUI207",
|
|
4
|
+
"severity": "error",
|
|
5
|
+
"message": "TOOL_CALL_RESULT references toolCallId 'call_ghost', which was never started",
|
|
6
|
+
"eventIndex": 1,
|
|
7
|
+
"specUrl": "https://docs.ag-ui.com/concepts/events#toolcallresult",
|
|
8
|
+
"eventType": "TOOL_CALL_RESULT",
|
|
9
|
+
"pointer": "/toolCallId"
|
|
10
|
+
}
|
|
11
|
+
]
|