ag-ui-validate 0.2.0 → 0.4.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.
Files changed (168) hide show
  1. package/README.md +82 -23
  2. package/dist/{catalog-BglXBNbL.js → catalog-3e6INLCp.js} +122 -4
  3. package/dist/catalog-3e6INLCp.js.map +1 -0
  4. package/dist/{catalog-Ci9dqc1a.cjs → catalog-DH5gDIbo.cjs} +122 -4
  5. package/dist/catalog-DH5gDIbo.cjs.map +1 -0
  6. package/dist/cli.js +641 -63
  7. package/dist/cli.js.map +1 -1
  8. package/dist/{index-Hmqj3r_r.d.cts → index-Cydfs-rB.d.ts} +4 -4
  9. package/dist/{index-oNG1kOp9.d.ts → index-DsVmjcLO.d.cts} +4 -4
  10. package/dist/index.cjs +2 -2
  11. package/dist/index.d.cts +2 -2
  12. package/dist/index.d.ts +2 -2
  13. package/dist/index.js +2 -2
  14. package/dist/report.cjs +11 -2
  15. package/dist/report.cjs.map +1 -1
  16. package/dist/report.d.cts +21 -12
  17. package/dist/report.d.ts +21 -12
  18. package/dist/report.js +11 -2
  19. package/dist/report.js.map +1 -1
  20. package/dist/{src-rGZ2G4qA.js → src-CezZ73Mm.js} +494 -59
  21. package/dist/src-CezZ73Mm.js.map +1 -0
  22. package/dist/{src-HmI-kxef.cjs → src-CyugLoks.cjs} +494 -59
  23. package/dist/src-CyugLoks.cjs.map +1 -0
  24. package/dist/transport.cjs +1 -1
  25. package/dist/transport.cjs.map +1 -1
  26. package/dist/transport.d.cts +1 -1
  27. package/dist/transport.d.ts +1 -1
  28. package/dist/transport.js +1 -1
  29. package/dist/transport.js.map +1 -1
  30. package/dist/{types-oH_QTnn2.d.ts → types-CUIgyj2N.d.cts} +3 -1
  31. package/dist/{types-oH_QTnn2.d.cts → types-CUIgyj2N.d.ts} +3 -1
  32. package/dist/vitest.js +616 -61
  33. package/dist/vitest.js.map +1 -1
  34. package/{src → js/src}/cli-args.ts +16 -0
  35. package/{src → js/src}/cli.ts +1 -1
  36. package/{src → js/src}/index.ts +5 -0
  37. package/{src → js/src}/protocol/event-table.ts +93 -2
  38. package/js/src/report/json.ts +31 -0
  39. package/{src → js/src}/report/sarif.ts +3 -6
  40. package/{src → js/src}/rules/catalog.ts +5 -1
  41. package/{src → js/src}/rules/checks/context.ts +48 -3
  42. package/{src → js/src}/rules/checks/lifecycle.ts +5 -2
  43. package/js/src/rules/checks/subagents.ts +78 -0
  44. package/{src → js/src}/rules/checks/text.ts +11 -3
  45. package/{src → js/src}/rules/checks/toolcalls.ts +8 -2
  46. package/{src → js/src}/transport/index.ts +1 -1
  47. package/package.json +15 -14
  48. package/{src/rules → spec}/catalog.json +109 -2
  49. package/spec/event-categories.json +60 -0
  50. package/spec/fixtures/README.md +91 -0
  51. package/spec/fixtures/invalid/AGUI001-first-event-not-run-started/expected.json +10 -0
  52. package/spec/fixtures/invalid/AGUI001-first-event-not-run-started/stream.jsonl +4 -0
  53. package/spec/fixtures/invalid/AGUI002-duplicate-run-started/expected.json +11 -0
  54. package/spec/fixtures/invalid/AGUI002-duplicate-run-started/stream.jsonl +3 -0
  55. package/spec/fixtures/invalid/AGUI003-run-never-terminated/expected.json +10 -0
  56. package/spec/fixtures/invalid/AGUI003-run-never-terminated/stream.jsonl +4 -0
  57. package/spec/fixtures/invalid/AGUI004-event-after-terminal/expected.json +11 -0
  58. package/spec/fixtures/invalid/AGUI004-event-after-terminal/stream.jsonl +3 -0
  59. package/spec/fixtures/invalid/AGUI005-finished-and-error/expected.json +11 -0
  60. package/spec/fixtures/invalid/AGUI005-finished-and-error/stream.jsonl +3 -0
  61. package/spec/fixtures/invalid/AGUI006-step-finished-unmatched/expected.json +11 -0
  62. package/spec/fixtures/invalid/AGUI006-step-finished-unmatched/stream.jsonl +3 -0
  63. package/spec/fixtures/invalid/AGUI007-step-unterminated/expected.json +10 -0
  64. package/spec/fixtures/invalid/AGUI007-step-unterminated/stream.jsonl +3 -0
  65. package/spec/fixtures/invalid/AGUI008-unstable-run-ids/expected.json +12 -0
  66. package/spec/fixtures/invalid/AGUI008-unstable-run-ids/stream.jsonl +2 -0
  67. package/spec/fixtures/invalid/AGUI101-content-without-start/expected.json +11 -0
  68. package/spec/fixtures/invalid/AGUI101-content-without-start/stream.jsonl +3 -0
  69. package/spec/fixtures/invalid/AGUI102-end-without-start/expected.json +11 -0
  70. package/spec/fixtures/invalid/AGUI102-end-without-start/stream.jsonl +3 -0
  71. package/spec/fixtures/invalid/AGUI103-message-unterminated/expected.json +10 -0
  72. package/spec/fixtures/invalid/AGUI103-message-unterminated/stream.jsonl +4 -0
  73. package/spec/fixtures/invalid/AGUI104-duplicate-message-id/expected.json +12 -0
  74. package/spec/fixtures/invalid/AGUI104-duplicate-message-id/stream.jsonl +6 -0
  75. package/spec/fixtures/invalid/AGUI105-empty-content-delta/expected.json +12 -0
  76. package/spec/fixtures/invalid/AGUI105-empty-content-delta/stream.jsonl +5 -0
  77. package/spec/fixtures/invalid/AGUI106-interleaved-same-message-id/expected.json +12 -0
  78. package/spec/fixtures/invalid/AGUI106-interleaved-same-message-id/stream.jsonl +5 -0
  79. package/spec/fixtures/invalid/AGUI201-args-without-start/expected.json +11 -0
  80. package/spec/fixtures/invalid/AGUI201-args-without-start/stream.jsonl +3 -0
  81. package/spec/fixtures/invalid/AGUI202-end-without-start/expected.json +11 -0
  82. package/spec/fixtures/invalid/AGUI202-end-without-start/stream.jsonl +3 -0
  83. package/spec/fixtures/invalid/AGUI203-unterminated-tool-call/expected.json +10 -0
  84. package/spec/fixtures/invalid/AGUI203-unterminated-tool-call/stream.jsonl +4 -0
  85. package/spec/fixtures/invalid/AGUI204-args-not-json/expected.json +10 -0
  86. package/spec/fixtures/invalid/AGUI204-args-not-json/stream.jsonl +6 -0
  87. package/spec/fixtures/invalid/AGUI205-duplicate-tool-call-id/expected.json +12 -0
  88. package/spec/fixtures/invalid/AGUI205-duplicate-tool-call-id/stream.jsonl +5 -0
  89. package/spec/fixtures/invalid/AGUI206-result-before-end/expected.json +12 -0
  90. package/spec/fixtures/invalid/AGUI206-result-before-end/stream.jsonl +5 -0
  91. package/spec/fixtures/invalid/AGUI207-result-unknown-id/expected.json +11 -0
  92. package/spec/fixtures/invalid/AGUI207-result-unknown-id/stream.jsonl +3 -0
  93. package/spec/fixtures/invalid/AGUI208-unknown-parent-message-id/expected.json +11 -0
  94. package/spec/fixtures/invalid/AGUI208-unknown-parent-message-id/stream.jsonl +4 -0
  95. package/spec/fixtures/invalid/AGUI301-delta-before-snapshot/expected.json +10 -0
  96. package/spec/fixtures/invalid/AGUI301-delta-before-snapshot/stream.jsonl +3 -0
  97. package/spec/fixtures/invalid/AGUI302-delta-failed-to-apply/expected.json +11 -0
  98. package/spec/fixtures/invalid/AGUI302-delta-failed-to-apply/stream.jsonl +4 -0
  99. package/spec/fixtures/invalid/AGUI303-invalid-patch-document/expected.json +11 -0
  100. package/spec/fixtures/invalid/AGUI303-invalid-patch-document/stream.jsonl +4 -0
  101. package/spec/fixtures/invalid/AGUI304-midrun-snapshot-discards-deltas/expected.json +10 -0
  102. package/spec/fixtures/invalid/AGUI304-midrun-snapshot-discards-deltas/stream.jsonl +5 -0
  103. package/spec/fixtures/invalid/AGUI305-shared-state-never-established/expected.json +9 -0
  104. package/spec/fixtures/invalid/AGUI305-shared-state-never-established/options.json +5 -0
  105. package/spec/fixtures/invalid/AGUI305-shared-state-never-established/stream.jsonl +5 -0
  106. package/spec/fixtures/invalid/AGUI401-reasoning-content-without-start/expected.json +11 -0
  107. package/spec/fixtures/invalid/AGUI401-reasoning-content-without-start/stream.jsonl +3 -0
  108. package/spec/fixtures/invalid/AGUI402-reasoning-unterminated/expected.json +10 -0
  109. package/spec/fixtures/invalid/AGUI402-reasoning-unterminated/stream.jsonl +3 -0
  110. package/spec/fixtures/invalid/AGUI501-missing-data-prefix/expected.json +9 -0
  111. package/spec/fixtures/invalid/AGUI501-missing-data-prefix/scenario.json +17 -0
  112. package/spec/fixtures/invalid/AGUI502-payload-not-json/expected.json +10 -0
  113. package/spec/fixtures/invalid/AGUI502-payload-not-json/stream.jsonl +3 -0
  114. package/spec/fixtures/invalid/AGUI503-unknown-event-type/expected.json +10 -0
  115. package/spec/fixtures/invalid/AGUI503-unknown-event-type/stream.jsonl +3 -0
  116. package/spec/fixtures/invalid/AGUI504-schema-violation/expected.json +11 -0
  117. package/spec/fixtures/invalid/AGUI504-schema-violation/stream.jsonl +4 -0
  118. package/spec/fixtures/invalid/AGUI505-unexpected-content-type/expected.json +9 -0
  119. package/spec/fixtures/invalid/AGUI505-unexpected-content-type/scenario.json +25 -0
  120. package/spec/fixtures/invalid/AGUI506-keepalive-gap/expected.json +9 -0
  121. package/spec/fixtures/invalid/AGUI506-keepalive-gap/scenario.json +25 -0
  122. package/spec/fixtures/invalid/AGUI507-buffered-response/expected.json +9 -0
  123. package/spec/fixtures/invalid/AGUI507-buffered-response/scenario.json +9 -0
  124. package/spec/fixtures/invalid/AGUI508-connection-dropped/expected.json +17 -0
  125. package/spec/fixtures/invalid/AGUI508-connection-dropped/scenario.json +10 -0
  126. package/spec/fixtures/invalid/AGUI601-duplicate-subagent-started/expected.json +12 -0
  127. package/spec/fixtures/invalid/AGUI601-duplicate-subagent-started/stream.jsonl +5 -0
  128. package/spec/fixtures/invalid/AGUI602-finished-without-start/expected.json +11 -0
  129. package/spec/fixtures/invalid/AGUI602-finished-without-start/stream.jsonl +3 -0
  130. package/spec/fixtures/invalid/AGUI603-error-without-start/expected.json +11 -0
  131. package/spec/fixtures/invalid/AGUI603-error-without-start/stream.jsonl +3 -0
  132. package/spec/fixtures/invalid/AGUI604-subagent-unterminated/expected.json +10 -0
  133. package/spec/fixtures/invalid/AGUI604-subagent-unterminated/stream.jsonl +3 -0
  134. package/spec/fixtures/invalid/AGUI605-unknown-parent-subagent-run-id/expected.json +11 -0
  135. package/spec/fixtures/invalid/AGUI605-unknown-parent-subagent-run-id/stream.jsonl +4 -0
  136. package/spec/fixtures/invalid/AGUI606-continuation-owner-mismatch/expected.json +11 -0
  137. package/spec/fixtures/invalid/AGUI606-continuation-owner-mismatch/stream.jsonl +6 -0
  138. package/spec/fixtures/invalid/AGUI901-raw-wraps-typed-event/expected.json +11 -0
  139. package/spec/fixtures/invalid/AGUI901-raw-wraps-typed-event/stream.jsonl +3 -0
  140. package/spec/fixtures/invalid/AGUI902-no-timestamps/expected.json +9 -0
  141. package/spec/fixtures/invalid/AGUI902-no-timestamps/stream.jsonl +2 -0
  142. package/spec/fixtures/invalid/AGUI903-custom-name-not-namespaced/expected.json +11 -0
  143. package/spec/fixtures/invalid/AGUI903-custom-name-not-namespaced/stream.jsonl +3 -0
  144. package/spec/fixtures/valid/agentic-chat.jsonl +14 -0
  145. package/spec/fixtures/valid/agentic-generative-ui.jsonl +13 -0
  146. package/spec/fixtures/valid/backend-tool-rendering.jsonl +14 -0
  147. package/spec/fixtures/valid/human-in-the-loop.jsonl +13 -0
  148. package/spec/fixtures/valid/predictive-state-updates.expected.json +11 -0
  149. package/spec/fixtures/valid/predictive-state-updates.jsonl +11 -0
  150. package/spec/fixtures/valid/shared-state.jsonl +8 -0
  151. package/spec/fixtures/valid/tool-based-generative-ui.jsonl +5 -0
  152. package/dist/catalog-BglXBNbL.js.map +0 -1
  153. package/dist/catalog-Ci9dqc1a.cjs.map +0 -1
  154. package/dist/src-HmI-kxef.cjs.map +0 -1
  155. package/dist/src-rGZ2G4qA.js.map +0 -1
  156. package/src/report/json.ts +0 -20
  157. /package/{src → js/src}/protocol/jsonpatch.ts +0 -0
  158. /package/{src → js/src}/report/index.ts +0 -0
  159. /package/{src → js/src}/report/junit.ts +0 -0
  160. /package/{src → js/src}/report/pretty.ts +0 -0
  161. /package/{src → js/src}/rules/checks/reasoning.ts +0 -0
  162. /package/{src → js/src}/rules/checks/state.ts +0 -0
  163. /package/{src → js/src}/rules/checks/transport.ts +0 -0
  164. /package/{src → js/src}/transport/ndjson.ts +0 -0
  165. /package/{src → js/src}/transport/sse.ts +0 -0
  166. /package/{src → js/src}/types.ts +0 -0
  167. /package/{src → js/src}/vitest/index.ts +0 -0
  168. /package/{src → js/src}/vitest/matcher.ts +0 -0
@@ -0,0 +1,60 @@
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
+ "subagent"
13
+ ],
14
+ "eventCategory": {
15
+ "RUN_STARTED": "lifecycle",
16
+ "RUN_FINISHED": "lifecycle",
17
+ "RUN_ERROR": "lifecycle",
18
+ "STEP_STARTED": "lifecycle",
19
+ "STEP_FINISHED": "lifecycle",
20
+ "TEXT_MESSAGE_START": "text",
21
+ "TEXT_MESSAGE_CONTENT": "text",
22
+ "TEXT_MESSAGE_END": "text",
23
+ "TEXT_MESSAGE_CHUNK": "text",
24
+ "TOOL_CALL_START": "toolcall",
25
+ "TOOL_CALL_ARGS": "toolcall",
26
+ "TOOL_CALL_END": "toolcall",
27
+ "TOOL_CALL_CHUNK": "toolcall",
28
+ "TOOL_CALL_RESULT": "toolcall",
29
+ "STATE_SNAPSHOT": "state",
30
+ "STATE_DELTA": "state",
31
+ "MESSAGES_SNAPSHOT": "state",
32
+ "ACTIVITY_SNAPSHOT": "activity",
33
+ "ACTIVITY_DELTA": "activity",
34
+ "REASONING_START": "reasoning",
35
+ "REASONING_MESSAGE_START": "reasoning",
36
+ "REASONING_MESSAGE_CONTENT": "reasoning",
37
+ "REASONING_MESSAGE_END": "reasoning",
38
+ "REASONING_MESSAGE_CHUNK": "reasoning",
39
+ "REASONING_END": "reasoning",
40
+ "REASONING_ENCRYPTED_VALUE": "reasoning",
41
+ "THINKING_START": "thinking",
42
+ "THINKING_END": "thinking",
43
+ "THINKING_TEXT_MESSAGE_START": "thinking",
44
+ "THINKING_TEXT_MESSAGE_CONTENT": "thinking",
45
+ "THINKING_TEXT_MESSAGE_END": "thinking",
46
+ "RAW": "special",
47
+ "CUSTOM": "special",
48
+ "SUBAGENT_STARTED": "subagent",
49
+ "SUBAGENT_FINISHED": "subagent",
50
+ "SUBAGENT_ERROR": "subagent"
51
+ },
52
+ "$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.",
53
+ "deprecated": {
54
+ "THINKING_START": "REASONING_START",
55
+ "THINKING_END": "REASONING_END",
56
+ "THINKING_TEXT_MESSAGE_START": "REASONING_MESSAGE_START",
57
+ "THINKING_TEXT_MESSAGE_CONTENT": "REASONING_MESSAGE_CONTENT",
58
+ "THINKING_TEXT_MESSAGE_END": "REASONING_MESSAGE_END"
59
+ }
60
+ }
@@ -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,10 @@
1
+ [
2
+ {
3
+ "rule": "AGUI003",
4
+ "severity": "error",
5
+ "message": "Run 'run_001' ended without RUN_FINISHED or RUN_ERROR",
6
+ "eventIndex": -1,
7
+ "specUrl": "https://docs.ag-ui.com/concepts/events#runfinished",
8
+ "relatedEventIndex": 0
9
+ }
10
+ ]
@@ -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,10 @@
1
+ [
2
+ {
3
+ "rule": "AGUI007",
4
+ "severity": "error",
5
+ "message": "STEP_STARTED 'plan' never finished",
6
+ "eventIndex": 2,
7
+ "specUrl": "https://docs.ag-ui.com/concepts/events#stepstarted",
8
+ "relatedEventIndex": 1
9
+ }
10
+ ]
@@ -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,2 @@
1
+ {"type":"RUN_STARTED","threadId":"thread_001","runId":"run_001","timestamp":1755300010200}
2
+ {"type":"RUN_FINISHED","threadId":"thread_001","runId":"run_999","outcome":{"type":"success"},"timestamp":1755300010300}
@@ -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,10 @@
1
+ [
2
+ {
3
+ "rule": "AGUI103",
4
+ "severity": "error",
5
+ "message": "TEXT_MESSAGE_START messageId 'msg_001' never ended",
6
+ "eventIndex": 3,
7
+ "specUrl": "https://docs.ag-ui.com/concepts/events#text-message-events",
8
+ "relatedEventIndex": 1
9
+ }
10
+ ]
@@ -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,10 @@
1
+ [
2
+ {
3
+ "rule": "AGUI203",
4
+ "severity": "error",
5
+ "message": "TOOL_CALL_START id 'call_7' never terminated",
6
+ "eventIndex": 3,
7
+ "specUrl": "https://docs.ag-ui.com/concepts/events#tool-call-events",
8
+ "relatedEventIndex": 1
9
+ }
10
+ ]
@@ -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
+ ]
@@ -0,0 +1,3 @@
1
+ {"type":"RUN_STARTED","threadId":"thread_001","runId":"run_001","timestamp":1755300015600}
2
+ {"type":"TOOL_CALL_RESULT","messageId":"msg_001","toolCallId":"call_ghost","content":"orphan","timestamp":1755300015700}
3
+ {"type":"RUN_FINISHED","threadId":"thread_001","runId":"run_001","outcome":{"type":"success"},"timestamp":1755300015800}
@@ -0,0 +1,11 @@
1
+ [
2
+ {
3
+ "rule": "AGUI208",
4
+ "severity": "info",
5
+ "message": "TOOL_CALL_START parentMessageId 'msg_ghost' matches no message observed in this stream",
6
+ "eventIndex": 1,
7
+ "specUrl": "https://docs.ag-ui.com/concepts/events#toolcallstart",
8
+ "eventType": "TOOL_CALL_START",
9
+ "pointer": "/parentMessageId"
10
+ }
11
+ ]
@@ -0,0 +1,4 @@
1
+ {"type":"RUN_STARTED","threadId":"thread_001","runId":"run_001","timestamp":1755300015900}
2
+ {"type":"TOOL_CALL_START","toolCallId":"call_001","toolCallName":"get_weather","parentMessageId":"msg_ghost","timestamp":1755300016000}
3
+ {"type":"TOOL_CALL_END","toolCallId":"call_001","timestamp":1755300016100}
4
+ {"type":"RUN_FINISHED","threadId":"thread_001","runId":"run_001","outcome":{"type":"success"},"timestamp":1755300016200}
@@ -0,0 +1,10 @@
1
+ [
2
+ {
3
+ "rule": "AGUI301",
4
+ "severity": "info",
5
+ "message": "STATE_DELTA precedes any STATE_SNAPSHOT; the base it applies to is not observable on this stream",
6
+ "eventIndex": 1,
7
+ "specUrl": "https://docs.ag-ui.com/concepts/events#statesnapshot",
8
+ "eventType": "STATE_DELTA"
9
+ }
10
+ ]
@@ -0,0 +1,3 @@
1
+ {"type":"RUN_STARTED","threadId":"thread_001","runId":"run_001","timestamp":1755300016300}
2
+ {"type":"STATE_DELTA","delta":[{"op":"add","path":"/a","value":1}],"timestamp":1755300016400}
3
+ {"type":"RUN_FINISHED","threadId":"thread_001","runId":"run_001","outcome":{"type":"success"},"timestamp":1755300016500}
@@ -0,0 +1,11 @@
1
+ [
2
+ {
3
+ "rule": "AGUI302",
4
+ "severity": "error",
5
+ "message": "STATE_DELTA failed to apply: /items/3: '3' is not a valid index for an array of length 0",
6
+ "eventIndex": 2,
7
+ "specUrl": "https://docs.ag-ui.com/concepts/events#statedelta",
8
+ "eventType": "STATE_DELTA",
9
+ "pointer": "/delta/0"
10
+ }
11
+ ]
@@ -0,0 +1,4 @@
1
+ {"type":"RUN_STARTED","threadId":"thread_001","runId":"run_001","timestamp":1755300016600}
2
+ {"type":"STATE_SNAPSHOT","snapshot":{"items":[]},"timestamp":1755300016700}
3
+ {"type":"STATE_DELTA","delta":[{"op":"replace","path":"/items/3","value":"x"}],"timestamp":1755300016800}
4
+ {"type":"RUN_FINISHED","threadId":"thread_001","runId":"run_001","outcome":{"type":"success"},"timestamp":1755300016900}