@copilotkit/aimock 1.41.0 → 1.42.1

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 (218) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/.claude-plugin/plugin.json +1 -1
  3. package/CHANGELOG.md +18 -1
  4. package/README.md +2 -1
  5. package/dist/a2a-mock.cjs +18 -11
  6. package/dist/a2a-mock.cjs.map +1 -1
  7. package/dist/a2a-mock.d.cts +1 -0
  8. package/dist/a2a-mock.d.cts.map +1 -1
  9. package/dist/a2a-mock.d.ts +1 -0
  10. package/dist/a2a-mock.d.ts.map +1 -1
  11. package/dist/a2a-mock.js +18 -11
  12. package/dist/a2a-mock.js.map +1 -1
  13. package/dist/agui-handler.d.ts.map +1 -1
  14. package/dist/agui-mock.cjs +2 -0
  15. package/dist/agui-mock.cjs.map +1 -1
  16. package/dist/agui-mock.d.cts.map +1 -1
  17. package/dist/agui-mock.d.ts.map +1 -1
  18. package/dist/agui-mock.js +2 -0
  19. package/dist/agui-mock.js.map +1 -1
  20. package/dist/bedrock-converse.cjs +36 -2
  21. package/dist/bedrock-converse.cjs.map +1 -1
  22. package/dist/bedrock-converse.d.cts.map +1 -1
  23. package/dist/bedrock-converse.d.ts.map +1 -1
  24. package/dist/bedrock-converse.js +37 -3
  25. package/dist/bedrock-converse.js.map +1 -1
  26. package/dist/bedrock.cjs +50 -13
  27. package/dist/bedrock.cjs.map +1 -1
  28. package/dist/bedrock.d.cts.map +1 -1
  29. package/dist/bedrock.d.ts.map +1 -1
  30. package/dist/bedrock.js +51 -14
  31. package/dist/bedrock.js.map +1 -1
  32. package/dist/byteplus-video.cjs +2 -2
  33. package/dist/byteplus-video.cjs.map +1 -1
  34. package/dist/byteplus-video.d.cts.map +1 -1
  35. package/dist/byteplus-video.d.ts.map +1 -1
  36. package/dist/byteplus-video.js +2 -2
  37. package/dist/byteplus-video.js.map +1 -1
  38. package/dist/chaos.cjs +36 -7
  39. package/dist/chaos.cjs.map +1 -1
  40. package/dist/chaos.d.cts +8 -3
  41. package/dist/chaos.d.cts.map +1 -1
  42. package/dist/chaos.d.ts +8 -3
  43. package/dist/chaos.d.ts.map +1 -1
  44. package/dist/chaos.js +36 -8
  45. package/dist/chaos.js.map +1 -1
  46. package/dist/cohere.cjs +58 -5
  47. package/dist/cohere.cjs.map +1 -1
  48. package/dist/cohere.d.cts.map +1 -1
  49. package/dist/cohere.d.ts.map +1 -1
  50. package/dist/cohere.js +59 -6
  51. package/dist/cohere.js.map +1 -1
  52. package/dist/config-loader.d.cts.map +1 -1
  53. package/dist/config-loader.d.ts.map +1 -1
  54. package/dist/elevenlabs-audio.cjs +36 -2
  55. package/dist/elevenlabs-audio.cjs.map +1 -1
  56. package/dist/elevenlabs-audio.d.cts.map +1 -1
  57. package/dist/elevenlabs-audio.d.ts.map +1 -1
  58. package/dist/elevenlabs-audio.js +37 -3
  59. package/dist/elevenlabs-audio.js.map +1 -1
  60. package/dist/embeddings.cjs +58 -3
  61. package/dist/embeddings.cjs.map +1 -1
  62. package/dist/embeddings.d.cts.map +1 -1
  63. package/dist/embeddings.d.ts.map +1 -1
  64. package/dist/embeddings.js +59 -4
  65. package/dist/embeddings.js.map +1 -1
  66. package/dist/fal-audio.cjs +38 -2
  67. package/dist/fal-audio.cjs.map +1 -1
  68. package/dist/fal-audio.d.cts.map +1 -1
  69. package/dist/fal-audio.d.ts.map +1 -1
  70. package/dist/fal-audio.js +39 -3
  71. package/dist/fal-audio.js.map +1 -1
  72. package/dist/fixture-loader.cjs +0 -0
  73. package/dist/fixture-loader.cjs.map +1 -1
  74. package/dist/fixture-loader.d.cts +9 -1
  75. package/dist/fixture-loader.d.cts.map +1 -1
  76. package/dist/fixture-loader.d.ts +9 -1
  77. package/dist/fixture-loader.d.ts.map +1 -1
  78. package/dist/fixture-loader.js +0 -0
  79. package/dist/fixture-loader.js.map +1 -1
  80. package/dist/gemini-embeddings.cjs +19 -1
  81. package/dist/gemini-embeddings.cjs.map +1 -1
  82. package/dist/gemini-embeddings.js +20 -2
  83. package/dist/gemini-embeddings.js.map +1 -1
  84. package/dist/gemini-interactions.cjs +15 -1
  85. package/dist/gemini-interactions.cjs.map +1 -1
  86. package/dist/gemini-interactions.d.cts.map +1 -1
  87. package/dist/gemini-interactions.d.ts.map +1 -1
  88. package/dist/gemini-interactions.js +16 -2
  89. package/dist/gemini-interactions.js.map +1 -1
  90. package/dist/gemini.cjs +70 -6
  91. package/dist/gemini.cjs.map +1 -1
  92. package/dist/gemini.d.cts.map +1 -1
  93. package/dist/gemini.d.ts.map +1 -1
  94. package/dist/gemini.js +71 -7
  95. package/dist/gemini.js.map +1 -1
  96. package/dist/grok-video.cjs +2 -2
  97. package/dist/grok-video.cjs.map +1 -1
  98. package/dist/grok-video.d.cts.map +1 -1
  99. package/dist/grok-video.d.ts.map +1 -1
  100. package/dist/grok-video.js +2 -2
  101. package/dist/grok-video.js.map +1 -1
  102. package/dist/helpers.cjs +168 -7
  103. package/dist/helpers.cjs.map +1 -1
  104. package/dist/helpers.d.cts.map +1 -1
  105. package/dist/helpers.d.ts.map +1 -1
  106. package/dist/helpers.js +160 -8
  107. package/dist/helpers.js.map +1 -1
  108. package/dist/images.cjs +22 -4
  109. package/dist/images.cjs.map +1 -1
  110. package/dist/images.d.cts.map +1 -1
  111. package/dist/images.d.ts.map +1 -1
  112. package/dist/images.js +23 -5
  113. package/dist/images.js.map +1 -1
  114. package/dist/llmock.cjs +15 -0
  115. package/dist/llmock.cjs.map +1 -1
  116. package/dist/llmock.d.cts +12 -0
  117. package/dist/llmock.d.cts.map +1 -1
  118. package/dist/llmock.d.ts +12 -0
  119. package/dist/llmock.d.ts.map +1 -1
  120. package/dist/llmock.js +16 -1
  121. package/dist/llmock.js.map +1 -1
  122. package/dist/mcp-mock.cjs +11 -0
  123. package/dist/mcp-mock.cjs.map +1 -1
  124. package/dist/mcp-mock.d.cts.map +1 -1
  125. package/dist/mcp-mock.d.ts.map +1 -1
  126. package/dist/mcp-mock.js +11 -0
  127. package/dist/mcp-mock.js.map +1 -1
  128. package/dist/messages.cjs +18 -1
  129. package/dist/messages.cjs.map +1 -1
  130. package/dist/messages.d.cts.map +1 -1
  131. package/dist/messages.d.ts.map +1 -1
  132. package/dist/messages.js +19 -2
  133. package/dist/messages.js.map +1 -1
  134. package/dist/moderation.cjs +67 -3
  135. package/dist/moderation.cjs.map +1 -1
  136. package/dist/moderation.d.cts +1 -0
  137. package/dist/moderation.d.cts.map +1 -1
  138. package/dist/moderation.d.ts +1 -0
  139. package/dist/moderation.d.ts.map +1 -1
  140. package/dist/moderation.js +68 -4
  141. package/dist/moderation.js.map +1 -1
  142. package/dist/ollama.cjs +75 -5
  143. package/dist/ollama.cjs.map +1 -1
  144. package/dist/ollama.d.cts.map +1 -1
  145. package/dist/ollama.d.ts.map +1 -1
  146. package/dist/ollama.js +76 -6
  147. package/dist/ollama.js.map +1 -1
  148. package/dist/openrouter-video.cjs +4 -4
  149. package/dist/openrouter-video.cjs.map +1 -1
  150. package/dist/openrouter-video.d.cts.map +1 -1
  151. package/dist/openrouter-video.d.ts.map +1 -1
  152. package/dist/openrouter-video.js +4 -4
  153. package/dist/openrouter-video.js.map +1 -1
  154. package/dist/rerank.cjs +65 -2
  155. package/dist/rerank.cjs.map +1 -1
  156. package/dist/rerank.d.cts +1 -1
  157. package/dist/rerank.d.cts.map +1 -1
  158. package/dist/rerank.d.ts +1 -1
  159. package/dist/rerank.d.ts.map +1 -1
  160. package/dist/rerank.js +66 -3
  161. package/dist/rerank.js.map +1 -1
  162. package/dist/responses.cjs +18 -1
  163. package/dist/responses.cjs.map +1 -1
  164. package/dist/responses.d.cts.map +1 -1
  165. package/dist/responses.d.ts.map +1 -1
  166. package/dist/responses.js +19 -2
  167. package/dist/responses.js.map +1 -1
  168. package/dist/search.cjs +67 -3
  169. package/dist/search.cjs.map +1 -1
  170. package/dist/search.d.cts +1 -0
  171. package/dist/search.d.cts.map +1 -1
  172. package/dist/search.d.ts +1 -0
  173. package/dist/search.d.ts.map +1 -1
  174. package/dist/search.js +68 -4
  175. package/dist/search.js.map +1 -1
  176. package/dist/server.cjs +317 -13
  177. package/dist/server.cjs.map +1 -1
  178. package/dist/server.d.cts.map +1 -1
  179. package/dist/server.d.ts.map +1 -1
  180. package/dist/server.js +320 -16
  181. package/dist/server.js.map +1 -1
  182. package/dist/speech.cjs +18 -1
  183. package/dist/speech.cjs.map +1 -1
  184. package/dist/speech.d.cts.map +1 -1
  185. package/dist/speech.d.ts.map +1 -1
  186. package/dist/speech.js +19 -2
  187. package/dist/speech.js.map +1 -1
  188. package/dist/transcription.cjs +21 -2
  189. package/dist/transcription.cjs.map +1 -1
  190. package/dist/transcription.d.cts.map +1 -1
  191. package/dist/transcription.d.ts.map +1 -1
  192. package/dist/transcription.js +21 -2
  193. package/dist/transcription.js.map +1 -1
  194. package/dist/types.d.cts +39 -2
  195. package/dist/types.d.cts.map +1 -1
  196. package/dist/types.d.ts +39 -2
  197. package/dist/types.d.ts.map +1 -1
  198. package/dist/vector-mock.cjs +88 -0
  199. package/dist/vector-mock.cjs.map +1 -1
  200. package/dist/vector-mock.d.cts.map +1 -1
  201. package/dist/vector-mock.d.ts.map +1 -1
  202. package/dist/vector-mock.js +89 -1
  203. package/dist/vector-mock.js.map +1 -1
  204. package/dist/vector-types.d.cts.map +1 -1
  205. package/dist/vector-types.d.ts.map +1 -1
  206. package/dist/veo-video.cjs +2 -2
  207. package/dist/veo-video.cjs.map +1 -1
  208. package/dist/veo-video.d.cts.map +1 -1
  209. package/dist/veo-video.d.ts.map +1 -1
  210. package/dist/veo-video.js +2 -2
  211. package/dist/veo-video.js.map +1 -1
  212. package/dist/video.cjs +19 -2
  213. package/dist/video.cjs.map +1 -1
  214. package/dist/video.d.cts.map +1 -1
  215. package/dist/video.d.ts.map +1 -1
  216. package/dist/video.js +20 -3
  217. package/dist/video.js.map +1 -1
  218. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","names":[],"sources":["../src/types.ts"],"sourcesContent":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","names":[],"sources":["../src/types.ts"],"sourcesContent":[],"mappings":"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"}
@@ -60,10 +60,40 @@ var VectorMock = class {
60
60
  if (body) parsed = JSON.parse(body);
61
61
  } catch (parseErr) {
62
62
  const detail = parseErr instanceof Error ? parseErr.message : "unknown";
63
+ if (this.journal) this.journal.add({
64
+ method: req.method ?? "GET",
65
+ path: req.url ?? "/",
66
+ headers: require_helpers.flattenHeaders(req.headers),
67
+ body: null,
68
+ service: "vector",
69
+ response: {
70
+ status: 400,
71
+ fixture: null
72
+ }
73
+ });
63
74
  res.writeHead(400, { "Content-Type": "application/json" });
64
75
  res.end(JSON.stringify({ error: `Malformed JSON body: ${detail}` }));
65
76
  return true;
66
77
  }
78
+ if (!require_helpers.isJsonObject(parsed)) {
79
+ if (this.journal) this.journal.add({
80
+ method: req.method ?? "GET",
81
+ path: req.url ?? "/",
82
+ headers: require_helpers.flattenHeaders(req.headers),
83
+ body: null,
84
+ service: "vector",
85
+ response: {
86
+ status: 400,
87
+ fixture: null
88
+ }
89
+ });
90
+ res.writeHead(400, { "Content-Type": "application/json" });
91
+ res.end(JSON.stringify({ error: {
92
+ message: "Request body must be a JSON object",
93
+ type: "invalid_request_error"
94
+ } }));
95
+ return true;
96
+ }
67
97
  }
68
98
  const handled = this.requestHandler(req, res, pathname, parsed);
69
99
  if (handled && this.registry) {
@@ -84,6 +114,23 @@ var VectorMock = class {
84
114
  fixture: null
85
115
  }
86
116
  });
117
+ if (!handled && this.journal) {
118
+ const journal = this.journal;
119
+ res.once("finish", () => {
120
+ if (res.statusCode !== 404) return;
121
+ journal.add({
122
+ method: req.method ?? "GET",
123
+ path: req.url ?? "/",
124
+ headers: require_helpers.flattenHeaders(req.headers),
125
+ body: null,
126
+ service: "vector",
127
+ response: {
128
+ status: 404,
129
+ fixture: null
130
+ }
131
+ });
132
+ });
133
+ }
87
134
  return handled;
88
135
  }
89
136
  health() {
@@ -114,11 +161,41 @@ var VectorMock = class {
114
161
  } catch (parseErr) {
115
162
  if (req.method !== "GET") {
116
163
  const detail = parseErr instanceof Error ? parseErr.message : "unknown";
164
+ if (this.journal) this.journal.add({
165
+ method: req.method ?? "GET",
166
+ path: req.url ?? "/",
167
+ headers: require_helpers.flattenHeaders(req.headers),
168
+ body: null,
169
+ service: "vector",
170
+ response: {
171
+ status: 400,
172
+ fixture: null
173
+ }
174
+ });
117
175
  res.writeHead(400, { "Content-Type": "application/json" });
118
176
  res.end(JSON.stringify({ error: `Malformed JSON body: ${detail}` }));
119
177
  return;
120
178
  }
121
179
  }
180
+ if (req.method !== "GET" && !require_helpers.isJsonObject(parsed)) {
181
+ if (this.journal) this.journal.add({
182
+ method: req.method ?? "GET",
183
+ path: req.url ?? "/",
184
+ headers: require_helpers.flattenHeaders(req.headers),
185
+ body: null,
186
+ service: "vector",
187
+ response: {
188
+ status: 400,
189
+ fixture: null
190
+ }
191
+ });
192
+ res.writeHead(400, { "Content-Type": "application/json" });
193
+ res.end(JSON.stringify({ error: {
194
+ message: "Request body must be a JSON object",
195
+ type: "invalid_request_error"
196
+ } }));
197
+ return;
198
+ }
122
199
  const url = new URL(req.url ?? "/", `http://${host}`);
123
200
  const handled = this.requestHandler(req, res, url.pathname, parsed);
124
201
  if (handled && this.journal) this.journal.add({
@@ -133,6 +210,17 @@ var VectorMock = class {
133
210
  }
134
211
  });
135
212
  if (!handled) {
213
+ if (this.journal) this.journal.add({
214
+ method: req.method ?? "GET",
215
+ path: req.url ?? "/",
216
+ headers: require_helpers.flattenHeaders(req.headers),
217
+ body: null,
218
+ service: "vector",
219
+ response: {
220
+ status: 404,
221
+ fixture: null
222
+ }
223
+ });
136
224
  res.writeHead(404, { "Content-Type": "application/json" });
137
225
  res.end(JSON.stringify({ error: "Not found" }));
138
226
  }
@@ -1 +1 @@
1
- {"version":3,"file":"vector-mock.cjs","names":["readBody","flattenHeaders","http","createVectorRequestHandler"],"sources":["../src/vector-mock.ts"],"sourcesContent":["import * as http from \"node:http\";\nimport type { Mountable, JournalEntry } from \"./types.js\";\nimport type { Journal } from \"./journal.js\";\nimport type { MetricsRegistry } from \"./metrics.js\";\nimport type {\n VectorMockOptions,\n VectorCollection,\n VectorEntry,\n QueryResult,\n VectorQuery,\n QueryHandler,\n} from \"./vector-types.js\";\nimport { createVectorRequestHandler, type VectorState } from \"./vector-handler.js\";\nimport { flattenHeaders, readBody } from \"./helpers.js\";\n\nexport class VectorMock implements Mountable {\n private collections: Map<string, VectorCollection> = new Map();\n private queryHandlers: Map<string, QueryHandler> = new Map();\n private server: http.Server | null = null;\n private journal: Journal | null = null;\n private registry: MetricsRegistry | null = null;\n private options: VectorMockOptions;\n private requestHandler: ReturnType<typeof createVectorRequestHandler>;\n\n constructor(options?: VectorMockOptions) {\n this.options = options ?? {};\n this.requestHandler = this.buildHandler();\n }\n\n // ---- Configuration ----\n\n addCollection(name: string, opts: { dimension: number }): this {\n const collection: VectorCollection = {\n name,\n dimension: opts.dimension,\n vectors: new Map(),\n };\n this.collections.set(name, collection);\n this.requestHandler = this.buildHandler();\n return this;\n }\n\n upsert(collection: string, vectors: VectorEntry[]): this {\n let col = this.collections.get(collection);\n if (!col) {\n const dim = vectors.length > 0 ? vectors[0].values.length : 0;\n col = { name: collection, dimension: dim, vectors: new Map() };\n this.collections.set(collection, col);\n }\n for (const v of vectors) {\n col.vectors.set(v.id, v);\n }\n this.requestHandler = this.buildHandler();\n return this;\n }\n\n onQuery(\n collection: string,\n results: QueryResult[] | ((query: VectorQuery) => QueryResult[]),\n ): this {\n this.queryHandlers.set(collection, results);\n this.requestHandler = this.buildHandler();\n return this;\n }\n\n deleteCollection(name: string): this {\n this.collections.delete(name);\n this.queryHandlers.delete(name);\n this.requestHandler = this.buildHandler();\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 // Only consume the request body for methods that carry a body,\n // avoiding double-consumption when the route doesn't match.\n let parsed: Record<string, unknown> = {};\n if (req.method !== \"GET\" && req.method !== \"DELETE\" && req.method !== \"HEAD\") {\n const body = await readBody(req);\n try {\n if (body) parsed = JSON.parse(body);\n } catch (parseErr) {\n const detail = parseErr instanceof Error ? parseErr.message : \"unknown\";\n res.writeHead(400, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify({ error: `Malformed JSON body: ${detail}` }));\n return true;\n }\n }\n\n const handled = this.requestHandler(req, res, pathname, parsed);\n\n // Record vector operation metric\n if (handled && this.registry) {\n const { operation, provider } = classifyVectorRequest(req.method ?? \"GET\", pathname);\n this.registry.incrementCounter(\"aimock_vector_requests_total\", { operation, provider });\n }\n\n // Journal the request after the handler completes\n if (handled && this.journal) {\n this.journal.add({\n method: req.method ?? \"GET\",\n path: req.url ?? \"/\",\n headers: flattenHeaders(req.headers),\n body: null,\n service: \"vector\",\n response: { status: res.statusCode, fixture: null },\n });\n }\n\n return handled;\n }\n\n health(): { status: string; collections: number } {\n return {\n status: \"ok\",\n collections: this.collections.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(\"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((resolve, reject) => {\n const srv = http.createServer((req, res) => {\n const chunks: Buffer[] = [];\n req.on(\"data\", (chunk: Buffer) => chunks.push(chunk));\n req.on(\"end\", () => {\n const body = Buffer.concat(chunks).toString();\n let parsed: Record<string, unknown> = {};\n try {\n if (body) parsed = JSON.parse(body);\n } catch (parseErr) {\n if (req.method !== \"GET\") {\n const detail = parseErr instanceof Error ? parseErr.message : \"unknown\";\n res.writeHead(400, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify({ error: `Malformed JSON body: ${detail}` }));\n return;\n }\n }\n\n const url = new URL(req.url ?? \"/\", `http://${host}`);\n\n const handled = this.requestHandler(req, res, url.pathname, parsed);\n\n if (handled && this.journal) {\n this.journal.add({\n method: req.method ?? \"GET\",\n path: req.url ?? \"/\",\n headers: flattenHeaders(req.headers),\n body: null,\n service: \"vector\",\n response: { status: res.statusCode, fixture: null },\n });\n }\n if (!handled) {\n res.writeHead(404, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify({ error: \"Not found\" }));\n }\n });\n });\n\n srv.listen(port, host, () => {\n this.server = srv;\n const addr = srv.address();\n if (typeof addr === \"object\" && addr !== null) {\n resolve(`http://${host}:${addr.port}`);\n } else {\n resolve(`http://${host}:${port}`);\n }\n });\n\n srv.on(\"error\", reject);\n });\n }\n\n async stop(): Promise<void> {\n if (!this.server) {\n throw new Error(\"Server not started\");\n }\n const srv = this.server;\n this.server = null;\n await new Promise<void>((resolve, reject) => {\n srv.close((err) => (err ? reject(err) : resolve()));\n });\n }\n\n // ---- Inspection ----\n\n getRequests(): JournalEntry[] {\n if (!this.journal) return [];\n return this.journal.getAll().filter((e) => e.service === \"vector\");\n }\n\n reset(): this {\n this.collections.clear();\n this.queryHandlers.clear();\n this.requestHandler = this.buildHandler();\n return this;\n }\n\n // ---- Internal ----\n\n private buildHandler() {\n const state: VectorState = {\n collections: this.collections,\n queryHandlers: this.queryHandlers,\n };\n return createVectorRequestHandler(state);\n }\n}\n\n// ---- Helpers ----\n\n/**\n * Classify a vector request by operation and provider based on HTTP method and pathname.\n */\nfunction classifyVectorRequest(\n method: string,\n pathname: string,\n): { operation: string; provider: string } {\n // Pinecone paths\n if (pathname === \"/query\" && method === \"POST\") {\n return { operation: \"query\", provider: \"pinecone\" };\n }\n if (pathname === \"/vectors/upsert\" && method === \"POST\") {\n return { operation: \"upsert\", provider: \"pinecone\" };\n }\n if (pathname === \"/vectors/delete\" && method === \"POST\") {\n return { operation: \"delete\", provider: \"pinecone\" };\n }\n if (pathname === \"/describe-index-stats\" && method === \"GET\") {\n return { operation: \"describe\", provider: \"pinecone\" };\n }\n\n // Qdrant paths\n if (/^\\/collections\\/[^/]+\\/points\\/search$/.test(pathname) && method === \"POST\") {\n return { operation: \"query\", provider: \"qdrant\" };\n }\n if (/^\\/collections\\/[^/]+\\/points$/.test(pathname) && method === \"PUT\") {\n return { operation: \"upsert\", provider: \"qdrant\" };\n }\n if (/^\\/collections\\/[^/]+\\/points\\/delete$/.test(pathname) && method === \"POST\") {\n return { operation: \"delete\", provider: \"qdrant\" };\n }\n\n // ChromaDB paths\n if (/^\\/api\\/v1\\/collections\\/[^/]+\\/query$/.test(pathname) && method === \"POST\") {\n return { operation: \"query\", provider: \"chromadb\" };\n }\n if (/^\\/api\\/v1\\/collections\\/[^/]+\\/add$/.test(pathname) && method === \"POST\") {\n return { operation: \"upsert\", provider: \"chromadb\" };\n }\n if (pathname === \"/api/v1/collections\" && method === \"GET\") {\n return { operation: \"list\", provider: \"chromadb\" };\n }\n if (/^\\/api\\/v1\\/collections\\/[^/]+$/.test(pathname) && method === \"DELETE\") {\n return { operation: \"delete\", provider: \"chromadb\" };\n }\n\n return { operation: \"unknown\", provider: \"unknown\" };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"vector-mock.cjs","names":["readBody","flattenHeaders","isJsonObject","http","createVectorRequestHandler"],"sources":["../src/vector-mock.ts"],"sourcesContent":["import * as http from \"node:http\";\nimport type { Mountable, JournalEntry } from \"./types.js\";\nimport type { Journal } from \"./journal.js\";\nimport type { MetricsRegistry } from \"./metrics.js\";\nimport type {\n VectorMockOptions,\n VectorCollection,\n VectorEntry,\n QueryResult,\n VectorQuery,\n QueryHandler,\n} from \"./vector-types.js\";\nimport { createVectorRequestHandler, type VectorState } from \"./vector-handler.js\";\nimport { flattenHeaders, isJsonObject, readBody } from \"./helpers.js\";\n\nexport class VectorMock implements Mountable {\n private collections: Map<string, VectorCollection> = new Map();\n private queryHandlers: Map<string, QueryHandler> = new Map();\n private server: http.Server | null = null;\n private journal: Journal | null = null;\n private registry: MetricsRegistry | null = null;\n private options: VectorMockOptions;\n private requestHandler: ReturnType<typeof createVectorRequestHandler>;\n\n constructor(options?: VectorMockOptions) {\n this.options = options ?? {};\n this.requestHandler = this.buildHandler();\n }\n\n // ---- Configuration ----\n\n addCollection(name: string, opts: { dimension: number }): this {\n const collection: VectorCollection = {\n name,\n dimension: opts.dimension,\n vectors: new Map(),\n };\n this.collections.set(name, collection);\n this.requestHandler = this.buildHandler();\n return this;\n }\n\n upsert(collection: string, vectors: VectorEntry[]): this {\n let col = this.collections.get(collection);\n if (!col) {\n const dim = vectors.length > 0 ? vectors[0].values.length : 0;\n col = { name: collection, dimension: dim, vectors: new Map() };\n this.collections.set(collection, col);\n }\n for (const v of vectors) {\n col.vectors.set(v.id, v);\n }\n this.requestHandler = this.buildHandler();\n return this;\n }\n\n onQuery(\n collection: string,\n results: QueryResult[] | ((query: VectorQuery) => QueryResult[]),\n ): this {\n this.queryHandlers.set(collection, results);\n this.requestHandler = this.buildHandler();\n return this;\n }\n\n deleteCollection(name: string): this {\n this.collections.delete(name);\n this.queryHandlers.delete(name);\n this.requestHandler = this.buildHandler();\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 // Only consume the request body for methods that carry a body,\n // avoiding double-consumption when the route doesn't match.\n let parsed: Record<string, unknown> = {};\n if (req.method !== \"GET\" && req.method !== \"DELETE\" && req.method !== \"HEAD\") {\n const body = await readBody(req);\n try {\n if (body) parsed = JSON.parse(body);\n } catch (parseErr) {\n const detail = parseErr instanceof Error ? parseErr.message : \"unknown\";\n if (this.journal) {\n this.journal.add({\n method: req.method ?? \"GET\",\n path: req.url ?? \"/\",\n headers: flattenHeaders(req.headers),\n body: null,\n service: \"vector\",\n response: { status: 400, fixture: null },\n });\n }\n res.writeHead(400, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify({ error: `Malformed JSON body: ${detail}` }));\n return true;\n }\n\n // Reject bodies that parsed but are not a JSON object (e.g. `null`)\n // before the route handlers touch fields — `body.ids`, `body.vectors`,\n // `body.points` and friends throw a TypeError on `null` that nothing\n // catches, killing the process rather than answering the request.\n // Arrays and scalars are rejected for the same reason the JSON handlers\n // reject them: every field reads as `undefined` and the handler answers\n // a misleading `200` on a degenerate empty result.\n if (!isJsonObject(parsed)) {\n if (this.journal) {\n this.journal.add({\n method: req.method ?? \"GET\",\n path: req.url ?? \"/\",\n headers: flattenHeaders(req.headers),\n body: null,\n service: \"vector\",\n response: { status: 400, fixture: null },\n });\n }\n res.writeHead(400, { \"Content-Type\": \"application/json\" });\n res.end(\n JSON.stringify({\n error: {\n message: \"Request body must be a JSON object\",\n type: \"invalid_request_error\",\n },\n }),\n );\n return true;\n }\n }\n\n const handled = this.requestHandler(req, res, pathname, parsed);\n\n // Record vector operation metric\n if (handled && this.registry) {\n const { operation, provider } = classifyVectorRequest(req.method ?? \"GET\", pathname);\n this.registry.incrementCounter(\"aimock_vector_requests_total\", { operation, provider });\n }\n\n // Journal the request after the handler completes\n if (handled && this.journal) {\n this.journal.add({\n method: req.method ?? \"GET\",\n path: req.url ?? \"/\",\n headers: flattenHeaders(req.headers),\n body: null,\n service: \"vector\",\n response: { status: res.statusCode, fixture: null },\n });\n }\n\n // When mounted, an unmatched path is answered by the parent server, not\n // here, so journal it once the response is out and only if it really was\n // a 404 — otherwise a path this wrapper declines but the server rewrites\n // and serves would be journaled twice. Keeps mounted mode in step with\n // the standalone 404 journaling below.\n if (!handled && this.journal) {\n const journal = this.journal;\n res.once(\"finish\", () => {\n if (res.statusCode !== 404) return;\n journal.add({\n method: req.method ?? \"GET\",\n path: req.url ?? \"/\",\n headers: flattenHeaders(req.headers),\n body: null,\n service: \"vector\",\n response: { status: 404, fixture: null },\n });\n });\n }\n\n return handled;\n }\n\n health(): { status: string; collections: number } {\n return {\n status: \"ok\",\n collections: this.collections.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(\"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((resolve, reject) => {\n const srv = http.createServer((req, res) => {\n const chunks: Buffer[] = [];\n req.on(\"data\", (chunk: Buffer) => chunks.push(chunk));\n req.on(\"end\", () => {\n const body = Buffer.concat(chunks).toString();\n let parsed: Record<string, unknown> = {};\n try {\n if (body) parsed = JSON.parse(body);\n } catch (parseErr) {\n if (req.method !== \"GET\") {\n const detail = parseErr instanceof Error ? parseErr.message : \"unknown\";\n if (this.journal) {\n this.journal.add({\n method: req.method ?? \"GET\",\n path: req.url ?? \"/\",\n headers: flattenHeaders(req.headers),\n body: null,\n service: \"vector\",\n response: { status: 400, fixture: null },\n });\n }\n res.writeHead(400, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify({ error: `Malformed JSON body: ${detail}` }));\n return;\n }\n }\n\n // Same non-object rejection as the mounted path above — a `null`\n // body otherwise reaches the route handlers and throws an uncaught\n // TypeError that takes the standalone server's process down.\n if (req.method !== \"GET\" && !isJsonObject(parsed)) {\n if (this.journal) {\n this.journal.add({\n method: req.method ?? \"GET\",\n path: req.url ?? \"/\",\n headers: flattenHeaders(req.headers),\n body: null,\n service: \"vector\",\n response: { status: 400, fixture: null },\n });\n }\n res.writeHead(400, { \"Content-Type\": \"application/json\" });\n res.end(\n JSON.stringify({\n error: {\n message: \"Request body must be a JSON object\",\n type: \"invalid_request_error\",\n },\n }),\n );\n return;\n }\n\n const url = new URL(req.url ?? \"/\", `http://${host}`);\n\n const handled = this.requestHandler(req, res, url.pathname, parsed);\n\n if (handled && this.journal) {\n this.journal.add({\n method: req.method ?? \"GET\",\n path: req.url ?? \"/\",\n headers: flattenHeaders(req.headers),\n body: null,\n service: \"vector\",\n response: { status: res.statusCode, fixture: null },\n });\n }\n if (!handled) {\n if (this.journal) {\n this.journal.add({\n method: req.method ?? \"GET\",\n path: req.url ?? \"/\",\n headers: flattenHeaders(req.headers),\n body: null,\n service: \"vector\",\n response: { status: 404, fixture: null },\n });\n }\n res.writeHead(404, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify({ error: \"Not found\" }));\n }\n });\n });\n\n srv.listen(port, host, () => {\n this.server = srv;\n const addr = srv.address();\n if (typeof addr === \"object\" && addr !== null) {\n resolve(`http://${host}:${addr.port}`);\n } else {\n resolve(`http://${host}:${port}`);\n }\n });\n\n srv.on(\"error\", reject);\n });\n }\n\n async stop(): Promise<void> {\n if (!this.server) {\n throw new Error(\"Server not started\");\n }\n const srv = this.server;\n this.server = null;\n await new Promise<void>((resolve, reject) => {\n srv.close((err) => (err ? reject(err) : resolve()));\n });\n }\n\n // ---- Inspection ----\n\n getRequests(): JournalEntry[] {\n if (!this.journal) return [];\n return this.journal.getAll().filter((e) => e.service === \"vector\");\n }\n\n reset(): this {\n this.collections.clear();\n this.queryHandlers.clear();\n this.requestHandler = this.buildHandler();\n return this;\n }\n\n // ---- Internal ----\n\n private buildHandler() {\n const state: VectorState = {\n collections: this.collections,\n queryHandlers: this.queryHandlers,\n };\n return createVectorRequestHandler(state);\n }\n}\n\n// ---- Helpers ----\n\n/**\n * Classify a vector request by operation and provider based on HTTP method and pathname.\n */\nfunction classifyVectorRequest(\n method: string,\n pathname: string,\n): { operation: string; provider: string } {\n // Pinecone paths\n if (pathname === \"/query\" && method === \"POST\") {\n return { operation: \"query\", provider: \"pinecone\" };\n }\n if (pathname === \"/vectors/upsert\" && method === \"POST\") {\n return { operation: \"upsert\", provider: \"pinecone\" };\n }\n if (pathname === \"/vectors/delete\" && method === \"POST\") {\n return { operation: \"delete\", provider: \"pinecone\" };\n }\n if (pathname === \"/describe-index-stats\" && method === \"GET\") {\n return { operation: \"describe\", provider: \"pinecone\" };\n }\n\n // Qdrant paths\n if (/^\\/collections\\/[^/]+\\/points\\/search$/.test(pathname) && method === \"POST\") {\n return { operation: \"query\", provider: \"qdrant\" };\n }\n if (/^\\/collections\\/[^/]+\\/points$/.test(pathname) && method === \"PUT\") {\n return { operation: \"upsert\", provider: \"qdrant\" };\n }\n if (/^\\/collections\\/[^/]+\\/points\\/delete$/.test(pathname) && method === \"POST\") {\n return { operation: \"delete\", provider: \"qdrant\" };\n }\n\n // ChromaDB paths\n if (/^\\/api\\/v1\\/collections\\/[^/]+\\/query$/.test(pathname) && method === \"POST\") {\n return { operation: \"query\", provider: \"chromadb\" };\n }\n if (/^\\/api\\/v1\\/collections\\/[^/]+\\/add$/.test(pathname) && method === \"POST\") {\n return { operation: \"upsert\", provider: \"chromadb\" };\n }\n if (pathname === \"/api/v1/collections\" && method === \"GET\") {\n return { operation: \"list\", provider: \"chromadb\" };\n }\n if (/^\\/api\\/v1\\/collections\\/[^/]+$/.test(pathname) && method === \"DELETE\") {\n return { operation: \"delete\", provider: \"chromadb\" };\n }\n\n return { operation: \"unknown\", provider: \"unknown\" };\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"vector-mock.d.cts","names":[],"sources":["../src/vector-mock.ts"],"sourcesContent":[],"mappings":";;;;;;;cAea,UAAA,YAAsB;;EAAtB,QAAA,aAAW;EAAA,QAAA,MAAA;UASA,OAAA;UAkBc,QAAA;UAgBzB,OAAA;UAAyB,cAAA;aAAgB,CAAA,OAAA,CAAA,EAlC9B,iBAkC8B;eAiBxC,CAAA,IAAA,EAAA,MAAA,EAAA,IAAA,EAAA;IACL,SAAK,EAAA,MAAA;MAET,IAAA;QA8CiB,CAAA,UAAA,EAAA,MAAA,EAAA,OAAA,EAlFgB,WAkFhB,EAAA,CAAA,EAAA,IAAA;SAIE,CAAA,UAAA,EAAA,MAAA,EAAA,OAAA,EAtEX,WAsEW,EAAA,GAAA,CAAA,CAAA,KAAA,EAtEc,WAsEd,EAAA,GAtE8B,WAsE9B,EAAA,CAAA,CAAA,EAAA,IAAA;kBAMP,CAAA,IAAA,EAAA,MAAA,CAAA,EAAA,IAAA;eA6DD,CAAA,GAAA,EAxHP,MAAA,CAAK,eAwHE,EAAA,GAAA,EAvHP,MAAA,CAAK,cAuHE,EAAA,QAAA,EAAA,MAAA,CAAA,EArHX,OAqHW,CAAA,OAAA,CAAA;QAaC,CAAA,CAAA,EAAA;IAjMkB,MAAA,EAAA,MAAA;IAAS,WAAA,EAAA,MAAA;;sBA6GtB;wBAIE;WAMP;UA6DD;iBAaC"}
1
+ {"version":3,"file":"vector-mock.d.cts","names":[],"sources":["../src/vector-mock.ts"],"sourcesContent":[],"mappings":";;;;;;;cAea,UAAA,YAAsB;;EAAtB,QAAA,aAAW;EAAA,QAAA,MAAA;UASA,OAAA;UAkBc,QAAA;UAgBzB,OAAA;UAAyB,cAAA;aAAgB,CAAA,OAAA,CAAA,EAlC9B,iBAkC8B;eAiBxC,CAAA,IAAA,EAAA,MAAA,EAAA,IAAA,EAAA;IACL,SAAK,EAAA,MAAA;MAET,IAAA;QA0GiB,CAAA,UAAA,EAAA,MAAA,EAAA,OAAA,EA9IgB,WA8IhB,EAAA,CAAA,EAAA,IAAA;SAIE,CAAA,UAAA,EAAA,MAAA,EAAA,OAAA,EAlIX,WAkIW,EAAA,GAAA,CAAA,CAAA,KAAA,EAlIc,WAkId,EAAA,GAlI8B,WAkI9B,EAAA,CAAA,CAAA,EAAA,IAAA;kBAMP,CAAA,IAAA,EAAA,MAAA,CAAA,EAAA,IAAA;eA2GD,CAAA,GAAA,EAlOP,MAAA,CAAK,eAkOE,EAAA,GAAA,EAjOP,MAAA,CAAK,cAiOE,EAAA,QAAA,EAAA,MAAA,CAAA,EA/NX,OA+NW,CAAA,OAAA,CAAA;QAaC,CAAA,CAAA,EAAA;IA3SkB,MAAA,EAAA,MAAA;IAAS,WAAA,EAAA,MAAA;;sBAyKtB;wBAIE;WAMP;UA2GD;iBAaC"}
@@ -1 +1 @@
1
- {"version":3,"file":"vector-mock.d.ts","names":[],"sources":["../src/vector-mock.ts"],"sourcesContent":[],"mappings":";;;;;;;cAea,UAAA,YAAsB;;EAAtB,QAAA,aAAW;EAAA,QAAA,MAAA;UASA,OAAA;UAkBc,QAAA;UAgBzB,OAAA;UAAyB,cAAA;aAAgB,CAAA,OAAA,CAAA,EAlC9B,iBAkC8B;eAiBxC,CAAA,IAAA,EAAA,MAAA,EAAA,IAAA,EAAA;IACL,SAAK,EAAA,MAAA;MAET,IAAA;QA8CiB,CAAA,UAAA,EAAA,MAAA,EAAA,OAAA,EAlFgB,WAkFhB,EAAA,CAAA,EAAA,IAAA;SAIE,CAAA,UAAA,EAAA,MAAA,EAAA,OAAA,EAtEX,WAsEW,EAAA,GAAA,CAAA,CAAA,KAAA,EAtEc,WAsEd,EAAA,GAtE8B,WAsE9B,EAAA,CAAA,CAAA,EAAA,IAAA;kBAMP,CAAA,IAAA,EAAA,MAAA,CAAA,EAAA,IAAA;eA6DD,CAAA,GAAA,EAxHP,MAAA,CAAK,eAwHE,EAAA,GAAA,EAvHP,MAAA,CAAK,cAuHE,EAAA,QAAA,EAAA,MAAA,CAAA,EArHX,OAqHW,CAAA,OAAA,CAAA;QAaC,CAAA,CAAA,EAAA;IAjMkB,MAAA,EAAA,MAAA;IAAS,WAAA,EAAA,MAAA;;sBA6GtB;wBAIE;WAMP;UA6DD;iBAaC"}
1
+ {"version":3,"file":"vector-mock.d.ts","names":[],"sources":["../src/vector-mock.ts"],"sourcesContent":[],"mappings":";;;;;;;cAea,UAAA,YAAsB;;EAAtB,QAAA,aAAW;EAAA,QAAA,MAAA;UASA,OAAA;UAkBc,QAAA;UAgBzB,OAAA;UAAyB,cAAA;aAAgB,CAAA,OAAA,CAAA,EAlC9B,iBAkC8B;eAiBxC,CAAA,IAAA,EAAA,MAAA,EAAA,IAAA,EAAA;IACL,SAAK,EAAA,MAAA;MAET,IAAA;QA0GiB,CAAA,UAAA,EAAA,MAAA,EAAA,OAAA,EA9IgB,WA8IhB,EAAA,CAAA,EAAA,IAAA;SAIE,CAAA,UAAA,EAAA,MAAA,EAAA,OAAA,EAlIX,WAkIW,EAAA,GAAA,CAAA,CAAA,KAAA,EAlIc,WAkId,EAAA,GAlI8B,WAkI9B,EAAA,CAAA,CAAA,EAAA,IAAA;kBAMP,CAAA,IAAA,EAAA,MAAA,CAAA,EAAA,IAAA;eA2GD,CAAA,GAAA,EAlOP,MAAA,CAAK,eAkOE,EAAA,GAAA,EAjOP,MAAA,CAAK,cAiOE,EAAA,QAAA,EAAA,MAAA,CAAA,EA/NX,OA+NW,CAAA,OAAA,CAAA;QAaC,CAAA,CAAA,EAAA;IA3SkB,MAAA,EAAA,MAAA;IAAS,WAAA,EAAA,MAAA;;sBAyKtB;wBAIE;WAMP;UA2GD;iBAaC"}
@@ -1,4 +1,4 @@
1
- import { flattenHeaders, readBody } from "./helpers.js";
1
+ import { flattenHeaders, isJsonObject, readBody } from "./helpers.js";
2
2
  import { createVectorRequestHandler } from "./vector-handler.js";
3
3
  import * as http$1 from "node:http";
4
4
 
@@ -58,10 +58,40 @@ var VectorMock = class {
58
58
  if (body) parsed = JSON.parse(body);
59
59
  } catch (parseErr) {
60
60
  const detail = parseErr instanceof Error ? parseErr.message : "unknown";
61
+ if (this.journal) this.journal.add({
62
+ method: req.method ?? "GET",
63
+ path: req.url ?? "/",
64
+ headers: flattenHeaders(req.headers),
65
+ body: null,
66
+ service: "vector",
67
+ response: {
68
+ status: 400,
69
+ fixture: null
70
+ }
71
+ });
61
72
  res.writeHead(400, { "Content-Type": "application/json" });
62
73
  res.end(JSON.stringify({ error: `Malformed JSON body: ${detail}` }));
63
74
  return true;
64
75
  }
76
+ if (!isJsonObject(parsed)) {
77
+ if (this.journal) this.journal.add({
78
+ method: req.method ?? "GET",
79
+ path: req.url ?? "/",
80
+ headers: flattenHeaders(req.headers),
81
+ body: null,
82
+ service: "vector",
83
+ response: {
84
+ status: 400,
85
+ fixture: null
86
+ }
87
+ });
88
+ res.writeHead(400, { "Content-Type": "application/json" });
89
+ res.end(JSON.stringify({ error: {
90
+ message: "Request body must be a JSON object",
91
+ type: "invalid_request_error"
92
+ } }));
93
+ return true;
94
+ }
65
95
  }
66
96
  const handled = this.requestHandler(req, res, pathname, parsed);
67
97
  if (handled && this.registry) {
@@ -82,6 +112,23 @@ var VectorMock = class {
82
112
  fixture: null
83
113
  }
84
114
  });
115
+ if (!handled && this.journal) {
116
+ const journal = this.journal;
117
+ res.once("finish", () => {
118
+ if (res.statusCode !== 404) return;
119
+ journal.add({
120
+ method: req.method ?? "GET",
121
+ path: req.url ?? "/",
122
+ headers: flattenHeaders(req.headers),
123
+ body: null,
124
+ service: "vector",
125
+ response: {
126
+ status: 404,
127
+ fixture: null
128
+ }
129
+ });
130
+ });
131
+ }
85
132
  return handled;
86
133
  }
87
134
  health() {
@@ -112,11 +159,41 @@ var VectorMock = class {
112
159
  } catch (parseErr) {
113
160
  if (req.method !== "GET") {
114
161
  const detail = parseErr instanceof Error ? parseErr.message : "unknown";
162
+ if (this.journal) this.journal.add({
163
+ method: req.method ?? "GET",
164
+ path: req.url ?? "/",
165
+ headers: flattenHeaders(req.headers),
166
+ body: null,
167
+ service: "vector",
168
+ response: {
169
+ status: 400,
170
+ fixture: null
171
+ }
172
+ });
115
173
  res.writeHead(400, { "Content-Type": "application/json" });
116
174
  res.end(JSON.stringify({ error: `Malformed JSON body: ${detail}` }));
117
175
  return;
118
176
  }
119
177
  }
178
+ if (req.method !== "GET" && !isJsonObject(parsed)) {
179
+ if (this.journal) this.journal.add({
180
+ method: req.method ?? "GET",
181
+ path: req.url ?? "/",
182
+ headers: flattenHeaders(req.headers),
183
+ body: null,
184
+ service: "vector",
185
+ response: {
186
+ status: 400,
187
+ fixture: null
188
+ }
189
+ });
190
+ res.writeHead(400, { "Content-Type": "application/json" });
191
+ res.end(JSON.stringify({ error: {
192
+ message: "Request body must be a JSON object",
193
+ type: "invalid_request_error"
194
+ } }));
195
+ return;
196
+ }
120
197
  const url = new URL(req.url ?? "/", `http://${host}`);
121
198
  const handled = this.requestHandler(req, res, url.pathname, parsed);
122
199
  if (handled && this.journal) this.journal.add({
@@ -131,6 +208,17 @@ var VectorMock = class {
131
208
  }
132
209
  });
133
210
  if (!handled) {
211
+ if (this.journal) this.journal.add({
212
+ method: req.method ?? "GET",
213
+ path: req.url ?? "/",
214
+ headers: flattenHeaders(req.headers),
215
+ body: null,
216
+ service: "vector",
217
+ response: {
218
+ status: 404,
219
+ fixture: null
220
+ }
221
+ });
134
222
  res.writeHead(404, { "Content-Type": "application/json" });
135
223
  res.end(JSON.stringify({ error: "Not found" }));
136
224
  }
@@ -1 +1 @@
1
- {"version":3,"file":"vector-mock.js","names":["http"],"sources":["../src/vector-mock.ts"],"sourcesContent":["import * as http from \"node:http\";\nimport type { Mountable, JournalEntry } from \"./types.js\";\nimport type { Journal } from \"./journal.js\";\nimport type { MetricsRegistry } from \"./metrics.js\";\nimport type {\n VectorMockOptions,\n VectorCollection,\n VectorEntry,\n QueryResult,\n VectorQuery,\n QueryHandler,\n} from \"./vector-types.js\";\nimport { createVectorRequestHandler, type VectorState } from \"./vector-handler.js\";\nimport { flattenHeaders, readBody } from \"./helpers.js\";\n\nexport class VectorMock implements Mountable {\n private collections: Map<string, VectorCollection> = new Map();\n private queryHandlers: Map<string, QueryHandler> = new Map();\n private server: http.Server | null = null;\n private journal: Journal | null = null;\n private registry: MetricsRegistry | null = null;\n private options: VectorMockOptions;\n private requestHandler: ReturnType<typeof createVectorRequestHandler>;\n\n constructor(options?: VectorMockOptions) {\n this.options = options ?? {};\n this.requestHandler = this.buildHandler();\n }\n\n // ---- Configuration ----\n\n addCollection(name: string, opts: { dimension: number }): this {\n const collection: VectorCollection = {\n name,\n dimension: opts.dimension,\n vectors: new Map(),\n };\n this.collections.set(name, collection);\n this.requestHandler = this.buildHandler();\n return this;\n }\n\n upsert(collection: string, vectors: VectorEntry[]): this {\n let col = this.collections.get(collection);\n if (!col) {\n const dim = vectors.length > 0 ? vectors[0].values.length : 0;\n col = { name: collection, dimension: dim, vectors: new Map() };\n this.collections.set(collection, col);\n }\n for (const v of vectors) {\n col.vectors.set(v.id, v);\n }\n this.requestHandler = this.buildHandler();\n return this;\n }\n\n onQuery(\n collection: string,\n results: QueryResult[] | ((query: VectorQuery) => QueryResult[]),\n ): this {\n this.queryHandlers.set(collection, results);\n this.requestHandler = this.buildHandler();\n return this;\n }\n\n deleteCollection(name: string): this {\n this.collections.delete(name);\n this.queryHandlers.delete(name);\n this.requestHandler = this.buildHandler();\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 // Only consume the request body for methods that carry a body,\n // avoiding double-consumption when the route doesn't match.\n let parsed: Record<string, unknown> = {};\n if (req.method !== \"GET\" && req.method !== \"DELETE\" && req.method !== \"HEAD\") {\n const body = await readBody(req);\n try {\n if (body) parsed = JSON.parse(body);\n } catch (parseErr) {\n const detail = parseErr instanceof Error ? parseErr.message : \"unknown\";\n res.writeHead(400, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify({ error: `Malformed JSON body: ${detail}` }));\n return true;\n }\n }\n\n const handled = this.requestHandler(req, res, pathname, parsed);\n\n // Record vector operation metric\n if (handled && this.registry) {\n const { operation, provider } = classifyVectorRequest(req.method ?? \"GET\", pathname);\n this.registry.incrementCounter(\"aimock_vector_requests_total\", { operation, provider });\n }\n\n // Journal the request after the handler completes\n if (handled && this.journal) {\n this.journal.add({\n method: req.method ?? \"GET\",\n path: req.url ?? \"/\",\n headers: flattenHeaders(req.headers),\n body: null,\n service: \"vector\",\n response: { status: res.statusCode, fixture: null },\n });\n }\n\n return handled;\n }\n\n health(): { status: string; collections: number } {\n return {\n status: \"ok\",\n collections: this.collections.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(\"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((resolve, reject) => {\n const srv = http.createServer((req, res) => {\n const chunks: Buffer[] = [];\n req.on(\"data\", (chunk: Buffer) => chunks.push(chunk));\n req.on(\"end\", () => {\n const body = Buffer.concat(chunks).toString();\n let parsed: Record<string, unknown> = {};\n try {\n if (body) parsed = JSON.parse(body);\n } catch (parseErr) {\n if (req.method !== \"GET\") {\n const detail = parseErr instanceof Error ? parseErr.message : \"unknown\";\n res.writeHead(400, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify({ error: `Malformed JSON body: ${detail}` }));\n return;\n }\n }\n\n const url = new URL(req.url ?? \"/\", `http://${host}`);\n\n const handled = this.requestHandler(req, res, url.pathname, parsed);\n\n if (handled && this.journal) {\n this.journal.add({\n method: req.method ?? \"GET\",\n path: req.url ?? \"/\",\n headers: flattenHeaders(req.headers),\n body: null,\n service: \"vector\",\n response: { status: res.statusCode, fixture: null },\n });\n }\n if (!handled) {\n res.writeHead(404, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify({ error: \"Not found\" }));\n }\n });\n });\n\n srv.listen(port, host, () => {\n this.server = srv;\n const addr = srv.address();\n if (typeof addr === \"object\" && addr !== null) {\n resolve(`http://${host}:${addr.port}`);\n } else {\n resolve(`http://${host}:${port}`);\n }\n });\n\n srv.on(\"error\", reject);\n });\n }\n\n async stop(): Promise<void> {\n if (!this.server) {\n throw new Error(\"Server not started\");\n }\n const srv = this.server;\n this.server = null;\n await new Promise<void>((resolve, reject) => {\n srv.close((err) => (err ? reject(err) : resolve()));\n });\n }\n\n // ---- Inspection ----\n\n getRequests(): JournalEntry[] {\n if (!this.journal) return [];\n return this.journal.getAll().filter((e) => e.service === \"vector\");\n }\n\n reset(): this {\n this.collections.clear();\n this.queryHandlers.clear();\n this.requestHandler = this.buildHandler();\n return this;\n }\n\n // ---- Internal ----\n\n private buildHandler() {\n const state: VectorState = {\n collections: this.collections,\n queryHandlers: this.queryHandlers,\n };\n return createVectorRequestHandler(state);\n }\n}\n\n// ---- Helpers ----\n\n/**\n * Classify a vector request by operation and provider based on HTTP method and pathname.\n */\nfunction classifyVectorRequest(\n method: string,\n pathname: string,\n): { operation: string; provider: string } {\n // Pinecone paths\n if (pathname === \"/query\" && method === \"POST\") {\n return { operation: \"query\", provider: \"pinecone\" };\n }\n if (pathname === \"/vectors/upsert\" && method === \"POST\") {\n return { operation: \"upsert\", provider: \"pinecone\" };\n }\n if (pathname === \"/vectors/delete\" && method === \"POST\") {\n return { operation: \"delete\", provider: \"pinecone\" };\n }\n if (pathname === \"/describe-index-stats\" && method === \"GET\") {\n return { operation: \"describe\", provider: \"pinecone\" };\n }\n\n // Qdrant paths\n if (/^\\/collections\\/[^/]+\\/points\\/search$/.test(pathname) && method === \"POST\") {\n return { operation: \"query\", provider: \"qdrant\" };\n }\n if (/^\\/collections\\/[^/]+\\/points$/.test(pathname) && method === \"PUT\") {\n return { operation: \"upsert\", provider: \"qdrant\" };\n }\n if (/^\\/collections\\/[^/]+\\/points\\/delete$/.test(pathname) && method === \"POST\") {\n return { operation: \"delete\", provider: \"qdrant\" };\n }\n\n // ChromaDB paths\n if (/^\\/api\\/v1\\/collections\\/[^/]+\\/query$/.test(pathname) && method === \"POST\") {\n return { operation: \"query\", provider: \"chromadb\" };\n }\n if (/^\\/api\\/v1\\/collections\\/[^/]+\\/add$/.test(pathname) && method === \"POST\") {\n return { operation: \"upsert\", provider: \"chromadb\" };\n }\n if (pathname === \"/api/v1/collections\" && method === \"GET\") {\n return { operation: \"list\", provider: \"chromadb\" };\n }\n if (/^\\/api\\/v1\\/collections\\/[^/]+$/.test(pathname) && method === \"DELETE\") {\n return { operation: \"delete\", provider: \"chromadb\" };\n }\n\n return { operation: \"unknown\", provider: \"unknown\" };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"vector-mock.js","names":["http"],"sources":["../src/vector-mock.ts"],"sourcesContent":["import * as http from \"node:http\";\nimport type { Mountable, JournalEntry } from \"./types.js\";\nimport type { Journal } from \"./journal.js\";\nimport type { MetricsRegistry } from \"./metrics.js\";\nimport type {\n VectorMockOptions,\n VectorCollection,\n VectorEntry,\n QueryResult,\n VectorQuery,\n QueryHandler,\n} from \"./vector-types.js\";\nimport { createVectorRequestHandler, type VectorState } from \"./vector-handler.js\";\nimport { flattenHeaders, isJsonObject, readBody } from \"./helpers.js\";\n\nexport class VectorMock implements Mountable {\n private collections: Map<string, VectorCollection> = new Map();\n private queryHandlers: Map<string, QueryHandler> = new Map();\n private server: http.Server | null = null;\n private journal: Journal | null = null;\n private registry: MetricsRegistry | null = null;\n private options: VectorMockOptions;\n private requestHandler: ReturnType<typeof createVectorRequestHandler>;\n\n constructor(options?: VectorMockOptions) {\n this.options = options ?? {};\n this.requestHandler = this.buildHandler();\n }\n\n // ---- Configuration ----\n\n addCollection(name: string, opts: { dimension: number }): this {\n const collection: VectorCollection = {\n name,\n dimension: opts.dimension,\n vectors: new Map(),\n };\n this.collections.set(name, collection);\n this.requestHandler = this.buildHandler();\n return this;\n }\n\n upsert(collection: string, vectors: VectorEntry[]): this {\n let col = this.collections.get(collection);\n if (!col) {\n const dim = vectors.length > 0 ? vectors[0].values.length : 0;\n col = { name: collection, dimension: dim, vectors: new Map() };\n this.collections.set(collection, col);\n }\n for (const v of vectors) {\n col.vectors.set(v.id, v);\n }\n this.requestHandler = this.buildHandler();\n return this;\n }\n\n onQuery(\n collection: string,\n results: QueryResult[] | ((query: VectorQuery) => QueryResult[]),\n ): this {\n this.queryHandlers.set(collection, results);\n this.requestHandler = this.buildHandler();\n return this;\n }\n\n deleteCollection(name: string): this {\n this.collections.delete(name);\n this.queryHandlers.delete(name);\n this.requestHandler = this.buildHandler();\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 // Only consume the request body for methods that carry a body,\n // avoiding double-consumption when the route doesn't match.\n let parsed: Record<string, unknown> = {};\n if (req.method !== \"GET\" && req.method !== \"DELETE\" && req.method !== \"HEAD\") {\n const body = await readBody(req);\n try {\n if (body) parsed = JSON.parse(body);\n } catch (parseErr) {\n const detail = parseErr instanceof Error ? parseErr.message : \"unknown\";\n if (this.journal) {\n this.journal.add({\n method: req.method ?? \"GET\",\n path: req.url ?? \"/\",\n headers: flattenHeaders(req.headers),\n body: null,\n service: \"vector\",\n response: { status: 400, fixture: null },\n });\n }\n res.writeHead(400, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify({ error: `Malformed JSON body: ${detail}` }));\n return true;\n }\n\n // Reject bodies that parsed but are not a JSON object (e.g. `null`)\n // before the route handlers touch fields — `body.ids`, `body.vectors`,\n // `body.points` and friends throw a TypeError on `null` that nothing\n // catches, killing the process rather than answering the request.\n // Arrays and scalars are rejected for the same reason the JSON handlers\n // reject them: every field reads as `undefined` and the handler answers\n // a misleading `200` on a degenerate empty result.\n if (!isJsonObject(parsed)) {\n if (this.journal) {\n this.journal.add({\n method: req.method ?? \"GET\",\n path: req.url ?? \"/\",\n headers: flattenHeaders(req.headers),\n body: null,\n service: \"vector\",\n response: { status: 400, fixture: null },\n });\n }\n res.writeHead(400, { \"Content-Type\": \"application/json\" });\n res.end(\n JSON.stringify({\n error: {\n message: \"Request body must be a JSON object\",\n type: \"invalid_request_error\",\n },\n }),\n );\n return true;\n }\n }\n\n const handled = this.requestHandler(req, res, pathname, parsed);\n\n // Record vector operation metric\n if (handled && this.registry) {\n const { operation, provider } = classifyVectorRequest(req.method ?? \"GET\", pathname);\n this.registry.incrementCounter(\"aimock_vector_requests_total\", { operation, provider });\n }\n\n // Journal the request after the handler completes\n if (handled && this.journal) {\n this.journal.add({\n method: req.method ?? \"GET\",\n path: req.url ?? \"/\",\n headers: flattenHeaders(req.headers),\n body: null,\n service: \"vector\",\n response: { status: res.statusCode, fixture: null },\n });\n }\n\n // When mounted, an unmatched path is answered by the parent server, not\n // here, so journal it once the response is out and only if it really was\n // a 404 — otherwise a path this wrapper declines but the server rewrites\n // and serves would be journaled twice. Keeps mounted mode in step with\n // the standalone 404 journaling below.\n if (!handled && this.journal) {\n const journal = this.journal;\n res.once(\"finish\", () => {\n if (res.statusCode !== 404) return;\n journal.add({\n method: req.method ?? \"GET\",\n path: req.url ?? \"/\",\n headers: flattenHeaders(req.headers),\n body: null,\n service: \"vector\",\n response: { status: 404, fixture: null },\n });\n });\n }\n\n return handled;\n }\n\n health(): { status: string; collections: number } {\n return {\n status: \"ok\",\n collections: this.collections.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(\"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((resolve, reject) => {\n const srv = http.createServer((req, res) => {\n const chunks: Buffer[] = [];\n req.on(\"data\", (chunk: Buffer) => chunks.push(chunk));\n req.on(\"end\", () => {\n const body = Buffer.concat(chunks).toString();\n let parsed: Record<string, unknown> = {};\n try {\n if (body) parsed = JSON.parse(body);\n } catch (parseErr) {\n if (req.method !== \"GET\") {\n const detail = parseErr instanceof Error ? parseErr.message : \"unknown\";\n if (this.journal) {\n this.journal.add({\n method: req.method ?? \"GET\",\n path: req.url ?? \"/\",\n headers: flattenHeaders(req.headers),\n body: null,\n service: \"vector\",\n response: { status: 400, fixture: null },\n });\n }\n res.writeHead(400, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify({ error: `Malformed JSON body: ${detail}` }));\n return;\n }\n }\n\n // Same non-object rejection as the mounted path above — a `null`\n // body otherwise reaches the route handlers and throws an uncaught\n // TypeError that takes the standalone server's process down.\n if (req.method !== \"GET\" && !isJsonObject(parsed)) {\n if (this.journal) {\n this.journal.add({\n method: req.method ?? \"GET\",\n path: req.url ?? \"/\",\n headers: flattenHeaders(req.headers),\n body: null,\n service: \"vector\",\n response: { status: 400, fixture: null },\n });\n }\n res.writeHead(400, { \"Content-Type\": \"application/json\" });\n res.end(\n JSON.stringify({\n error: {\n message: \"Request body must be a JSON object\",\n type: \"invalid_request_error\",\n },\n }),\n );\n return;\n }\n\n const url = new URL(req.url ?? \"/\", `http://${host}`);\n\n const handled = this.requestHandler(req, res, url.pathname, parsed);\n\n if (handled && this.journal) {\n this.journal.add({\n method: req.method ?? \"GET\",\n path: req.url ?? \"/\",\n headers: flattenHeaders(req.headers),\n body: null,\n service: \"vector\",\n response: { status: res.statusCode, fixture: null },\n });\n }\n if (!handled) {\n if (this.journal) {\n this.journal.add({\n method: req.method ?? \"GET\",\n path: req.url ?? \"/\",\n headers: flattenHeaders(req.headers),\n body: null,\n service: \"vector\",\n response: { status: 404, fixture: null },\n });\n }\n res.writeHead(404, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify({ error: \"Not found\" }));\n }\n });\n });\n\n srv.listen(port, host, () => {\n this.server = srv;\n const addr = srv.address();\n if (typeof addr === \"object\" && addr !== null) {\n resolve(`http://${host}:${addr.port}`);\n } else {\n resolve(`http://${host}:${port}`);\n }\n });\n\n srv.on(\"error\", reject);\n });\n }\n\n async stop(): Promise<void> {\n if (!this.server) {\n throw new Error(\"Server not started\");\n }\n const srv = this.server;\n this.server = null;\n await new Promise<void>((resolve, reject) => {\n srv.close((err) => (err ? reject(err) : resolve()));\n });\n }\n\n // ---- Inspection ----\n\n getRequests(): JournalEntry[] {\n if (!this.journal) return [];\n return this.journal.getAll().filter((e) => e.service === \"vector\");\n }\n\n reset(): this {\n this.collections.clear();\n this.queryHandlers.clear();\n this.requestHandler = this.buildHandler();\n return this;\n }\n\n // ---- Internal ----\n\n private buildHandler() {\n const state: VectorState = {\n collections: this.collections,\n queryHandlers: this.queryHandlers,\n };\n return createVectorRequestHandler(state);\n }\n}\n\n// ---- Helpers ----\n\n/**\n * Classify a vector request by operation and provider based on HTTP method and pathname.\n */\nfunction classifyVectorRequest(\n method: string,\n pathname: string,\n): { operation: string; provider: string } {\n // Pinecone paths\n if (pathname === \"/query\" && method === \"POST\") {\n return { operation: \"query\", provider: \"pinecone\" };\n }\n if (pathname === \"/vectors/upsert\" && method === \"POST\") {\n return { operation: \"upsert\", provider: \"pinecone\" };\n }\n if (pathname === \"/vectors/delete\" && method === \"POST\") {\n return { operation: \"delete\", provider: \"pinecone\" };\n }\n if (pathname === \"/describe-index-stats\" && method === \"GET\") {\n return { operation: \"describe\", provider: \"pinecone\" };\n }\n\n // Qdrant paths\n if (/^\\/collections\\/[^/]+\\/points\\/search$/.test(pathname) && method === \"POST\") {\n return { operation: \"query\", provider: \"qdrant\" };\n }\n if (/^\\/collections\\/[^/]+\\/points$/.test(pathname) && method === \"PUT\") {\n return { operation: \"upsert\", provider: \"qdrant\" };\n }\n if (/^\\/collections\\/[^/]+\\/points\\/delete$/.test(pathname) && method === \"POST\") {\n return { operation: \"delete\", provider: \"qdrant\" };\n }\n\n // ChromaDB paths\n if (/^\\/api\\/v1\\/collections\\/[^/]+\\/query$/.test(pathname) && method === \"POST\") {\n return { operation: \"query\", provider: \"chromadb\" };\n }\n if (/^\\/api\\/v1\\/collections\\/[^/]+\\/add$/.test(pathname) && method === \"POST\") {\n return { operation: \"upsert\", provider: \"chromadb\" };\n }\n if (pathname === \"/api/v1/collections\" && method === \"GET\") {\n return { operation: \"list\", provider: \"chromadb\" };\n }\n if (/^\\/api\\/v1\\/collections\\/[^/]+$/.test(pathname) && method === \"DELETE\") {\n return { operation: \"delete\", provider: \"chromadb\" };\n }\n\n return { operation: \"unknown\", provider: \"unknown\" };\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"vector-types.d.cts","names":[],"sources":["../src/vector-types.ts"],"sourcesContent":[],"mappings":";UAAiB,iBAAA;EAAA,IAAA,CAAA,EAAA,MAAA;EAKA,IAAA,CAAA,EAAA,MAAA;;AAGM,UAHN,gBAAA,CAGM;MAAZ,EAAA,MAAA;EAAG,SAAA,EAAA,MAAA;EAGG,OAAA,EAHN,GAGM,CAAA,MAAW,EAHL,WAMV,CAAM;AAGnB;AAOiB,UAbA,WAAA,CAaW;EAOhB,EAAA,EAAA,MAAA;EAAY,MAAA,EAAA,MAAA,EAAA;UAAG,CAAA,EAjBd,MAiBc,CAAA,MAAA,EAAA,OAAA,CAAA;;AAAyC,UAdnD,WAAA,CAcmD;EAAW,EAAA,EAAA,MAAA;;aAXlE;;;UAII,WAAA;;;;;;KAOL,YAAA,GAAe,yBAAyB,gBAAgB"}
1
+ {"version":3,"file":"vector-types.d.cts","names":[],"sources":["../src/vector-types.ts"],"sourcesContent":[],"mappings":";UAAiB,iBAAA;EAAA,IAAA,CAAA,EAAA,MAAA;EAKA,IAAA,CAAA,EAAA,MAAA;;AAGM,UAHN,gBAAA,CAGM;MAAZ,EAAA,MAAA;EAAG,SAAA,EAAA,MAAA;EAGG,OAAA,EAHN,GAGM,CAAA,MAAW,EAHL,WAMJ,CAAA;AAGnB;AAOiB,UAbA,WAAA,CAaW;EAOhB,EAAA,EAAA,MAAA;EAAY,MAAA,EAAA,MAAA,EAAA;UAAG,CAAA,EAjBd,MAiBc,CAAA,MAAA,EAAA,OAAA,CAAA;;AAAyC,UAdnD,WAAA,CAcmD;EAAW,EAAA,EAAA,MAAA;;aAXlE;;;UAII,WAAA;;;;;;KAOL,YAAA,GAAe,yBAAyB,gBAAgB"}
@@ -1 +1 @@
1
- {"version":3,"file":"vector-types.d.ts","names":[],"sources":["../src/vector-types.ts"],"sourcesContent":[],"mappings":";UAAiB,iBAAA;EAAA,IAAA,CAAA,EAAA,MAAA;EAKA,IAAA,CAAA,EAAA,MAAA;;AAGM,UAHN,gBAAA,CAGM;MAAZ,EAAA,MAAA;EAAG,SAAA,EAAA,MAAA;EAGG,OAAA,EAHN,GAGM,CAAA,MAAW,EAHL,WAMJ,CAAA;AAGnB;AAOiB,UAbA,WAAA,CAaW;EAOhB,EAAA,EAAA,MAAA;EAAY,MAAA,EAAA,MAAA,EAAA;UAAG,CAAA,EAjBd,MAiBc,CAAA,MAAA,EAAA,OAAA,CAAA;;AAAyC,UAdnD,WAAA,CAcmD;EAAW,EAAA,EAAA,MAAA;;aAXlE;;;UAII,WAAA;;;;;;KAOL,YAAA,GAAe,yBAAyB,gBAAgB"}
1
+ {"version":3,"file":"vector-types.d.ts","names":[],"sources":["../src/vector-types.ts"],"sourcesContent":[],"mappings":";UAAiB,iBAAA;EAAA,IAAA,CAAA,EAAA,MAAA;EAKA,IAAA,CAAA,EAAA,MAAA;;AAGM,UAHN,gBAAA,CAGM;MAAZ,EAAA,MAAA;EAAG,SAAA,EAAA,MAAA;EAGG,OAAA,EAHN,GAGM,CAAA,MAAW,EAHL,WAMV,CAAM;AAGnB;AAOiB,UAbA,WAAA,CAaW;EAOhB,EAAA,EAAA,MAAA;EAAY,MAAA,EAAA,MAAA,EAAA;UAAG,CAAA,EAjBd,MAiBc,CAAA,MAAA,EAAA,OAAA,CAAA;;AAAyC,UAdnD,WAAA,CAcmD;EAAW,EAAA,EAAA,MAAA;;aAXlE;;;UAII,WAAA;;;;;;KAOL,YAAA,GAAe,yBAAyB,gBAAgB"}
@@ -192,7 +192,7 @@ async function handleVeoVideoCreate(req, res, raw, model, fixtures, journal, def
192
192
  journal.incrementFixtureMatchCount(fixture, fixtures, testId);
193
193
  defaults.logger.debug(`Fixture matched: ${JSON.stringify(fixture.match).slice(0, 120)}`);
194
194
  } else defaults.logger.debug(`No fixture matched for Veo request (model=${model}, msg="${prompt.slice(0, 80)}")`);
195
- if (require_chaos.applyChaos(res, fixture, defaults.chaos, req.headers, journal, {
195
+ if (require_chaos.applyChaos(res, fixture, defaults.chaos, req.headers, req.url, journal, {
196
196
  method,
197
197
  path,
198
198
  headers: require_helpers.flattenHeaders(req.headers),
@@ -312,7 +312,7 @@ async function handleVeoVideoStatus(req, res, operationName, fixtures, journal,
312
312
  setCorsHeaders(res);
313
313
  const path = req.url ?? `/v1beta/${operationName}`;
314
314
  const method = req.method ?? "GET";
315
- if (require_chaos.applyChaos(res, null, defaults.chaos, req.headers, journal, {
315
+ if (require_chaos.applyChaos(res, null, defaults.chaos, req.headers, req.url, journal, {
316
316
  method,
317
317
  path,
318
318
  headers: require_helpers.flattenHeaders(req.headers),