@copilotkit/aimock 1.7.0 → 1.9.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 (134) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/.claude-plugin/plugin.json +1 -1
  3. package/README.md +3 -1
  4. package/dist/bedrock-converse.cjs +13 -8
  5. package/dist/bedrock-converse.cjs.map +1 -1
  6. package/dist/bedrock-converse.d.cts.map +1 -1
  7. package/dist/bedrock-converse.d.ts.map +1 -1
  8. package/dist/bedrock-converse.js +14 -9
  9. package/dist/bedrock-converse.js.map +1 -1
  10. package/dist/bedrock.cjs +51 -15
  11. package/dist/bedrock.cjs.map +1 -1
  12. package/dist/bedrock.d.cts.map +1 -1
  13. package/dist/bedrock.d.ts.map +1 -1
  14. package/dist/bedrock.js +52 -16
  15. package/dist/bedrock.js.map +1 -1
  16. package/dist/cohere.cjs +3 -2
  17. package/dist/cohere.cjs.map +1 -1
  18. package/dist/cohere.d.cts.map +1 -1
  19. package/dist/cohere.d.ts.map +1 -1
  20. package/dist/cohere.js +4 -3
  21. package/dist/cohere.js.map +1 -1
  22. package/dist/embeddings.cjs +3 -2
  23. package/dist/embeddings.cjs.map +1 -1
  24. package/dist/embeddings.d.cts.map +1 -1
  25. package/dist/embeddings.d.ts.map +1 -1
  26. package/dist/embeddings.js +4 -3
  27. package/dist/embeddings.js.map +1 -1
  28. package/dist/gemini.cjs +129 -35
  29. package/dist/gemini.cjs.map +1 -1
  30. package/dist/gemini.d.cts.map +1 -1
  31. package/dist/gemini.d.ts.map +1 -1
  32. package/dist/gemini.js +130 -36
  33. package/dist/gemini.js.map +1 -1
  34. package/dist/helpers.cjs +154 -3
  35. package/dist/helpers.cjs.map +1 -1
  36. package/dist/helpers.d.cts +1 -1
  37. package/dist/helpers.d.cts.map +1 -1
  38. package/dist/helpers.d.ts +1 -1
  39. package/dist/helpers.d.ts.map +1 -1
  40. package/dist/helpers.js +151 -4
  41. package/dist/helpers.js.map +1 -1
  42. package/dist/index.cjs +1 -0
  43. package/dist/index.d.cts +2 -2
  44. package/dist/index.d.ts +2 -2
  45. package/dist/index.js +2 -2
  46. package/dist/journal.cjs +26 -9
  47. package/dist/journal.cjs.map +1 -1
  48. package/dist/journal.d.cts +10 -5
  49. package/dist/journal.d.cts.map +1 -1
  50. package/dist/journal.d.ts +10 -5
  51. package/dist/journal.d.ts.map +1 -1
  52. package/dist/journal.js +26 -10
  53. package/dist/journal.js.map +1 -1
  54. package/dist/llmock.cjs +2 -2
  55. package/dist/llmock.cjs.map +1 -1
  56. package/dist/llmock.d.cts +1 -1
  57. package/dist/llmock.d.ts +1 -1
  58. package/dist/llmock.js +2 -2
  59. package/dist/llmock.js.map +1 -1
  60. package/dist/messages.cjs +192 -2
  61. package/dist/messages.cjs.map +1 -1
  62. package/dist/messages.d.cts.map +1 -1
  63. package/dist/messages.d.ts.map +1 -1
  64. package/dist/messages.js +193 -3
  65. package/dist/messages.js.map +1 -1
  66. package/dist/ollama.cjs +39 -13
  67. package/dist/ollama.cjs.map +1 -1
  68. package/dist/ollama.d.cts.map +1 -1
  69. package/dist/ollama.d.ts.map +1 -1
  70. package/dist/ollama.js +40 -14
  71. package/dist/ollama.js.map +1 -1
  72. package/dist/recorder.cjs +1 -1
  73. package/dist/recorder.cjs.map +1 -1
  74. package/dist/recorder.d.cts +1 -0
  75. package/dist/recorder.d.cts.map +1 -1
  76. package/dist/recorder.d.ts +1 -0
  77. package/dist/recorder.d.ts.map +1 -1
  78. package/dist/recorder.js +1 -1
  79. package/dist/recorder.js.map +1 -1
  80. package/dist/responses.cjs +250 -126
  81. package/dist/responses.cjs.map +1 -1
  82. package/dist/responses.d.cts.map +1 -1
  83. package/dist/responses.d.ts.map +1 -1
  84. package/dist/responses.js +251 -127
  85. package/dist/responses.js.map +1 -1
  86. package/dist/router.cjs +16 -10
  87. package/dist/router.cjs.map +1 -1
  88. package/dist/router.d.cts +1 -1
  89. package/dist/router.d.cts.map +1 -1
  90. package/dist/router.d.ts +1 -1
  91. package/dist/router.d.ts.map +1 -1
  92. package/dist/router.js +16 -10
  93. package/dist/router.js.map +1 -1
  94. package/dist/server.cjs +47 -7
  95. package/dist/server.cjs.map +1 -1
  96. package/dist/server.d.cts.map +1 -1
  97. package/dist/server.d.ts.map +1 -1
  98. package/dist/server.js +48 -8
  99. package/dist/server.js.map +1 -1
  100. package/dist/stream-collapse.cjs +48 -40
  101. package/dist/stream-collapse.cjs.map +1 -1
  102. package/dist/stream-collapse.d.cts.map +1 -1
  103. package/dist/stream-collapse.d.ts.map +1 -1
  104. package/dist/stream-collapse.js +48 -40
  105. package/dist/stream-collapse.js.map +1 -1
  106. package/dist/types.d.cts +22 -1
  107. package/dist/types.d.cts.map +1 -1
  108. package/dist/types.d.ts +22 -1
  109. package/dist/types.d.ts.map +1 -1
  110. package/dist/ws-gemini-live.cjs +4 -2
  111. package/dist/ws-gemini-live.cjs.map +1 -1
  112. package/dist/ws-gemini-live.d.cts +3 -1
  113. package/dist/ws-gemini-live.d.cts.map +1 -1
  114. package/dist/ws-gemini-live.d.ts +3 -1
  115. package/dist/ws-gemini-live.d.ts.map +1 -1
  116. package/dist/ws-gemini-live.js +4 -2
  117. package/dist/ws-gemini-live.js.map +1 -1
  118. package/dist/ws-realtime.cjs +4 -2
  119. package/dist/ws-realtime.cjs.map +1 -1
  120. package/dist/ws-realtime.d.cts +3 -1
  121. package/dist/ws-realtime.d.cts.map +1 -1
  122. package/dist/ws-realtime.d.ts +3 -1
  123. package/dist/ws-realtime.d.ts.map +1 -1
  124. package/dist/ws-realtime.js +4 -2
  125. package/dist/ws-realtime.js.map +1 -1
  126. package/dist/ws-responses.cjs +4 -2
  127. package/dist/ws-responses.cjs.map +1 -1
  128. package/dist/ws-responses.d.cts +3 -1
  129. package/dist/ws-responses.d.cts.map +1 -1
  130. package/dist/ws-responses.d.ts +3 -1
  131. package/dist/ws-responses.d.ts.map +1 -1
  132. package/dist/ws-responses.js +4 -2
  133. package/dist/ws-responses.js.map +1 -1
  134. package/package.json +5 -1
package/dist/helpers.js CHANGED
@@ -33,16 +33,33 @@ function isTextResponse(r) {
33
33
  function isToolCallResponse(r) {
34
34
  return "toolCalls" in r && Array.isArray(r.toolCalls);
35
35
  }
36
+ function isContentWithToolCallsResponse(r) {
37
+ return "content" in r && typeof r.content === "string" && "toolCalls" in r && Array.isArray(r.toolCalls);
38
+ }
36
39
  function isErrorResponse(r) {
37
40
  return "error" in r && r.error !== null && typeof r.error === "object";
38
41
  }
39
42
  function isEmbeddingResponse(r) {
40
43
  return "embedding" in r && Array.isArray(r.embedding);
41
44
  }
42
- function buildTextChunks(content, model, chunkSize) {
45
+ function buildTextChunks(content, model, chunkSize, reasoning) {
43
46
  const id = generateId();
44
47
  const created = Math.floor(Date.now() / 1e3);
45
48
  const chunks = [];
49
+ if (reasoning) for (let i = 0; i < reasoning.length; i += chunkSize) {
50
+ const slice = reasoning.slice(i, i + chunkSize);
51
+ chunks.push({
52
+ id,
53
+ object: "chat.completion.chunk",
54
+ created,
55
+ model,
56
+ choices: [{
57
+ index: 0,
58
+ delta: { reasoning_content: slice },
59
+ finish_reason: null
60
+ }]
61
+ });
62
+ }
46
63
  chunks.push({
47
64
  id,
48
65
  object: "chat.completion.chunk",
@@ -156,7 +173,7 @@ function buildToolCallChunks(toolCalls, model, chunkSize) {
156
173
  });
157
174
  return chunks;
158
175
  }
159
- function buildTextCompletion(content, model) {
176
+ function buildTextCompletion(content, model, reasoning) {
160
177
  return {
161
178
  id: generateId(),
162
179
  object: "chat.completion",
@@ -167,7 +184,8 @@ function buildTextCompletion(content, model) {
167
184
  message: {
168
185
  role: "assistant",
169
186
  content,
170
- refusal: null
187
+ refusal: null,
188
+ ...reasoning ? { reasoning_content: reasoning } : {}
171
189
  },
172
190
  finish_reason: "stop"
173
191
  }],
@@ -208,6 +226,122 @@ function buildToolCallCompletion(toolCalls, model) {
208
226
  }
209
227
  };
210
228
  }
229
+ function buildContentWithToolCallsChunks(content, toolCalls, model, chunkSize) {
230
+ const id = generateId();
231
+ const created = Math.floor(Date.now() / 1e3);
232
+ const chunks = [];
233
+ chunks.push({
234
+ id,
235
+ object: "chat.completion.chunk",
236
+ created,
237
+ model,
238
+ choices: [{
239
+ index: 0,
240
+ delta: {
241
+ role: "assistant",
242
+ content: ""
243
+ },
244
+ finish_reason: null
245
+ }]
246
+ });
247
+ for (let i = 0; i < content.length; i += chunkSize) {
248
+ const slice = content.slice(i, i + chunkSize);
249
+ chunks.push({
250
+ id,
251
+ object: "chat.completion.chunk",
252
+ created,
253
+ model,
254
+ choices: [{
255
+ index: 0,
256
+ delta: { content: slice },
257
+ finish_reason: null
258
+ }]
259
+ });
260
+ }
261
+ for (let tcIdx = 0; tcIdx < toolCalls.length; tcIdx++) {
262
+ const tc = toolCalls[tcIdx];
263
+ const tcId = tc.id || generateToolCallId();
264
+ chunks.push({
265
+ id,
266
+ object: "chat.completion.chunk",
267
+ created,
268
+ model,
269
+ choices: [{
270
+ index: 0,
271
+ delta: { tool_calls: [{
272
+ index: tcIdx,
273
+ id: tcId,
274
+ type: "function",
275
+ function: {
276
+ name: tc.name,
277
+ arguments: ""
278
+ }
279
+ }] },
280
+ finish_reason: null
281
+ }]
282
+ });
283
+ const args = tc.arguments;
284
+ for (let i = 0; i < args.length; i += chunkSize) {
285
+ const slice = args.slice(i, i + chunkSize);
286
+ chunks.push({
287
+ id,
288
+ object: "chat.completion.chunk",
289
+ created,
290
+ model,
291
+ choices: [{
292
+ index: 0,
293
+ delta: { tool_calls: [{
294
+ index: tcIdx,
295
+ function: { arguments: slice }
296
+ }] },
297
+ finish_reason: null
298
+ }]
299
+ });
300
+ }
301
+ }
302
+ chunks.push({
303
+ id,
304
+ object: "chat.completion.chunk",
305
+ created,
306
+ model,
307
+ choices: [{
308
+ index: 0,
309
+ delta: {},
310
+ finish_reason: "tool_calls"
311
+ }]
312
+ });
313
+ return chunks;
314
+ }
315
+ function buildContentWithToolCallsCompletion(content, toolCalls, model) {
316
+ return {
317
+ id: generateId(),
318
+ object: "chat.completion",
319
+ created: Math.floor(Date.now() / 1e3),
320
+ model,
321
+ choices: [{
322
+ index: 0,
323
+ message: {
324
+ role: "assistant",
325
+ content,
326
+ refusal: null,
327
+ tool_calls: toolCalls.map((tc) => ({
328
+ id: tc.id || generateToolCallId(),
329
+ type: "function",
330
+ function: {
331
+ name: tc.name,
332
+ arguments: tc.arguments
333
+ }
334
+ }))
335
+ },
336
+ finish_reason: "tool_calls"
337
+ }],
338
+ usage: {
339
+ prompt_tokens: 0,
340
+ completion_tokens: 0,
341
+ total_tokens: 0
342
+ }
343
+ };
344
+ }
211
345
  function readBody(req) {
212
346
  return new Promise((resolve, reject) => {
213
347
  const chunks = [];
@@ -220,6 +354,19 @@ function matchesPattern(text, pattern) {
220
354
  if (typeof pattern === "string") return text.toLowerCase().includes(pattern.toLowerCase());
221
355
  return pattern.test(text);
222
356
  }
357
+ function getTestId(req) {
358
+ const headerValue = req.headers["x-test-id"];
359
+ if (Array.isArray(headerValue)) {
360
+ if (headerValue.length > 0 && headerValue[0]) return headerValue[0];
361
+ } else if (typeof headerValue === "string" && headerValue) return headerValue;
362
+ const url = req.url ?? "/";
363
+ const qIdx = url.indexOf("?");
364
+ if (qIdx !== -1) {
365
+ const queryValue = new URLSearchParams(url.slice(qIdx + 1)).get("testId");
366
+ if (queryValue) return queryValue;
367
+ }
368
+ return "__default__";
369
+ }
223
370
  const DEFAULT_EMBEDDING_DIMENSIONS = 1536;
224
371
  /**
225
372
  * Generate a deterministic embedding vector from input text.
@@ -255,5 +402,5 @@ function buildEmbeddingResponse(embeddings, model) {
255
402
  }
256
403
 
257
404
  //#endregion
258
- export { buildEmbeddingResponse, buildTextChunks, buildTextCompletion, buildToolCallChunks, buildToolCallCompletion, flattenHeaders, generateDeterministicEmbedding, generateId, generateMessageId, generateToolCallId, generateToolUseId, isEmbeddingResponse, isErrorResponse, isTextResponse, isToolCallResponse, matchesPattern, readBody };
405
+ export { buildContentWithToolCallsChunks, buildContentWithToolCallsCompletion, buildEmbeddingResponse, buildTextChunks, buildTextCompletion, buildToolCallChunks, buildToolCallCompletion, flattenHeaders, generateDeterministicEmbedding, generateId, generateMessageId, generateToolCallId, generateToolUseId, getTestId, isContentWithToolCallsResponse, isEmbeddingResponse, isErrorResponse, isTextResponse, isToolCallResponse, matchesPattern, readBody };
259
406
  //# sourceMappingURL=helpers.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"helpers.js","names":[],"sources":["../src/helpers.ts"],"sourcesContent":["import { createHash, randomBytes } from \"node:crypto\";\nimport type * as http from \"node:http\";\nimport type {\n FixtureResponse,\n TextResponse,\n ToolCallResponse,\n ErrorResponse,\n EmbeddingResponse,\n SSEChunk,\n ToolCall,\n ChatCompletion,\n} from \"./types.js\";\n\nconst REDACTED_HEADERS = new Set([\"authorization\", \"x-api-key\", \"api-key\"]);\n\nexport function flattenHeaders(headers: http.IncomingHttpHeaders): Record<string, string> {\n const flat: Record<string, string> = {};\n for (const [key, value] of Object.entries(headers)) {\n if (value === undefined) continue;\n if (REDACTED_HEADERS.has(key.toLowerCase())) {\n flat[key] = \"[REDACTED]\";\n } else {\n flat[key] = Array.isArray(value) ? value.join(\", \") : value;\n }\n }\n return flat;\n}\n\nexport function generateId(prefix = \"chatcmpl\"): string {\n return `${prefix}-${randomBytes(12).toString(\"base64url\")}`;\n}\n\nexport function generateToolCallId(): string {\n return `call_${randomBytes(12).toString(\"base64url\")}`;\n}\n\nexport function generateMessageId(): string {\n return `msg_${randomBytes(12).toString(\"base64url\")}`;\n}\n\nexport function generateToolUseId(): string {\n return `toolu_${randomBytes(12).toString(\"base64url\")}`;\n}\n\nexport function isTextResponse(r: FixtureResponse): r is TextResponse {\n return \"content\" in r && typeof (r as TextResponse).content === \"string\";\n}\n\nexport function isToolCallResponse(r: FixtureResponse): r is ToolCallResponse {\n return \"toolCalls\" in r && Array.isArray((r as ToolCallResponse).toolCalls);\n}\n\nexport function isErrorResponse(r: FixtureResponse): r is ErrorResponse {\n return (\n \"error\" in r &&\n (r as ErrorResponse).error !== null &&\n typeof (r as ErrorResponse).error === \"object\"\n );\n}\n\nexport function isEmbeddingResponse(r: FixtureResponse): r is EmbeddingResponse {\n return \"embedding\" in r && Array.isArray((r as EmbeddingResponse).embedding);\n}\n\nexport function buildTextChunks(content: string, model: string, chunkSize: number): SSEChunk[] {\n const id = generateId();\n const created = Math.floor(Date.now() / 1000);\n const chunks: SSEChunk[] = [];\n\n // Role chunk\n chunks.push({\n id,\n object: \"chat.completion.chunk\",\n created,\n model,\n choices: [{ index: 0, delta: { role: \"assistant\", content: \"\" }, finish_reason: null }],\n });\n\n // Content chunks\n for (let i = 0; i < content.length; i += chunkSize) {\n const slice = content.slice(i, i + chunkSize);\n chunks.push({\n id,\n object: \"chat.completion.chunk\",\n created,\n model,\n choices: [{ index: 0, delta: { content: slice }, finish_reason: null }],\n });\n }\n\n // Finish chunk\n chunks.push({\n id,\n object: \"chat.completion.chunk\",\n created,\n model,\n choices: [{ index: 0, delta: {}, finish_reason: \"stop\" }],\n });\n\n return chunks;\n}\n\nexport function buildToolCallChunks(\n toolCalls: ToolCall[],\n model: string,\n chunkSize: number,\n): SSEChunk[] {\n const id = generateId();\n const created = Math.floor(Date.now() / 1000);\n const chunks: SSEChunk[] = [];\n\n // Role chunk\n chunks.push({\n id,\n object: \"chat.completion.chunk\",\n created,\n model,\n choices: [{ index: 0, delta: { role: \"assistant\", content: null }, finish_reason: null }],\n });\n\n // Tool call chunks — one initial chunk per tool call, then argument chunks\n for (let tcIdx = 0; tcIdx < toolCalls.length; tcIdx++) {\n const tc = toolCalls[tcIdx];\n const tcId = tc.id || generateToolCallId();\n\n // Initial tool call chunk (id + function name)\n chunks.push({\n id,\n object: \"chat.completion.chunk\",\n created,\n model,\n choices: [\n {\n index: 0,\n delta: {\n tool_calls: [\n {\n index: tcIdx,\n id: tcId,\n type: \"function\",\n function: { name: tc.name, arguments: \"\" },\n },\n ],\n },\n finish_reason: null,\n },\n ],\n });\n\n // Argument streaming chunks\n const args = tc.arguments;\n for (let i = 0; i < args.length; i += chunkSize) {\n const slice = args.slice(i, i + chunkSize);\n chunks.push({\n id,\n object: \"chat.completion.chunk\",\n created,\n model,\n choices: [\n {\n index: 0,\n delta: {\n tool_calls: [{ index: tcIdx, function: { arguments: slice } }],\n },\n finish_reason: null,\n },\n ],\n });\n }\n }\n\n // Finish chunk\n chunks.push({\n id,\n object: \"chat.completion.chunk\",\n created,\n model,\n choices: [{ index: 0, delta: {}, finish_reason: \"tool_calls\" }],\n });\n\n return chunks;\n}\n\n// Non-streaming response builders\n\nexport function buildTextCompletion(content: string, model: string): ChatCompletion {\n return {\n id: generateId(),\n object: \"chat.completion\",\n created: Math.floor(Date.now() / 1000),\n model,\n choices: [\n {\n index: 0,\n message: { role: \"assistant\", content, refusal: null },\n finish_reason: \"stop\",\n },\n ],\n usage: { prompt_tokens: 0, completion_tokens: 0, total_tokens: 0 },\n };\n}\n\nexport function buildToolCallCompletion(toolCalls: ToolCall[], model: string): ChatCompletion {\n return {\n id: generateId(),\n object: \"chat.completion\",\n created: Math.floor(Date.now() / 1000),\n model,\n choices: [\n {\n index: 0,\n message: {\n role: \"assistant\",\n content: null,\n refusal: null,\n tool_calls: toolCalls.map((tc) => ({\n id: tc.id || generateToolCallId(),\n type: \"function\" as const,\n function: { name: tc.name, arguments: tc.arguments },\n })),\n },\n finish_reason: \"tool_calls\",\n },\n ],\n usage: { prompt_tokens: 0, completion_tokens: 0, total_tokens: 0 },\n };\n}\n\n// ─── HTTP helpers ─────────────────────────────────────────────────────────\n\nexport function readBody(req: http.IncomingMessage): Promise<string> {\n return new Promise((resolve, reject) => {\n const chunks: Buffer[] = [];\n req.on(\"data\", (chunk: Buffer) => chunks.push(chunk));\n req.on(\"end\", () => resolve(Buffer.concat(chunks).toString()));\n req.on(\"error\", reject);\n });\n}\n\n// ─── Pattern matching ─────────────────────────────────────────────────────\n\nexport function matchesPattern(text: string, pattern: string | RegExp): boolean {\n if (typeof pattern === \"string\") {\n return text.toLowerCase().includes(pattern.toLowerCase());\n }\n return pattern.test(text);\n}\n\n// ─── Embedding helpers ─────────────────────────────────────────────────────\n\nconst DEFAULT_EMBEDDING_DIMENSIONS = 1536;\n\n/**\n * Generate a deterministic embedding vector from input text.\n * Hashes the input with SHA-256 and spreads the hash bytes across\n * the requested number of dimensions, producing values in [-1, 1].\n */\nexport function generateDeterministicEmbedding(\n input: string,\n dimensions: number = DEFAULT_EMBEDDING_DIMENSIONS,\n): number[] {\n let currentHash = createHash(\"sha256\").update(input).digest();\n const embedding: number[] = new Array(dimensions);\n for (let i = 0; i < dimensions; i++) {\n if (i > 0 && i % 32 === 0) {\n currentHash = createHash(\"sha256\").update(currentHash).digest();\n }\n // Map 0-255 → -1.0 to 1.0\n embedding[i] = currentHash[i % 32] / 127.5 - 1;\n }\n return embedding;\n}\n\nexport interface EmbeddingAPIResponse {\n object: \"list\";\n data: { object: \"embedding\"; index: number; embedding: number[] }[];\n model: string;\n usage: { prompt_tokens: number; total_tokens: number };\n}\n\n/**\n * Build an OpenAI-format embeddings API response for one or more inputs.\n */\nexport function buildEmbeddingResponse(\n embeddings: number[][],\n model: string,\n): EmbeddingAPIResponse {\n return {\n object: \"list\",\n data: embeddings.map((embedding, index) => ({\n object: \"embedding\" as const,\n index,\n embedding,\n })),\n model,\n usage: { prompt_tokens: 0, total_tokens: 0 },\n };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"helpers.js","names":[],"sources":["../src/helpers.ts"],"sourcesContent":["import { createHash, randomBytes } from \"node:crypto\";\nimport type * as http from \"node:http\";\nimport type {\n FixtureResponse,\n TextResponse,\n ToolCallResponse,\n ContentWithToolCallsResponse,\n ErrorResponse,\n EmbeddingResponse,\n SSEChunk,\n ToolCall,\n ChatCompletion,\n} from \"./types.js\";\n\nconst REDACTED_HEADERS = new Set([\"authorization\", \"x-api-key\", \"api-key\"]);\n\nexport function flattenHeaders(headers: http.IncomingHttpHeaders): Record<string, string> {\n const flat: Record<string, string> = {};\n for (const [key, value] of Object.entries(headers)) {\n if (value === undefined) continue;\n if (REDACTED_HEADERS.has(key.toLowerCase())) {\n flat[key] = \"[REDACTED]\";\n } else {\n flat[key] = Array.isArray(value) ? value.join(\", \") : value;\n }\n }\n return flat;\n}\n\nexport function generateId(prefix = \"chatcmpl\"): string {\n return `${prefix}-${randomBytes(12).toString(\"base64url\")}`;\n}\n\nexport function generateToolCallId(): string {\n return `call_${randomBytes(12).toString(\"base64url\")}`;\n}\n\nexport function generateMessageId(): string {\n return `msg_${randomBytes(12).toString(\"base64url\")}`;\n}\n\nexport function generateToolUseId(): string {\n return `toolu_${randomBytes(12).toString(\"base64url\")}`;\n}\n\nexport function isTextResponse(r: FixtureResponse): r is TextResponse {\n return \"content\" in r && typeof (r as TextResponse).content === \"string\";\n}\n\nexport function isToolCallResponse(r: FixtureResponse): r is ToolCallResponse {\n return \"toolCalls\" in r && Array.isArray((r as ToolCallResponse).toolCalls);\n}\n\nexport function isContentWithToolCallsResponse(\n r: FixtureResponse,\n): r is ContentWithToolCallsResponse {\n return (\n \"content\" in r &&\n typeof (r as ContentWithToolCallsResponse).content === \"string\" &&\n \"toolCalls\" in r &&\n Array.isArray((r as ContentWithToolCallsResponse).toolCalls)\n );\n}\n\nexport function isErrorResponse(r: FixtureResponse): r is ErrorResponse {\n return (\n \"error\" in r &&\n (r as ErrorResponse).error !== null &&\n typeof (r as ErrorResponse).error === \"object\"\n );\n}\n\nexport function isEmbeddingResponse(r: FixtureResponse): r is EmbeddingResponse {\n return \"embedding\" in r && Array.isArray((r as EmbeddingResponse).embedding);\n}\n\nexport function buildTextChunks(\n content: string,\n model: string,\n chunkSize: number,\n reasoning?: string,\n): SSEChunk[] {\n const id = generateId();\n const created = Math.floor(Date.now() / 1000);\n const chunks: SSEChunk[] = [];\n\n // Reasoning chunks (emitted before content, OpenRouter format)\n if (reasoning) {\n for (let i = 0; i < reasoning.length; i += chunkSize) {\n const slice = reasoning.slice(i, i + chunkSize);\n chunks.push({\n id,\n object: \"chat.completion.chunk\",\n created,\n model,\n choices: [{ index: 0, delta: { reasoning_content: slice }, finish_reason: null }],\n });\n }\n }\n\n // Role chunk\n chunks.push({\n id,\n object: \"chat.completion.chunk\",\n created,\n model,\n choices: [{ index: 0, delta: { role: \"assistant\", content: \"\" }, finish_reason: null }],\n });\n\n // Content chunks\n for (let i = 0; i < content.length; i += chunkSize) {\n const slice = content.slice(i, i + chunkSize);\n chunks.push({\n id,\n object: \"chat.completion.chunk\",\n created,\n model,\n choices: [{ index: 0, delta: { content: slice }, finish_reason: null }],\n });\n }\n\n // Finish chunk\n chunks.push({\n id,\n object: \"chat.completion.chunk\",\n created,\n model,\n choices: [{ index: 0, delta: {}, finish_reason: \"stop\" }],\n });\n\n return chunks;\n}\n\nexport function buildToolCallChunks(\n toolCalls: ToolCall[],\n model: string,\n chunkSize: number,\n): SSEChunk[] {\n const id = generateId();\n const created = Math.floor(Date.now() / 1000);\n const chunks: SSEChunk[] = [];\n\n // Role chunk\n chunks.push({\n id,\n object: \"chat.completion.chunk\",\n created,\n model,\n choices: [{ index: 0, delta: { role: \"assistant\", content: null }, finish_reason: null }],\n });\n\n // Tool call chunks — one initial chunk per tool call, then argument chunks\n for (let tcIdx = 0; tcIdx < toolCalls.length; tcIdx++) {\n const tc = toolCalls[tcIdx];\n const tcId = tc.id || generateToolCallId();\n\n // Initial tool call chunk (id + function name)\n chunks.push({\n id,\n object: \"chat.completion.chunk\",\n created,\n model,\n choices: [\n {\n index: 0,\n delta: {\n tool_calls: [\n {\n index: tcIdx,\n id: tcId,\n type: \"function\",\n function: { name: tc.name, arguments: \"\" },\n },\n ],\n },\n finish_reason: null,\n },\n ],\n });\n\n // Argument streaming chunks\n const args = tc.arguments;\n for (let i = 0; i < args.length; i += chunkSize) {\n const slice = args.slice(i, i + chunkSize);\n chunks.push({\n id,\n object: \"chat.completion.chunk\",\n created,\n model,\n choices: [\n {\n index: 0,\n delta: {\n tool_calls: [{ index: tcIdx, function: { arguments: slice } }],\n },\n finish_reason: null,\n },\n ],\n });\n }\n }\n\n // Finish chunk\n chunks.push({\n id,\n object: \"chat.completion.chunk\",\n created,\n model,\n choices: [{ index: 0, delta: {}, finish_reason: \"tool_calls\" }],\n });\n\n return chunks;\n}\n\n// Non-streaming response builders\n\nexport function buildTextCompletion(\n content: string,\n model: string,\n reasoning?: string,\n): ChatCompletion {\n return {\n id: generateId(),\n object: \"chat.completion\",\n created: Math.floor(Date.now() / 1000),\n model,\n choices: [\n {\n index: 0,\n message: {\n role: \"assistant\",\n content,\n refusal: null,\n ...(reasoning ? { reasoning_content: reasoning } : {}),\n },\n finish_reason: \"stop\",\n },\n ],\n usage: { prompt_tokens: 0, completion_tokens: 0, total_tokens: 0 },\n };\n}\n\nexport function buildToolCallCompletion(toolCalls: ToolCall[], model: string): ChatCompletion {\n return {\n id: generateId(),\n object: \"chat.completion\",\n created: Math.floor(Date.now() / 1000),\n model,\n choices: [\n {\n index: 0,\n message: {\n role: \"assistant\",\n content: null,\n refusal: null,\n tool_calls: toolCalls.map((tc) => ({\n id: tc.id || generateToolCallId(),\n type: \"function\" as const,\n function: { name: tc.name, arguments: tc.arguments },\n })),\n },\n finish_reason: \"tool_calls\",\n },\n ],\n usage: { prompt_tokens: 0, completion_tokens: 0, total_tokens: 0 },\n };\n}\n\nexport function buildContentWithToolCallsChunks(\n content: string,\n toolCalls: ToolCall[],\n model: string,\n chunkSize: number,\n): SSEChunk[] {\n const id = generateId();\n const created = Math.floor(Date.now() / 1000);\n const chunks: SSEChunk[] = [];\n\n // Role chunk\n chunks.push({\n id,\n object: \"chat.completion.chunk\",\n created,\n model,\n choices: [{ index: 0, delta: { role: \"assistant\", content: \"\" }, finish_reason: null }],\n });\n\n // Content chunks\n for (let i = 0; i < content.length; i += chunkSize) {\n const slice = content.slice(i, i + chunkSize);\n chunks.push({\n id,\n object: \"chat.completion.chunk\",\n created,\n model,\n choices: [{ index: 0, delta: { content: slice }, finish_reason: null }],\n });\n }\n\n // Tool call chunks — one initial chunk per tool call, then argument chunks\n for (let tcIdx = 0; tcIdx < toolCalls.length; tcIdx++) {\n const tc = toolCalls[tcIdx];\n const tcId = tc.id || generateToolCallId();\n\n // Initial tool call chunk (id + function name)\n chunks.push({\n id,\n object: \"chat.completion.chunk\",\n created,\n model,\n choices: [\n {\n index: 0,\n delta: {\n tool_calls: [\n {\n index: tcIdx,\n id: tcId,\n type: \"function\",\n function: { name: tc.name, arguments: \"\" },\n },\n ],\n },\n finish_reason: null,\n },\n ],\n });\n\n // Argument streaming chunks\n const args = tc.arguments;\n for (let i = 0; i < args.length; i += chunkSize) {\n const slice = args.slice(i, i + chunkSize);\n chunks.push({\n id,\n object: \"chat.completion.chunk\",\n created,\n model,\n choices: [\n {\n index: 0,\n delta: {\n tool_calls: [{ index: tcIdx, function: { arguments: slice } }],\n },\n finish_reason: null,\n },\n ],\n });\n }\n }\n\n // Finish chunk\n chunks.push({\n id,\n object: \"chat.completion.chunk\",\n created,\n model,\n choices: [{ index: 0, delta: {}, finish_reason: \"tool_calls\" }],\n });\n\n return chunks;\n}\n\nexport function buildContentWithToolCallsCompletion(\n content: string,\n toolCalls: ToolCall[],\n model: string,\n): ChatCompletion {\n return {\n id: generateId(),\n object: \"chat.completion\",\n created: Math.floor(Date.now() / 1000),\n model,\n choices: [\n {\n index: 0,\n message: {\n role: \"assistant\",\n content,\n refusal: null,\n tool_calls: toolCalls.map((tc) => ({\n id: tc.id || generateToolCallId(),\n type: \"function\" as const,\n function: { name: tc.name, arguments: tc.arguments },\n })),\n },\n finish_reason: \"tool_calls\",\n },\n ],\n usage: { prompt_tokens: 0, completion_tokens: 0, total_tokens: 0 },\n };\n}\n\n// ─── HTTP helpers ─────────────────────────────────────────────────────────\n\nexport function readBody(req: http.IncomingMessage): Promise<string> {\n return new Promise((resolve, reject) => {\n const chunks: Buffer[] = [];\n req.on(\"data\", (chunk: Buffer) => chunks.push(chunk));\n req.on(\"end\", () => resolve(Buffer.concat(chunks).toString()));\n req.on(\"error\", reject);\n });\n}\n\n// ─── Pattern matching ─────────────────────────────────────────────────────\n\nexport function matchesPattern(text: string, pattern: string | RegExp): boolean {\n if (typeof pattern === \"string\") {\n return text.toLowerCase().includes(pattern.toLowerCase());\n }\n return pattern.test(text);\n}\n\nexport function getTestId(req: http.IncomingMessage): string {\n const headerValue = req.headers[\"x-test-id\"];\n if (Array.isArray(headerValue)) {\n if (headerValue.length > 0 && headerValue[0]) return headerValue[0];\n } else if (typeof headerValue === \"string\" && headerValue) {\n return headerValue;\n }\n\n const url = req.url ?? \"/\";\n const qIdx = url.indexOf(\"?\");\n if (qIdx !== -1) {\n const params = new URLSearchParams(url.slice(qIdx + 1));\n const queryValue = params.get(\"testId\");\n if (queryValue) return queryValue;\n }\n\n // Duplicated from journal.ts DEFAULT_TEST_ID — importing it here would create\n // a circular dependency (journal.ts imports from helpers.ts).\n return \"__default__\";\n}\n\n// ─── Embedding helpers ─────────────────────────────────────────────────────\n\nconst DEFAULT_EMBEDDING_DIMENSIONS = 1536;\n\n/**\n * Generate a deterministic embedding vector from input text.\n * Hashes the input with SHA-256 and spreads the hash bytes across\n * the requested number of dimensions, producing values in [-1, 1].\n */\nexport function generateDeterministicEmbedding(\n input: string,\n dimensions: number = DEFAULT_EMBEDDING_DIMENSIONS,\n): number[] {\n let currentHash = createHash(\"sha256\").update(input).digest();\n const embedding: number[] = new Array(dimensions);\n for (let i = 0; i < dimensions; i++) {\n if (i > 0 && i % 32 === 0) {\n currentHash = createHash(\"sha256\").update(currentHash).digest();\n }\n // Map 0-255 → -1.0 to 1.0\n embedding[i] = currentHash[i % 32] / 127.5 - 1;\n }\n return embedding;\n}\n\nexport interface EmbeddingAPIResponse {\n object: \"list\";\n data: { object: \"embedding\"; index: number; embedding: number[] }[];\n model: string;\n usage: { prompt_tokens: number; total_tokens: number };\n}\n\n/**\n * Build an OpenAI-format embeddings API response for one or more inputs.\n */\nexport function buildEmbeddingResponse(\n embeddings: number[][],\n model: string,\n): EmbeddingAPIResponse {\n return {\n object: \"list\",\n data: embeddings.map((embedding, index) => ({\n object: \"embedding\" as const,\n index,\n embedding,\n })),\n model,\n usage: { prompt_tokens: 0, total_tokens: 0 },\n };\n}\n"],"mappings":"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"}
package/dist/index.cjs CHANGED
@@ -38,6 +38,7 @@ const require_config_loader = require('./config-loader.cjs');
38
38
  const require_suite = require('./suite.cjs');
39
39
 
40
40
  exports.A2AMock = require_a2a_mock.A2AMock;
41
+ exports.DEFAULT_TEST_ID = require_journal.DEFAULT_TEST_ID;
41
42
  exports.Journal = require_journal.Journal;
42
43
  exports.LLMock = require_llmock.LLMock;
43
44
  exports.Logger = require_logger.Logger;
package/dist/index.d.cts CHANGED
@@ -1,4 +1,4 @@
1
- import { Journal } from "./journal.cjs";
1
+ import { DEFAULT_TEST_ID, Journal } from "./journal.cjs";
2
2
  import { LogLevel, Logger } from "./logger.cjs";
3
3
  import { MetricsRegistry, createMetricsRegistry, normalizePathLabel } from "./metrics.cjs";
4
4
  import { ChaosAction, ChaosConfig, ChatCompletion, ChatCompletionChoice, ChatCompletionMessage, ChatCompletionRequest, ChatMessage, ContentPart, EmbeddingFixtureOpts, EmbeddingResponse, ErrorResponse, Fixture, FixtureFile, FixtureFileEntry, FixtureMatch, FixtureOpts, FixtureResponse, JournalEntry, MockServerOptions, Mountable, RecordConfig, RecordProviderKey, SSEChoice, SSEChunk, SSEDelta, SSEToolCallDelta, StreamingProfile, TextResponse, ToolCall, ToolCallMessage, ToolCallResponse, ToolDefinition } from "./types.cjs";
@@ -39,4 +39,4 @@ import { MCPMock } from "./mcp-mock.cjs";
39
39
  import { VectorMock } from "./vector-mock.cjs";
40
40
  import { JsonRpcDispatcherOptions, JsonRpcResponse, MethodHandler, createJsonRpcDispatcher } from "./jsonrpc.cjs";
41
41
  import { MockSuite, MockSuiteOptions, createMockSuite } from "./suite.cjs";
42
- export { type A2AAgentDefinition, type A2AArtifact, type A2AMessage, A2AMock, type A2AMockOptions, type A2APart, type A2ARole, type A2AStreamEvent, type A2ATask, type A2ATaskResponse, type A2ATaskState, type AimockConfig, type ChaosAction, type ChaosConfig, type ChatCompletion, type ChatCompletionChoice, type ChatCompletionMessage, type ChatCompletionRequest, type ChatMessage, type CollapseResult, type ContentPart, type EmbeddingAPIResponse, type EmbeddingFixtureOpts, type EmbeddingResponse, type ErrorResponse, type Fixture, type FixtureFile, type FixtureFileEntry, type FixtureMatch, type FixtureOpts, type FixtureResponse, type InterruptionControl, Journal, type JournalEntry, type JsonRpcDispatcherOptions, type JsonRpcResponse, LLMock, type LogLevel, Logger, type MCPContent, MCPMock, type MCPMockOptions, type MCPPromptDefinition, type MCPPromptResult, type MCPResourceContent, type MCPResourceDefinition, type MCPSession, type MCPToolDefinition, type MethodHandler, type MetricsRegistry, type MockServerOptions, type MockSuite, type MockSuiteOptions, type ModerationFixture, type ModerationResult, type Mountable, type NDJSONStreamOptions, type QueryHandler, type QueryResult, type RecordConfig, type RecordProviderKey, type RerankFixture, type RerankResult, type ResponsesSSEEvent, type SSEChoice, type SSEChunk, type SSEDelta, type SSEToolCallDelta, type SearchFixture, type SearchResult, type ServerInstance, type ServiceFixtures, type StreamOptions, type StreamingProfile, type TextResponse, type ToolCall, type ToolCallMessage, type ToolCallResponse, type ToolDefinition, type ValidationResult, type VectorCollection, type VectorEntry, VectorMock, type VectorMockOptions, type VectorQuery, WebSocketConnection, applyChaos, bedrockToCompletionRequest, buildEmbeddingResponse, buildTextChunks, buildTextStreamEvents, buildToolCallChunks, buildToolCallStreamEvents, calculateDelay, cohereToCompletionRequest, collapseAnthropicSSE, collapseBedrockEventStream, collapseCohereSSE, collapseGeminiSSE, collapseOllamaNDJSON, collapseOpenAISSE, collapseStreamingResponse, computeAcceptKey, converseToCompletionRequest, createInterruptionSignal, createJsonRpcDispatcher, createMetricsRegistry, createMockSuite, createServer, delay, encodeEventStreamFrame, encodeEventStreamMessage, evaluateChaos, flattenHeaders, generateDeterministicEmbedding, generateId, generateMessageId, generateToolCallId, generateToolUseId, getTextContent, handleBedrock, handleBedrockStream, handleCohere, handleConverse, handleConverseStream, handleEmbeddings, handleGemini, handleMessages, handleModeration, handleOllama, handleOllamaGenerate, handleRerank, handleResponses, handleSearch, handleWebSocketGeminiLive, handleWebSocketRealtime, handleWebSocketResponses, isEmbeddingResponse, loadConfig, loadFixtureFile, loadFixturesFromDir, matchFixture, normalizePathLabel, ollamaToCompletionRequest, proxyAndRecord, resolveUpstreamUrl, startFromConfig, upgradeToWebSocket, validateFixtures, writeErrorResponse, writeEventStream, writeNDJSONStream, writeSSEStream };
42
+ export { type A2AAgentDefinition, type A2AArtifact, type A2AMessage, A2AMock, type A2AMockOptions, type A2APart, type A2ARole, type A2AStreamEvent, type A2ATask, type A2ATaskResponse, type A2ATaskState, type AimockConfig, type ChaosAction, type ChaosConfig, type ChatCompletion, type ChatCompletionChoice, type ChatCompletionMessage, type ChatCompletionRequest, type ChatMessage, type CollapseResult, type ContentPart, DEFAULT_TEST_ID, type EmbeddingAPIResponse, type EmbeddingFixtureOpts, type EmbeddingResponse, type ErrorResponse, type Fixture, type FixtureFile, type FixtureFileEntry, type FixtureMatch, type FixtureOpts, type FixtureResponse, type InterruptionControl, Journal, type JournalEntry, type JsonRpcDispatcherOptions, type JsonRpcResponse, LLMock, type LogLevel, Logger, type MCPContent, MCPMock, type MCPMockOptions, type MCPPromptDefinition, type MCPPromptResult, type MCPResourceContent, type MCPResourceDefinition, type MCPSession, type MCPToolDefinition, type MethodHandler, type MetricsRegistry, type MockServerOptions, type MockSuite, type MockSuiteOptions, type ModerationFixture, type ModerationResult, type Mountable, type NDJSONStreamOptions, type QueryHandler, type QueryResult, type RecordConfig, type RecordProviderKey, type RerankFixture, type RerankResult, type ResponsesSSEEvent, type SSEChoice, type SSEChunk, type SSEDelta, type SSEToolCallDelta, type SearchFixture, type SearchResult, type ServerInstance, type ServiceFixtures, type StreamOptions, type StreamingProfile, type TextResponse, type ToolCall, type ToolCallMessage, type ToolCallResponse, type ToolDefinition, type ValidationResult, type VectorCollection, type VectorEntry, VectorMock, type VectorMockOptions, type VectorQuery, WebSocketConnection, applyChaos, bedrockToCompletionRequest, buildEmbeddingResponse, buildTextChunks, buildTextStreamEvents, buildToolCallChunks, buildToolCallStreamEvents, calculateDelay, cohereToCompletionRequest, collapseAnthropicSSE, collapseBedrockEventStream, collapseCohereSSE, collapseGeminiSSE, collapseOllamaNDJSON, collapseOpenAISSE, collapseStreamingResponse, computeAcceptKey, converseToCompletionRequest, createInterruptionSignal, createJsonRpcDispatcher, createMetricsRegistry, createMockSuite, createServer, delay, encodeEventStreamFrame, encodeEventStreamMessage, evaluateChaos, flattenHeaders, generateDeterministicEmbedding, generateId, generateMessageId, generateToolCallId, generateToolUseId, getTextContent, handleBedrock, handleBedrockStream, handleCohere, handleConverse, handleConverseStream, handleEmbeddings, handleGemini, handleMessages, handleModeration, handleOllama, handleOllamaGenerate, handleRerank, handleResponses, handleSearch, handleWebSocketGeminiLive, handleWebSocketRealtime, handleWebSocketResponses, isEmbeddingResponse, loadConfig, loadFixtureFile, loadFixturesFromDir, matchFixture, normalizePathLabel, ollamaToCompletionRequest, proxyAndRecord, resolveUpstreamUrl, startFromConfig, upgradeToWebSocket, validateFixtures, writeErrorResponse, writeEventStream, writeNDJSONStream, writeSSEStream };
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { Journal } from "./journal.js";
1
+ import { DEFAULT_TEST_ID, Journal } from "./journal.js";
2
2
  import { LogLevel, Logger } from "./logger.js";
3
3
  import { MetricsRegistry, createMetricsRegistry, normalizePathLabel } from "./metrics.js";
4
4
  import { ChaosAction, ChaosConfig, ChatCompletion, ChatCompletionChoice, ChatCompletionMessage, ChatCompletionRequest, ChatMessage, ContentPart, EmbeddingFixtureOpts, EmbeddingResponse, ErrorResponse, Fixture, FixtureFile, FixtureFileEntry, FixtureMatch, FixtureOpts, FixtureResponse, JournalEntry, MockServerOptions, Mountable, RecordConfig, RecordProviderKey, SSEChoice, SSEChunk, SSEDelta, SSEToolCallDelta, StreamingProfile, TextResponse, ToolCall, ToolCallMessage, ToolCallResponse, ToolDefinition } from "./types.js";
@@ -39,4 +39,4 @@ import { MCPMock } from "./mcp-mock.js";
39
39
  import { VectorMock } from "./vector-mock.js";
40
40
  import { JsonRpcDispatcherOptions, JsonRpcResponse, MethodHandler, createJsonRpcDispatcher } from "./jsonrpc.js";
41
41
  import { MockSuite, MockSuiteOptions, createMockSuite } from "./suite.js";
42
- export { type A2AAgentDefinition, type A2AArtifact, type A2AMessage, A2AMock, type A2AMockOptions, type A2APart, type A2ARole, type A2AStreamEvent, type A2ATask, type A2ATaskResponse, type A2ATaskState, type AimockConfig, type ChaosAction, type ChaosConfig, type ChatCompletion, type ChatCompletionChoice, type ChatCompletionMessage, type ChatCompletionRequest, type ChatMessage, type CollapseResult, type ContentPart, type EmbeddingAPIResponse, type EmbeddingFixtureOpts, type EmbeddingResponse, type ErrorResponse, type Fixture, type FixtureFile, type FixtureFileEntry, type FixtureMatch, type FixtureOpts, type FixtureResponse, type InterruptionControl, Journal, type JournalEntry, type JsonRpcDispatcherOptions, type JsonRpcResponse, LLMock, type LogLevel, Logger, type MCPContent, MCPMock, type MCPMockOptions, type MCPPromptDefinition, type MCPPromptResult, type MCPResourceContent, type MCPResourceDefinition, type MCPSession, type MCPToolDefinition, type MethodHandler, type MetricsRegistry, type MockServerOptions, type MockSuite, type MockSuiteOptions, type ModerationFixture, type ModerationResult, type Mountable, type NDJSONStreamOptions, type QueryHandler, type QueryResult, type RecordConfig, type RecordProviderKey, type RerankFixture, type RerankResult, type ResponsesSSEEvent, type SSEChoice, type SSEChunk, type SSEDelta, type SSEToolCallDelta, type SearchFixture, type SearchResult, type ServerInstance, type ServiceFixtures, type StreamOptions, type StreamingProfile, type TextResponse, type ToolCall, type ToolCallMessage, type ToolCallResponse, type ToolDefinition, type ValidationResult, type VectorCollection, type VectorEntry, VectorMock, type VectorMockOptions, type VectorQuery, WebSocketConnection, applyChaos, bedrockToCompletionRequest, buildEmbeddingResponse, buildTextChunks, buildTextStreamEvents, buildToolCallChunks, buildToolCallStreamEvents, calculateDelay, cohereToCompletionRequest, collapseAnthropicSSE, collapseBedrockEventStream, collapseCohereSSE, collapseGeminiSSE, collapseOllamaNDJSON, collapseOpenAISSE, collapseStreamingResponse, computeAcceptKey, converseToCompletionRequest, createInterruptionSignal, createJsonRpcDispatcher, createMetricsRegistry, createMockSuite, createServer, delay, encodeEventStreamFrame, encodeEventStreamMessage, evaluateChaos, flattenHeaders, generateDeterministicEmbedding, generateId, generateMessageId, generateToolCallId, generateToolUseId, getTextContent, handleBedrock, handleBedrockStream, handleCohere, handleConverse, handleConverseStream, handleEmbeddings, handleGemini, handleMessages, handleModeration, handleOllama, handleOllamaGenerate, handleRerank, handleResponses, handleSearch, handleWebSocketGeminiLive, handleWebSocketRealtime, handleWebSocketResponses, isEmbeddingResponse, loadConfig, loadFixtureFile, loadFixturesFromDir, matchFixture, normalizePathLabel, ollamaToCompletionRequest, proxyAndRecord, resolveUpstreamUrl, startFromConfig, upgradeToWebSocket, validateFixtures, writeErrorResponse, writeEventStream, writeNDJSONStream, writeSSEStream };
42
+ export { type A2AAgentDefinition, type A2AArtifact, type A2AMessage, A2AMock, type A2AMockOptions, type A2APart, type A2ARole, type A2AStreamEvent, type A2ATask, type A2ATaskResponse, type A2ATaskState, type AimockConfig, type ChaosAction, type ChaosConfig, type ChatCompletion, type ChatCompletionChoice, type ChatCompletionMessage, type ChatCompletionRequest, type ChatMessage, type CollapseResult, type ContentPart, DEFAULT_TEST_ID, type EmbeddingAPIResponse, type EmbeddingFixtureOpts, type EmbeddingResponse, type ErrorResponse, type Fixture, type FixtureFile, type FixtureFileEntry, type FixtureMatch, type FixtureOpts, type FixtureResponse, type InterruptionControl, Journal, type JournalEntry, type JsonRpcDispatcherOptions, type JsonRpcResponse, LLMock, type LogLevel, Logger, type MCPContent, MCPMock, type MCPMockOptions, type MCPPromptDefinition, type MCPPromptResult, type MCPResourceContent, type MCPResourceDefinition, type MCPSession, type MCPToolDefinition, type MethodHandler, type MetricsRegistry, type MockServerOptions, type MockSuite, type MockSuiteOptions, type ModerationFixture, type ModerationResult, type Mountable, type NDJSONStreamOptions, type QueryHandler, type QueryResult, type RecordConfig, type RecordProviderKey, type RerankFixture, type RerankResult, type ResponsesSSEEvent, type SSEChoice, type SSEChunk, type SSEDelta, type SSEToolCallDelta, type SearchFixture, type SearchResult, type ServerInstance, type ServiceFixtures, type StreamOptions, type StreamingProfile, type TextResponse, type ToolCall, type ToolCallMessage, type ToolCallResponse, type ToolDefinition, type ValidationResult, type VectorCollection, type VectorEntry, VectorMock, type VectorMockOptions, type VectorQuery, WebSocketConnection, applyChaos, bedrockToCompletionRequest, buildEmbeddingResponse, buildTextChunks, buildTextStreamEvents, buildToolCallChunks, buildToolCallStreamEvents, calculateDelay, cohereToCompletionRequest, collapseAnthropicSSE, collapseBedrockEventStream, collapseCohereSSE, collapseGeminiSSE, collapseOllamaNDJSON, collapseOpenAISSE, collapseStreamingResponse, computeAcceptKey, converseToCompletionRequest, createInterruptionSignal, createJsonRpcDispatcher, createMetricsRegistry, createMockSuite, createServer, delay, encodeEventStreamFrame, encodeEventStreamMessage, evaluateChaos, flattenHeaders, generateDeterministicEmbedding, generateId, generateMessageId, generateToolCallId, generateToolUseId, getTextContent, handleBedrock, handleBedrockStream, handleCohere, handleConverse, handleConverseStream, handleEmbeddings, handleGemini, handleMessages, handleModeration, handleOllama, handleOllamaGenerate, handleRerank, handleResponses, handleSearch, handleWebSocketGeminiLive, handleWebSocketRealtime, handleWebSocketResponses, isEmbeddingResponse, loadConfig, loadFixtureFile, loadFixturesFromDir, matchFixture, normalizePathLabel, ollamaToCompletionRequest, proxyAndRecord, resolveUpstreamUrl, startFromConfig, upgradeToWebSocket, validateFixtures, writeErrorResponse, writeEventStream, writeNDJSONStream, writeSSEStream };
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import { buildEmbeddingResponse, buildTextChunks, buildToolCallChunks, flattenHeaders, generateDeterministicEmbedding, generateId, generateMessageId, generateToolCallId, generateToolUseId, isEmbeddingResponse } from "./helpers.js";
2
2
  import { createJsonRpcDispatcher } from "./jsonrpc.js";
3
3
  import { A2AMock } from "./a2a-mock.js";
4
- import { Journal } from "./journal.js";
4
+ import { DEFAULT_TEST_ID, Journal } from "./journal.js";
5
5
  import { getTextContent, matchFixture } from "./router.js";
6
6
  import { loadFixtureFile, loadFixturesFromDir, validateFixtures } from "./fixture-loader.js";
7
7
  import { calculateDelay, delay, writeErrorResponse, writeSSEStream } from "./sse-writer.js";
@@ -36,4 +36,4 @@ import { VectorMock } from "./vector-mock.js";
36
36
  import { loadConfig, startFromConfig } from "./config-loader.js";
37
37
  import { createMockSuite } from "./suite.js";
38
38
 
39
- export { A2AMock, Journal, LLMock, Logger, MCPMock, VectorMock, WebSocketConnection, applyChaos, bedrockToCompletionRequest, buildEmbeddingResponse, buildTextChunks, buildTextStreamEvents, buildToolCallChunks, buildToolCallStreamEvents, calculateDelay, cohereToCompletionRequest, collapseAnthropicSSE, collapseBedrockEventStream, collapseCohereSSE, collapseGeminiSSE, collapseOllamaNDJSON, collapseOpenAISSE, collapseStreamingResponse, computeAcceptKey, converseToCompletionRequest, createInterruptionSignal, createJsonRpcDispatcher, createMetricsRegistry, createMockSuite, createServer, delay, encodeEventStreamFrame, encodeEventStreamMessage, evaluateChaos, flattenHeaders, generateDeterministicEmbedding, generateId, generateMessageId, generateToolCallId, generateToolUseId, getTextContent, handleBedrock, handleBedrockStream, handleCohere, handleConverse, handleConverseStream, handleEmbeddings, handleGemini, handleMessages, handleModeration, handleOllama, handleOllamaGenerate, handleRerank, handleResponses, handleSearch, handleWebSocketGeminiLive, handleWebSocketRealtime, handleWebSocketResponses, isEmbeddingResponse, loadConfig, loadFixtureFile, loadFixturesFromDir, matchFixture, normalizePathLabel, ollamaToCompletionRequest, proxyAndRecord, resolveUpstreamUrl, startFromConfig, upgradeToWebSocket, validateFixtures, writeErrorResponse, writeEventStream, writeNDJSONStream, writeSSEStream };
39
+ export { A2AMock, DEFAULT_TEST_ID, Journal, LLMock, Logger, MCPMock, VectorMock, WebSocketConnection, applyChaos, bedrockToCompletionRequest, buildEmbeddingResponse, buildTextChunks, buildTextStreamEvents, buildToolCallChunks, buildToolCallStreamEvents, calculateDelay, cohereToCompletionRequest, collapseAnthropicSSE, collapseBedrockEventStream, collapseCohereSSE, collapseGeminiSSE, collapseOllamaNDJSON, collapseOpenAISSE, collapseStreamingResponse, computeAcceptKey, converseToCompletionRequest, createInterruptionSignal, createJsonRpcDispatcher, createMetricsRegistry, createMockSuite, createServer, delay, encodeEventStreamFrame, encodeEventStreamMessage, evaluateChaos, flattenHeaders, generateDeterministicEmbedding, generateId, generateMessageId, generateToolCallId, generateToolUseId, getTextContent, handleBedrock, handleBedrockStream, handleCohere, handleConverse, handleConverseStream, handleEmbeddings, handleGemini, handleMessages, handleModeration, handleOllama, handleOllamaGenerate, handleRerank, handleResponses, handleSearch, handleWebSocketGeminiLive, handleWebSocketRealtime, handleWebSocketResponses, isEmbeddingResponse, loadConfig, loadFixtureFile, loadFixturesFromDir, matchFixture, normalizePathLabel, ollamaToCompletionRequest, proxyAndRecord, resolveUpstreamUrl, startFromConfig, upgradeToWebSocket, validateFixtures, writeErrorResponse, writeEventStream, writeNDJSONStream, writeSSEStream };
package/dist/journal.cjs CHANGED
@@ -1,6 +1,8 @@
1
1
  const require_helpers = require('./helpers.cjs');
2
2
 
3
3
  //#region src/journal.ts
4
+ /** Sentinel testId used when no explicit test scope is provided. */
5
+ const DEFAULT_TEST_ID = "__default__";
4
6
  /**
5
7
  * Compare two field values, handling RegExp by source+flags rather than reference.
6
8
  */
@@ -17,7 +19,11 @@ function matchCriteriaEqual(a, b) {
17
19
  }
18
20
  var Journal = class {
19
21
  entries = [];
20
- fixtureMatchCounts = /* @__PURE__ */ new Map();
22
+ fixtureMatchCountsByTestId = /* @__PURE__ */ new Map();
23
+ /** Backwards-compatible accessor — returns the default (no testId) count map. */
24
+ get fixtureMatchCounts() {
25
+ return this.getFixtureMatchCountsForTest(DEFAULT_TEST_ID);
26
+ }
21
27
  add(entry) {
22
28
  const full = {
23
29
  id: require_helpers.generateId("req"),
@@ -37,23 +43,33 @@ var Journal = class {
37
43
  findByFixture(fixture) {
38
44
  return this.entries.filter((e) => e.response.fixture === fixture);
39
45
  }
40
- getFixtureMatchCount(fixture) {
41
- return this.fixtureMatchCounts.get(fixture) ?? 0;
46
+ getFixtureMatchCountsForTest(testId) {
47
+ let counts = this.fixtureMatchCountsByTestId.get(testId);
48
+ if (!counts) {
49
+ counts = /* @__PURE__ */ new Map();
50
+ this.fixtureMatchCountsByTestId.set(testId, counts);
51
+ }
52
+ return counts;
53
+ }
54
+ getFixtureMatchCount(fixture, testId = DEFAULT_TEST_ID) {
55
+ return this.getFixtureMatchCountsForTest(testId).get(fixture) ?? 0;
42
56
  }
43
- incrementFixtureMatchCount(fixture, allFixtures) {
44
- this.fixtureMatchCounts.set(fixture, this.getFixtureMatchCount(fixture) + 1);
57
+ incrementFixtureMatchCount(fixture, allFixtures, testId = DEFAULT_TEST_ID) {
58
+ const counts = this.getFixtureMatchCountsForTest(testId);
59
+ counts.set(fixture, (counts.get(fixture) ?? 0) + 1);
45
60
  if (fixture.match.sequenceIndex !== void 0 && allFixtures) for (const sibling of allFixtures) {
46
61
  if (sibling === fixture) continue;
47
62
  if (sibling.match.sequenceIndex === void 0) continue;
48
- if (matchCriteriaEqual(fixture.match, sibling.match)) this.fixtureMatchCounts.set(sibling, this.getFixtureMatchCount(sibling) + 1);
63
+ if (matchCriteriaEqual(fixture.match, sibling.match)) counts.set(sibling, (counts.get(sibling) ?? 0) + 1);
49
64
  }
50
65
  }
51
- clearMatchCounts() {
52
- this.fixtureMatchCounts.clear();
66
+ clearMatchCounts(testId) {
67
+ if (testId !== void 0) this.fixtureMatchCountsByTestId.delete(testId);
68
+ else this.fixtureMatchCountsByTestId.clear();
53
69
  }
54
70
  clear() {
55
71
  this.entries = [];
56
- this.fixtureMatchCounts.clear();
72
+ this.fixtureMatchCountsByTestId.clear();
57
73
  }
58
74
  get size() {
59
75
  return this.entries.length;
@@ -61,5 +77,6 @@ var Journal = class {
61
77
  };
62
78
 
63
79
  //#endregion
80
+ exports.DEFAULT_TEST_ID = DEFAULT_TEST_ID;
64
81
  exports.Journal = Journal;
65
82
  //# sourceMappingURL=journal.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"journal.cjs","names":["generateId"],"sources":["../src/journal.ts"],"sourcesContent":["import { generateId } from \"./helpers.js\";\nimport type { Fixture, FixtureMatch, JournalEntry } from \"./types.js\";\n\n/**\n * Compare two field values, handling RegExp by source+flags rather than reference.\n */\nfunction fieldEqual(a: unknown, b: unknown): boolean {\n if (a instanceof RegExp && b instanceof RegExp)\n return a.source === b.source && a.flags === b.flags;\n return a === b;\n}\n\n/**\n * Check whether two fixture match objects have the same criteria\n * (ignoring sequenceIndex). Used to group sequenced fixtures.\n */\nfunction matchCriteriaEqual(a: FixtureMatch, b: FixtureMatch): boolean {\n return (\n fieldEqual(a.userMessage, b.userMessage) &&\n fieldEqual(a.inputText, b.inputText) &&\n fieldEqual(a.toolCallId, b.toolCallId) &&\n fieldEqual(a.toolName, b.toolName) &&\n fieldEqual(a.model, b.model) &&\n fieldEqual(a.responseFormat, b.responseFormat) &&\n fieldEqual(a.predicate, b.predicate)\n );\n}\n\nexport class Journal {\n private entries: JournalEntry[] = [];\n readonly fixtureMatchCounts: Map<Fixture, number> = new Map();\n\n add(entry: Omit<JournalEntry, \"id\" | \"timestamp\">): JournalEntry {\n const full: JournalEntry = {\n id: generateId(\"req\"),\n timestamp: Date.now(),\n ...entry,\n };\n this.entries.push(full);\n return full;\n }\n\n getAll(opts?: { limit?: number }): JournalEntry[] {\n if (opts?.limit !== undefined) {\n return this.entries.slice(-opts.limit);\n }\n return this.entries.slice();\n }\n\n getLast(): JournalEntry | null {\n return this.entries.length > 0 ? this.entries[this.entries.length - 1] : null;\n }\n\n findByFixture(fixture: Fixture): JournalEntry[] {\n return this.entries.filter((e) => e.response.fixture === fixture);\n }\n\n getFixtureMatchCount(fixture: Fixture): number {\n return this.fixtureMatchCounts.get(fixture) ?? 0;\n }\n\n incrementFixtureMatchCount(fixture: Fixture, allFixtures?: readonly Fixture[]): void {\n this.fixtureMatchCounts.set(fixture, this.getFixtureMatchCount(fixture) + 1);\n // When a sequenced fixture matches, also increment all siblings with matching criteria\n if (fixture.match.sequenceIndex !== undefined && allFixtures) {\n for (const sibling of allFixtures) {\n if (sibling === fixture) continue;\n if (sibling.match.sequenceIndex === undefined) continue;\n if (matchCriteriaEqual(fixture.match, sibling.match)) {\n this.fixtureMatchCounts.set(sibling, this.getFixtureMatchCount(sibling) + 1);\n }\n }\n }\n }\n\n clearMatchCounts(): void {\n this.fixtureMatchCounts.clear();\n }\n\n clear(): void {\n this.entries = [];\n this.fixtureMatchCounts.clear();\n }\n\n get size(): number {\n return this.entries.length;\n }\n}\n"],"mappings":";;;;;;AAMA,SAAS,WAAW,GAAY,GAAqB;AACnD,KAAI,aAAa,UAAU,aAAa,OACtC,QAAO,EAAE,WAAW,EAAE,UAAU,EAAE,UAAU,EAAE;AAChD,QAAO,MAAM;;;;;;AAOf,SAAS,mBAAmB,GAAiB,GAA0B;AACrE,QACE,WAAW,EAAE,aAAa,EAAE,YAAY,IACxC,WAAW,EAAE,WAAW,EAAE,UAAU,IACpC,WAAW,EAAE,YAAY,EAAE,WAAW,IACtC,WAAW,EAAE,UAAU,EAAE,SAAS,IAClC,WAAW,EAAE,OAAO,EAAE,MAAM,IAC5B,WAAW,EAAE,gBAAgB,EAAE,eAAe,IAC9C,WAAW,EAAE,WAAW,EAAE,UAAU;;AAIxC,IAAa,UAAb,MAAqB;CACnB,AAAQ,UAA0B,EAAE;CACpC,AAAS,qCAA2C,IAAI,KAAK;CAE7D,IAAI,OAA6D;EAC/D,MAAM,OAAqB;GACzB,IAAIA,2BAAW,MAAM;GACrB,WAAW,KAAK,KAAK;GACrB,GAAG;GACJ;AACD,OAAK,QAAQ,KAAK,KAAK;AACvB,SAAO;;CAGT,OAAO,MAA2C;AAChD,MAAI,MAAM,UAAU,OAClB,QAAO,KAAK,QAAQ,MAAM,CAAC,KAAK,MAAM;AAExC,SAAO,KAAK,QAAQ,OAAO;;CAG7B,UAA+B;AAC7B,SAAO,KAAK,QAAQ,SAAS,IAAI,KAAK,QAAQ,KAAK,QAAQ,SAAS,KAAK;;CAG3E,cAAc,SAAkC;AAC9C,SAAO,KAAK,QAAQ,QAAQ,MAAM,EAAE,SAAS,YAAY,QAAQ;;CAGnE,qBAAqB,SAA0B;AAC7C,SAAO,KAAK,mBAAmB,IAAI,QAAQ,IAAI;;CAGjD,2BAA2B,SAAkB,aAAwC;AACnF,OAAK,mBAAmB,IAAI,SAAS,KAAK,qBAAqB,QAAQ,GAAG,EAAE;AAE5E,MAAI,QAAQ,MAAM,kBAAkB,UAAa,YAC/C,MAAK,MAAM,WAAW,aAAa;AACjC,OAAI,YAAY,QAAS;AACzB,OAAI,QAAQ,MAAM,kBAAkB,OAAW;AAC/C,OAAI,mBAAmB,QAAQ,OAAO,QAAQ,MAAM,CAClD,MAAK,mBAAmB,IAAI,SAAS,KAAK,qBAAqB,QAAQ,GAAG,EAAE;;;CAMpF,mBAAyB;AACvB,OAAK,mBAAmB,OAAO;;CAGjC,QAAc;AACZ,OAAK,UAAU,EAAE;AACjB,OAAK,mBAAmB,OAAO;;CAGjC,IAAI,OAAe;AACjB,SAAO,KAAK,QAAQ"}
1
+ {"version":3,"file":"journal.cjs","names":["generateId"],"sources":["../src/journal.ts"],"sourcesContent":["import { generateId } from \"./helpers.js\";\nimport type { Fixture, FixtureMatch, JournalEntry } from \"./types.js\";\n\n/** Sentinel testId used when no explicit test scope is provided. */\nexport const DEFAULT_TEST_ID = \"__default__\";\n\n/**\n * Compare two field values, handling RegExp by source+flags rather than reference.\n */\nfunction fieldEqual(a: unknown, b: unknown): boolean {\n if (a instanceof RegExp && b instanceof RegExp)\n return a.source === b.source && a.flags === b.flags;\n return a === b;\n}\n\n/**\n * Check whether two fixture match objects have the same criteria\n * (ignoring sequenceIndex). Used to group sequenced fixtures.\n */\nfunction matchCriteriaEqual(a: FixtureMatch, b: FixtureMatch): boolean {\n return (\n fieldEqual(a.userMessage, b.userMessage) &&\n fieldEqual(a.inputText, b.inputText) &&\n fieldEqual(a.toolCallId, b.toolCallId) &&\n fieldEqual(a.toolName, b.toolName) &&\n fieldEqual(a.model, b.model) &&\n fieldEqual(a.responseFormat, b.responseFormat) &&\n fieldEqual(a.predicate, b.predicate)\n );\n}\n\nexport class Journal {\n private entries: JournalEntry[] = [];\n private readonly fixtureMatchCountsByTestId: Map<string, Map<Fixture, number>> = new Map();\n\n /** Backwards-compatible accessor — returns the default (no testId) count map. */\n get fixtureMatchCounts(): Map<Fixture, number> {\n return this.getFixtureMatchCountsForTest(DEFAULT_TEST_ID);\n }\n\n add(entry: Omit<JournalEntry, \"id\" | \"timestamp\">): JournalEntry {\n const full: JournalEntry = {\n id: generateId(\"req\"),\n timestamp: Date.now(),\n ...entry,\n };\n this.entries.push(full);\n return full;\n }\n\n getAll(opts?: { limit?: number }): JournalEntry[] {\n if (opts?.limit !== undefined) {\n return this.entries.slice(-opts.limit);\n }\n return this.entries.slice();\n }\n\n getLast(): JournalEntry | null {\n return this.entries.length > 0 ? this.entries[this.entries.length - 1] : null;\n }\n\n findByFixture(fixture: Fixture): JournalEntry[] {\n return this.entries.filter((e) => e.response.fixture === fixture);\n }\n\n getFixtureMatchCountsForTest(testId: string): Map<Fixture, number> {\n let counts = this.fixtureMatchCountsByTestId.get(testId);\n if (!counts) {\n counts = new Map();\n this.fixtureMatchCountsByTestId.set(testId, counts);\n }\n return counts;\n }\n\n getFixtureMatchCount(fixture: Fixture, testId = DEFAULT_TEST_ID): number {\n return this.getFixtureMatchCountsForTest(testId).get(fixture) ?? 0;\n }\n\n incrementFixtureMatchCount(\n fixture: Fixture,\n allFixtures?: readonly Fixture[],\n testId = DEFAULT_TEST_ID,\n ): void {\n const counts = this.getFixtureMatchCountsForTest(testId);\n counts.set(fixture, (counts.get(fixture) ?? 0) + 1);\n // When a sequenced fixture matches, also increment all siblings with matching criteria\n if (fixture.match.sequenceIndex !== undefined && allFixtures) {\n for (const sibling of allFixtures) {\n if (sibling === fixture) continue;\n if (sibling.match.sequenceIndex === undefined) continue;\n if (matchCriteriaEqual(fixture.match, sibling.match)) {\n counts.set(sibling, (counts.get(sibling) ?? 0) + 1);\n }\n }\n }\n }\n\n clearMatchCounts(testId?: string): void {\n if (testId !== undefined) {\n this.fixtureMatchCountsByTestId.delete(testId);\n } else {\n this.fixtureMatchCountsByTestId.clear();\n }\n }\n\n clear(): void {\n this.entries = [];\n this.fixtureMatchCountsByTestId.clear();\n }\n\n get size(): number {\n return this.entries.length;\n }\n}\n"],"mappings":";;;;AAIA,MAAa,kBAAkB;;;;AAK/B,SAAS,WAAW,GAAY,GAAqB;AACnD,KAAI,aAAa,UAAU,aAAa,OACtC,QAAO,EAAE,WAAW,EAAE,UAAU,EAAE,UAAU,EAAE;AAChD,QAAO,MAAM;;;;;;AAOf,SAAS,mBAAmB,GAAiB,GAA0B;AACrE,QACE,WAAW,EAAE,aAAa,EAAE,YAAY,IACxC,WAAW,EAAE,WAAW,EAAE,UAAU,IACpC,WAAW,EAAE,YAAY,EAAE,WAAW,IACtC,WAAW,EAAE,UAAU,EAAE,SAAS,IAClC,WAAW,EAAE,OAAO,EAAE,MAAM,IAC5B,WAAW,EAAE,gBAAgB,EAAE,eAAe,IAC9C,WAAW,EAAE,WAAW,EAAE,UAAU;;AAIxC,IAAa,UAAb,MAAqB;CACnB,AAAQ,UAA0B,EAAE;CACpC,AAAiB,6CAAgE,IAAI,KAAK;;CAG1F,IAAI,qBAA2C;AAC7C,SAAO,KAAK,6BAA6B,gBAAgB;;CAG3D,IAAI,OAA6D;EAC/D,MAAM,OAAqB;GACzB,IAAIA,2BAAW,MAAM;GACrB,WAAW,KAAK,KAAK;GACrB,GAAG;GACJ;AACD,OAAK,QAAQ,KAAK,KAAK;AACvB,SAAO;;CAGT,OAAO,MAA2C;AAChD,MAAI,MAAM,UAAU,OAClB,QAAO,KAAK,QAAQ,MAAM,CAAC,KAAK,MAAM;AAExC,SAAO,KAAK,QAAQ,OAAO;;CAG7B,UAA+B;AAC7B,SAAO,KAAK,QAAQ,SAAS,IAAI,KAAK,QAAQ,KAAK,QAAQ,SAAS,KAAK;;CAG3E,cAAc,SAAkC;AAC9C,SAAO,KAAK,QAAQ,QAAQ,MAAM,EAAE,SAAS,YAAY,QAAQ;;CAGnE,6BAA6B,QAAsC;EACjE,IAAI,SAAS,KAAK,2BAA2B,IAAI,OAAO;AACxD,MAAI,CAAC,QAAQ;AACX,4BAAS,IAAI,KAAK;AAClB,QAAK,2BAA2B,IAAI,QAAQ,OAAO;;AAErD,SAAO;;CAGT,qBAAqB,SAAkB,SAAS,iBAAyB;AACvE,SAAO,KAAK,6BAA6B,OAAO,CAAC,IAAI,QAAQ,IAAI;;CAGnE,2BACE,SACA,aACA,SAAS,iBACH;EACN,MAAM,SAAS,KAAK,6BAA6B,OAAO;AACxD,SAAO,IAAI,UAAU,OAAO,IAAI,QAAQ,IAAI,KAAK,EAAE;AAEnD,MAAI,QAAQ,MAAM,kBAAkB,UAAa,YAC/C,MAAK,MAAM,WAAW,aAAa;AACjC,OAAI,YAAY,QAAS;AACzB,OAAI,QAAQ,MAAM,kBAAkB,OAAW;AAC/C,OAAI,mBAAmB,QAAQ,OAAO,QAAQ,MAAM,CAClD,QAAO,IAAI,UAAU,OAAO,IAAI,QAAQ,IAAI,KAAK,EAAE;;;CAM3D,iBAAiB,QAAuB;AACtC,MAAI,WAAW,OACb,MAAK,2BAA2B,OAAO,OAAO;MAE9C,MAAK,2BAA2B,OAAO;;CAI3C,QAAc;AACZ,OAAK,UAAU,EAAE;AACjB,OAAK,2BAA2B,OAAO;;CAGzC,IAAI,OAAe;AACjB,SAAO,KAAK,QAAQ"}
@@ -1,23 +1,28 @@
1
1
  import { Fixture, JournalEntry } from "./types.cjs";
2
2
 
3
3
  //#region src/journal.d.ts
4
+ /** Sentinel testId used when no explicit test scope is provided. */
5
+ declare const DEFAULT_TEST_ID = "__default__";
4
6
  declare class Journal {
5
7
  private entries;
6
- readonly fixtureMatchCounts: Map<Fixture, number>;
8
+ private readonly fixtureMatchCountsByTestId;
9
+ /** Backwards-compatible accessor — returns the default (no testId) count map. */
10
+ get fixtureMatchCounts(): Map<Fixture, number>;
7
11
  add(entry: Omit<JournalEntry, "id" | "timestamp">): JournalEntry;
8
12
  getAll(opts?: {
9
13
  limit?: number;
10
14
  }): JournalEntry[];
11
15
  getLast(): JournalEntry | null;
12
16
  findByFixture(fixture: Fixture): JournalEntry[];
13
- getFixtureMatchCount(fixture: Fixture): number;
14
- incrementFixtureMatchCount(fixture: Fixture, allFixtures?: readonly Fixture[]): void;
15
- clearMatchCounts(): void;
17
+ getFixtureMatchCountsForTest(testId: string): Map<Fixture, number>;
18
+ getFixtureMatchCount(fixture: Fixture, testId?: string): number;
19
+ incrementFixtureMatchCount(fixture: Fixture, allFixtures?: readonly Fixture[], testId?: string): void;
20
+ clearMatchCounts(testId?: string): void;
16
21
  clear(): void;
17
22
  get size(): number;
18
23
  }
19
24
  //# sourceMappingURL=journal.d.ts.map
20
25
 
21
26
  //#endregion
22
- export { Journal };
27
+ export { DEFAULT_TEST_ID, Journal };
23
28
  //# sourceMappingURL=journal.d.cts.map
@@ -1 +1 @@
1
- {"version":3,"file":"journal.d.cts","names":[],"sources":["../src/journal.ts"],"sourcesContent":[],"mappings":";;;cA4Ba,OAAA;;EAAA,SAAA,kBAAO,EAEW,GAFX,CAEe,OAFf,EAAA,MAAA,CAAA;EAAA,GAAA,CAAA,KAAA,EAIP,IAJO,CAIF,YAJE,EAAA,IAAA,GAAA,WAAA,CAAA,CAAA,EAIkC,YAJlC;QAEe,CAAA,KAAA,EAAA;IAAJ,KAAA,CAAA,EAAA,MAAA;MAYM,YAVnB,EAAA;SAAL,CAAA,CAAA,EAiBA,YAjBA,GAAA,IAAA;eAAyC,CAAA,OAAA,EAqB7B,OArB6B,CAAA,EAqBnB,YArBmB,EAAA;sBAUjB,CAAA,OAAA,EAeL,OAfK,CAAA,EAAA,MAAA;4BAOxB,CAAA,OAAA,EAYyB,OAZzB,EAAA,WAAA,CAAA,EAAA,SAYyD,OAZzD,EAAA,CAAA,EAAA,IAAA;kBAIY,CAAA,CAAA,EAAA,IAAA;OAAU,CAAA,CAAA,EAAA,IAAA;MAIH,IAAA,CAAA,CAAA,EAAA,MAAA"}
1
+ {"version":3,"file":"journal.d.cts","names":[],"sources":["../src/journal.ts"],"sourcesContent":[],"mappings":";;;;cAIa,eAAA;AAAA,cA2BA,OAAA,CA3Be;EA2Bf,QAAA,OAAO;EAAA,iBAAA,0BAAA;;MAKQ,kBAAA,CAAA,CAAA,EAAA,GAAA,CAAI,OAAJ,EAAA,MAAA,CAAA;KAIV,CAAA,KAAA,EAAL,IAAK,CAAA,YAAA,EAAA,IAAA,GAAA,WAAA,CAAA,CAAA,EAAoC,YAApC;QAAL,CAAA,KAAA,EAAA;IAAyC,KAAA,CAAA,EAAA,MAAA;MAUjB,YAAA,EAAA;SAOxB,CAAA,CAAA,EAAA,YAAA,GAAA,IAAA;eAIY,CAAA,OAAA,EAAA,OAAA,CAAA,EAAU,YAAV,EAAA;8BAAU,CAAA,MAAA,EAAA,MAAA,CAAA,EAIa,GAJb,CAIiB,OAJjB,EAAA,MAAA,CAAA;sBAIiB,CAAA,OAAA,EASpB,OAToB,EAAA,MAAA,CAAA,EAAA,MAAA,CAAA,EAAA,MAAA;4BAAJ,CAAA,OAAA,EAcnC,OAdmC,EAAA,WAAA,CAAA,EAAA,SAerB,OAfqB,EAAA,EAAA,MAAA,CAAA,EAAA,MAAA,CAAA,EAAA,IAAA;kBAShB,CAAA,MAAA,CAAA,EAAA,MAAA,CAAA,EAAA,IAAA;OAKnB,CAAA,CAAA,EAAA,IAAA;MACc,IAAA,CAAA,CAAA,EAAA,MAAA"}
package/dist/journal.d.ts CHANGED
@@ -1,23 +1,28 @@
1
1
  import { Fixture, JournalEntry } from "./types.js";
2
2
 
3
3
  //#region src/journal.d.ts
4
+ /** Sentinel testId used when no explicit test scope is provided. */
5
+ declare const DEFAULT_TEST_ID = "__default__";
4
6
  declare class Journal {
5
7
  private entries;
6
- readonly fixtureMatchCounts: Map<Fixture, number>;
8
+ private readonly fixtureMatchCountsByTestId;
9
+ /** Backwards-compatible accessor — returns the default (no testId) count map. */
10
+ get fixtureMatchCounts(): Map<Fixture, number>;
7
11
  add(entry: Omit<JournalEntry, "id" | "timestamp">): JournalEntry;
8
12
  getAll(opts?: {
9
13
  limit?: number;
10
14
  }): JournalEntry[];
11
15
  getLast(): JournalEntry | null;
12
16
  findByFixture(fixture: Fixture): JournalEntry[];
13
- getFixtureMatchCount(fixture: Fixture): number;
14
- incrementFixtureMatchCount(fixture: Fixture, allFixtures?: readonly Fixture[]): void;
15
- clearMatchCounts(): void;
17
+ getFixtureMatchCountsForTest(testId: string): Map<Fixture, number>;
18
+ getFixtureMatchCount(fixture: Fixture, testId?: string): number;
19
+ incrementFixtureMatchCount(fixture: Fixture, allFixtures?: readonly Fixture[], testId?: string): void;
20
+ clearMatchCounts(testId?: string): void;
16
21
  clear(): void;
17
22
  get size(): number;
18
23
  }
19
24
  //# sourceMappingURL=journal.d.ts.map
20
25
 
21
26
  //#endregion
22
- export { Journal };
27
+ export { DEFAULT_TEST_ID, Journal };
23
28
  //# sourceMappingURL=journal.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"journal.d.ts","names":[],"sources":["../src/journal.ts"],"sourcesContent":[],"mappings":";;;cA4Ba,OAAA;;EAAA,SAAA,kBAAO,EAEW,GAFX,CAEe,OAFf,EAAA,MAAA,CAAA;EAAA,GAAA,CAAA,KAAA,EAIP,IAJO,CAIF,YAJE,EAAA,IAAA,GAAA,WAAA,CAAA,CAAA,EAIkC,YAJlC;QAEe,CAAA,KAAA,EAAA;IAAJ,KAAA,CAAA,EAAA,MAAA;MAYM,YAVnB,EAAA;SAAL,CAAA,CAAA,EAiBA,YAjBA,GAAA,IAAA;eAAyC,CAAA,OAAA,EAqB7B,OArB6B,CAAA,EAqBnB,YArBmB,EAAA;sBAUjB,CAAA,OAAA,EAeL,OAfK,CAAA,EAAA,MAAA;4BAOxB,CAAA,OAAA,EAYyB,OAZzB,EAAA,WAAA,CAAA,EAAA,SAYyD,OAZzD,EAAA,CAAA,EAAA,IAAA;kBAIY,CAAA,CAAA,EAAA,IAAA;OAAU,CAAA,CAAA,EAAA,IAAA;MAIH,IAAA,CAAA,CAAA,EAAA,MAAA"}
1
+ {"version":3,"file":"journal.d.ts","names":[],"sources":["../src/journal.ts"],"sourcesContent":[],"mappings":";;;;cAIa,eAAA;AAAA,cA2BA,OAAA,CA3Be;EA2Bf,QAAA,OAAO;EAAA,iBAAA,0BAAA;;MAKQ,kBAAA,CAAA,CAAA,EAAA,GAAA,CAAI,OAAJ,EAAA,MAAA,CAAA;KAIV,CAAA,KAAA,EAAL,IAAK,CAAA,YAAA,EAAA,IAAA,GAAA,WAAA,CAAA,CAAA,EAAoC,YAApC;QAAL,CAAA,KAAA,EAAA;IAAyC,KAAA,CAAA,EAAA,MAAA;MAUjB,YAAA,EAAA;SAOxB,CAAA,CAAA,EAAA,YAAA,GAAA,IAAA;eAIY,CAAA,OAAA,EAAA,OAAA,CAAA,EAAU,YAAV,EAAA;8BAAU,CAAA,MAAA,EAAA,MAAA,CAAA,EAIa,GAJb,CAIiB,OAJjB,EAAA,MAAA,CAAA;sBAIiB,CAAA,OAAA,EASpB,OAToB,EAAA,MAAA,CAAA,EAAA,MAAA,CAAA,EAAA,MAAA;4BAAJ,CAAA,OAAA,EAcnC,OAdmC,EAAA,WAAA,CAAA,EAAA,SAerB,OAfqB,EAAA,EAAA,MAAA,CAAA,EAAA,MAAA,CAAA,EAAA,IAAA;kBAShB,CAAA,MAAA,CAAA,EAAA,MAAA,CAAA,EAAA,IAAA;OAKnB,CAAA,CAAA,EAAA,IAAA;MACc,IAAA,CAAA,CAAA,EAAA,MAAA"}
package/dist/journal.js CHANGED
@@ -1,6 +1,8 @@
1
1
  import { generateId } from "./helpers.js";
2
2
 
3
3
  //#region src/journal.ts
4
+ /** Sentinel testId used when no explicit test scope is provided. */
5
+ const DEFAULT_TEST_ID = "__default__";
4
6
  /**
5
7
  * Compare two field values, handling RegExp by source+flags rather than reference.
6
8
  */
@@ -17,7 +19,11 @@ function matchCriteriaEqual(a, b) {
17
19
  }
18
20
  var Journal = class {
19
21
  entries = [];
20
- fixtureMatchCounts = /* @__PURE__ */ new Map();
22
+ fixtureMatchCountsByTestId = /* @__PURE__ */ new Map();
23
+ /** Backwards-compatible accessor — returns the default (no testId) count map. */
24
+ get fixtureMatchCounts() {
25
+ return this.getFixtureMatchCountsForTest(DEFAULT_TEST_ID);
26
+ }
21
27
  add(entry) {
22
28
  const full = {
23
29
  id: generateId("req"),
@@ -37,23 +43,33 @@ var Journal = class {
37
43
  findByFixture(fixture) {
38
44
  return this.entries.filter((e) => e.response.fixture === fixture);
39
45
  }
40
- getFixtureMatchCount(fixture) {
41
- return this.fixtureMatchCounts.get(fixture) ?? 0;
46
+ getFixtureMatchCountsForTest(testId) {
47
+ let counts = this.fixtureMatchCountsByTestId.get(testId);
48
+ if (!counts) {
49
+ counts = /* @__PURE__ */ new Map();
50
+ this.fixtureMatchCountsByTestId.set(testId, counts);
51
+ }
52
+ return counts;
53
+ }
54
+ getFixtureMatchCount(fixture, testId = DEFAULT_TEST_ID) {
55
+ return this.getFixtureMatchCountsForTest(testId).get(fixture) ?? 0;
42
56
  }
43
- incrementFixtureMatchCount(fixture, allFixtures) {
44
- this.fixtureMatchCounts.set(fixture, this.getFixtureMatchCount(fixture) + 1);
57
+ incrementFixtureMatchCount(fixture, allFixtures, testId = DEFAULT_TEST_ID) {
58
+ const counts = this.getFixtureMatchCountsForTest(testId);
59
+ counts.set(fixture, (counts.get(fixture) ?? 0) + 1);
45
60
  if (fixture.match.sequenceIndex !== void 0 && allFixtures) for (const sibling of allFixtures) {
46
61
  if (sibling === fixture) continue;
47
62
  if (sibling.match.sequenceIndex === void 0) continue;
48
- if (matchCriteriaEqual(fixture.match, sibling.match)) this.fixtureMatchCounts.set(sibling, this.getFixtureMatchCount(sibling) + 1);
63
+ if (matchCriteriaEqual(fixture.match, sibling.match)) counts.set(sibling, (counts.get(sibling) ?? 0) + 1);
49
64
  }
50
65
  }
51
- clearMatchCounts() {
52
- this.fixtureMatchCounts.clear();
66
+ clearMatchCounts(testId) {
67
+ if (testId !== void 0) this.fixtureMatchCountsByTestId.delete(testId);
68
+ else this.fixtureMatchCountsByTestId.clear();
53
69
  }
54
70
  clear() {
55
71
  this.entries = [];
56
- this.fixtureMatchCounts.clear();
72
+ this.fixtureMatchCountsByTestId.clear();
57
73
  }
58
74
  get size() {
59
75
  return this.entries.length;
@@ -61,5 +77,5 @@ var Journal = class {
61
77
  };
62
78
 
63
79
  //#endregion
64
- export { Journal };
80
+ export { DEFAULT_TEST_ID, Journal };
65
81
  //# sourceMappingURL=journal.js.map