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.
Files changed (144) hide show
  1. package/README.md +70 -10
  2. package/dist/{catalog-Ci9dqc1a.cjs → catalog-AB5vuZ8j.cjs} +3 -3
  3. package/dist/catalog-AB5vuZ8j.cjs.map +1 -0
  4. package/dist/{catalog-BglXBNbL.js → catalog-DqTI4VLt.js} +3 -3
  5. package/dist/catalog-DqTI4VLt.js.map +1 -0
  6. package/dist/cli.js +2 -2
  7. package/dist/cli.js.map +1 -1
  8. package/dist/index.cjs +2 -2
  9. package/dist/index.js +2 -2
  10. package/dist/report.cjs +1 -1
  11. package/dist/report.cjs.map +1 -1
  12. package/dist/report.js +1 -1
  13. package/dist/report.js.map +1 -1
  14. package/dist/{src-HmI-kxef.cjs → src-D04i3Vso.cjs} +2 -2
  15. package/dist/src-D04i3Vso.cjs.map +1 -0
  16. package/dist/{src-rGZ2G4qA.js → src-Dcuqz2QC.js} +2 -2
  17. package/dist/src-Dcuqz2QC.js.map +1 -0
  18. package/dist/transport.cjs +1 -1
  19. package/dist/transport.cjs.map +1 -1
  20. package/dist/transport.js +1 -1
  21. package/dist/transport.js.map +1 -1
  22. package/dist/vitest.js +2 -2
  23. package/dist/vitest.js.map +1 -1
  24. package/{src → js/src}/rules/catalog.ts +1 -1
  25. package/{src → js/src}/transport/index.ts +1 -1
  26. package/package.json +14 -13
  27. package/{src/rules → spec}/catalog.json +1 -1
  28. package/spec/event-categories.json +56 -0
  29. package/spec/fixtures/README.md +91 -0
  30. package/spec/fixtures/invalid/AGUI001-first-event-not-run-started/expected.json +10 -0
  31. package/spec/fixtures/invalid/AGUI001-first-event-not-run-started/stream.jsonl +4 -0
  32. package/spec/fixtures/invalid/AGUI002-duplicate-run-started/expected.json +11 -0
  33. package/spec/fixtures/invalid/AGUI002-duplicate-run-started/stream.jsonl +3 -0
  34. package/spec/fixtures/invalid/AGUI003-run-never-terminated/expected.json +10 -0
  35. package/spec/fixtures/invalid/AGUI003-run-never-terminated/stream.jsonl +4 -0
  36. package/spec/fixtures/invalid/AGUI004-event-after-terminal/expected.json +11 -0
  37. package/spec/fixtures/invalid/AGUI004-event-after-terminal/stream.jsonl +3 -0
  38. package/spec/fixtures/invalid/AGUI005-finished-and-error/expected.json +11 -0
  39. package/spec/fixtures/invalid/AGUI005-finished-and-error/stream.jsonl +3 -0
  40. package/spec/fixtures/invalid/AGUI006-step-finished-unmatched/expected.json +11 -0
  41. package/spec/fixtures/invalid/AGUI006-step-finished-unmatched/stream.jsonl +3 -0
  42. package/spec/fixtures/invalid/AGUI007-step-unterminated/expected.json +10 -0
  43. package/spec/fixtures/invalid/AGUI007-step-unterminated/stream.jsonl +3 -0
  44. package/spec/fixtures/invalid/AGUI008-unstable-run-ids/expected.json +12 -0
  45. package/spec/fixtures/invalid/AGUI008-unstable-run-ids/stream.jsonl +2 -0
  46. package/spec/fixtures/invalid/AGUI101-content-without-start/expected.json +11 -0
  47. package/spec/fixtures/invalid/AGUI101-content-without-start/stream.jsonl +3 -0
  48. package/spec/fixtures/invalid/AGUI102-end-without-start/expected.json +11 -0
  49. package/spec/fixtures/invalid/AGUI102-end-without-start/stream.jsonl +3 -0
  50. package/spec/fixtures/invalid/AGUI103-message-unterminated/expected.json +10 -0
  51. package/spec/fixtures/invalid/AGUI103-message-unterminated/stream.jsonl +4 -0
  52. package/spec/fixtures/invalid/AGUI104-duplicate-message-id/expected.json +12 -0
  53. package/spec/fixtures/invalid/AGUI104-duplicate-message-id/stream.jsonl +6 -0
  54. package/spec/fixtures/invalid/AGUI105-empty-content-delta/expected.json +12 -0
  55. package/spec/fixtures/invalid/AGUI105-empty-content-delta/stream.jsonl +5 -0
  56. package/spec/fixtures/invalid/AGUI106-interleaved-same-message-id/expected.json +12 -0
  57. package/spec/fixtures/invalid/AGUI106-interleaved-same-message-id/stream.jsonl +5 -0
  58. package/spec/fixtures/invalid/AGUI201-args-without-start/expected.json +11 -0
  59. package/spec/fixtures/invalid/AGUI201-args-without-start/stream.jsonl +3 -0
  60. package/spec/fixtures/invalid/AGUI202-end-without-start/expected.json +11 -0
  61. package/spec/fixtures/invalid/AGUI202-end-without-start/stream.jsonl +3 -0
  62. package/spec/fixtures/invalid/AGUI203-unterminated-tool-call/expected.json +10 -0
  63. package/spec/fixtures/invalid/AGUI203-unterminated-tool-call/stream.jsonl +4 -0
  64. package/spec/fixtures/invalid/AGUI204-args-not-json/expected.json +10 -0
  65. package/spec/fixtures/invalid/AGUI204-args-not-json/stream.jsonl +6 -0
  66. package/spec/fixtures/invalid/AGUI205-duplicate-tool-call-id/expected.json +12 -0
  67. package/spec/fixtures/invalid/AGUI205-duplicate-tool-call-id/stream.jsonl +5 -0
  68. package/spec/fixtures/invalid/AGUI206-result-before-end/expected.json +12 -0
  69. package/spec/fixtures/invalid/AGUI206-result-before-end/stream.jsonl +5 -0
  70. package/spec/fixtures/invalid/AGUI207-result-unknown-id/expected.json +11 -0
  71. package/spec/fixtures/invalid/AGUI207-result-unknown-id/stream.jsonl +3 -0
  72. package/spec/fixtures/invalid/AGUI208-unknown-parent-message-id/expected.json +11 -0
  73. package/spec/fixtures/invalid/AGUI208-unknown-parent-message-id/stream.jsonl +4 -0
  74. package/spec/fixtures/invalid/AGUI301-delta-before-snapshot/expected.json +10 -0
  75. package/spec/fixtures/invalid/AGUI301-delta-before-snapshot/stream.jsonl +3 -0
  76. package/spec/fixtures/invalid/AGUI302-delta-failed-to-apply/expected.json +11 -0
  77. package/spec/fixtures/invalid/AGUI302-delta-failed-to-apply/stream.jsonl +4 -0
  78. package/spec/fixtures/invalid/AGUI303-invalid-patch-document/expected.json +11 -0
  79. package/spec/fixtures/invalid/AGUI303-invalid-patch-document/stream.jsonl +4 -0
  80. package/spec/fixtures/invalid/AGUI304-midrun-snapshot-discards-deltas/expected.json +10 -0
  81. package/spec/fixtures/invalid/AGUI304-midrun-snapshot-discards-deltas/stream.jsonl +5 -0
  82. package/spec/fixtures/invalid/AGUI305-shared-state-never-established/expected.json +9 -0
  83. package/spec/fixtures/invalid/AGUI305-shared-state-never-established/options.json +5 -0
  84. package/spec/fixtures/invalid/AGUI305-shared-state-never-established/stream.jsonl +5 -0
  85. package/spec/fixtures/invalid/AGUI401-reasoning-content-without-start/expected.json +11 -0
  86. package/spec/fixtures/invalid/AGUI401-reasoning-content-without-start/stream.jsonl +3 -0
  87. package/spec/fixtures/invalid/AGUI402-reasoning-unterminated/expected.json +10 -0
  88. package/spec/fixtures/invalid/AGUI402-reasoning-unterminated/stream.jsonl +3 -0
  89. package/spec/fixtures/invalid/AGUI501-missing-data-prefix/expected.json +9 -0
  90. package/spec/fixtures/invalid/AGUI501-missing-data-prefix/scenario.json +17 -0
  91. package/spec/fixtures/invalid/AGUI502-payload-not-json/expected.json +10 -0
  92. package/spec/fixtures/invalid/AGUI502-payload-not-json/stream.jsonl +3 -0
  93. package/spec/fixtures/invalid/AGUI503-unknown-event-type/expected.json +10 -0
  94. package/spec/fixtures/invalid/AGUI503-unknown-event-type/stream.jsonl +3 -0
  95. package/spec/fixtures/invalid/AGUI504-schema-violation/expected.json +11 -0
  96. package/spec/fixtures/invalid/AGUI504-schema-violation/stream.jsonl +4 -0
  97. package/spec/fixtures/invalid/AGUI505-unexpected-content-type/expected.json +9 -0
  98. package/spec/fixtures/invalid/AGUI505-unexpected-content-type/scenario.json +25 -0
  99. package/spec/fixtures/invalid/AGUI506-keepalive-gap/expected.json +9 -0
  100. package/spec/fixtures/invalid/AGUI506-keepalive-gap/scenario.json +25 -0
  101. package/spec/fixtures/invalid/AGUI507-buffered-response/expected.json +9 -0
  102. package/spec/fixtures/invalid/AGUI507-buffered-response/scenario.json +9 -0
  103. package/spec/fixtures/invalid/AGUI508-connection-dropped/expected.json +17 -0
  104. package/spec/fixtures/invalid/AGUI508-connection-dropped/scenario.json +10 -0
  105. package/spec/fixtures/invalid/AGUI901-raw-wraps-typed-event/expected.json +11 -0
  106. package/spec/fixtures/invalid/AGUI901-raw-wraps-typed-event/stream.jsonl +3 -0
  107. package/spec/fixtures/invalid/AGUI902-no-timestamps/expected.json +9 -0
  108. package/spec/fixtures/invalid/AGUI902-no-timestamps/stream.jsonl +2 -0
  109. package/spec/fixtures/invalid/AGUI903-custom-name-not-namespaced/expected.json +11 -0
  110. package/spec/fixtures/invalid/AGUI903-custom-name-not-namespaced/stream.jsonl +3 -0
  111. package/spec/fixtures/valid/agentic-chat.jsonl +14 -0
  112. package/spec/fixtures/valid/agentic-generative-ui.jsonl +13 -0
  113. package/spec/fixtures/valid/backend-tool-rendering.jsonl +14 -0
  114. package/spec/fixtures/valid/human-in-the-loop.jsonl +13 -0
  115. package/spec/fixtures/valid/predictive-state-updates.expected.json +11 -0
  116. package/spec/fixtures/valid/predictive-state-updates.jsonl +11 -0
  117. package/spec/fixtures/valid/shared-state.jsonl +8 -0
  118. package/spec/fixtures/valid/tool-based-generative-ui.jsonl +5 -0
  119. package/dist/catalog-BglXBNbL.js.map +0 -1
  120. package/dist/catalog-Ci9dqc1a.cjs.map +0 -1
  121. package/dist/src-HmI-kxef.cjs.map +0 -1
  122. package/dist/src-rGZ2G4qA.js.map +0 -1
  123. /package/{src → js/src}/cli-args.ts +0 -0
  124. /package/{src → js/src}/cli.ts +0 -0
  125. /package/{src → js/src}/index.ts +0 -0
  126. /package/{src → js/src}/protocol/event-table.ts +0 -0
  127. /package/{src → js/src}/protocol/jsonpatch.ts +0 -0
  128. /package/{src → js/src}/report/index.ts +0 -0
  129. /package/{src → js/src}/report/json.ts +0 -0
  130. /package/{src → js/src}/report/junit.ts +0 -0
  131. /package/{src → js/src}/report/pretty.ts +0 -0
  132. /package/{src → js/src}/report/sarif.ts +0 -0
  133. /package/{src → js/src}/rules/checks/context.ts +0 -0
  134. /package/{src → js/src}/rules/checks/lifecycle.ts +0 -0
  135. /package/{src → js/src}/rules/checks/reasoning.ts +0 -0
  136. /package/{src → js/src}/rules/checks/state.ts +0 -0
  137. /package/{src → js/src}/rules/checks/text.ts +0 -0
  138. /package/{src → js/src}/rules/checks/toolcalls.ts +0 -0
  139. /package/{src → js/src}/rules/checks/transport.ts +0 -0
  140. /package/{src → js/src}/transport/ndjson.ts +0 -0
  141. /package/{src → js/src}/transport/sse.ts +0 -0
  142. /package/{src → js/src}/types.ts +0 -0
  143. /package/{src → js/src}/vitest/index.ts +0 -0
  144. /package/{src → js/src}/vitest/matcher.ts +0 -0
@@ -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}
@@ -0,0 +1,11 @@
1
+ [
2
+ {
3
+ "rule": "AGUI303",
4
+ "severity": "error",
5
+ "message": "STATE_DELTA is not a valid RFC 6902 patch document: operation 0 has invalid op 'merge'",
6
+ "eventIndex": 2,
7
+ "specUrl": "https://docs.ag-ui.com/concepts/events#statedelta",
8
+ "eventType": "STATE_DELTA",
9
+ "pointer": "/delta/0/op"
10
+ }
11
+ ]
@@ -0,0 +1,4 @@
1
+ {"type":"RUN_STARTED","threadId":"thread_001","runId":"run_001","timestamp":1755300017000}
2
+ {"type":"STATE_SNAPSHOT","snapshot":{},"timestamp":1755300017100}
3
+ {"type":"STATE_DELTA","delta":[{"op":"merge","path":"/a","value":1}],"timestamp":1755300017200}
4
+ {"type":"RUN_FINISHED","threadId":"thread_001","runId":"run_001","outcome":{"type":"success"},"timestamp":1755300017300}
@@ -0,0 +1,10 @@
1
+ [
2
+ {
3
+ "rule": "AGUI304",
4
+ "severity": "info",
5
+ "message": "STATE_SNAPSHOT replaces state previously built from 1 delta(s)",
6
+ "eventIndex": 3,
7
+ "specUrl": "https://docs.ag-ui.com/concepts/events#statesnapshot",
8
+ "eventType": "STATE_SNAPSHOT"
9
+ }
10
+ ]
@@ -0,0 +1,5 @@
1
+ {"type":"RUN_STARTED","threadId":"thread_001","runId":"run_001","timestamp":1755300017400}
2
+ {"type":"STATE_SNAPSHOT","snapshot":{"a":1},"timestamp":1755300017500}
3
+ {"type":"STATE_DELTA","delta":[{"op":"replace","path":"/a","value":2}],"timestamp":1755300017600}
4
+ {"type":"STATE_SNAPSHOT","snapshot":{"a":99},"timestamp":1755300017700}
5
+ {"type":"RUN_FINISHED","threadId":"thread_001","runId":"run_001","outcome":{"type":"success"},"timestamp":1755300017800}
@@ -0,0 +1,9 @@
1
+ [
2
+ {
3
+ "rule": "AGUI305",
4
+ "severity": "warning",
5
+ "message": "features include 'shared-state' but no STATE_SNAPSHOT was emitted",
6
+ "eventIndex": -1,
7
+ "specUrl": "https://docs.ag-ui.com/concepts/events#state-management-events"
8
+ }
9
+ ]
@@ -0,0 +1,5 @@
1
+ {
2
+ "features": [
3
+ "shared-state"
4
+ ]
5
+ }
@@ -0,0 +1,5 @@
1
+ {"type":"RUN_STARTED","threadId":"thread_001","runId":"run_001","timestamp":1755300017900}
2
+ {"type":"TEXT_MESSAGE_START","messageId":"msg_001","role":"assistant","timestamp":1755300018000}
3
+ {"type":"TEXT_MESSAGE_CONTENT","messageId":"msg_001","delta":"No state events at all.","timestamp":1755300018100}
4
+ {"type":"TEXT_MESSAGE_END","messageId":"msg_001","timestamp":1755300018200}
5
+ {"type":"RUN_FINISHED","threadId":"thread_001","runId":"run_001","outcome":{"type":"success"},"timestamp":1755300018300}
@@ -0,0 +1,11 @@
1
+ [
2
+ {
3
+ "rule": "AGUI401",
4
+ "severity": "error",
5
+ "message": "REASONING_MESSAGE_CONTENT for messageId 'rmsg_ghost' with no open REASONING_MESSAGE_START",
6
+ "eventIndex": 1,
7
+ "specUrl": "https://docs.ag-ui.com/concepts/events#reasoningmessagecontent",
8
+ "eventType": "REASONING_MESSAGE_CONTENT",
9
+ "pointer": "/messageId"
10
+ }
11
+ ]
@@ -0,0 +1,3 @@
1
+ {"type":"RUN_STARTED","threadId":"thread_001","runId":"run_001","timestamp":1755300018400}
2
+ {"type":"REASONING_MESSAGE_CONTENT","messageId":"rmsg_ghost","delta":"orphan","timestamp":1755300018500}
3
+ {"type":"RUN_FINISHED","threadId":"thread_001","runId":"run_001","outcome":{"type":"success"},"timestamp":1755300018600}
@@ -0,0 +1,10 @@
1
+ [
2
+ {
3
+ "rule": "AGUI402",
4
+ "severity": "warning",
5
+ "message": "REASONING_START messageId 'rsn_001' never ended",
6
+ "eventIndex": 2,
7
+ "specUrl": "https://docs.ag-ui.com/concepts/events#reasoning-events",
8
+ "relatedEventIndex": 1
9
+ }
10
+ ]
@@ -0,0 +1,3 @@
1
+ {"type":"RUN_STARTED","threadId":"thread_001","runId":"run_001","timestamp":1755300018700}
2
+ {"type":"REASONING_START","messageId":"rsn_001","timestamp":1755300018800}
3
+ {"type":"RUN_FINISHED","threadId":"thread_001","runId":"run_001","outcome":{"type":"success"},"timestamp":1755300018900}
@@ -0,0 +1,9 @@
1
+ [
2
+ {
3
+ "rule": "AGUI501",
4
+ "severity": "error",
5
+ "message": "Malformed SSE framing: line '{\"type\":\"CUSTOM\",\"name\":\"acme.ping\",\"value\":1,\"timestamp\":17…' looks like a JSON payload but lacks the 'data:' field prefix, so SSE clients silently drop it",
6
+ "eventIndex": -1,
7
+ "specUrl": "https://html.spec.whatwg.org/multipage/server-sent-events.html#event-stream-interpretation"
8
+ }
9
+ ]
@@ -0,0 +1,17 @@
1
+ {
2
+ "contentType": "text/event-stream",
3
+ "chunks": [
4
+ {
5
+ "gapMs": 0,
6
+ "text": "data: {\"type\":\"RUN_STARTED\",\"threadId\":\"thread_001\",\"runId\":\"run_001\",\"timestamp\":1755300020500}\n\n"
7
+ },
8
+ {
9
+ "gapMs": 0,
10
+ "text": "{\"type\":\"CUSTOM\",\"name\":\"acme.ping\",\"value\":1,\"timestamp\":1755300020600}\n\n"
11
+ },
12
+ {
13
+ "gapMs": 0,
14
+ "text": "data: {\"type\":\"RUN_FINISHED\",\"threadId\":\"thread_001\",\"runId\":\"run_001\",\"outcome\":{\"type\":\"success\"},\"timestamp\":1755300020700}\n\n"
15
+ }
16
+ ]
17
+ }
@@ -0,0 +1,10 @@
1
+ [
2
+ {
3
+ "rule": "AGUI502",
4
+ "severity": "error",
5
+ "message": "Event payload is not valid JSON: Unexpected token 'b', \"{\"type\": broken json\" is not valid JSON",
6
+ "eventIndex": 1,
7
+ "specUrl": "https://docs.ag-ui.com/concepts/events#base-event-properties",
8
+ "eventType": ""
9
+ }
10
+ ]
@@ -0,0 +1,3 @@
1
+ {"type":"RUN_STARTED","threadId":"thread_001","runId":"run_001","timestamp":1755300019000}
2
+ {"type": broken json
3
+ {"type":"RUN_FINISHED","threadId":"thread_001","runId":"run_001","outcome":{"type":"success"},"timestamp":1755300019100}
@@ -0,0 +1,10 @@
1
+ [
2
+ {
3
+ "rule": "AGUI503",
4
+ "severity": "error",
5
+ "message": "Unknown event type 'AGUI_PING' (not in the installed AG-UI SDK v0.0.58, and not RAW or CUSTOM)",
6
+ "eventIndex": 1,
7
+ "specUrl": "https://docs.ag-ui.com/concepts/events#event-types-overview",
8
+ "eventType": "AGUI_PING"
9
+ }
10
+ ]
@@ -0,0 +1,3 @@
1
+ {"type":"RUN_STARTED","threadId":"thread_001","runId":"run_001","timestamp":1755300019200}
2
+ {"type":"AGUI_PING","timestamp":1755300019300}
3
+ {"type":"RUN_FINISHED","threadId":"thread_001","runId":"run_001","outcome":{"type":"success"},"timestamp":1755300019400}
@@ -0,0 +1,11 @@
1
+ [
2
+ {
3
+ "rule": "AGUI504",
4
+ "severity": "error",
5
+ "message": "TOOL_CALL_START: missing required field 'toolCallName' (string)",
6
+ "eventIndex": 1,
7
+ "specUrl": "https://docs.ag-ui.com/concepts/events#base-event-properties",
8
+ "eventType": "TOOL_CALL_START",
9
+ "pointer": "/toolCallName"
10
+ }
11
+ ]
@@ -0,0 +1,4 @@
1
+ {"type":"RUN_STARTED","threadId":"thread_001","runId":"run_001","timestamp":1755300019500}
2
+ {"type":"TOOL_CALL_START","toolCallId":"call_001","timestamp":1755300019600}
3
+ {"type":"TOOL_CALL_END","toolCallId":"call_001","timestamp":1755300019700}
4
+ {"type":"RUN_FINISHED","threadId":"thread_001","runId":"run_001","outcome":{"type":"success"},"timestamp":1755300019800}
@@ -0,0 +1,9 @@
1
+ [
2
+ {
3
+ "rule": "AGUI505",
4
+ "severity": "warning",
5
+ "message": "Content-Type 'application/json' is neither text/event-stream nor application/x-ndjson",
6
+ "eventIndex": -1,
7
+ "specUrl": "https://html.spec.whatwg.org/multipage/server-sent-events.html#sse-processing-model"
8
+ }
9
+ ]
@@ -0,0 +1,25 @@
1
+ {
2
+ "contentType": "application/json",
3
+ "chunks": [
4
+ {
5
+ "gapMs": 0,
6
+ "text": "data: {\"type\":\"RUN_STARTED\",\"threadId\":\"thread_001\",\"runId\":\"run_001\",\"timestamp\":1755300020800}\n\n"
7
+ },
8
+ {
9
+ "gapMs": 0,
10
+ "text": "data: {\"type\":\"TEXT_MESSAGE_START\",\"messageId\":\"msg_001\",\"role\":\"assistant\",\"timestamp\":1755300020900}\n\n"
11
+ },
12
+ {
13
+ "gapMs": 0,
14
+ "text": "data: {\"type\":\"TEXT_MESSAGE_CONTENT\",\"messageId\":\"msg_001\",\"delta\":\"All good here.\",\"timestamp\":1755300021000}\n\n"
15
+ },
16
+ {
17
+ "gapMs": 0,
18
+ "text": "data: {\"type\":\"TEXT_MESSAGE_END\",\"messageId\":\"msg_001\",\"timestamp\":1755300021100}\n\n"
19
+ },
20
+ {
21
+ "gapMs": 0,
22
+ "text": "data: {\"type\":\"RUN_FINISHED\",\"threadId\":\"thread_001\",\"runId\":\"run_001\",\"outcome\":{\"type\":\"success\"},\"timestamp\":1755300021200}\n\n"
23
+ }
24
+ ]
25
+ }
@@ -0,0 +1,9 @@
1
+ [
2
+ {
3
+ "rule": "AGUI506",
4
+ "severity": "info",
5
+ "message": "No event or keepalive frame for 47s",
6
+ "eventIndex": -1,
7
+ "specUrl": "https://docs.ag-ui.com/concepts/architecture#standard-http-client"
8
+ }
9
+ ]
@@ -0,0 +1,25 @@
1
+ {
2
+ "contentType": "text/event-stream",
3
+ "chunks": [
4
+ {
5
+ "gapMs": 0,
6
+ "text": "data: {\"type\":\"RUN_STARTED\",\"threadId\":\"thread_001\",\"runId\":\"run_001\",\"timestamp\":1755300021300}\n\n"
7
+ },
8
+ {
9
+ "gapMs": 0,
10
+ "text": "data: {\"type\":\"TEXT_MESSAGE_START\",\"messageId\":\"msg_001\",\"role\":\"assistant\",\"timestamp\":1755300021400}\n\n"
11
+ },
12
+ {
13
+ "gapMs": 0,
14
+ "text": "data: {\"type\":\"TEXT_MESSAGE_CONTENT\",\"messageId\":\"msg_001\",\"delta\":\"Thinking very hard…\",\"timestamp\":1755300021500}\n\n"
15
+ },
16
+ {
17
+ "gapMs": 0,
18
+ "text": "data: {\"type\":\"TEXT_MESSAGE_END\",\"messageId\":\"msg_001\",\"timestamp\":1755300021600}\n\n"
19
+ },
20
+ {
21
+ "gapMs": 47000,
22
+ "text": "data: {\"type\":\"RUN_FINISHED\",\"threadId\":\"thread_001\",\"runId\":\"run_001\",\"outcome\":{\"type\":\"success\"},\"timestamp\":1755300021700}\n\n"
23
+ }
24
+ ]
25
+ }
@@ -0,0 +1,9 @@
1
+ [
2
+ {
3
+ "rule": "AGUI507",
4
+ "severity": "info",
5
+ "message": "Response appears buffered: entire body (5 events) arrived in a single chunk",
6
+ "eventIndex": -1,
7
+ "specUrl": "https://docs.ag-ui.com/concepts/architecture#standard-http-client"
8
+ }
9
+ ]
@@ -0,0 +1,9 @@
1
+ {
2
+ "contentType": "text/event-stream",
3
+ "chunks": [
4
+ {
5
+ "gapMs": 0,
6
+ "text": "data: {\"type\":\"RUN_STARTED\",\"threadId\":\"thread_001\",\"runId\":\"run_001\",\"timestamp\":1755300021800}\n\ndata: {\"type\":\"TEXT_MESSAGE_START\",\"messageId\":\"msg_001\",\"role\":\"assistant\",\"timestamp\":1755300021900}\n\ndata: {\"type\":\"TEXT_MESSAGE_CONTENT\",\"messageId\":\"msg_001\",\"delta\":\"All good here.\",\"timestamp\":1755300022000}\n\ndata: {\"type\":\"TEXT_MESSAGE_END\",\"messageId\":\"msg_001\",\"timestamp\":1755300022100}\n\ndata: {\"type\":\"RUN_FINISHED\",\"threadId\":\"thread_001\",\"runId\":\"run_001\",\"outcome\":{\"type\":\"success\"},\"timestamp\":1755300022200}\n\n"
7
+ }
8
+ ]
9
+ }
@@ -0,0 +1,17 @@
1
+ [
2
+ {
3
+ "rule": "AGUI508",
4
+ "severity": "error",
5
+ "message": "Connection ended mid-run 'run_001' without RUN_FINISHED or RUN_ERROR",
6
+ "eventIndex": -1,
7
+ "specUrl": "https://docs.ag-ui.com/concepts/events#runfinished"
8
+ },
9
+ {
10
+ "rule": "AGUI003",
11
+ "severity": "error",
12
+ "message": "Run 'run_001' ended without RUN_FINISHED or RUN_ERROR",
13
+ "eventIndex": -1,
14
+ "specUrl": "https://docs.ag-ui.com/concepts/events#runfinished",
15
+ "relatedEventIndex": 0
16
+ }
17
+ ]
@@ -0,0 +1,10 @@
1
+ {
2
+ "contentType": "text/event-stream",
3
+ "chunks": [
4
+ {
5
+ "gapMs": 0,
6
+ "text": "data: {\"type\":\"RUN_STARTED\",\"threadId\":\"thread_001\",\"runId\":\"run_001\",\"timestamp\":1755300022300}\n\n"
7
+ }
8
+ ],
9
+ "abnormalEof": true
10
+ }
@@ -0,0 +1,11 @@
1
+ [
2
+ {
3
+ "rule": "AGUI901",
4
+ "severity": "info",
5
+ "message": "RAW event wraps an event of type 'TOOL_CALL_RESULT', which has a typed AG-UI equivalent",
6
+ "eventIndex": 1,
7
+ "specUrl": "https://docs.ag-ui.com/concepts/events#raw",
8
+ "eventType": "RAW",
9
+ "pointer": "/event/type"
10
+ }
11
+ ]
@@ -0,0 +1,3 @@
1
+ {"type":"RUN_STARTED","threadId":"thread_001","runId":"run_001","timestamp":1755300019900}
2
+ {"type":"RAW","event":{"type":"TOOL_CALL_RESULT","toolCallId":"call_001","content":"wrapped"},"timestamp":1755300020000}
3
+ {"type":"RUN_FINISHED","threadId":"thread_001","runId":"run_001","outcome":{"type":"success"},"timestamp":1755300020100}
@@ -0,0 +1,9 @@
1
+ [
2
+ {
3
+ "rule": "AGUI902",
4
+ "severity": "info",
5
+ "message": "None of the 2 events carry the optional timestamp property",
6
+ "eventIndex": -1,
7
+ "specUrl": "https://docs.ag-ui.com/concepts/events#base-event-properties"
8
+ }
9
+ ]
@@ -0,0 +1,2 @@
1
+ {"type":"RUN_STARTED","threadId":"thread_001","runId":"run_001"}
2
+ {"type":"RUN_FINISHED","threadId":"thread_001","runId":"run_001"}
@@ -0,0 +1,11 @@
1
+ [
2
+ {
3
+ "rule": "AGUI903",
4
+ "severity": "info",
5
+ "message": "CUSTOM event name 'update' has no namespace prefix (e.g. 'vendor.event')",
6
+ "eventIndex": 1,
7
+ "specUrl": "https://docs.ag-ui.com/concepts/events#custom",
8
+ "eventType": "CUSTOM",
9
+ "pointer": "/name"
10
+ }
11
+ ]
@@ -0,0 +1,3 @@
1
+ {"type":"RUN_STARTED","threadId":"thread_001","runId":"run_001","timestamp":1755300020200}
2
+ {"type":"CUSTOM","name":"update","value":{"x":1},"timestamp":1755300020300}
3
+ {"type":"RUN_FINISHED","threadId":"thread_001","runId":"run_001","outcome":{"type":"success"},"timestamp":1755300020400}
@@ -0,0 +1,14 @@
1
+ {"type":"RUN_STARTED","threadId":"thread_chat","runId":"run_001","timestamp":1755300000100}
2
+ {"type":"REASONING_START","messageId":"rsn_001","timestamp":1755300000200}
3
+ {"type":"REASONING_MESSAGE_START","messageId":"rmsg_001","role":"reasoning","timestamp":1755300000300}
4
+ {"type":"REASONING_MESSAGE_CONTENT","messageId":"rmsg_001","delta":"The user greeted me; respond warmly.","timestamp":1755300000400}
5
+ {"type":"REASONING_MESSAGE_END","messageId":"rmsg_001","timestamp":1755300000500}
6
+ {"type":"REASONING_END","messageId":"rsn_001","timestamp":1755300000600}
7
+ {"type":"TEXT_MESSAGE_START","messageId":"msg_001","role":"assistant","timestamp":1755300000700}
8
+ {"type":"TEXT_MESSAGE_CONTENT","messageId":"msg_001","delta":"Hello! ","timestamp":1755300000800}
9
+ {"type":"TEXT_MESSAGE_CONTENT","messageId":"msg_001","delta":"How can I help ","timestamp":1755300000900}
10
+ {"type":"TEXT_MESSAGE_CONTENT","messageId":"msg_001","delta":"you today?","timestamp":1755300001000}
11
+ {"type":"TEXT_MESSAGE_END","messageId":"msg_001","timestamp":1755300001100}
12
+ {"type":"TEXT_MESSAGE_CHUNK","messageId":"msg_002","delta":"Chunked messages ","timestamp":1755300001200}
13
+ {"type":"TEXT_MESSAGE_CHUNK","delta":"work too.","timestamp":1755300001300}
14
+ {"type":"RUN_FINISHED","threadId":"thread_chat","runId":"run_001","outcome":{"type":"success"},"timestamp":1755300001400}
@@ -0,0 +1,13 @@
1
+ {"type":"RUN_STARTED","threadId":"thread_genui","runId":"run_001","timestamp":1755300004200}
2
+ {"type":"STATE_SNAPSHOT","snapshot":{"steps":[{"name":"plan","status":"pending"},{"name":"execute","status":"pending"}]},"timestamp":1755300004300}
3
+ {"type":"STEP_STARTED","stepName":"plan","timestamp":1755300004400}
4
+ {"type":"STATE_DELTA","delta":[{"op":"replace","path":"/steps/0/status","value":"in_progress"}],"timestamp":1755300004500}
5
+ {"type":"STATE_DELTA","delta":[{"op":"replace","path":"/steps/0/status","value":"done"}],"timestamp":1755300004600}
6
+ {"type":"STEP_FINISHED","stepName":"plan","timestamp":1755300004700}
7
+ {"type":"STEP_STARTED","stepName":"execute","timestamp":1755300004800}
8
+ {"type":"STATE_DELTA","delta":[{"op":"replace","path":"/steps/1/status","value":"done"}],"timestamp":1755300004900}
9
+ {"type":"STEP_FINISHED","stepName":"execute","timestamp":1755300005000}
10
+ {"type":"TEXT_MESSAGE_START","messageId":"msg_001","role":"assistant","timestamp":1755300005100}
11
+ {"type":"TEXT_MESSAGE_CONTENT","messageId":"msg_001","delta":"All steps complete.","timestamp":1755300005200}
12
+ {"type":"TEXT_MESSAGE_END","messageId":"msg_001","timestamp":1755300005300}
13
+ {"type":"RUN_FINISHED","threadId":"thread_genui","runId":"run_001","outcome":{"type":"success"},"timestamp":1755300005400}
@@ -0,0 +1,14 @@
1
+ {"type":"RUN_STARTED","threadId":"thread_tools","runId":"run_001","timestamp":1755300001500}
2
+ {"type":"TEXT_MESSAGE_START","messageId":"msg_001","role":"assistant","timestamp":1755300001600}
3
+ {"type":"TEXT_MESSAGE_CONTENT","messageId":"msg_001","delta":"Checking the weather…","timestamp":1755300001700}
4
+ {"type":"TEXT_MESSAGE_END","messageId":"msg_001","timestamp":1755300001800}
5
+ {"type":"TOOL_CALL_START","toolCallId":"call_001","toolCallName":"get_weather","parentMessageId":"msg_001","timestamp":1755300001900}
6
+ {"type":"TOOL_CALL_ARGS","toolCallId":"call_001","delta":"{\"city\":\"Ber","timestamp":1755300002000}
7
+ {"type":"TOOL_CALL_ARGS","toolCallId":"call_001","delta":"lin\"}","timestamp":1755300002100}
8
+ {"type":"TOOL_CALL_END","toolCallId":"call_001","timestamp":1755300002200}
9
+ {"type":"TOOL_CALL_RESULT","messageId":"msg_002","toolCallId":"call_001","content":"{\"tempC\":21}","role":"tool","timestamp":1755300002300}
10
+ {"type":"RAW","event":{"kind":"langgraph_checkpoint","checkpoint_id":"ckpt_42"},"source":"langgraph","timestamp":1755300002400}
11
+ {"type":"TEXT_MESSAGE_START","messageId":"msg_003","role":"assistant","timestamp":1755300002500}
12
+ {"type":"TEXT_MESSAGE_CONTENT","messageId":"msg_003","delta":"It is 21°C in Berlin.","timestamp":1755300002600}
13
+ {"type":"TEXT_MESSAGE_END","messageId":"msg_003","timestamp":1755300002700}
14
+ {"type":"RUN_FINISHED","threadId":"thread_tools","runId":"run_001","outcome":{"type":"success"},"timestamp":1755300002800}
@@ -0,0 +1,13 @@
1
+ {"type":"RUN_STARTED","threadId":"thread_hitl","runId":"run_001","timestamp":1755300002900}
2
+ {"type":"TEXT_MESSAGE_START","messageId":"msg_001","role":"assistant","timestamp":1755300003000}
3
+ {"type":"TEXT_MESSAGE_CONTENT","messageId":"msg_001","delta":"I need your approval to delete 3 files.","timestamp":1755300003100}
4
+ {"type":"TEXT_MESSAGE_END","messageId":"msg_001","timestamp":1755300003200}
5
+ {"type":"TOOL_CALL_START","toolCallId":"call_001","toolCallName":"confirm_action","parentMessageId":"msg_001","timestamp":1755300003300}
6
+ {"type":"TOOL_CALL_ARGS","toolCallId":"call_001","delta":"{\"action\":\"delete\",\"count\":3}","timestamp":1755300003400}
7
+ {"type":"TOOL_CALL_END","toolCallId":"call_001","timestamp":1755300003500}
8
+ {"type":"RUN_FINISHED","threadId":"thread_hitl","runId":"run_001","outcome":{"type":"interrupt","interrupts":[{"id":"int_001","reason":"approval_required","toolCallId":"call_001"}]},"timestamp":1755300003600}
9
+ {"type":"RUN_STARTED","threadId":"thread_hitl","runId":"run_002","timestamp":1755300003700,"parentRunId":"run_001"}
10
+ {"type":"TEXT_MESSAGE_START","messageId":"msg_002","role":"assistant","timestamp":1755300003800}
11
+ {"type":"TEXT_MESSAGE_CONTENT","messageId":"msg_002","delta":"Done — 3 files deleted.","timestamp":1755300003900}
12
+ {"type":"TEXT_MESSAGE_END","messageId":"msg_002","timestamp":1755300004000}
13
+ {"type":"RUN_FINISHED","threadId":"thread_hitl","runId":"run_002","outcome":{"type":"success"},"timestamp":1755300004100}
@@ -0,0 +1,11 @@
1
+ [
2
+ {
3
+ "rule": "AGUI903",
4
+ "severity": "info",
5
+ "message": "CUSTOM event name 'PredictState' has no namespace prefix (e.g. 'vendor.event')",
6
+ "eventIndex": 2,
7
+ "specUrl": "https://docs.ag-ui.com/concepts/events#custom",
8
+ "eventType": "CUSTOM",
9
+ "pointer": "/name"
10
+ }
11
+ ]
@@ -0,0 +1,11 @@
1
+ {"type":"RUN_STARTED","threadId":"thread_predict","runId":"run_001","timestamp":1755300006800}
2
+ {"type":"STATE_SNAPSHOT","snapshot":{"document":""},"timestamp":1755300006900}
3
+ {"type":"CUSTOM","name":"PredictState","value":[{"state_key":"document","tool":"write_document","tool_argument":"document"}],"timestamp":1755300007000}
4
+ {"type":"TOOL_CALL_START","toolCallId":"call_001","toolCallName":"write_document","timestamp":1755300007100}
5
+ {"type":"TOOL_CALL_ARGS","toolCallId":"call_001","delta":"{\"document\":\"Hello world.\"}","timestamp":1755300007200}
6
+ {"type":"TOOL_CALL_END","toolCallId":"call_001","timestamp":1755300007300}
7
+ {"type":"STATE_DELTA","delta":[{"op":"replace","path":"/document","value":"Hello world."}],"timestamp":1755300007400}
8
+ {"type":"TEXT_MESSAGE_START","messageId":"msg_001","role":"assistant","timestamp":1755300007500}
9
+ {"type":"TEXT_MESSAGE_CONTENT","messageId":"msg_001","delta":"Written.","timestamp":1755300007600}
10
+ {"type":"TEXT_MESSAGE_END","messageId":"msg_001","timestamp":1755300007700}
11
+ {"type":"RUN_FINISHED","threadId":"thread_predict","runId":"run_001","outcome":{"type":"success"},"timestamp":1755300007800}
@@ -0,0 +1,8 @@
1
+ {"type":"RUN_STARTED","threadId":"thread_state","runId":"run_001","timestamp":1755300006000}
2
+ {"type":"STATE_SNAPSHOT","snapshot":{"recipe":{"title":"Pasta","ingredients":["tomato"]}},"timestamp":1755300006100}
3
+ {"type":"TEXT_MESSAGE_START","messageId":"msg_001","role":"assistant","timestamp":1755300006200}
4
+ {"type":"TEXT_MESSAGE_CONTENT","messageId":"msg_001","delta":"Adding garlic to the recipe.","timestamp":1755300006300}
5
+ {"type":"TEXT_MESSAGE_END","messageId":"msg_001","timestamp":1755300006400}
6
+ {"type":"STATE_DELTA","delta":[{"op":"add","path":"/recipe/ingredients/-","value":"garlic"}],"timestamp":1755300006500}
7
+ {"type":"STATE_DELTA","delta":[{"op":"test","path":"/recipe/title","value":"Pasta"},{"op":"replace","path":"/recipe/title","value":"Garlic Pasta"}],"timestamp":1755300006600}
8
+ {"type":"RUN_FINISHED","threadId":"thread_state","runId":"run_001","outcome":{"type":"success"},"timestamp":1755300006700}
@@ -0,0 +1,5 @@
1
+ {"type":"RUN_STARTED","threadId":"thread_fe_tools","runId":"run_001","timestamp":1755300005500}
2
+ {"type":"TOOL_CALL_START","toolCallId":"call_001","toolCallName":"generate_haiku","timestamp":1755300005600}
3
+ {"type":"TOOL_CALL_ARGS","toolCallId":"call_001","delta":"{\"topic\":\"conformance\"}","timestamp":1755300005700}
4
+ {"type":"TOOL_CALL_END","toolCallId":"call_001","timestamp":1755300005800}
5
+ {"type":"RUN_FINISHED","threadId":"thread_fe_tools","runId":"run_001","outcome":{"type":"success"},"timestamp":1755300005900}
@@ -1 +0,0 @@
1
- {"version":3,"file":"catalog-BglXBNbL.js","names":["catalogJson"],"sources":["../src/rules/catalog.json","../src/rules/catalog.ts"],"sourcesContent":["","// Typed loader for the rule catalog. The catalog itself is data\n// (catalog.json) so other implementations can share it; this module gives it\n// types and validates its invariants once at load time.\n//\n// Note the asymmetry: the validator never throws on stream input, but a\n// malformed catalog is a programming error in this package, so the loader\n// throws loudly at import time.\n\nimport catalogJson from \"./catalog.json\"\n\nexport type Severity = \"error\" | \"warning\" | \"info\"\nexport type SeverityOrOff = Severity | \"off\"\n\nconst SEVERITIES: readonly string[] = [\"error\", \"warning\", \"info\"]\nconst LAYERS: readonly string[] = [\"core\", \"transport\"]\n\nexport interface RuleDefinition {\n /** e.g. \"AGUI203\" */\n id: string\n severity: Severity\n title: string\n /** Human template with {placeholder} slots filled per diagnostic. */\n messageTemplate: string\n /** Governing spec section. Mandatory: rules that cannot cite one don't ship. */\n specUrl: string\n /** Exact sentence from the spec section, where one exists. */\n specQuote?: string\n since: string\n /** Canonical AG-UI feature this rule relates to, if any. */\n feature?: string\n /** True when the rule only fires if opts.features declares `feature`. */\n requiresFeature?: boolean\n /** Cross-reference into docs/spec-questions.md for downgraded/ambiguous rules. */\n specQuestion?: string\n /** Where the rule is evaluated. Transport rules are skipped (and the skip\n * reported) when validating recorded input with no transport in play. */\n checkedIn: \"core\" | \"transport\"\n}\n\nexport interface Catalog {\n catalogVersion: string\n spec: string\n rules: readonly RuleDefinition[]\n}\n\n/** Validates catalog data and returns it typed. Throws on structural problems. */\nexport function validateCatalog(data: unknown): Catalog {\n const problems: string[] = []\n const cat = data as Catalog\n if (typeof cat !== \"object\" || cat === null || !Array.isArray(cat.rules)) {\n throw new Error(\"rule catalog: expected an object with a rules array\")\n }\n const seen = new Set<string>()\n for (const rule of cat.rules) {\n const where = rule?.id ?? \"<missing id>\"\n if (!/^AGUI\\d{3}$/.test(rule.id ?? \"\")) problems.push(`${where}: id must match AGUI###`)\n if (seen.has(rule.id)) problems.push(`${where}: duplicate id`)\n seen.add(rule.id)\n if (!SEVERITIES.includes(rule.severity)) problems.push(`${where}: bad severity '${rule.severity}'`)\n if (!rule.title) problems.push(`${where}: missing title`)\n if (!rule.messageTemplate) problems.push(`${where}: missing messageTemplate`)\n if (!rule.specUrl?.startsWith(\"https://\")) problems.push(`${where}: specUrl must be an https URL`)\n if (!rule.since) problems.push(`${where}: missing since`)\n if (!LAYERS.includes(rule.checkedIn)) problems.push(`${where}: bad checkedIn '${rule.checkedIn}'`)\n if (rule.requiresFeature && !rule.feature) problems.push(`${where}: requiresFeature without feature`)\n }\n if (problems.length > 0) {\n throw new Error(`rule catalog is invalid:\\n ${problems.join(\"\\n \")}`)\n }\n return cat\n}\n\nexport const CATALOG: Catalog = validateCatalog(catalogJson)\n\nexport const RULES: ReadonlyMap<string, RuleDefinition> = new Map(\n CATALOG.rules.map((r) => [r.id, r]),\n)\n\n/** Fills a rule's messageTemplate. Unknown placeholders are left intact. */\nexport function formatMessage(rule: RuleDefinition, params: Record<string, unknown>): string {\n return rule.messageTemplate.replace(/\\{(\\w+)\\}/g, (whole, key: string) =>\n key in params ? String(params[key]) : whole,\n )\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACaA,MAAM,aAAgC;CAAC;CAAS;CAAW;AAAM;AACjE,MAAM,SAA4B,CAAC,QAAQ,WAAW;;AAgCtD,SAAgB,gBAAgB,MAAwB;CACtD,MAAM,WAAqB,CAAC;CAC5B,MAAM,MAAM;CACZ,IAAI,OAAO,QAAQ,YAAY,QAAQ,QAAQ,CAAC,MAAM,QAAQ,IAAI,KAAK,GACrE,MAAM,IAAI,MAAM,qDAAqD;CAEvE,MAAM,uBAAO,IAAI,IAAY;CAC7B,KAAK,MAAM,QAAQ,IAAI,OAAO;EAC5B,MAAM,QAAQ,MAAM,MAAM;EAC1B,IAAI,CAAC,cAAc,KAAK,KAAK,MAAM,EAAE,GAAG,SAAS,KAAK,GAAG,MAAM,wBAAwB;EACvF,IAAI,KAAK,IAAI,KAAK,EAAE,GAAG,SAAS,KAAK,GAAG,MAAM,eAAe;EAC7D,KAAK,IAAI,KAAK,EAAE;EAChB,IAAI,CAAC,WAAW,SAAS,KAAK,QAAQ,GAAG,SAAS,KAAK,GAAG,MAAM,kBAAkB,KAAK,SAAS,EAAE;EAClG,IAAI,CAAC,KAAK,OAAO,SAAS,KAAK,GAAG,MAAM,gBAAgB;EACxD,IAAI,CAAC,KAAK,iBAAiB,SAAS,KAAK,GAAG,MAAM,0BAA0B;EAC5E,IAAI,CAAC,KAAK,SAAS,WAAW,UAAU,GAAG,SAAS,KAAK,GAAG,MAAM,+BAA+B;EACjG,IAAI,CAAC,KAAK,OAAO,SAAS,KAAK,GAAG,MAAM,gBAAgB;EACxD,IAAI,CAAC,OAAO,SAAS,KAAK,SAAS,GAAG,SAAS,KAAK,GAAG,MAAM,mBAAmB,KAAK,UAAU,EAAE;EACjG,IAAI,KAAK,mBAAmB,CAAC,KAAK,SAAS,SAAS,KAAK,GAAG,MAAM,kCAAkC;CACtG;CACA,IAAI,SAAS,SAAS,GACpB,MAAM,IAAI,MAAM,+BAA+B,SAAS,KAAK,MAAM,GAAG;CAExE,OAAO;AACT;AAEA,MAAa,UAAmB,gBAAgBA,eAAW;AAE3D,MAAa,QAA6C,IAAI,IAC5D,QAAQ,MAAM,KAAK,MAAM,CAAC,EAAE,IAAI,CAAC,CAAC,CACpC;;AAGA,SAAgB,cAAc,MAAsB,QAAyC;CAC3F,OAAO,KAAK,gBAAgB,QAAQ,eAAe,OAAO,QACxD,OAAO,SAAS,OAAO,OAAO,IAAI,IAAI,KACxC;AACF"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"catalog-Ci9dqc1a.cjs","names":["catalogJson"],"sources":["../src/rules/catalog.json","../src/rules/catalog.ts"],"sourcesContent":["","// Typed loader for the rule catalog. The catalog itself is data\n// (catalog.json) so other implementations can share it; this module gives it\n// types and validates its invariants once at load time.\n//\n// Note the asymmetry: the validator never throws on stream input, but a\n// malformed catalog is a programming error in this package, so the loader\n// throws loudly at import time.\n\nimport catalogJson from \"./catalog.json\"\n\nexport type Severity = \"error\" | \"warning\" | \"info\"\nexport type SeverityOrOff = Severity | \"off\"\n\nconst SEVERITIES: readonly string[] = [\"error\", \"warning\", \"info\"]\nconst LAYERS: readonly string[] = [\"core\", \"transport\"]\n\nexport interface RuleDefinition {\n /** e.g. \"AGUI203\" */\n id: string\n severity: Severity\n title: string\n /** Human template with {placeholder} slots filled per diagnostic. */\n messageTemplate: string\n /** Governing spec section. Mandatory: rules that cannot cite one don't ship. */\n specUrl: string\n /** Exact sentence from the spec section, where one exists. */\n specQuote?: string\n since: string\n /** Canonical AG-UI feature this rule relates to, if any. */\n feature?: string\n /** True when the rule only fires if opts.features declares `feature`. */\n requiresFeature?: boolean\n /** Cross-reference into docs/spec-questions.md for downgraded/ambiguous rules. */\n specQuestion?: string\n /** Where the rule is evaluated. Transport rules are skipped (and the skip\n * reported) when validating recorded input with no transport in play. */\n checkedIn: \"core\" | \"transport\"\n}\n\nexport interface Catalog {\n catalogVersion: string\n spec: string\n rules: readonly RuleDefinition[]\n}\n\n/** Validates catalog data and returns it typed. Throws on structural problems. */\nexport function validateCatalog(data: unknown): Catalog {\n const problems: string[] = []\n const cat = data as Catalog\n if (typeof cat !== \"object\" || cat === null || !Array.isArray(cat.rules)) {\n throw new Error(\"rule catalog: expected an object with a rules array\")\n }\n const seen = new Set<string>()\n for (const rule of cat.rules) {\n const where = rule?.id ?? \"<missing id>\"\n if (!/^AGUI\\d{3}$/.test(rule.id ?? \"\")) problems.push(`${where}: id must match AGUI###`)\n if (seen.has(rule.id)) problems.push(`${where}: duplicate id`)\n seen.add(rule.id)\n if (!SEVERITIES.includes(rule.severity)) problems.push(`${where}: bad severity '${rule.severity}'`)\n if (!rule.title) problems.push(`${where}: missing title`)\n if (!rule.messageTemplate) problems.push(`${where}: missing messageTemplate`)\n if (!rule.specUrl?.startsWith(\"https://\")) problems.push(`${where}: specUrl must be an https URL`)\n if (!rule.since) problems.push(`${where}: missing since`)\n if (!LAYERS.includes(rule.checkedIn)) problems.push(`${where}: bad checkedIn '${rule.checkedIn}'`)\n if (rule.requiresFeature && !rule.feature) problems.push(`${where}: requiresFeature without feature`)\n }\n if (problems.length > 0) {\n throw new Error(`rule catalog is invalid:\\n ${problems.join(\"\\n \")}`)\n }\n return cat\n}\n\nexport const CATALOG: Catalog = validateCatalog(catalogJson)\n\nexport const RULES: ReadonlyMap<string, RuleDefinition> = new Map(\n CATALOG.rules.map((r) => [r.id, r]),\n)\n\n/** Fills a rule's messageTemplate. Unknown placeholders are left intact. */\nexport function formatMessage(rule: RuleDefinition, params: Record<string, unknown>): string {\n return rule.messageTemplate.replace(/\\{(\\w+)\\}/g, (whole, key: string) =>\n key in params ? String(params[key]) : whole,\n )\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACaA,MAAM,aAAgC;CAAC;CAAS;CAAW;AAAM;AACjE,MAAM,SAA4B,CAAC,QAAQ,WAAW;;AAgCtD,SAAgB,gBAAgB,MAAwB;CACtD,MAAM,WAAqB,CAAC;CAC5B,MAAM,MAAM;CACZ,IAAI,OAAO,QAAQ,YAAY,QAAQ,QAAQ,CAAC,MAAM,QAAQ,IAAI,KAAK,GACrE,MAAM,IAAI,MAAM,qDAAqD;CAEvE,MAAM,uBAAO,IAAI,IAAY;CAC7B,KAAK,MAAM,QAAQ,IAAI,OAAO;EAC5B,MAAM,QAAQ,MAAM,MAAM;EAC1B,IAAI,CAAC,cAAc,KAAK,KAAK,MAAM,EAAE,GAAG,SAAS,KAAK,GAAG,MAAM,wBAAwB;EACvF,IAAI,KAAK,IAAI,KAAK,EAAE,GAAG,SAAS,KAAK,GAAG,MAAM,eAAe;EAC7D,KAAK,IAAI,KAAK,EAAE;EAChB,IAAI,CAAC,WAAW,SAAS,KAAK,QAAQ,GAAG,SAAS,KAAK,GAAG,MAAM,kBAAkB,KAAK,SAAS,EAAE;EAClG,IAAI,CAAC,KAAK,OAAO,SAAS,KAAK,GAAG,MAAM,gBAAgB;EACxD,IAAI,CAAC,KAAK,iBAAiB,SAAS,KAAK,GAAG,MAAM,0BAA0B;EAC5E,IAAI,CAAC,KAAK,SAAS,WAAW,UAAU,GAAG,SAAS,KAAK,GAAG,MAAM,+BAA+B;EACjG,IAAI,CAAC,KAAK,OAAO,SAAS,KAAK,GAAG,MAAM,gBAAgB;EACxD,IAAI,CAAC,OAAO,SAAS,KAAK,SAAS,GAAG,SAAS,KAAK,GAAG,MAAM,mBAAmB,KAAK,UAAU,EAAE;EACjG,IAAI,KAAK,mBAAmB,CAAC,KAAK,SAAS,SAAS,KAAK,GAAG,MAAM,kCAAkC;CACtG;CACA,IAAI,SAAS,SAAS,GACpB,MAAM,IAAI,MAAM,+BAA+B,SAAS,KAAK,MAAM,GAAG;CAExE,OAAO;AACT;AAEA,MAAa,UAAmB,gBAAgBA,eAAW;AAE3D,MAAa,QAA6C,IAAI,IAC5D,QAAQ,MAAM,KAAK,MAAM,CAAC,EAAE,IAAI,CAAC,CAAC,CACpC;;AAGA,SAAgB,cAAc,MAAsB,QAAyC;CAC3F,OAAO,KAAK,gBAAgB,QAAQ,eAAe,OAAO,QACxD,OAAO,SAAS,OAAO,OAAO,IAAI,IAAI,KACxC;AACF"}