@copilotkit/aimock 1.16.4 → 1.17.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 (269) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/.claude-plugin/plugin.json +1 -1
  3. package/CHANGELOG.md +24 -0
  4. package/README.md +10 -10
  5. package/dist/a2a-mock.d.cts +2 -2
  6. package/dist/a2a-mock.d.cts.map +1 -1
  7. package/dist/a2a-mock.d.ts +2 -2
  8. package/dist/a2a-mock.d.ts.map +1 -1
  9. package/dist/a2a-mock.js +2 -2
  10. package/dist/a2a-mock.js.map +1 -1
  11. package/dist/agui-handler.cjs +120 -5
  12. package/dist/agui-handler.cjs.map +1 -1
  13. package/dist/agui-handler.d.cts +41 -5
  14. package/dist/agui-handler.d.cts.map +1 -1
  15. package/dist/agui-handler.d.ts +41 -5
  16. package/dist/agui-handler.d.ts.map +1 -1
  17. package/dist/agui-handler.js +114 -6
  18. package/dist/agui-handler.js.map +1 -1
  19. package/dist/agui-mock.cjs +18 -7
  20. package/dist/agui-mock.cjs.map +1 -1
  21. package/dist/agui-mock.d.cts +2 -2
  22. package/dist/agui-mock.d.cts.map +1 -1
  23. package/dist/agui-mock.d.ts +2 -2
  24. package/dist/agui-mock.d.ts.map +1 -1
  25. package/dist/agui-mock.js +20 -9
  26. package/dist/agui-mock.js.map +1 -1
  27. package/dist/agui-recorder.cjs +43 -22
  28. package/dist/agui-recorder.cjs.map +1 -1
  29. package/dist/agui-recorder.d.cts +4 -3
  30. package/dist/agui-recorder.d.cts.map +1 -1
  31. package/dist/agui-recorder.d.ts +4 -3
  32. package/dist/agui-recorder.d.ts.map +1 -1
  33. package/dist/agui-recorder.js +45 -24
  34. package/dist/agui-recorder.js.map +1 -1
  35. package/dist/agui-stub.cjs +28 -0
  36. package/dist/agui-stub.d.cts +5 -0
  37. package/dist/agui-stub.d.ts +5 -0
  38. package/dist/agui-stub.js +5 -0
  39. package/dist/agui-types.d.cts +33 -6
  40. package/dist/agui-types.d.cts.map +1 -1
  41. package/dist/agui-types.d.ts +33 -6
  42. package/dist/agui-types.d.ts.map +1 -1
  43. package/dist/aimock-cli.cjs +1 -1
  44. package/dist/aimock-cli.js +1 -1
  45. package/dist/aws-event-stream.d.cts +2 -2
  46. package/dist/aws-event-stream.d.cts.map +1 -1
  47. package/dist/aws-event-stream.d.ts +2 -2
  48. package/dist/aws-event-stream.d.ts.map +1 -1
  49. package/dist/bedrock-converse.d.cts +3 -3
  50. package/dist/bedrock-converse.d.cts.map +1 -1
  51. package/dist/bedrock-converse.d.ts +3 -3
  52. package/dist/bedrock-converse.d.ts.map +1 -1
  53. package/dist/bedrock.d.cts +3 -3
  54. package/dist/bedrock.d.cts.map +1 -1
  55. package/dist/bedrock.d.ts +3 -3
  56. package/dist/bedrock.d.ts.map +1 -1
  57. package/dist/chaos.d.cts +3 -3
  58. package/dist/chaos.d.cts.map +1 -1
  59. package/dist/chaos.d.ts +3 -3
  60. package/dist/chaos.d.ts.map +1 -1
  61. package/dist/cli.cjs +6 -5
  62. package/dist/cli.cjs.map +1 -1
  63. package/dist/cli.js +6 -5
  64. package/dist/cli.js.map +1 -1
  65. package/dist/cohere.d.cts +2 -2
  66. package/dist/cohere.d.cts.map +1 -1
  67. package/dist/cohere.d.ts +2 -2
  68. package/dist/cohere.d.ts.map +1 -1
  69. package/dist/config-loader.cjs +3 -3
  70. package/dist/config-loader.d.cts +1 -1
  71. package/dist/config-loader.d.cts.map +1 -1
  72. package/dist/config-loader.d.ts +1 -1
  73. package/dist/config-loader.d.ts.map +1 -1
  74. package/dist/config-loader.js +2 -2
  75. package/dist/convert-vidaimock.cjs +1 -1
  76. package/dist/convert-vidaimock.js +1 -1
  77. package/dist/convert.cjs +1 -1
  78. package/dist/convert.js +1 -1
  79. package/dist/elevenlabs-audio.cjs +209 -0
  80. package/dist/elevenlabs-audio.cjs.map +1 -0
  81. package/dist/elevenlabs-audio.d.cts +11 -0
  82. package/dist/elevenlabs-audio.d.cts.map +1 -0
  83. package/dist/elevenlabs-audio.d.ts +11 -0
  84. package/dist/elevenlabs-audio.d.ts.map +1 -0
  85. package/dist/elevenlabs-audio.js +209 -0
  86. package/dist/elevenlabs-audio.js.map +1 -0
  87. package/dist/embeddings.d.cts +2 -2
  88. package/dist/embeddings.d.cts.map +1 -1
  89. package/dist/embeddings.d.ts +2 -2
  90. package/dist/embeddings.d.ts.map +1 -1
  91. package/dist/fal-audio.cjs +477 -0
  92. package/dist/fal-audio.cjs.map +1 -0
  93. package/dist/fal-audio.d.cts +10 -0
  94. package/dist/fal-audio.d.cts.map +1 -0
  95. package/dist/fal-audio.d.ts +10 -0
  96. package/dist/fal-audio.d.ts.map +1 -0
  97. package/dist/fal-audio.js +474 -0
  98. package/dist/fal-audio.js.map +1 -0
  99. package/dist/fixture-loader.cjs +14 -1
  100. package/dist/fixture-loader.cjs.map +1 -1
  101. package/dist/fixture-loader.js +14 -1
  102. package/dist/fixture-loader.js.map +1 -1
  103. package/dist/fixtures-remote.cjs +1 -1
  104. package/dist/fixtures-remote.js +1 -1
  105. package/dist/gemini-interactions.cjs +617 -0
  106. package/dist/gemini-interactions.cjs.map +1 -0
  107. package/dist/gemini-interactions.d.cts +46 -0
  108. package/dist/gemini-interactions.d.cts.map +1 -0
  109. package/dist/gemini-interactions.d.ts +46 -0
  110. package/dist/gemini-interactions.d.ts.map +1 -0
  111. package/dist/gemini-interactions.js +616 -0
  112. package/dist/gemini-interactions.js.map +1 -0
  113. package/dist/gemini.cjs +76 -0
  114. package/dist/gemini.cjs.map +1 -1
  115. package/dist/gemini.d.cts +2 -2
  116. package/dist/gemini.d.cts.map +1 -1
  117. package/dist/gemini.d.ts +2 -2
  118. package/dist/gemini.d.ts.map +1 -1
  119. package/dist/gemini.js +77 -1
  120. package/dist/gemini.js.map +1 -1
  121. package/dist/helpers.cjs +24 -1
  122. package/dist/helpers.cjs.map +1 -1
  123. package/dist/helpers.d.cts +13 -3
  124. package/dist/helpers.d.cts.map +1 -1
  125. package/dist/helpers.d.ts +13 -3
  126. package/dist/helpers.d.ts.map +1 -1
  127. package/dist/helpers.js +23 -2
  128. package/dist/helpers.js.map +1 -1
  129. package/dist/images.d.cts +2 -2
  130. package/dist/images.d.cts.map +1 -1
  131. package/dist/images.d.ts +2 -2
  132. package/dist/images.d.ts.map +1 -1
  133. package/dist/index.cjs +21 -4
  134. package/dist/index.d.cts +10 -7
  135. package/dist/index.d.ts +10 -7
  136. package/dist/index.js +10 -7
  137. package/dist/jest.cjs +1 -1
  138. package/dist/jest.js +1 -1
  139. package/dist/jsonrpc.d.cts +3 -3
  140. package/dist/jsonrpc.d.cts.map +1 -1
  141. package/dist/jsonrpc.d.ts +3 -3
  142. package/dist/jsonrpc.d.ts.map +1 -1
  143. package/dist/llmock.cjs +38 -2
  144. package/dist/llmock.cjs.map +1 -1
  145. package/dist/llmock.d.cts +4 -0
  146. package/dist/llmock.d.cts.map +1 -1
  147. package/dist/llmock.d.ts +4 -0
  148. package/dist/llmock.d.ts.map +1 -1
  149. package/dist/llmock.js +38 -2
  150. package/dist/llmock.js.map +1 -1
  151. package/dist/logger.cjs +5 -4
  152. package/dist/logger.cjs.map +1 -1
  153. package/dist/logger.d.cts +1 -1
  154. package/dist/logger.d.cts.map +1 -1
  155. package/dist/logger.d.ts +1 -1
  156. package/dist/logger.d.ts.map +1 -1
  157. package/dist/logger.js +5 -4
  158. package/dist/logger.js.map +1 -1
  159. package/dist/mcp-mock.d.cts +2 -2
  160. package/dist/mcp-mock.d.cts.map +1 -1
  161. package/dist/mcp-mock.d.ts +2 -2
  162. package/dist/mcp-mock.d.ts.map +1 -1
  163. package/dist/mcp-mock.js +2 -2
  164. package/dist/mcp-mock.js.map +1 -1
  165. package/dist/messages.d.cts +2 -2
  166. package/dist/messages.d.cts.map +1 -1
  167. package/dist/messages.d.ts +2 -2
  168. package/dist/messages.d.ts.map +1 -1
  169. package/dist/moderation.d.cts +3 -3
  170. package/dist/moderation.d.cts.map +1 -1
  171. package/dist/moderation.d.ts +3 -3
  172. package/dist/moderation.d.ts.map +1 -1
  173. package/dist/ndjson-writer.d.cts +2 -2
  174. package/dist/ndjson-writer.d.cts.map +1 -1
  175. package/dist/ndjson-writer.d.ts +2 -2
  176. package/dist/ndjson-writer.d.ts.map +1 -1
  177. package/dist/ollama.d.cts +3 -3
  178. package/dist/ollama.d.cts.map +1 -1
  179. package/dist/ollama.d.ts +3 -3
  180. package/dist/ollama.d.ts.map +1 -1
  181. package/dist/recorder.cjs +64 -21
  182. package/dist/recorder.cjs.map +1 -1
  183. package/dist/recorder.d.cts +2 -2
  184. package/dist/recorder.d.cts.map +1 -1
  185. package/dist/recorder.d.ts +2 -2
  186. package/dist/recorder.d.ts.map +1 -1
  187. package/dist/recorder.js +66 -23
  188. package/dist/recorder.js.map +1 -1
  189. package/dist/rerank.d.cts +3 -3
  190. package/dist/rerank.d.cts.map +1 -1
  191. package/dist/rerank.d.ts +3 -3
  192. package/dist/rerank.d.ts.map +1 -1
  193. package/dist/responses.d.cts +2 -2
  194. package/dist/responses.d.cts.map +1 -1
  195. package/dist/responses.d.ts +2 -2
  196. package/dist/responses.d.ts.map +1 -1
  197. package/dist/router.cjs +1 -1
  198. package/dist/router.cjs.map +1 -1
  199. package/dist/router.js +1 -1
  200. package/dist/router.js.map +1 -1
  201. package/dist/search.d.cts +3 -3
  202. package/dist/search.d.cts.map +1 -1
  203. package/dist/search.d.ts +3 -3
  204. package/dist/search.d.ts.map +1 -1
  205. package/dist/server.cjs +170 -1
  206. package/dist/server.cjs.map +1 -1
  207. package/dist/server.d.cts +2 -2
  208. package/dist/server.d.cts.map +1 -1
  209. package/dist/server.d.ts +2 -2
  210. package/dist/server.d.ts.map +1 -1
  211. package/dist/server.js +173 -4
  212. package/dist/server.js.map +1 -1
  213. package/dist/speech.cjs +18 -9
  214. package/dist/speech.cjs.map +1 -1
  215. package/dist/speech.d.cts +2 -2
  216. package/dist/speech.d.cts.map +1 -1
  217. package/dist/speech.d.ts +2 -2
  218. package/dist/speech.d.ts.map +1 -1
  219. package/dist/speech.js +18 -9
  220. package/dist/speech.js.map +1 -1
  221. package/dist/sse-writer.d.cts +3 -3
  222. package/dist/sse-writer.d.cts.map +1 -1
  223. package/dist/sse-writer.d.ts +3 -3
  224. package/dist/sse-writer.d.ts.map +1 -1
  225. package/dist/stream-collapse.cjs +80 -9
  226. package/dist/stream-collapse.cjs.map +1 -1
  227. package/dist/stream-collapse.d.cts +11 -1
  228. package/dist/stream-collapse.d.cts.map +1 -1
  229. package/dist/stream-collapse.d.ts +11 -1
  230. package/dist/stream-collapse.d.ts.map +1 -1
  231. package/dist/stream-collapse.js +80 -10
  232. package/dist/stream-collapse.js.map +1 -1
  233. package/dist/suite.cjs +1 -1
  234. package/dist/suite.d.cts +2 -2
  235. package/dist/suite.d.ts +2 -2
  236. package/dist/suite.js +1 -1
  237. package/dist/transcription.d.cts +2 -2
  238. package/dist/transcription.d.cts.map +1 -1
  239. package/dist/transcription.d.ts +2 -2
  240. package/dist/transcription.d.ts.map +1 -1
  241. package/dist/types.d.cts +10 -7
  242. package/dist/types.d.cts.map +1 -1
  243. package/dist/types.d.ts +10 -7
  244. package/dist/types.d.ts.map +1 -1
  245. package/dist/vector-mock.d.cts +2 -2
  246. package/dist/vector-mock.d.cts.map +1 -1
  247. package/dist/vector-mock.d.ts +2 -2
  248. package/dist/vector-mock.d.ts.map +1 -1
  249. package/dist/vector-mock.js +2 -2
  250. package/dist/vector-mock.js.map +1 -1
  251. package/dist/vector-types.d.ts.map +1 -1
  252. package/dist/video.d.cts +3 -3
  253. package/dist/video.d.cts.map +1 -1
  254. package/dist/video.d.ts +3 -3
  255. package/dist/video.d.ts.map +1 -1
  256. package/dist/vitest.cjs +1 -1
  257. package/dist/vitest.js +1 -1
  258. package/dist/ws-framing.d.cts +2 -2
  259. package/dist/ws-framing.d.cts.map +1 -1
  260. package/dist/ws-framing.d.ts +2 -2
  261. package/dist/ws-framing.d.ts.map +1 -1
  262. package/dist/ws-gemini-live.cjs +145 -2
  263. package/dist/ws-gemini-live.cjs.map +1 -1
  264. package/dist/ws-gemini-live.d.cts.map +1 -1
  265. package/dist/ws-gemini-live.d.ts.map +1 -1
  266. package/dist/ws-gemini-live.js +146 -3
  267. package/dist/ws-gemini-live.js.map +1 -1
  268. package/package.json +16 -2
  269. package/skills/write-fixtures/SKILL.md +10 -10
@@ -9,7 +9,7 @@
9
9
  "source": {
10
10
  "source": "npm",
11
11
  "package": "@copilotkit/aimock",
12
- "version": "^1.16.0"
12
+ "version": "^1.17.0"
13
13
  },
14
14
  "description": "Fixture authoring skill for @copilotkit/aimock — LLM, multimedia (image/TTS/transcription/video), MCP, A2A, AG-UI, vector, embeddings, structured output, sequential responses, streaming physics, record/replay, agent loop patterns, and debugging"
15
15
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "aimock",
3
- "version": "1.16.1",
3
+ "version": "1.17.0",
4
4
  "description": "Fixture authoring guidance for @copilotkit/aimock — LLM, multimedia, MCP, A2A, AG-UI, vector, and service mocking",
5
5
  "author": {
6
6
  "name": "CopilotKit"
package/CHANGELOG.md CHANGED
@@ -1,5 +1,29 @@
1
1
  # @copilotkit/aimock
2
2
 
3
+ ## [1.17.0] - 2026-05-04
4
+
5
+ ### Added
6
+
7
+ - **Gemini Interactions API** — 12th LLM provider. Full record/replay support for Google's Gemini Interactions streaming API (`/v1beta/models/{model}:streamGenerateContent`), including multi-turn conversations, function calling, streaming text, and safety metadata. Drift tests, integration tests, and documentation included. (PR #139)
8
+ - **AG-UI interrupt-aware types** — `AGUIInterrupt`, `AGUIResumeEntry`, and `AGUIRunFinishedOutcome` (discriminated union: success | interrupt) from ag-ui PR #1569. `outcome` field on `AGUIRunFinishedEvent`, `resume` field on `AGUIRunAgentInput`.
9
+ - **AG-UI convenience builders** — `buildActivityDelta`, `buildToolCallChunk`, `buildRawEvent`, `buildCustomEvent`, `buildReasoningChunk`, `buildReasoningEncryptedValue`.
10
+ - **`./agui` subpath export** — `agui-stub.ts` wired into `tsdown.config.ts` and `package.json` exports, matching `./a2a`, `./mcp`, `./vector` pattern.
11
+ - **Complete AG-UI type exports** — All event types (reasoning, step, thinking, raw, custom, chunk), `AGUIBuildOpts`, `matchesAGUIFixture`, `AGUIReasoningEncryptedValueSubtype`, `AGUIMessageRole` now exported from package root.
12
+ - **`"warn"` log level** — New log level between `"silent"` and `"info"` with proper hierarchy. `AGUIMockOptions.logLevel` option added; AG-UI mock defaults to `"warn"` instead of `"silent"`.
13
+ - **Non-speech audio generation** — Mock support for ElevenLabs sound effects (`/v1/sound-generation`) and music (`/v1/music/*`), fal.ai queue-based audio (`/fal/queue/submit/*`, `/fal/queue/requests/*`, `/fal/run/*`), Gemini HTTP audio via `generateContent`/`streamGenerateContent` with `inlineData` audio parts, and Gemini Live WebSocket audio. Convenience methods: `onAudio()`, `onSoundEffect()`, `onMusic()`, `onFalAudio()`. (PR #140, closes #118)
14
+ - **AudioResponse broadened** — `audio` field now supports both `string` (base64) and `{ b64Json, contentType }` object form
15
+ - **Gemini audio recording** — Record and replay Gemini audio responses (both streaming SSE and non-streaming JSON)
16
+ - **Router audio-gen filtering** — Bidirectional endpoint filtering for `audio-gen` and `fal-audio` endpoint types
17
+
18
+ ### Fixed
19
+
20
+ - **AG-UI type alignment** — `AGUIMessage.id` and `AGUIRunAgentInput.threadId`/`runId` now required (was optional). `AGUIToolDefinition.description` now required, `metadata` field added. `encryptedValue` and `error` fields added to `AGUIMessage`. `AGUIMessageRole` union covers all 7 protocol roles.
21
+ - **AG-UI handler hardening** — `writeAGUIEventStream` logs all caught errors (was silently swallowing non-TypeError/RangeError), preserves user-supplied timestamps (was always overwriting with `Date.now()`). `buildCompositeResponse` omits `RUN_FINISHED` when inner events contain `RUN_ERROR` (protocol compliance). `matchesFixture` resets `lastIndex` on regex before `test()`.
22
+ - **AG-UI recorder SSE parsing** — Handle `data:` lines without space after colon per SSE spec. Serialize predicate-match fixtures as `__NO_USER_MESSAGE__` sentinel on disk instead of producing catch-all `{}`. Return actual HTTP status from proxy (was always boolean/200). Forward upstream content-type on non-2xx responses instead of SSE headers.
23
+ - **AG-UI mock error handling** — `readBody` wrapped in try/catch (was unguarded await producing opaque 500s). JSON parse errors now include detail in 400 response. Proxy status correctly journaled.
24
+ - **Drift auto-remediation pipeline** — `drift-report-collector` now clones canonical ag-ui repo and runs AG-UI schema drift test alongside HTTP API drift. `test-drift.yml` Slack notification distinguishes AG-UI schema vs HTTP API drift vs infra error; uses `jq` for safe JSON construction. `fix-drift.yml` clones ag-ui before collection, adds `continue-on-error` on autofix with `success()` guard on PR creation. `fix-drift.ts` corrected `src/agui.ts` references to `src/agui-handler.ts`, added SDK type to drift prompt, flexible changelog title matching, ENOENT-specific catch in `syncDescriptionFromReadme`, exit code 4 for no-changes (was collision with exit 2), version bump wrapped in try/catch.
25
+ - **AG-UI schema drift test hardening** — `skipIf` guard checks both source files (was only canonical). Field regex handles multi-arg Zod types. Recursive parent field resolution for multi-level inheritance. Comment lines stripped before field matching. Base fields parsed dynamically from source with hardcoded fallback.
26
+
3
27
  ## [1.16.4] - 2026-04-30
4
28
 
5
29
  ### Fixed
package/README.md CHANGED
@@ -1,7 +1,7 @@
1
1
  # aimock [![Unit Tests](https://github.com/CopilotKit/aimock/actions/workflows/test-unit.yml/badge.svg)](https://github.com/CopilotKit/aimock/actions/workflows/test-unit.yml) [![Drift Tests](https://github.com/CopilotKit/aimock/actions/workflows/test-drift.yml/badge.svg)](https://github.com/CopilotKit/aimock/actions/workflows/test-drift.yml) [![npm version](https://img.shields.io/npm/v/@copilotkit/aimock)](https://www.npmjs.com/package/@copilotkit/aimock)
2
2
 
3
3
 
4
- Mock infrastructure for AI application testing — LLM APIs, image generation, text-to-speech, transcription, video generation, MCP tools, A2A agents, AG-UI event streams, vector databases, search, rerank, and moderation. One package, one port, zero dependencies.
4
+ Mock infrastructure for AI application testing — LLM APIs, image generation, text-to-speech, transcription, audio generation, video generation, MCP tools, A2A agents, AG-UI event streams, vector databases, search, rerank, and moderation. One package, one port, zero dependencies.
5
5
 
6
6
  ## Quick Start
7
7
 
@@ -34,14 +34,14 @@ await mock.stop();
34
34
 
35
35
  aimock mocks everything your AI app talks to:
36
36
 
37
- | Tool | What it mocks | Docs |
38
- | -------------- | ------------------------------------------------------------------------------------------------------- | --------------------------------------------------- |
39
- | **LLMock** | OpenAI (Chat/Responses/Realtime), Claude, Gemini (REST/Live), Bedrock, Azure, Vertex AI, Ollama, Cohere | [Providers](https://aimock.copilotkit.dev/docs) |
40
- | **MCPMock** | MCP tools, resources, prompts with session management | [MCP](https://aimock.copilotkit.dev/mcp-mock) |
41
- | **A2AMock** | Agent-to-agent protocol with SSE streaming | [A2A](https://aimock.copilotkit.dev/a2a-mock) |
42
- | **AGUIMock** | AG-UI agent-to-UI event streams for frontend testing | [AG-UI](https://aimock.copilotkit.dev/agui-mock) |
43
- | **VectorMock** | Pinecone, Qdrant, ChromaDB compatible endpoints | [Vector](https://aimock.copilotkit.dev/vector-mock) |
44
- | **Services** | Tavily search, Cohere rerank, OpenAI moderation | [Services](https://aimock.copilotkit.dev/services) |
37
+ | Tool | What it mocks | Docs |
38
+ | -------------- | -------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------- |
39
+ | **LLMock** | OpenAI (Chat/Responses/Realtime), Claude, Gemini (REST/Live/Interactions), Bedrock, Azure, Vertex AI, Ollama, Cohere | [Providers](https://aimock.copilotkit.dev/docs) |
40
+ | **MCPMock** | MCP tools, resources, prompts with session management | [MCP](https://aimock.copilotkit.dev/mcp-mock) |
41
+ | **A2AMock** | Agent-to-agent protocol with SSE streaming | [A2A](https://aimock.copilotkit.dev/a2a-mock) |
42
+ | **AGUIMock** | AG-UI agent-to-UI event streams for frontend testing | [AG-UI](https://aimock.copilotkit.dev/agui-mock) |
43
+ | **VectorMock** | Pinecone, Qdrant, ChromaDB compatible endpoints | [Vector](https://aimock.copilotkit.dev/vector-mock) |
44
+ | **Services** | Tavily search, Cohere rerank, OpenAI moderation | [Services](https://aimock.copilotkit.dev/services) |
45
45
 
46
46
  Run them all on one port with `npx @copilotkit/aimock --config aimock.json`, or use the programmatic API to compose exactly what you need.
47
47
 
@@ -49,7 +49,7 @@ Run them all on one port with `npx @copilotkit/aimock --config aimock.json`, or
49
49
 
50
50
  - **[Record & Replay](https://aimock.copilotkit.dev/record-replay)** — Proxy real APIs, save as fixtures, replay deterministically forever
51
51
  - **[Multi-turn Conversations](https://aimock.copilotkit.dev/multi-turn)** — Record and replay multi-turn traces with tool rounds; match distinct turns via `turnIndex`, `hasToolResult`, `toolCallId`, `sequenceIndex`, or custom predicates
52
- - **[11 LLM Providers](https://aimock.copilotkit.dev/docs)** — OpenAI Chat, OpenAI Responses, OpenAI Realtime, Claude, Gemini, Gemini Live, Azure, Bedrock, Vertex AI, Ollama, Cohere — full streaming support
52
+ - **[12 LLM Providers](https://aimock.copilotkit.dev/docs)** — OpenAI Chat, OpenAI Responses, OpenAI Realtime, Claude, Gemini, Gemini Live, Gemini Interactions, Azure, Bedrock, Vertex AI, Ollama, Cohere — full streaming support
53
53
  - **Multimedia APIs** — [image generation](https://aimock.copilotkit.dev/images) (DALL-E, Imagen), [text-to-speech](https://aimock.copilotkit.dev/speech), [audio transcription](https://aimock.copilotkit.dev/transcription), [video generation](https://aimock.copilotkit.dev/video)
54
54
  - **[MCP](https://aimock.copilotkit.dev/mcp-mock) / [A2A](https://aimock.copilotkit.dev/a2a-mock) / [AG-UI](https://aimock.copilotkit.dev/agui-mock) / [Vector](https://aimock.copilotkit.dev/vector-mock)** — Mock every protocol your AI agents use
55
55
  - **[Chaos Testing](https://aimock.copilotkit.dev/chaos-testing)** — 500 errors, malformed JSON, mid-stream disconnects at any probability
@@ -2,7 +2,7 @@ import { Journal } from "./journal.cjs";
2
2
  import { MetricsRegistry } from "./metrics.cjs";
3
3
  import { Mountable } from "./types.cjs";
4
4
  import { A2AAgentDefinition, A2AArtifact, A2AMockOptions, A2APart, A2AStreamEvent } from "./a2a-types.cjs";
5
- import * as http from "node:http";
5
+ import * as http$1 from "node:http";
6
6
 
7
7
  //#region src/a2a-mock.d.ts
8
8
  declare class A2AMock implements Mountable {
@@ -20,7 +20,7 @@ declare class A2AMock implements Mountable {
20
20
  onMessage(agentName: string, pattern: string | RegExp, parts: A2APart[]): this;
21
21
  onTask(agentName: string, pattern: string | RegExp, artifacts: A2AArtifact[]): this;
22
22
  onStreamingTask(agentName: string, pattern: string | RegExp, events: A2AStreamEvent[], delayMs?: number): this;
23
- handleRequest(req: http.IncomingMessage, res: http.ServerResponse, pathname: string): Promise<boolean>;
23
+ handleRequest(req: http$1.IncomingMessage, res: http$1.ServerResponse, pathname: string): Promise<boolean>;
24
24
  health(): {
25
25
  status: string;
26
26
  agents: number;
@@ -1 +1 @@
1
- {"version":3,"file":"a2a-mock.d.cts","names":[],"sources":["../src/a2a-mock.ts"],"sourcesContent":[],"mappings":";;;;;;;cAuBa,OAAA,YAAmB;;EAAnB,QAAA,KAAQ;EAAA,QAAA,MAAA;UAUG,OAAA;UAYH,QAAA;UAO4B,OAAA;UAAe,OAAA;UASlB,UAAA;aAAmB,CAAA,OAAA,CAAA,EA5BzC,cA4ByC;UAW3C,eAAA;eACV,CAAA,GAAA,EA5BS,kBA4BT,CAAA,EAAA,IAAA;WAcE,CAAA,SAAA,EAAA,MAAA,EAAA,OAAA,EAAA,MAAA,GAnCmC,MAmCnC,EAAA,KAAA,EAnCkD,OAmClD,EAAA,CAAA,EAAA,IAAA;QACL,CAAA,SAAK,EAAA,MAAA,EAAA,OAAA,EAAA,MAAA,GA3BgC,MA2BhC,EAAA,SAAA,EA3BmD,WA2BnD,EAAA,CAAA,EAAA,IAAA;iBAET,CAAA,SAAA,EAAA,MAAA,EAAA,OAAA,EAAA,MAAA,GAlBiB,MAkBjB,EAAA,MAAA,EAjBO,cAiBP,EAAA,EAAA,OAAA,CAAA,EAAA,MAAA,CAAA,EAAA,IAAA;eAoFiB,CAAA,GAAA,EAvFb,IAAA,CAAK,eAuFQ,EAAA,GAAA,EAtFb,IAAA,CAAK,cAsFQ,EAAA,QAAA,EAAA,MAAA,CAAA,EApFjB,OAoFiB,CAAA,OAAA,CAAA;QAIE,CAAA,CAAA,EAAA;IAMP,MAAA,EAAA,MAAA;IAiCD,MAAA,EAAA,MAAA;IAlMgB,KAAA,EAAA,MAAA;EAAS,CAAA;sBAuJnB;wBAIE;WAMP;UAiCD"}
1
+ {"version":3,"file":"a2a-mock.d.cts","names":[],"sources":["../src/a2a-mock.ts"],"sourcesContent":[],"mappings":";;;;;;;cAuBa,OAAA,YAAmB;;EAAnB,QAAA,KAAQ;EAAA,QAAA,MAAA;UAUG,OAAA;UAYH,QAAA;UAO4B,OAAA;UAAe,OAAA;UASlB,UAAA;aAAmB,CAAA,OAAA,CAAA,EA5BzC,cA4ByC;UAW3C,eAAA;eACV,CAAA,GAAA,EA5BS,kBA4BT,CAAA,EAAA,IAAA;WAcH,CAAK,SAAA,EAAA,MAAA,EAAA,OAAA,EAAA,MAAA,GAnCmC,MAmCnC,EAAA,KAAA,EAnCkD,OAmClD,EAAA,CAAA,EAAA,IAAA;QACL,CAAA,SAAK,EAAA,MAAA,EAAA,OAAA,EAAA,MAAA,GA3BgC,MA2BhC,EAAA,SAAA,EA3BmD,WA2BnD,EAAA,CAAA,EAAA,IAAA;iBAET,CAAA,SAAA,EAAA,MAAA,EAAA,OAAA,EAAA,MAAA,GAlBiB,MAkBjB,EAAA,MAAA,EAjBO,cAiBP,EAAA,EAAA,OAAA,CAAA,EAAA,MAAA,CAAA,EAAA,IAAA;eAoFiB,CAAA,GAAA,EAvFb,MAAA,CAAK,eAuFQ,EAAA,GAAA,EAtFb,MAAA,CAAK,cAsFQ,EAAA,QAAA,EAAA,MAAA,CAAA,EApFjB,OAoFiB,CAAA,OAAA,CAAA;QAIE,CAAA,CAAA,EAAA;IAMP,MAAA,EAAA,MAAA;IAiCD,MAAA,EAAA,MAAA;IAlMgB,KAAA,EAAA,MAAA;EAAS,CAAA;sBAuJnB;wBAIE;WAMP;UAiCD"}
@@ -2,7 +2,7 @@ import { Journal } from "./journal.js";
2
2
  import { MetricsRegistry } from "./metrics.js";
3
3
  import { Mountable } from "./types.js";
4
4
  import { A2AAgentDefinition, A2AArtifact, A2AMockOptions, A2APart, A2AStreamEvent } from "./a2a-types.js";
5
- import * as http from "node:http";
5
+ import * as http$1 from "node:http";
6
6
 
7
7
  //#region src/a2a-mock.d.ts
8
8
  declare class A2AMock implements Mountable {
@@ -20,7 +20,7 @@ declare class A2AMock implements Mountable {
20
20
  onMessage(agentName: string, pattern: string | RegExp, parts: A2APart[]): this;
21
21
  onTask(agentName: string, pattern: string | RegExp, artifacts: A2AArtifact[]): this;
22
22
  onStreamingTask(agentName: string, pattern: string | RegExp, events: A2AStreamEvent[], delayMs?: number): this;
23
- handleRequest(req: http.IncomingMessage, res: http.ServerResponse, pathname: string): Promise<boolean>;
23
+ handleRequest(req: http$1.IncomingMessage, res: http$1.ServerResponse, pathname: string): Promise<boolean>;
24
24
  health(): {
25
25
  status: string;
26
26
  agents: number;
@@ -1 +1 @@
1
- {"version":3,"file":"a2a-mock.d.ts","names":[],"sources":["../src/a2a-mock.ts"],"sourcesContent":[],"mappings":";;;;;;;cAuBa,OAAA,YAAmB;;EAAnB,QAAA,KAAQ;EAAA,QAAA,MAAA;UAUG,OAAA;UAYH,QAAA;UAO4B,OAAA;UAAe,OAAA;UASlB,UAAA;aAAmB,CAAA,OAAA,CAAA,EA5BzC,cA4ByC;UAW3C,eAAA;eACV,CAAA,GAAA,EA5BS,kBA4BT,CAAA,EAAA,IAAA;WAcE,CAAA,SAAA,EAAA,MAAA,EAAA,OAAA,EAAA,MAAA,GAnCmC,MAmCnC,EAAA,KAAA,EAnCkD,OAmClD,EAAA,CAAA,EAAA,IAAA;QACL,CAAA,SAAK,EAAA,MAAA,EAAA,OAAA,EAAA,MAAA,GA3BgC,MA2BhC,EAAA,SAAA,EA3BmD,WA2BnD,EAAA,CAAA,EAAA,IAAA;iBAET,CAAA,SAAA,EAAA,MAAA,EAAA,OAAA,EAAA,MAAA,GAlBiB,MAkBjB,EAAA,MAAA,EAjBO,cAiBP,EAAA,EAAA,OAAA,CAAA,EAAA,MAAA,CAAA,EAAA,IAAA;eAoFiB,CAAA,GAAA,EAvFb,IAAA,CAAK,eAuFQ,EAAA,GAAA,EAtFb,IAAA,CAAK,cAsFQ,EAAA,QAAA,EAAA,MAAA,CAAA,EApFjB,OAoFiB,CAAA,OAAA,CAAA;QAIE,CAAA,CAAA,EAAA;IAMP,MAAA,EAAA,MAAA;IAiCD,MAAA,EAAA,MAAA;IAlMgB,KAAA,EAAA,MAAA;EAAS,CAAA;sBAuJnB;wBAIE;WAMP;UAiCD"}
1
+ {"version":3,"file":"a2a-mock.d.ts","names":[],"sources":["../src/a2a-mock.ts"],"sourcesContent":[],"mappings":";;;;;;;cAuBa,OAAA,YAAmB;;EAAnB,QAAA,KAAQ;EAAA,QAAA,MAAA;UAUG,OAAA;UAYH,QAAA;UAO4B,OAAA;UAAe,OAAA;UASlB,UAAA;aAAmB,CAAA,OAAA,CAAA,EA5BzC,cA4ByC;UAW3C,eAAA;eACV,CAAA,GAAA,EA5BS,kBA4BT,CAAA,EAAA,IAAA;WAcH,CAAK,SAAA,EAAA,MAAA,EAAA,OAAA,EAAA,MAAA,GAnCmC,MAmCnC,EAAA,KAAA,EAnCkD,OAmClD,EAAA,CAAA,EAAA,IAAA;QACL,CAAA,SAAK,EAAA,MAAA,EAAA,OAAA,EAAA,MAAA,GA3BgC,MA2BhC,EAAA,SAAA,EA3BmD,WA2BnD,EAAA,CAAA,EAAA,IAAA;iBAET,CAAA,SAAA,EAAA,MAAA,EAAA,OAAA,EAAA,MAAA,GAlBiB,MAkBjB,EAAA,MAAA,EAjBO,cAiBP,EAAA,EAAA,OAAA,CAAA,EAAA,MAAA,CAAA,EAAA,IAAA;eAoFiB,CAAA,GAAA,EAvFb,MAAA,CAAK,eAuFQ,EAAA,GAAA,EAtFb,MAAA,CAAK,cAsFQ,EAAA,QAAA,EAAA,MAAA,CAAA,EApFjB,OAoFiB,CAAA,OAAA,CAAA;QAIE,CAAA,CAAA,EAAA;IAMP,MAAA,EAAA,MAAA;IAiCD,MAAA,EAAA,MAAA;IAlMgB,KAAA,EAAA,MAAA;EAAS,CAAA;sBAuJnB;wBAIE;WAMP;UAiCD"}
package/dist/a2a-mock.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import { flattenHeaders, generateId, readBody } from "./helpers.js";
2
2
  import { TERMINAL_STATES, buildAgentCard, createA2AMethods, extractText, findStreamingMatch } from "./a2a-handler.js";
3
3
  import { createJsonRpcDispatcher } from "./jsonrpc.js";
4
- import * as http from "node:http";
4
+ import * as http$1 from "node:http";
5
5
 
6
6
  //#region src/a2a-mock.ts
7
7
  var A2AMock = class {
@@ -135,7 +135,7 @@ var A2AMock = class {
135
135
  const host = this.options.host ?? "127.0.0.1";
136
136
  const port = this.options.port ?? 0;
137
137
  return new Promise((resolve, reject) => {
138
- const srv = http.createServer(async (req, res) => {
138
+ const srv = http$1.createServer(async (req, res) => {
139
139
  const url = new URL(req.url ?? "/", `http://${req.headers.host ?? "localhost"}`);
140
140
  await this.handleRequest(req, res, url.pathname).catch((err) => {
141
141
  console.error("A2AMock request error:", err);
@@ -1 +1 @@
1
- {"version":3,"file":"a2a-mock.js","names":[],"sources":["../src/a2a-mock.ts"],"sourcesContent":["import * as http from \"node:http\";\nimport type { Mountable } from \"./types.js\";\nimport type { Journal } from \"./journal.js\";\nimport type { MetricsRegistry } from \"./metrics.js\";\nimport type {\n A2AAgentDefinition,\n A2AArtifact,\n A2AMockOptions,\n A2APart,\n A2AStreamEvent,\n A2ATask,\n} from \"./a2a-types.js\";\nimport type { PatternEntry } from \"./a2a-handler.js\";\nimport {\n buildAgentCard,\n createA2AMethods,\n extractText,\n findStreamingMatch,\n TERMINAL_STATES,\n} from \"./a2a-handler.js\";\nimport { createJsonRpcDispatcher } from \"./jsonrpc.js\";\nimport { generateId, flattenHeaders, readBody } from \"./helpers.js\";\n\nexport class A2AMock implements Mountable {\n private agents: Map<string, { def: A2AAgentDefinition; patterns: PatternEntry[] }> = new Map();\n private tasks: Map<string, A2ATask> = new Map();\n private server: http.Server | null = null;\n private journal: Journal | null = null;\n private registry: MetricsRegistry | null = null;\n private options: A2AMockOptions;\n private baseUrl = \"\";\n private dispatcher: ReturnType<typeof createJsonRpcDispatcher>;\n\n constructor(options?: A2AMockOptions) {\n this.options = options ?? {};\n this.dispatcher = this.buildDispatcher();\n }\n\n private buildDispatcher() {\n const methods = createA2AMethods(this.agents, this.tasks);\n return createJsonRpcDispatcher({ methods });\n }\n\n // ---- Agent registration ----\n\n registerAgent(def: A2AAgentDefinition): this {\n this.agents.set(def.name, { def, patterns: [] });\n return this;\n }\n\n // ---- Pattern registration ----\n\n onMessage(agentName: string, pattern: string | RegExp, parts: A2APart[]): this {\n const agent = this.agents.get(agentName);\n if (!agent) {\n throw new Error(`Agent \"${agentName}\" not registered`);\n }\n agent.patterns.push({ kind: \"message\", pattern, agentName, parts });\n return this;\n }\n\n onTask(agentName: string, pattern: string | RegExp, artifacts: A2AArtifact[]): this {\n const agent = this.agents.get(agentName);\n if (!agent) {\n throw new Error(`Agent \"${agentName}\" not registered`);\n }\n agent.patterns.push({ kind: \"task\", pattern, agentName, artifacts });\n return this;\n }\n\n onStreamingTask(\n agentName: string,\n pattern: string | RegExp,\n events: A2AStreamEvent[],\n delayMs?: number,\n ): this {\n const agent = this.agents.get(agentName);\n if (!agent) {\n throw new Error(`Agent \"${agentName}\" not registered`);\n }\n agent.patterns.push({ kind: \"streamingTask\", pattern, agentName, events, delayMs });\n return this;\n }\n\n // ---- Mountable interface ----\n\n async handleRequest(\n req: http.IncomingMessage,\n res: http.ServerResponse,\n pathname: string,\n ): Promise<boolean> {\n // Agent card endpoint\n if (req.method === \"GET\" && pathname === \"/.well-known/agent-card.json\") {\n if (this.registry) {\n this.registry.incrementCounter(\"aimock_a2a_requests_total\", { method: \"GetAgentCard\" });\n }\n const card = buildAgentCard(this.agents, this.baseUrl);\n res.writeHead(200, {\n \"Content-Type\": \"application/json\",\n \"A2A-Version\": \"1.0\",\n });\n res.end(JSON.stringify(card));\n return true;\n }\n\n // JSON-RPC endpoint\n if (req.method === \"POST\" && (pathname === \"/\" || pathname === \"\")) {\n const body = await readBody(req);\n\n // Check for SendStreamingMessage before dispatching\n let parsed: unknown;\n try {\n parsed = JSON.parse(body);\n } catch {\n res.writeHead(200, {\n \"Content-Type\": \"application/json\",\n \"A2A-Version\": \"1.0\",\n });\n res.end(\n JSON.stringify({\n jsonrpc: \"2.0\",\n id: null,\n error: { code: -32700, message: \"Parse error\" },\n }),\n );\n return true;\n }\n\n // Record A2A method metric\n if (this.registry) {\n const rpcMethod =\n typeof parsed === \"object\" && parsed !== null && \"method\" in parsed\n ? String((parsed as Record<string, unknown>).method)\n : \"unknown\";\n this.registry.incrementCounter(\"aimock_a2a_requests_total\", { method: rpcMethod });\n }\n\n if (isStreamingRequest(parsed)) {\n await this.handleStreamingMessage(parsed as Record<string, unknown>, req, res);\n return true;\n }\n\n // Regular JSON-RPC dispatch\n // Add A2A-Version header before dispatching\n res.setHeader(\"A2A-Version\", \"1.0\");\n\n await this.dispatcher(req, res, body);\n\n // Journal the request after the handler completes\n if (this.journal) {\n this.journal.add({\n method: req.method ?? \"POST\",\n path: pathname,\n headers: flattenHeaders(req.headers),\n body: null,\n service: \"a2a\",\n response: { status: res.statusCode, fixture: null },\n });\n }\n\n return true;\n }\n\n return false;\n }\n\n health(): { status: string; agents: number; tasks: number } {\n return {\n status: \"ok\",\n agents: this.agents.size,\n tasks: this.tasks.size,\n };\n }\n\n setJournal(journal: Journal): void {\n this.journal = journal;\n }\n\n setRegistry(registry: MetricsRegistry): void {\n this.registry = registry;\n }\n\n // ---- Standalone mode ----\n\n async start(): Promise<string> {\n if (this.server) {\n throw new Error(\"A2AMock server already started\");\n }\n\n const host = this.options.host ?? \"127.0.0.1\";\n const port = this.options.port ?? 0;\n\n return new Promise<string>((resolve, reject) => {\n const srv = http.createServer(async (req, res) => {\n const url = new URL(req.url ?? \"/\", `http://${req.headers.host ?? \"localhost\"}`);\n await this.handleRequest(req, res, url.pathname).catch((err) => {\n console.error(\"A2AMock request error:\", err);\n if (!res.headersSent) {\n res.writeHead(500);\n res.end(\"Internal server error\");\n }\n });\n });\n\n srv.on(\"error\", reject);\n\n srv.listen(port, host, () => {\n const addr = srv.address();\n if (typeof addr === \"object\" && addr !== null) {\n this.baseUrl = `http://${host}:${addr.port}`;\n }\n this.server = srv;\n resolve(this.baseUrl);\n });\n });\n }\n\n async stop(): Promise<void> {\n if (!this.server) {\n throw new Error(\"A2AMock server not started\");\n }\n const srv = this.server;\n await new Promise<void>((resolve, reject) => {\n srv.close((err: Error | undefined) => (err ? reject(err) : resolve()));\n });\n this.server = null;\n }\n\n get url(): string {\n if (!this.server) {\n throw new Error(\"A2AMock server not started\");\n }\n return this.baseUrl;\n }\n\n // ---- Reset ----\n\n reset(): this {\n this.agents.clear();\n this.tasks.clear();\n return this;\n }\n\n // ---- Internal: set base URL when mounted ----\n\n setBaseUrl(url: string): void {\n this.baseUrl = url;\n }\n\n // ---- Private: streaming handler ----\n\n private async handleStreamingMessage(\n parsed: Record<string, unknown>,\n req: http.IncomingMessage,\n res: http.ServerResponse,\n ): Promise<void> {\n const params = parsed.params as Record<string, unknown> | undefined;\n const id = parsed.id as string | number;\n const text = extractText(params);\n const entry = findStreamingMatch(text, this.agents);\n\n if (!entry) {\n res.writeHead(200, {\n \"Content-Type\": \"application/json\",\n \"A2A-Version\": \"1.0\",\n });\n res.end(\n JSON.stringify({\n jsonrpc: \"2.0\",\n id,\n error: { code: -32000, message: \"No matching pattern for message\" },\n }),\n );\n return;\n }\n\n // Create task for the streaming response\n const taskId = generateId(\"task\");\n const contextId = generateId(\"ctx\");\n const userParts: A2APart[] = params?.message\n ? (((params.message as Record<string, unknown>).parts as A2APart[]) ?? [{ text }])\n : [{ text }];\n\n const task: A2ATask = {\n id: taskId,\n contextId,\n status: { state: \"TASK_STATE_WORKING\", timestamp: new Date().toISOString() },\n artifacts: [],\n history: [\n {\n messageId: generateId(\"msg\"),\n role: \"ROLE_USER\",\n parts: userParts,\n },\n ],\n };\n this.tasks.set(taskId, task);\n\n // Write SSE response\n res.writeHead(200, {\n \"Content-Type\": \"text/event-stream\",\n \"Cache-Control\": \"no-cache\",\n Connection: \"keep-alive\",\n \"A2A-Version\": \"1.0\",\n });\n\n const delayMs = entry.delayMs ?? 0;\n\n for (const event of entry.events) {\n if (delayMs > 0) {\n await delay(delayMs);\n }\n\n let resultPayload: Record<string, unknown>;\n\n if (event.type === \"status\") {\n task.status = { state: event.state, timestamp: new Date().toISOString() };\n resultPayload = {\n task: {\n id: task.id,\n contextId: task.contextId,\n status: task.status,\n },\n };\n } else {\n // artifact event\n const artifact = {\n parts: event.parts,\n name: event.name,\n append: event.append,\n lastChunk: event.lastChunk,\n };\n task.artifacts.push({ parts: event.parts, name: event.name });\n resultPayload = {\n task: {\n id: task.id,\n contextId: task.contextId,\n status: task.status,\n },\n artifact,\n };\n }\n\n const envelope = JSON.stringify({\n jsonrpc: \"2.0\",\n id,\n result: resultPayload,\n });\n\n res.write(`data: ${envelope}\\n\\n`);\n }\n\n // Final completion — only set COMPLETED if the task is not already in a terminal state\n if (!TERMINAL_STATES.has(task.status.state)) {\n task.status = { state: \"TASK_STATE_COMPLETED\", timestamp: new Date().toISOString() };\n }\n\n res.end();\n\n // Journal\n if (this.journal) {\n this.journal.add({\n method: \"POST\",\n path: \"/\",\n headers: flattenHeaders(req.headers),\n body: null,\n service: \"a2a\",\n response: { status: res.statusCode, fixture: null },\n });\n }\n }\n}\n\n// ---- Helpers ----\n\nfunction isStreamingRequest(parsed: unknown): boolean {\n if (typeof parsed !== \"object\" || parsed === null || Array.isArray(parsed)) return false;\n const obj = parsed as Record<string, unknown>;\n return obj.method === \"SendStreamingMessage\";\n}\n\nfunction delay(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"a2a-mock.js","names":["http"],"sources":["../src/a2a-mock.ts"],"sourcesContent":["import * as http from \"node:http\";\nimport type { Mountable } from \"./types.js\";\nimport type { Journal } from \"./journal.js\";\nimport type { MetricsRegistry } from \"./metrics.js\";\nimport type {\n A2AAgentDefinition,\n A2AArtifact,\n A2AMockOptions,\n A2APart,\n A2AStreamEvent,\n A2ATask,\n} from \"./a2a-types.js\";\nimport type { PatternEntry } from \"./a2a-handler.js\";\nimport {\n buildAgentCard,\n createA2AMethods,\n extractText,\n findStreamingMatch,\n TERMINAL_STATES,\n} from \"./a2a-handler.js\";\nimport { createJsonRpcDispatcher } from \"./jsonrpc.js\";\nimport { generateId, flattenHeaders, readBody } from \"./helpers.js\";\n\nexport class A2AMock implements Mountable {\n private agents: Map<string, { def: A2AAgentDefinition; patterns: PatternEntry[] }> = new Map();\n private tasks: Map<string, A2ATask> = new Map();\n private server: http.Server | null = null;\n private journal: Journal | null = null;\n private registry: MetricsRegistry | null = null;\n private options: A2AMockOptions;\n private baseUrl = \"\";\n private dispatcher: ReturnType<typeof createJsonRpcDispatcher>;\n\n constructor(options?: A2AMockOptions) {\n this.options = options ?? {};\n this.dispatcher = this.buildDispatcher();\n }\n\n private buildDispatcher() {\n const methods = createA2AMethods(this.agents, this.tasks);\n return createJsonRpcDispatcher({ methods });\n }\n\n // ---- Agent registration ----\n\n registerAgent(def: A2AAgentDefinition): this {\n this.agents.set(def.name, { def, patterns: [] });\n return this;\n }\n\n // ---- Pattern registration ----\n\n onMessage(agentName: string, pattern: string | RegExp, parts: A2APart[]): this {\n const agent = this.agents.get(agentName);\n if (!agent) {\n throw new Error(`Agent \"${agentName}\" not registered`);\n }\n agent.patterns.push({ kind: \"message\", pattern, agentName, parts });\n return this;\n }\n\n onTask(agentName: string, pattern: string | RegExp, artifacts: A2AArtifact[]): this {\n const agent = this.agents.get(agentName);\n if (!agent) {\n throw new Error(`Agent \"${agentName}\" not registered`);\n }\n agent.patterns.push({ kind: \"task\", pattern, agentName, artifacts });\n return this;\n }\n\n onStreamingTask(\n agentName: string,\n pattern: string | RegExp,\n events: A2AStreamEvent[],\n delayMs?: number,\n ): this {\n const agent = this.agents.get(agentName);\n if (!agent) {\n throw new Error(`Agent \"${agentName}\" not registered`);\n }\n agent.patterns.push({ kind: \"streamingTask\", pattern, agentName, events, delayMs });\n return this;\n }\n\n // ---- Mountable interface ----\n\n async handleRequest(\n req: http.IncomingMessage,\n res: http.ServerResponse,\n pathname: string,\n ): Promise<boolean> {\n // Agent card endpoint\n if (req.method === \"GET\" && pathname === \"/.well-known/agent-card.json\") {\n if (this.registry) {\n this.registry.incrementCounter(\"aimock_a2a_requests_total\", { method: \"GetAgentCard\" });\n }\n const card = buildAgentCard(this.agents, this.baseUrl);\n res.writeHead(200, {\n \"Content-Type\": \"application/json\",\n \"A2A-Version\": \"1.0\",\n });\n res.end(JSON.stringify(card));\n return true;\n }\n\n // JSON-RPC endpoint\n if (req.method === \"POST\" && (pathname === \"/\" || pathname === \"\")) {\n const body = await readBody(req);\n\n // Check for SendStreamingMessage before dispatching\n let parsed: unknown;\n try {\n parsed = JSON.parse(body);\n } catch {\n res.writeHead(200, {\n \"Content-Type\": \"application/json\",\n \"A2A-Version\": \"1.0\",\n });\n res.end(\n JSON.stringify({\n jsonrpc: \"2.0\",\n id: null,\n error: { code: -32700, message: \"Parse error\" },\n }),\n );\n return true;\n }\n\n // Record A2A method metric\n if (this.registry) {\n const rpcMethod =\n typeof parsed === \"object\" && parsed !== null && \"method\" in parsed\n ? String((parsed as Record<string, unknown>).method)\n : \"unknown\";\n this.registry.incrementCounter(\"aimock_a2a_requests_total\", { method: rpcMethod });\n }\n\n if (isStreamingRequest(parsed)) {\n await this.handleStreamingMessage(parsed as Record<string, unknown>, req, res);\n return true;\n }\n\n // Regular JSON-RPC dispatch\n // Add A2A-Version header before dispatching\n res.setHeader(\"A2A-Version\", \"1.0\");\n\n await this.dispatcher(req, res, body);\n\n // Journal the request after the handler completes\n if (this.journal) {\n this.journal.add({\n method: req.method ?? \"POST\",\n path: pathname,\n headers: flattenHeaders(req.headers),\n body: null,\n service: \"a2a\",\n response: { status: res.statusCode, fixture: null },\n });\n }\n\n return true;\n }\n\n return false;\n }\n\n health(): { status: string; agents: number; tasks: number } {\n return {\n status: \"ok\",\n agents: this.agents.size,\n tasks: this.tasks.size,\n };\n }\n\n setJournal(journal: Journal): void {\n this.journal = journal;\n }\n\n setRegistry(registry: MetricsRegistry): void {\n this.registry = registry;\n }\n\n // ---- Standalone mode ----\n\n async start(): Promise<string> {\n if (this.server) {\n throw new Error(\"A2AMock server already started\");\n }\n\n const host = this.options.host ?? \"127.0.0.1\";\n const port = this.options.port ?? 0;\n\n return new Promise<string>((resolve, reject) => {\n const srv = http.createServer(async (req, res) => {\n const url = new URL(req.url ?? \"/\", `http://${req.headers.host ?? \"localhost\"}`);\n await this.handleRequest(req, res, url.pathname).catch((err) => {\n console.error(\"A2AMock request error:\", err);\n if (!res.headersSent) {\n res.writeHead(500);\n res.end(\"Internal server error\");\n }\n });\n });\n\n srv.on(\"error\", reject);\n\n srv.listen(port, host, () => {\n const addr = srv.address();\n if (typeof addr === \"object\" && addr !== null) {\n this.baseUrl = `http://${host}:${addr.port}`;\n }\n this.server = srv;\n resolve(this.baseUrl);\n });\n });\n }\n\n async stop(): Promise<void> {\n if (!this.server) {\n throw new Error(\"A2AMock server not started\");\n }\n const srv = this.server;\n await new Promise<void>((resolve, reject) => {\n srv.close((err: Error | undefined) => (err ? reject(err) : resolve()));\n });\n this.server = null;\n }\n\n get url(): string {\n if (!this.server) {\n throw new Error(\"A2AMock server not started\");\n }\n return this.baseUrl;\n }\n\n // ---- Reset ----\n\n reset(): this {\n this.agents.clear();\n this.tasks.clear();\n return this;\n }\n\n // ---- Internal: set base URL when mounted ----\n\n setBaseUrl(url: string): void {\n this.baseUrl = url;\n }\n\n // ---- Private: streaming handler ----\n\n private async handleStreamingMessage(\n parsed: Record<string, unknown>,\n req: http.IncomingMessage,\n res: http.ServerResponse,\n ): Promise<void> {\n const params = parsed.params as Record<string, unknown> | undefined;\n const id = parsed.id as string | number;\n const text = extractText(params);\n const entry = findStreamingMatch(text, this.agents);\n\n if (!entry) {\n res.writeHead(200, {\n \"Content-Type\": \"application/json\",\n \"A2A-Version\": \"1.0\",\n });\n res.end(\n JSON.stringify({\n jsonrpc: \"2.0\",\n id,\n error: { code: -32000, message: \"No matching pattern for message\" },\n }),\n );\n return;\n }\n\n // Create task for the streaming response\n const taskId = generateId(\"task\");\n const contextId = generateId(\"ctx\");\n const userParts: A2APart[] = params?.message\n ? (((params.message as Record<string, unknown>).parts as A2APart[]) ?? [{ text }])\n : [{ text }];\n\n const task: A2ATask = {\n id: taskId,\n contextId,\n status: { state: \"TASK_STATE_WORKING\", timestamp: new Date().toISOString() },\n artifacts: [],\n history: [\n {\n messageId: generateId(\"msg\"),\n role: \"ROLE_USER\",\n parts: userParts,\n },\n ],\n };\n this.tasks.set(taskId, task);\n\n // Write SSE response\n res.writeHead(200, {\n \"Content-Type\": \"text/event-stream\",\n \"Cache-Control\": \"no-cache\",\n Connection: \"keep-alive\",\n \"A2A-Version\": \"1.0\",\n });\n\n const delayMs = entry.delayMs ?? 0;\n\n for (const event of entry.events) {\n if (delayMs > 0) {\n await delay(delayMs);\n }\n\n let resultPayload: Record<string, unknown>;\n\n if (event.type === \"status\") {\n task.status = { state: event.state, timestamp: new Date().toISOString() };\n resultPayload = {\n task: {\n id: task.id,\n contextId: task.contextId,\n status: task.status,\n },\n };\n } else {\n // artifact event\n const artifact = {\n parts: event.parts,\n name: event.name,\n append: event.append,\n lastChunk: event.lastChunk,\n };\n task.artifacts.push({ parts: event.parts, name: event.name });\n resultPayload = {\n task: {\n id: task.id,\n contextId: task.contextId,\n status: task.status,\n },\n artifact,\n };\n }\n\n const envelope = JSON.stringify({\n jsonrpc: \"2.0\",\n id,\n result: resultPayload,\n });\n\n res.write(`data: ${envelope}\\n\\n`);\n }\n\n // Final completion — only set COMPLETED if the task is not already in a terminal state\n if (!TERMINAL_STATES.has(task.status.state)) {\n task.status = { state: \"TASK_STATE_COMPLETED\", timestamp: new Date().toISOString() };\n }\n\n res.end();\n\n // Journal\n if (this.journal) {\n this.journal.add({\n method: \"POST\",\n path: \"/\",\n headers: flattenHeaders(req.headers),\n body: null,\n service: \"a2a\",\n response: { status: res.statusCode, fixture: null },\n });\n }\n }\n}\n\n// ---- Helpers ----\n\nfunction isStreamingRequest(parsed: unknown): boolean {\n if (typeof parsed !== \"object\" || parsed === null || Array.isArray(parsed)) return false;\n const obj = parsed as Record<string, unknown>;\n return obj.method === \"SendStreamingMessage\";\n}\n\nfunction delay(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n"],"mappings":"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"}
@@ -22,7 +22,10 @@ function matchesFixture(input, match) {
22
22
  const text = extractLastUserMessage(input);
23
23
  if (typeof match.message === "string") {
24
24
  if (!text.includes(match.message)) return false;
25
- } else if (!match.message.test(text)) return false;
25
+ } else {
26
+ match.message.lastIndex = 0;
27
+ if (!match.message.test(text)) return false;
28
+ }
26
29
  }
27
30
  if (match.toolName !== void 0) {
28
31
  if (!(input.tools ?? []).some((t) => t.name === match.toolName)) return false;
@@ -50,11 +53,13 @@ function makeRunStarted(opts) {
50
53
  ...opts?.parentRunId ? { parentRunId: opts.parentRunId } : {}
51
54
  };
52
55
  }
53
- function makeRunFinished(started) {
56
+ function makeRunFinished(started, finishOpts) {
54
57
  return {
55
58
  type: "RUN_FINISHED",
56
59
  threadId: started.threadId,
57
- runId: started.runId
60
+ runId: started.runId,
61
+ ...finishOpts?.result !== void 0 ? { result: finishOpts.result } : {},
62
+ ...finishOpts?.outcome !== void 0 ? { outcome: finishOpts.outcome } : {}
58
63
  };
59
64
  }
60
65
  /**
@@ -287,9 +292,110 @@ function buildCompositeResponse(builderOutputs, opts) {
287
292
  const started = makeRunStarted(opts);
288
293
  const inner = [];
289
294
  for (const events of builderOutputs) for (const event of events) if (event.type !== "RUN_STARTED" && event.type !== "RUN_FINISHED") inner.push(event);
295
+ const hasError = inner.some((e) => e.type === "RUN_ERROR");
290
296
  return [
291
297
  started,
292
298
  ...inner,
299
+ ...hasError ? [] : [makeRunFinished(started)]
300
+ ];
301
+ }
302
+ /**
303
+ * Build an activity delta response (JSON Patch on an activity).
304
+ * [RUN_STARTED, ACTIVITY_DELTA, RUN_FINISHED]
305
+ */
306
+ function buildActivityDelta(messageId, activityType, patch, opts) {
307
+ const started = makeRunStarted(opts);
308
+ return [
309
+ started,
310
+ {
311
+ type: "ACTIVITY_DELTA",
312
+ messageId,
313
+ activityType,
314
+ patch
315
+ },
316
+ makeRunFinished(started)
317
+ ];
318
+ }
319
+ /**
320
+ * Build a tool call chunk response (single chunk, no start/end envelope).
321
+ * [RUN_STARTED, TOOL_CALL_CHUNK, RUN_FINISHED]
322
+ */
323
+ function buildToolCallChunk(delta, opts) {
324
+ const started = makeRunStarted(opts);
325
+ return [
326
+ started,
327
+ {
328
+ type: "TOOL_CALL_CHUNK",
329
+ ...opts?.toolCallId !== void 0 ? { toolCallId: opts.toolCallId } : {},
330
+ ...opts?.toolCallName !== void 0 ? { toolCallName: opts.toolCallName } : {},
331
+ ...opts?.parentMessageId !== void 0 ? { parentMessageId: opts.parentMessageId } : {},
332
+ delta
333
+ },
334
+ makeRunFinished(started)
335
+ ];
336
+ }
337
+ /**
338
+ * Build a raw event response.
339
+ * [RUN_STARTED, RAW, RUN_FINISHED]
340
+ */
341
+ function buildRawEvent(event, source, opts) {
342
+ const started = makeRunStarted(opts);
343
+ return [
344
+ started,
345
+ {
346
+ type: "RAW",
347
+ event,
348
+ ...source !== void 0 ? { source } : {}
349
+ },
350
+ makeRunFinished(started)
351
+ ];
352
+ }
353
+ /**
354
+ * Build a custom event response.
355
+ * [RUN_STARTED, CUSTOM, RUN_FINISHED]
356
+ */
357
+ function buildCustomEvent(name, value, opts) {
358
+ const started = makeRunStarted(opts);
359
+ return [
360
+ started,
361
+ {
362
+ type: "CUSTOM",
363
+ name,
364
+ value
365
+ },
366
+ makeRunFinished(started)
367
+ ];
368
+ }
369
+ /**
370
+ * Build a reasoning message chunk response (single chunk, no start/end envelope).
371
+ * [RUN_STARTED, REASONING_MESSAGE_CHUNK, RUN_FINISHED]
372
+ */
373
+ function buildReasoningChunk(delta, opts) {
374
+ const started = makeRunStarted(opts);
375
+ return [
376
+ started,
377
+ {
378
+ type: "REASONING_MESSAGE_CHUNK",
379
+ ...opts?.messageId !== void 0 ? { messageId: opts.messageId } : {},
380
+ delta
381
+ },
382
+ makeRunFinished(started)
383
+ ];
384
+ }
385
+ /**
386
+ * Build a reasoning encrypted value event response.
387
+ * [RUN_STARTED, REASONING_ENCRYPTED_VALUE, RUN_FINISHED]
388
+ */
389
+ function buildReasoningEncryptedValue(subtype, entityId, encryptedValue, opts) {
390
+ const started = makeRunStarted(opts);
391
+ return [
392
+ started,
393
+ {
394
+ type: "REASONING_ENCRYPTED_VALUE",
395
+ subtype,
396
+ entityId,
397
+ encryptedValue
398
+ },
293
399
  makeRunFinished(started)
294
400
  ];
295
401
  }
@@ -310,11 +416,13 @@ async function writeAGUIEventStream(res, events, opts) {
310
416
  if (res.socket?.destroyed) break;
311
417
  const stamped = {
312
418
  ...event,
313
- timestamp: Date.now()
419
+ timestamp: event.timestamp ?? Date.now()
314
420
  };
315
421
  try {
316
422
  res.write(`data: ${JSON.stringify(stamped)}\n\n`);
317
- } catch {
423
+ } catch (err) {
424
+ if (err instanceof TypeError || err instanceof RangeError) console.warn("AG-UI SSE write failed (serialization):", err.message);
425
+ else if (err instanceof Error) console.warn("AG-UI SSE write failed:", err.message);
318
426
  break;
319
427
  }
320
428
  if (delayMs > 0) await new Promise((resolve) => setTimeout(resolve, delayMs));
@@ -323,18 +431,25 @@ async function writeAGUIEventStream(res, events, opts) {
323
431
  }
324
432
 
325
433
  //#endregion
434
+ exports.buildActivityDelta = buildActivityDelta;
326
435
  exports.buildActivityResponse = buildActivityResponse;
327
436
  exports.buildCompositeResponse = buildCompositeResponse;
437
+ exports.buildCustomEvent = buildCustomEvent;
328
438
  exports.buildErrorResponse = buildErrorResponse;
329
439
  exports.buildMessagesSnapshot = buildMessagesSnapshot;
440
+ exports.buildRawEvent = buildRawEvent;
441
+ exports.buildReasoningChunk = buildReasoningChunk;
442
+ exports.buildReasoningEncryptedValue = buildReasoningEncryptedValue;
330
443
  exports.buildReasoningResponse = buildReasoningResponse;
331
444
  exports.buildStateDelta = buildStateDelta;
332
445
  exports.buildStateUpdate = buildStateUpdate;
333
446
  exports.buildStepWithText = buildStepWithText;
334
447
  exports.buildTextChunkResponse = buildTextChunkResponse;
335
448
  exports.buildTextResponse = buildTextResponse;
449
+ exports.buildToolCallChunk = buildToolCallChunk;
336
450
  exports.buildToolCallResponse = buildToolCallResponse;
337
451
  exports.extractLastUserMessage = extractLastUserMessage;
338
452
  exports.findFixture = findFixture;
453
+ exports.matchesFixture = matchesFixture;
339
454
  exports.writeAGUIEventStream = writeAGUIEventStream;
340
455
  //# sourceMappingURL=agui-handler.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"agui-handler.cjs","names":[],"sources":["../src/agui-handler.ts"],"sourcesContent":["// ─── AG-UI Handler ───────────────────────────────────────────────────────────\n//\n// Matching functions, event builders, and SSE writer for AG-UI protocol.\n\nimport * as http from \"node:http\";\nimport { randomUUID } from \"node:crypto\";\n\nimport type {\n AGUIRunAgentInput,\n AGUIFixtureMatch,\n AGUIFixture,\n AGUIEvent,\n AGUIMessage,\n AGUIRunStartedEvent,\n AGUIRunFinishedEvent,\n AGUIRunErrorEvent,\n AGUITextMessageStartEvent,\n AGUITextMessageContentEvent,\n AGUITextMessageEndEvent,\n AGUITextMessageChunkEvent,\n AGUIToolCallStartEvent,\n AGUIToolCallArgsEvent,\n AGUIToolCallEndEvent,\n AGUIToolCallResultEvent,\n AGUIStateSnapshotEvent,\n AGUIStateDeltaEvent,\n AGUIMessagesSnapshotEvent,\n AGUIStepStartedEvent,\n AGUIStepFinishedEvent,\n AGUIReasoningStartEvent,\n AGUIReasoningMessageStartEvent,\n AGUIReasoningMessageContentEvent,\n AGUIReasoningMessageEndEvent,\n AGUIReasoningEndEvent,\n AGUIActivitySnapshotEvent,\n} from \"./agui-types.js\";\n\n// ─── Matching functions ──────────────────────────────────────────────────────\n\n/**\n * Extract the content of the last message with role \"user\" from the input.\n */\nexport function extractLastUserMessage(input: AGUIRunAgentInput): string {\n if (!input.messages || input.messages.length === 0) return \"\";\n for (let i = input.messages.length - 1; i >= 0; i--) {\n const msg = input.messages[i];\n if (msg.role === \"user\" && typeof msg.content === \"string\") {\n return msg.content;\n }\n }\n return \"\";\n}\n\n/**\n * Check whether an input matches a fixture's match criteria.\n * All specified criteria must pass (AND logic).\n */\nexport function matchesFixture(input: AGUIRunAgentInput, match: AGUIFixtureMatch): boolean {\n if (match.message !== undefined) {\n const text = extractLastUserMessage(input);\n if (typeof match.message === \"string\") {\n if (!text.includes(match.message)) return false;\n } else {\n if (!match.message.test(text)) return false;\n }\n }\n\n if (match.toolName !== undefined) {\n const tools = input.tools ?? [];\n if (!tools.some((t) => t.name === match.toolName)) return false;\n }\n\n if (match.stateKey !== undefined) {\n if (\n input.state === null ||\n input.state === undefined ||\n typeof input.state !== \"object\" ||\n !(match.stateKey in (input.state as Record<string, unknown>))\n ) {\n return false;\n }\n }\n\n if (match.predicate !== undefined) {\n if (!match.predicate(input)) return false;\n }\n\n return true;\n}\n\n/**\n * Find the first fixture whose match criteria pass for the given input.\n */\nexport function findFixture(input: AGUIRunAgentInput, fixtures: AGUIFixture[]): AGUIFixture | null {\n for (const fixture of fixtures) {\n if (matchesFixture(input, fixture.match)) {\n return fixture;\n }\n }\n return null;\n}\n\n// ─── Builder options ─────────────────────────────────────────────────────────\n\nexport interface AGUIBuildOpts {\n threadId?: string;\n runId?: string;\n parentRunId?: string;\n /** For tool call builder: include a result event */\n result?: string;\n}\n\n// ─── Event builders ──────────────────────────────────────────────────────────\n\nfunction makeRunStarted(opts?: AGUIBuildOpts): AGUIRunStartedEvent {\n return {\n type: \"RUN_STARTED\",\n threadId: opts?.threadId ?? randomUUID(),\n runId: opts?.runId ?? randomUUID(),\n ...(opts?.parentRunId ? { parentRunId: opts.parentRunId } : {}),\n };\n}\n\nfunction makeRunFinished(started: AGUIRunStartedEvent): AGUIRunFinishedEvent {\n return {\n type: \"RUN_FINISHED\",\n threadId: started.threadId,\n runId: started.runId,\n };\n}\n\n/**\n * Build a complete text message response sequence.\n * [RUN_STARTED, TEXT_MESSAGE_START, TEXT_MESSAGE_CONTENT, TEXT_MESSAGE_END, RUN_FINISHED]\n */\nexport function buildTextResponse(text: string, opts?: AGUIBuildOpts): AGUIEvent[] {\n const started = makeRunStarted(opts);\n const messageId = randomUUID();\n return [\n started,\n {\n type: \"TEXT_MESSAGE_START\",\n messageId,\n role: \"assistant\",\n } as AGUITextMessageStartEvent,\n {\n type: \"TEXT_MESSAGE_CONTENT\",\n messageId,\n delta: text,\n } as AGUITextMessageContentEvent,\n {\n type: \"TEXT_MESSAGE_END\",\n messageId,\n } as AGUITextMessageEndEvent,\n makeRunFinished(started),\n ];\n}\n\n/**\n * Build a text chunk response (single chunk, no start/end envelope).\n * [RUN_STARTED, TEXT_MESSAGE_CHUNK, RUN_FINISHED]\n */\nexport function buildTextChunkResponse(text: string, opts?: AGUIBuildOpts): AGUIEvent[] {\n const started = makeRunStarted(opts);\n return [\n started,\n {\n type: \"TEXT_MESSAGE_CHUNK\",\n messageId: randomUUID(),\n role: \"assistant\",\n delta: text,\n } as AGUITextMessageChunkEvent,\n makeRunFinished(started),\n ];\n}\n\n/**\n * Build a tool call response sequence.\n * [RUN_STARTED, TOOL_CALL_START, TOOL_CALL_ARGS, TOOL_CALL_END, (TOOL_CALL_RESULT)?, RUN_FINISHED]\n */\nexport function buildToolCallResponse(\n toolName: string,\n args: string,\n opts?: AGUIBuildOpts,\n): AGUIEvent[] {\n const started = makeRunStarted(opts);\n const toolCallId = randomUUID();\n const events: AGUIEvent[] = [\n started,\n {\n type: \"TOOL_CALL_START\",\n toolCallId,\n toolCallName: toolName,\n } as AGUIToolCallStartEvent,\n {\n type: \"TOOL_CALL_ARGS\",\n toolCallId,\n delta: args,\n } as AGUIToolCallArgsEvent,\n {\n type: \"TOOL_CALL_END\",\n toolCallId,\n } as AGUIToolCallEndEvent,\n ];\n\n if (opts?.result !== undefined) {\n events.push({\n type: \"TOOL_CALL_RESULT\",\n messageId: randomUUID(),\n toolCallId,\n content: opts.result,\n role: \"tool\",\n } as AGUIToolCallResultEvent);\n }\n\n events.push(makeRunFinished(started));\n return events;\n}\n\n/**\n * Build a state snapshot response.\n * [RUN_STARTED, STATE_SNAPSHOT, RUN_FINISHED]\n */\nexport function buildStateUpdate(snapshot: unknown, opts?: AGUIBuildOpts): AGUIEvent[] {\n const started = makeRunStarted(opts);\n return [\n started,\n {\n type: \"STATE_SNAPSHOT\",\n snapshot,\n } as AGUIStateSnapshotEvent,\n makeRunFinished(started),\n ];\n}\n\n/**\n * Build a state delta response (JSON Patch).\n * [RUN_STARTED, STATE_DELTA, RUN_FINISHED]\n */\nexport function buildStateDelta(patches: unknown[], opts?: AGUIBuildOpts): AGUIEvent[] {\n const started = makeRunStarted(opts);\n return [\n started,\n {\n type: \"STATE_DELTA\",\n delta: patches,\n } as AGUIStateDeltaEvent,\n makeRunFinished(started),\n ];\n}\n\n/**\n * Build a messages snapshot response.\n * [RUN_STARTED, MESSAGES_SNAPSHOT, RUN_FINISHED]\n */\nexport function buildMessagesSnapshot(messages: AGUIMessage[], opts?: AGUIBuildOpts): AGUIEvent[] {\n const started = makeRunStarted(opts);\n return [\n started,\n {\n type: \"MESSAGES_SNAPSHOT\",\n messages,\n } as AGUIMessagesSnapshotEvent,\n makeRunFinished(started),\n ];\n}\n\n/**\n * Build a reasoning response sequence.\n * [RUN_STARTED, REASONING_START, REASONING_MESSAGE_START, REASONING_MESSAGE_CONTENT,\n * REASONING_MESSAGE_END, REASONING_END, RUN_FINISHED]\n */\nexport function buildReasoningResponse(text: string, opts?: AGUIBuildOpts): AGUIEvent[] {\n const started = makeRunStarted(opts);\n const messageId = randomUUID();\n return [\n started,\n {\n type: \"REASONING_START\",\n messageId,\n } as AGUIReasoningStartEvent,\n {\n type: \"REASONING_MESSAGE_START\",\n messageId,\n role: \"reasoning\",\n } as AGUIReasoningMessageStartEvent,\n {\n type: \"REASONING_MESSAGE_CONTENT\",\n messageId,\n delta: text,\n } as AGUIReasoningMessageContentEvent,\n {\n type: \"REASONING_MESSAGE_END\",\n messageId,\n } as AGUIReasoningMessageEndEvent,\n {\n type: \"REASONING_END\",\n messageId,\n } as AGUIReasoningEndEvent,\n makeRunFinished(started),\n ];\n}\n\n/**\n * Build an activity snapshot response.\n * [RUN_STARTED, ACTIVITY_SNAPSHOT, RUN_FINISHED]\n */\nexport function buildActivityResponse(\n messageId: string,\n activityType: string,\n content: Record<string, unknown>,\n opts?: AGUIBuildOpts,\n): AGUIEvent[] {\n const started = makeRunStarted(opts);\n return [\n started,\n {\n type: \"ACTIVITY_SNAPSHOT\",\n messageId,\n activityType,\n content,\n replace: true,\n } as AGUIActivitySnapshotEvent,\n makeRunFinished(started),\n ];\n}\n\n/**\n * Build an error response.\n * [RUN_STARTED, RUN_ERROR] (no RUN_FINISHED — the run errored)\n */\nexport function buildErrorResponse(\n message: string,\n code?: string,\n opts?: AGUIBuildOpts,\n): AGUIEvent[] {\n const started = makeRunStarted(opts);\n return [\n started,\n {\n type: \"RUN_ERROR\",\n message,\n ...(code !== undefined ? { code } : {}),\n } as AGUIRunErrorEvent,\n ];\n}\n\n/**\n * Build a step-wrapped text response.\n * [RUN_STARTED, STEP_STARTED, TEXT_MESSAGE_START, TEXT_MESSAGE_CONTENT,\n * TEXT_MESSAGE_END, STEP_FINISHED, RUN_FINISHED]\n */\nexport function buildStepWithText(\n stepName: string,\n text: string,\n opts?: AGUIBuildOpts,\n): AGUIEvent[] {\n const started = makeRunStarted(opts);\n const messageId = randomUUID();\n return [\n started,\n {\n type: \"STEP_STARTED\",\n stepName,\n } as AGUIStepStartedEvent,\n {\n type: \"TEXT_MESSAGE_START\",\n messageId,\n role: \"assistant\",\n } as AGUITextMessageStartEvent,\n {\n type: \"TEXT_MESSAGE_CONTENT\",\n messageId,\n delta: text,\n } as AGUITextMessageContentEvent,\n {\n type: \"TEXT_MESSAGE_END\",\n messageId,\n } as AGUITextMessageEndEvent,\n {\n type: \"STEP_FINISHED\",\n stepName,\n } as AGUIStepFinishedEvent,\n makeRunFinished(started),\n ];\n}\n\n/**\n * Combine multiple builder outputs into a single run.\n * Strips RUN_STARTED/RUN_FINISHED from each input, wraps all inner events\n * in one RUN_STARTED...RUN_FINISHED pair.\n */\nexport function buildCompositeResponse(\n builderOutputs: AGUIEvent[][],\n opts?: AGUIBuildOpts,\n): AGUIEvent[] {\n const started = makeRunStarted(opts);\n const inner: AGUIEvent[] = [];\n\n for (const events of builderOutputs) {\n for (const event of events) {\n if (event.type !== \"RUN_STARTED\" && event.type !== \"RUN_FINISHED\") {\n inner.push(event);\n }\n }\n }\n\n return [started, ...inner, makeRunFinished(started)];\n}\n\n// ─── SSE writer ──────────────────────────────────────────────────────────────\n\n/**\n * Write AG-UI events as an SSE stream to an HTTP response.\n * Sets appropriate headers, serializes each event as `data: {...}\\n\\n`,\n * and optionally delays between events.\n */\nexport async function writeAGUIEventStream(\n res: http.ServerResponse,\n events: AGUIEvent[],\n opts?: { delayMs?: number; signal?: AbortSignal },\n): Promise<void> {\n const delayMs = opts?.delayMs ?? 0;\n\n res.writeHead(200, {\n \"Content-Type\": \"text/event-stream\",\n \"Cache-Control\": \"no-cache\",\n Connection: \"keep-alive\",\n });\n\n for (const event of events) {\n if (opts?.signal?.aborted) break;\n if (res.socket?.destroyed) break;\n\n const stamped = { ...event, timestamp: Date.now() };\n try {\n res.write(`data: ${JSON.stringify(stamped)}\\n\\n`);\n } catch {\n break; // client disconnected or stream error — stop writing\n }\n\n if (delayMs > 0) {\n await new Promise<void>((resolve) => setTimeout(resolve, delayMs));\n }\n }\n\n if (!res.writableEnded) res.end();\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"agui-handler.cjs","names":[],"sources":["../src/agui-handler.ts"],"sourcesContent":["// ─── AG-UI Handler ───────────────────────────────────────────────────────────\n//\n// Matching functions, event builders, and SSE writer for AG-UI protocol.\n\nimport * as http from \"node:http\";\nimport { randomUUID } from \"node:crypto\";\n\nimport type {\n AGUIRunAgentInput,\n AGUIFixtureMatch,\n AGUIFixture,\n AGUIEvent,\n AGUIMessage,\n AGUIRunStartedEvent,\n AGUIRunFinishedEvent,\n AGUIRunFinishedOutcome,\n AGUIRunErrorEvent,\n AGUITextMessageStartEvent,\n AGUITextMessageContentEvent,\n AGUITextMessageEndEvent,\n AGUITextMessageChunkEvent,\n AGUIToolCallStartEvent,\n AGUIToolCallArgsEvent,\n AGUIToolCallEndEvent,\n AGUIToolCallChunkEvent,\n AGUIToolCallResultEvent,\n AGUIStateSnapshotEvent,\n AGUIStateDeltaEvent,\n AGUIMessagesSnapshotEvent,\n AGUIStepStartedEvent,\n AGUIStepFinishedEvent,\n AGUIReasoningStartEvent,\n AGUIReasoningMessageStartEvent,\n AGUIReasoningMessageContentEvent,\n AGUIReasoningMessageEndEvent,\n AGUIReasoningMessageChunkEvent,\n AGUIReasoningEndEvent,\n AGUIReasoningEncryptedValueEvent,\n AGUIReasoningEncryptedValueSubtype,\n AGUIActivitySnapshotEvent,\n AGUIActivityDeltaEvent,\n AGUIRawEvent,\n AGUICustomEvent,\n} from \"./agui-types.js\";\n\n// ─── Matching functions ──────────────────────────────────────────────────────\n\n/**\n * Extract the content of the last message with role \"user\" from the input.\n */\nexport function extractLastUserMessage(input: AGUIRunAgentInput): string {\n if (!input.messages || input.messages.length === 0) return \"\";\n for (let i = input.messages.length - 1; i >= 0; i--) {\n const msg = input.messages[i];\n if (msg.role === \"user\" && typeof msg.content === \"string\") {\n return msg.content;\n }\n }\n return \"\";\n}\n\n/**\n * Check whether an input matches a fixture's match criteria.\n * All specified criteria must pass (AND logic).\n */\nexport function matchesFixture(input: AGUIRunAgentInput, match: AGUIFixtureMatch): boolean {\n if (match.message !== undefined) {\n const text = extractLastUserMessage(input);\n if (typeof match.message === \"string\") {\n if (!text.includes(match.message)) return false;\n } else {\n match.message.lastIndex = 0;\n if (!match.message.test(text)) return false;\n }\n }\n\n if (match.toolName !== undefined) {\n const tools = input.tools ?? [];\n if (!tools.some((t) => t.name === match.toolName)) return false;\n }\n\n if (match.stateKey !== undefined) {\n if (\n input.state === null ||\n input.state === undefined ||\n typeof input.state !== \"object\" ||\n !(match.stateKey in (input.state as Record<string, unknown>))\n ) {\n return false;\n }\n }\n\n if (match.predicate !== undefined) {\n if (!match.predicate(input)) return false;\n }\n\n return true;\n}\n\n/**\n * Find the first fixture whose match criteria pass for the given input.\n */\nexport function findFixture(input: AGUIRunAgentInput, fixtures: AGUIFixture[]): AGUIFixture | null {\n for (const fixture of fixtures) {\n if (matchesFixture(input, fixture.match)) {\n return fixture;\n }\n }\n return null;\n}\n\n// ─── Builder options ─────────────────────────────────────────────────────────\n\nexport interface AGUIBuildOpts {\n threadId?: string;\n runId?: string;\n parentRunId?: string;\n /** For tool call builder: include a result event */\n result?: string;\n}\n\n// ─── Event builders ──────────────────────────────────────────────────────────\n\nfunction makeRunStarted(opts?: AGUIBuildOpts): AGUIRunStartedEvent {\n return {\n type: \"RUN_STARTED\",\n threadId: opts?.threadId ?? randomUUID(),\n runId: opts?.runId ?? randomUUID(),\n ...(opts?.parentRunId ? { parentRunId: opts.parentRunId } : {}),\n };\n}\n\nfunction makeRunFinished(\n started: AGUIRunStartedEvent,\n finishOpts?: { outcome?: AGUIRunFinishedOutcome; result?: unknown },\n): AGUIRunFinishedEvent {\n return {\n type: \"RUN_FINISHED\",\n threadId: started.threadId,\n runId: started.runId,\n ...(finishOpts?.result !== undefined ? { result: finishOpts.result } : {}),\n ...(finishOpts?.outcome !== undefined ? { outcome: finishOpts.outcome } : {}),\n };\n}\n\n/**\n * Build a complete text message response sequence.\n * [RUN_STARTED, TEXT_MESSAGE_START, TEXT_MESSAGE_CONTENT, TEXT_MESSAGE_END, RUN_FINISHED]\n */\nexport function buildTextResponse(text: string, opts?: AGUIBuildOpts): AGUIEvent[] {\n const started = makeRunStarted(opts);\n const messageId = randomUUID();\n return [\n started,\n {\n type: \"TEXT_MESSAGE_START\",\n messageId,\n role: \"assistant\",\n } as AGUITextMessageStartEvent,\n {\n type: \"TEXT_MESSAGE_CONTENT\",\n messageId,\n delta: text,\n } as AGUITextMessageContentEvent,\n {\n type: \"TEXT_MESSAGE_END\",\n messageId,\n } as AGUITextMessageEndEvent,\n makeRunFinished(started),\n ];\n}\n\n/**\n * Build a text chunk response (single chunk, no start/end envelope).\n * [RUN_STARTED, TEXT_MESSAGE_CHUNK, RUN_FINISHED]\n */\nexport function buildTextChunkResponse(text: string, opts?: AGUIBuildOpts): AGUIEvent[] {\n const started = makeRunStarted(opts);\n return [\n started,\n {\n type: \"TEXT_MESSAGE_CHUNK\",\n messageId: randomUUID(),\n role: \"assistant\",\n delta: text,\n } as AGUITextMessageChunkEvent,\n makeRunFinished(started),\n ];\n}\n\n/**\n * Build a tool call response sequence.\n * [RUN_STARTED, TOOL_CALL_START, TOOL_CALL_ARGS, TOOL_CALL_END, (TOOL_CALL_RESULT)?, RUN_FINISHED]\n */\nexport function buildToolCallResponse(\n toolName: string,\n args: string,\n opts?: AGUIBuildOpts,\n): AGUIEvent[] {\n const started = makeRunStarted(opts);\n const toolCallId = randomUUID();\n const events: AGUIEvent[] = [\n started,\n {\n type: \"TOOL_CALL_START\",\n toolCallId,\n toolCallName: toolName,\n } as AGUIToolCallStartEvent,\n {\n type: \"TOOL_CALL_ARGS\",\n toolCallId,\n delta: args,\n } as AGUIToolCallArgsEvent,\n {\n type: \"TOOL_CALL_END\",\n toolCallId,\n } as AGUIToolCallEndEvent,\n ];\n\n if (opts?.result !== undefined) {\n events.push({\n type: \"TOOL_CALL_RESULT\",\n messageId: randomUUID(),\n toolCallId,\n content: opts.result,\n role: \"tool\",\n } as AGUIToolCallResultEvent);\n }\n\n events.push(makeRunFinished(started));\n return events;\n}\n\n/**\n * Build a state snapshot response.\n * [RUN_STARTED, STATE_SNAPSHOT, RUN_FINISHED]\n */\nexport function buildStateUpdate(snapshot: unknown, opts?: AGUIBuildOpts): AGUIEvent[] {\n const started = makeRunStarted(opts);\n return [\n started,\n {\n type: \"STATE_SNAPSHOT\",\n snapshot,\n } as AGUIStateSnapshotEvent,\n makeRunFinished(started),\n ];\n}\n\n/**\n * Build a state delta response (JSON Patch).\n * [RUN_STARTED, STATE_DELTA, RUN_FINISHED]\n */\nexport function buildStateDelta(patches: unknown[], opts?: AGUIBuildOpts): AGUIEvent[] {\n const started = makeRunStarted(opts);\n return [\n started,\n {\n type: \"STATE_DELTA\",\n delta: patches,\n } as AGUIStateDeltaEvent,\n makeRunFinished(started),\n ];\n}\n\n/**\n * Build a messages snapshot response.\n * [RUN_STARTED, MESSAGES_SNAPSHOT, RUN_FINISHED]\n */\nexport function buildMessagesSnapshot(messages: AGUIMessage[], opts?: AGUIBuildOpts): AGUIEvent[] {\n const started = makeRunStarted(opts);\n return [\n started,\n {\n type: \"MESSAGES_SNAPSHOT\",\n messages,\n } as AGUIMessagesSnapshotEvent,\n makeRunFinished(started),\n ];\n}\n\n/**\n * Build a reasoning response sequence.\n * [RUN_STARTED, REASONING_START, REASONING_MESSAGE_START, REASONING_MESSAGE_CONTENT,\n * REASONING_MESSAGE_END, REASONING_END, RUN_FINISHED]\n */\nexport function buildReasoningResponse(text: string, opts?: AGUIBuildOpts): AGUIEvent[] {\n const started = makeRunStarted(opts);\n const messageId = randomUUID();\n return [\n started,\n {\n type: \"REASONING_START\",\n messageId,\n } as AGUIReasoningStartEvent,\n {\n type: \"REASONING_MESSAGE_START\",\n messageId,\n role: \"reasoning\",\n } as AGUIReasoningMessageStartEvent,\n {\n type: \"REASONING_MESSAGE_CONTENT\",\n messageId,\n delta: text,\n } as AGUIReasoningMessageContentEvent,\n {\n type: \"REASONING_MESSAGE_END\",\n messageId,\n } as AGUIReasoningMessageEndEvent,\n {\n type: \"REASONING_END\",\n messageId,\n } as AGUIReasoningEndEvent,\n makeRunFinished(started),\n ];\n}\n\n/**\n * Build an activity snapshot response.\n * [RUN_STARTED, ACTIVITY_SNAPSHOT, RUN_FINISHED]\n */\nexport function buildActivityResponse(\n messageId: string,\n activityType: string,\n content: Record<string, unknown>,\n opts?: AGUIBuildOpts,\n): AGUIEvent[] {\n const started = makeRunStarted(opts);\n return [\n started,\n {\n type: \"ACTIVITY_SNAPSHOT\",\n messageId,\n activityType,\n content,\n replace: true,\n } as AGUIActivitySnapshotEvent,\n makeRunFinished(started),\n ];\n}\n\n/**\n * Build an error response.\n * [RUN_STARTED, RUN_ERROR] (no RUN_FINISHED — the run errored)\n */\nexport function buildErrorResponse(\n message: string,\n code?: string,\n opts?: AGUIBuildOpts,\n): AGUIEvent[] {\n const started = makeRunStarted(opts);\n return [\n started,\n {\n type: \"RUN_ERROR\",\n message,\n ...(code !== undefined ? { code } : {}),\n } as AGUIRunErrorEvent,\n ];\n}\n\n/**\n * Build a step-wrapped text response.\n * [RUN_STARTED, STEP_STARTED, TEXT_MESSAGE_START, TEXT_MESSAGE_CONTENT,\n * TEXT_MESSAGE_END, STEP_FINISHED, RUN_FINISHED]\n */\nexport function buildStepWithText(\n stepName: string,\n text: string,\n opts?: AGUIBuildOpts,\n): AGUIEvent[] {\n const started = makeRunStarted(opts);\n const messageId = randomUUID();\n return [\n started,\n {\n type: \"STEP_STARTED\",\n stepName,\n } as AGUIStepStartedEvent,\n {\n type: \"TEXT_MESSAGE_START\",\n messageId,\n role: \"assistant\",\n } as AGUITextMessageStartEvent,\n {\n type: \"TEXT_MESSAGE_CONTENT\",\n messageId,\n delta: text,\n } as AGUITextMessageContentEvent,\n {\n type: \"TEXT_MESSAGE_END\",\n messageId,\n } as AGUITextMessageEndEvent,\n {\n type: \"STEP_FINISHED\",\n stepName,\n } as AGUIStepFinishedEvent,\n makeRunFinished(started),\n ];\n}\n\n/**\n * Combine multiple builder outputs into a single run.\n * Strips RUN_STARTED/RUN_FINISHED from each input, wraps all inner events\n * in one RUN_STARTED...RUN_FINISHED pair.\n */\nexport function buildCompositeResponse(\n builderOutputs: AGUIEvent[][],\n opts?: AGUIBuildOpts,\n): AGUIEvent[] {\n const started = makeRunStarted(opts);\n const inner: AGUIEvent[] = [];\n\n for (const events of builderOutputs) {\n for (const event of events) {\n if (event.type !== \"RUN_STARTED\" && event.type !== \"RUN_FINISHED\") {\n inner.push(event);\n }\n }\n }\n\n const hasError = inner.some((e) => e.type === \"RUN_ERROR\");\n return [started, ...inner, ...(hasError ? [] : [makeRunFinished(started)])];\n}\n\n// ─── Convenience event builders ─────────────────────────────────────────────\n\n/**\n * Build an activity delta response (JSON Patch on an activity).\n * [RUN_STARTED, ACTIVITY_DELTA, RUN_FINISHED]\n */\nexport function buildActivityDelta(\n messageId: string,\n activityType: string,\n patch: unknown[],\n opts?: AGUIBuildOpts,\n): AGUIEvent[] {\n const started = makeRunStarted(opts);\n return [\n started,\n {\n type: \"ACTIVITY_DELTA\",\n messageId,\n activityType,\n patch,\n } as AGUIActivityDeltaEvent,\n makeRunFinished(started),\n ];\n}\n\n/**\n * Build a tool call chunk response (single chunk, no start/end envelope).\n * [RUN_STARTED, TOOL_CALL_CHUNK, RUN_FINISHED]\n */\nexport function buildToolCallChunk(\n delta: string,\n opts?: AGUIBuildOpts & {\n toolCallId?: string;\n toolCallName?: string;\n parentMessageId?: string;\n },\n): AGUIEvent[] {\n const started = makeRunStarted(opts);\n return [\n started,\n {\n type: \"TOOL_CALL_CHUNK\",\n ...(opts?.toolCallId !== undefined ? { toolCallId: opts.toolCallId } : {}),\n ...(opts?.toolCallName !== undefined ? { toolCallName: opts.toolCallName } : {}),\n ...(opts?.parentMessageId !== undefined ? { parentMessageId: opts.parentMessageId } : {}),\n delta,\n } as AGUIToolCallChunkEvent,\n makeRunFinished(started),\n ];\n}\n\n/**\n * Build a raw event response.\n * [RUN_STARTED, RAW, RUN_FINISHED]\n */\nexport function buildRawEvent(event: unknown, source?: string, opts?: AGUIBuildOpts): AGUIEvent[] {\n const started = makeRunStarted(opts);\n return [\n started,\n {\n type: \"RAW\",\n event,\n ...(source !== undefined ? { source } : {}),\n } as AGUIRawEvent,\n makeRunFinished(started),\n ];\n}\n\n/**\n * Build a custom event response.\n * [RUN_STARTED, CUSTOM, RUN_FINISHED]\n */\nexport function buildCustomEvent(name: string, value: unknown, opts?: AGUIBuildOpts): AGUIEvent[] {\n const started = makeRunStarted(opts);\n return [\n started,\n {\n type: \"CUSTOM\",\n name,\n value,\n } as AGUICustomEvent,\n makeRunFinished(started),\n ];\n}\n\n/**\n * Build a reasoning message chunk response (single chunk, no start/end envelope).\n * [RUN_STARTED, REASONING_MESSAGE_CHUNK, RUN_FINISHED]\n */\nexport function buildReasoningChunk(\n delta: string,\n opts?: AGUIBuildOpts & { messageId?: string },\n): AGUIEvent[] {\n const started = makeRunStarted(opts);\n return [\n started,\n {\n type: \"REASONING_MESSAGE_CHUNK\",\n ...(opts?.messageId !== undefined ? { messageId: opts.messageId } : {}),\n delta,\n } as AGUIReasoningMessageChunkEvent,\n makeRunFinished(started),\n ];\n}\n\n/**\n * Build a reasoning encrypted value event response.\n * [RUN_STARTED, REASONING_ENCRYPTED_VALUE, RUN_FINISHED]\n */\nexport function buildReasoningEncryptedValue(\n subtype: AGUIReasoningEncryptedValueSubtype,\n entityId: string,\n encryptedValue: string,\n opts?: AGUIBuildOpts,\n): AGUIEvent[] {\n const started = makeRunStarted(opts);\n return [\n started,\n {\n type: \"REASONING_ENCRYPTED_VALUE\",\n subtype,\n entityId,\n encryptedValue,\n } as AGUIReasoningEncryptedValueEvent,\n makeRunFinished(started),\n ];\n}\n\n// ─── SSE writer ──────────────────────────────────────────────────────────────\n\n/**\n * Write AG-UI events as an SSE stream to an HTTP response.\n * Sets appropriate headers, serializes each event as `data: {...}\\n\\n`,\n * and optionally delays between events.\n */\nexport async function writeAGUIEventStream(\n res: http.ServerResponse,\n events: AGUIEvent[],\n opts?: { delayMs?: number; signal?: AbortSignal },\n): Promise<void> {\n const delayMs = opts?.delayMs ?? 0;\n\n res.writeHead(200, {\n \"Content-Type\": \"text/event-stream\",\n \"Cache-Control\": \"no-cache\",\n Connection: \"keep-alive\",\n });\n\n for (const event of events) {\n if (opts?.signal?.aborted) break;\n if (res.socket?.destroyed) break;\n\n const stamped = { ...event, timestamp: event.timestamp ?? Date.now() };\n try {\n res.write(`data: ${JSON.stringify(stamped)}\\n\\n`);\n } catch (err) {\n if (err instanceof TypeError || err instanceof RangeError) {\n console.warn(\"AG-UI SSE write failed (serialization):\", (err as Error).message);\n } else if (err instanceof Error) {\n console.warn(\"AG-UI SSE write failed:\", err.message);\n }\n break;\n }\n\n if (delayMs > 0) {\n await new Promise<void>((resolve) => setTimeout(resolve, delayMs));\n }\n }\n\n if (!res.writableEnded) res.end();\n}\n"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
- import { AGUIEvent, AGUIFixture, AGUIMessage, AGUIRunAgentInput } from "./agui-types.cjs";
2
- import * as http from "node:http";
1
+ import { AGUIEvent, AGUIFixture, AGUIFixtureMatch, AGUIMessage, AGUIReasoningEncryptedValueSubtype, AGUIRunAgentInput } from "./agui-types.cjs";
2
+ import * as http$1 from "node:http";
3
3
 
4
4
  //#region src/agui-handler.d.ts
5
5
 
@@ -11,7 +11,7 @@ declare function extractLastUserMessage(input: AGUIRunAgentInput): string;
11
11
  * Check whether an input matches a fixture's match criteria.
12
12
  * All specified criteria must pass (AND logic).
13
13
  */
14
-
14
+ declare function matchesFixture(input: AGUIRunAgentInput, match: AGUIFixtureMatch): boolean;
15
15
  /**
16
16
  * Find the first fixture whose match criteria pass for the given input.
17
17
  */
@@ -81,16 +81,52 @@ declare function buildStepWithText(stepName: string, text: string, opts?: AGUIBu
81
81
  * in one RUN_STARTED...RUN_FINISHED pair.
82
82
  */
83
83
  declare function buildCompositeResponse(builderOutputs: AGUIEvent[][], opts?: AGUIBuildOpts): AGUIEvent[];
84
+ /**
85
+ * Build an activity delta response (JSON Patch on an activity).
86
+ * [RUN_STARTED, ACTIVITY_DELTA, RUN_FINISHED]
87
+ */
88
+ declare function buildActivityDelta(messageId: string, activityType: string, patch: unknown[], opts?: AGUIBuildOpts): AGUIEvent[];
89
+ /**
90
+ * Build a tool call chunk response (single chunk, no start/end envelope).
91
+ * [RUN_STARTED, TOOL_CALL_CHUNK, RUN_FINISHED]
92
+ */
93
+ declare function buildToolCallChunk(delta: string, opts?: AGUIBuildOpts & {
94
+ toolCallId?: string;
95
+ toolCallName?: string;
96
+ parentMessageId?: string;
97
+ }): AGUIEvent[];
98
+ /**
99
+ * Build a raw event response.
100
+ * [RUN_STARTED, RAW, RUN_FINISHED]
101
+ */
102
+ declare function buildRawEvent(event: unknown, source?: string, opts?: AGUIBuildOpts): AGUIEvent[];
103
+ /**
104
+ * Build a custom event response.
105
+ * [RUN_STARTED, CUSTOM, RUN_FINISHED]
106
+ */
107
+ declare function buildCustomEvent(name: string, value: unknown, opts?: AGUIBuildOpts): AGUIEvent[];
108
+ /**
109
+ * Build a reasoning message chunk response (single chunk, no start/end envelope).
110
+ * [RUN_STARTED, REASONING_MESSAGE_CHUNK, RUN_FINISHED]
111
+ */
112
+ declare function buildReasoningChunk(delta: string, opts?: AGUIBuildOpts & {
113
+ messageId?: string;
114
+ }): AGUIEvent[];
115
+ /**
116
+ * Build a reasoning encrypted value event response.
117
+ * [RUN_STARTED, REASONING_ENCRYPTED_VALUE, RUN_FINISHED]
118
+ */
119
+ declare function buildReasoningEncryptedValue(subtype: AGUIReasoningEncryptedValueSubtype, entityId: string, encryptedValue: string, opts?: AGUIBuildOpts): AGUIEvent[];
84
120
  /**
85
121
  * Write AG-UI events as an SSE stream to an HTTP response.
86
122
  * Sets appropriate headers, serializes each event as `data: {...}\n\n`,
87
123
  * and optionally delays between events.
88
124
  */
89
- declare function writeAGUIEventStream(res: http.ServerResponse, events: AGUIEvent[], opts?: {
125
+ declare function writeAGUIEventStream(res: http$1.ServerResponse, events: AGUIEvent[], opts?: {
90
126
  delayMs?: number;
91
127
  signal?: AbortSignal;
92
128
  }): Promise<void>;
93
129
  //# sourceMappingURL=agui-handler.d.ts.map
94
130
  //#endregion
95
- export { buildActivityResponse, buildCompositeResponse, buildErrorResponse, buildMessagesSnapshot, buildReasoningResponse, buildStateDelta, buildStateUpdate, buildStepWithText, buildTextChunkResponse, buildTextResponse, buildToolCallResponse, extractLastUserMessage, findFixture, writeAGUIEventStream };
131
+ export { AGUIBuildOpts, buildActivityDelta, buildActivityResponse, buildCompositeResponse, buildCustomEvent, buildErrorResponse, buildMessagesSnapshot, buildRawEvent, buildReasoningChunk, buildReasoningEncryptedValue, buildReasoningResponse, buildStateDelta, buildStateUpdate, buildStepWithText, buildTextChunkResponse, buildTextResponse, buildToolCallChunk, buildToolCallResponse, extractLastUserMessage, findFixture, matchesFixture, writeAGUIEventStream };
96
132
  //# sourceMappingURL=agui-handler.d.cts.map
@@ -1 +1 @@
1
- {"version":3,"file":"agui-handler.d.cts","names":[],"sources":["../src/agui-handler.ts"],"sourcesContent":[],"mappings":";;;;;;;AA0CA;AAmDgB,iBAnDA,sBAAA,CAmDW,KAAA,EAnDmB,iBAmDnB,CAAA,EAAA,MAAA;;;;;;AAW3B;AA+BA;;AAAuD,iBA1CvC,WAAA,CA0CuC,KAAA,EA1CpB,iBA0CoB,EAAA,QAAA,EA1CS,WA0CT,EAAA,CAAA,EA1CyB,WA0CzB,GAAA,IAAA;AAAgB,UA/BtD,aAAA,CA+BsD;EAAS,QAAA,CAAA,EAAA,MAAA;EA2BhE,KAAA,CAAA,EAAA,MAAA;EAAsB,WAAA,CAAA,EAAA,MAAA;;QAAsC,CAAA,EAAA,MAAA;;AAkB5E;;;;AAIY,iBAjDI,iBAAA,CAiDJ,IAAA,EAAA,MAAA,EAAA,IAAA,CAAA,EAjD2C,aAiD3C,CAAA,EAjD2D,SAiD3D,EAAA;AAuCZ;;;;AAAoF,iBA7DpE,sBAAA,CA6DoE,IAAA,EAAA,MAAA,EAAA,IAAA,CAAA,EA7DxB,aA6DwB,CAAA,EA7DR,SA6DQ,EAAA;AAgBpF;;;;AAAoF,iBA3DpE,qBAAA,CA2DoE,QAAA,EAAA,MAAA,EAAA,IAAA,EAAA,MAAA,EAAA,IAAA,CAAA,EAxD3E,aAwD2E,CAAA,EAvDjF,SAuDiF,EAAA;AAgBpF;;;;AAAsF,iBAhCtE,gBAAA,CAgCsE,QAAA,EAAA,OAAA,EAAA,IAAA,CAAA,EAhC3B,aAgC2B,CAAA,EAhCX,SAgCW,EAAA;;AAiBtF;;;AAA4E,iBAjC5D,eAAA,CAiC4D,OAAA,EAAA,OAAA,EAAA,EAAA,IAAA,CAAA,EAjCjB,aAiCiB,CAAA,EAjCD,SAiCC,EAAA;;AAmC5E;;;AAIS,iBAxDO,qBAAA,CAwDP,QAAA,EAxDuC,WAwDvC,EAAA,EAAA,IAAA,CAAA,EAxD6D,aAwD7D,CAAA,EAxD6E,SAwD7E,EAAA;;;AAoBT;;;AAIG,iBA/Da,sBAAA,CA+Db,IAAA,EAAA,MAAA,EAAA,IAAA,CAAA,EA/DyD,aA+DzD,CAAA,EA/DyE,SA+DzE,EAAA;;AAiBH;;;AAIG,iBAjDa,qBAAA,CAiDb,SAAA,EAAA,MAAA,EAAA,YAAA,EAAA,MAAA,EAAA,OAAA,EA9CQ,MA8CR,CAAA,MAAA,EAAA,OAAA,CAAA,EAAA,IAAA,CAAA,EA7CM,aA6CN,CAAA,EA5CA,SA4CA,EAAA;;AAoCH;;;AAES,iBA/DO,kBAAA,CA+DP,OAAA,EAAA,MAAA,EAAA,IAAA,CAAA,EAAA,MAAA,EAAA,IAAA,CAAA,EA5DA,aA4DA,CAAA,EA3DN,SA2DM,EAAA;;;AAuBT;;;AAEU,iBAnEM,iBAAA,CAmEN,QAAA,EAAA,MAAA,EAAA,IAAA,EAAA,MAAA,EAAA,IAAA,CAAA,EAhED,aAgEC,CAAA,EA/DP,SA+DO,EAAA;;;;;;iBA3BM,sBAAA,iBACE,sBACT,gBACN;;;;;;iBAsBmB,oBAAA,MACf,IAAA,CAAK,wBACF;;WAC4B;IACnC"}
1
+ {"version":3,"file":"agui-handler.d.cts","names":[],"sources":["../src/agui-handler.ts"],"sourcesContent":[],"mappings":"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"}