{"version":3,"file":"fixture-loader.cjs","names":["isContentWithToolCallsResponse","isTextResponse","isToolCallResponse","isErrorResponse","isEmbeddingResponse","isImageResponse","isAudioResponse","isTranscriptionResponse","isVideoResponse","isJSONResponse"],"sources":["../src/fixture-loader.ts"],"sourcesContent":["import { readFileSync, readdirSync, statSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport type {\n  Fixture,\n  FixtureFile,\n  FixtureFileEntry,\n  FixtureFileResponse,\n  FixtureResponse,\n  ResponseOverrides,\n} from \"./types.js\";\nimport {\n  isTextResponse,\n  isToolCallResponse,\n  isContentWithToolCallsResponse,\n  isErrorResponse,\n  isEmbeddingResponse,\n  isImageResponse,\n  isAudioResponse,\n  isTranscriptionResponse,\n  isVideoResponse,\n  isJSONResponse,\n} from \"./helpers.js\";\nimport type { Logger } from \"./logger.js\";\n\n/**\n * Auto-stringify object-valued `content` and `toolCalls[].arguments` fields.\n * This lets fixture authors write plain JSON objects instead of escaped strings.\n * All other fields (including ResponseOverrides) pass through unmodified.\n */\nexport function normalizeResponse(raw: FixtureFileResponse): FixtureResponse {\n  // Shallow-clone so we don't mutate the parsed JSON input.\n  const response = { ...raw } as Record<string, unknown>;\n\n  // Auto-stringify object content (e.g. structured output)\n  if (typeof response.content === \"object\" && response.content !== null) {\n    response.content = JSON.stringify(response.content);\n  }\n\n  // Auto-stringify object arguments in toolCalls\n  if (Array.isArray(response.toolCalls)) {\n    response.toolCalls = (response.toolCalls as Array<Record<string, unknown>>).map((tc) => {\n      if (typeof tc.arguments === \"object\" && tc.arguments !== null) {\n        return { ...tc, arguments: JSON.stringify(tc.arguments) };\n      }\n      return tc;\n    });\n  }\n\n  return response as unknown as FixtureResponse;\n}\n\nexport function entryToFixture(entry: FixtureFileEntry, logger?: Logger): Fixture {\n  const fixture: Fixture = {\n    match: {\n      userMessage: entry.match.userMessage,\n      systemMessage: entry.match.systemMessage,\n      inputText: entry.match.inputText,\n      toolCallId: entry.match.toolCallId,\n      toolName: entry.match.toolName,\n      model: entry.match.model,\n      responseFormat: entry.match.responseFormat,\n      endpoint: entry.match.endpoint,\n      ...(entry.match.sequenceIndex !== undefined && { sequenceIndex: entry.match.sequenceIndex }),\n      ...(entry.match.turnIndex !== undefined && {\n        turnIndex: entry.match.turnIndex,\n      }),\n      ...(entry.match.hasToolResult !== undefined && {\n        hasToolResult: entry.match.hasToolResult,\n      }),\n      ...(entry.match.context !== undefined && { context: entry.match.context }),\n    },\n    response: normalizeResponse(entry.response),\n    ...(entry.latency !== undefined && { latency: entry.latency }),\n    ...(entry.chunkSize !== undefined && { chunkSize: entry.chunkSize }),\n    ...(entry.truncateAfterChunks !== undefined && {\n      truncateAfterChunks: entry.truncateAfterChunks,\n    }),\n    ...(entry.disconnectAfterMs !== undefined && { disconnectAfterMs: entry.disconnectAfterMs }),\n    ...(entry.streamingProfile !== undefined && { streamingProfile: entry.streamingProfile }),\n    ...(entry.recordedTimings !== undefined && { recordedTimings: entry.recordedTimings }),\n    ...(entry.replaySpeed != null && { replaySpeed: entry.replaySpeed }),\n    ...(entry.chaos !== undefined && { chaos: entry.chaos }),\n    ...(entry.metadata !== undefined && { metadata: entry.metadata }),\n  };\n\n  // Sanitize recordedTimings to guard against NaN or negative values that\n  // would silently degrade replay timing calculations.\n  if (fixture.recordedTimings) {\n    const rt = fixture.recordedTimings;\n    if (!Number.isFinite(rt.ttftMs) || rt.ttftMs < 0) rt.ttftMs = 0;\n    rt.interChunkDelaysMs = rt.interChunkDelaysMs.filter((d) => Number.isFinite(d) && d >= 0);\n    if (!Number.isFinite(rt.totalDurationMs) || rt.totalDurationMs < 0) rt.totalDurationMs = 0;\n  }\n\n  if (fixture.replaySpeed != null && fixture.replaySpeed <= 0) {\n    logger?.warn(`Fixture replaySpeed must be positive, got ${fixture.replaySpeed}. Ignoring.`);\n    delete fixture.replaySpeed;\n  }\n\n  return fixture;\n}\n\n// Logging helper — uses logger if provided, falls back to console.warn.\nfunction warn(logger: Logger | undefined, msg: string, ...rest: unknown[]): void {\n  if (logger) {\n    logger.warn(msg, ...rest);\n  } else {\n    console.warn(`[fixture-loader] ${msg}`, ...rest);\n  }\n}\n\nexport function loadFixtureFile(filePath: string, logger?: Logger): Fixture[] {\n  let raw: string;\n  try {\n    raw = readFileSync(filePath, \"utf-8\");\n  } catch (err) {\n    warn(logger, `Could not read file ${filePath}:`, err);\n    return [];\n  }\n\n  let parsed: unknown;\n  try {\n    parsed = JSON.parse(raw);\n  } catch (err) {\n    warn(logger, `Invalid JSON in ${filePath}:`, err);\n    return [];\n  }\n\n  if (\n    typeof parsed !== \"object\" ||\n    parsed === null ||\n    !Array.isArray((parsed as FixtureFile).fixtures)\n  ) {\n    warn(logger, `Missing or invalid \"fixtures\" array in ${filePath}`);\n    return [];\n  }\n\n  return (parsed as FixtureFile).fixtures.map((e) => entryToFixture(e, logger));\n}\n\nexport function loadFixturesFromDir(dirPath: string, logger?: Logger): Fixture[] {\n  let entries: string[];\n  try {\n    entries = readdirSync(dirPath);\n  } catch (err) {\n    warn(logger, `Could not read directory ${dirPath}:`, err);\n    return [];\n  }\n\n  const jsonFiles: string[] = [];\n  const subdirs: string[] = [];\n  for (const name of entries) {\n    const fullPath = join(dirPath, name);\n    try {\n      if (statSync(fullPath).isDirectory()) {\n        subdirs.push(name);\n        continue;\n      }\n    } catch (err) {\n      const code = (err as NodeJS.ErrnoException).code;\n      if (code !== \"ENOENT\") {\n        warn(logger, `Could not stat ${fullPath}:`, err);\n      }\n      continue;\n    }\n    if (name.endsWith(\".json\")) {\n      jsonFiles.push(name);\n    }\n  }\n  jsonFiles.sort();\n\n  const fixtures: Fixture[] = [];\n  for (const name of jsonFiles) {\n    const filePath = join(dirPath, name);\n    fixtures.push(...loadFixtureFile(filePath, logger));\n  }\n\n  // Recurse into all subdirectories (full depth) to support nested layouts\n  // like showcase/aimock/d6/<integration>/<feature>.json.\n  subdirs.sort();\n  for (const sub of subdirs) {\n    fixtures.push(...loadFixturesFromDir(join(dirPath, sub), logger));\n  }\n\n  return fixtures;\n}\n\n// ---------------------------------------------------------------------------\n// Fixture validation\n// ---------------------------------------------------------------------------\n\nexport interface ValidationResult {\n  severity: \"error\" | \"warning\";\n  fixtureIndex: number;\n  message: string;\n}\n\nfunction validateReasoning(\n  response: { reasoning?: unknown },\n  fixtureIndex: number,\n  results: ValidationResult[],\n): void {\n  if (response.reasoning !== undefined) {\n    if (typeof response.reasoning !== \"string\") {\n      results.push({\n        severity: \"error\",\n        fixtureIndex,\n        message: \"reasoning must be a string\",\n      });\n    } else if (response.reasoning === \"\") {\n      results.push({\n        severity: \"warning\",\n        fixtureIndex,\n        message: \"reasoning is empty string — no reasoning events will be emitted\",\n      });\n    }\n  }\n}\n\nfunction validateWebSearches(\n  response: { webSearches?: unknown },\n  fixtureIndex: number,\n  results: ValidationResult[],\n): void {\n  if (response.webSearches !== undefined) {\n    if (!Array.isArray(response.webSearches)) {\n      results.push({\n        severity: \"error\",\n        fixtureIndex,\n        message: \"webSearches must be an array of strings\",\n      });\n    } else if (response.webSearches.length === 0) {\n      results.push({\n        severity: \"warning\",\n        fixtureIndex,\n        message: \"webSearches is empty array — no web search events will be emitted\",\n      });\n    } else {\n      for (let j = 0; j < response.webSearches.length; j++) {\n        if (typeof response.webSearches[j] !== \"string\") {\n          results.push({\n            severity: \"error\",\n            fixtureIndex,\n            message: `webSearches[${j}] is not a string`,\n          });\n          break;\n        }\n        if (response.webSearches[j] === \"\") {\n          results.push({\n            severity: \"warning\",\n            fixtureIndex,\n            message: `webSearches[${j}] is empty string`,\n          });\n        }\n      }\n    }\n  }\n}\n\nexport function validateFixtures(fixtures: Fixture[]): ValidationResult[] {\n  const results: ValidationResult[] = [];\n\n  const seenUserMessages = new Map<string, number>();\n\n  for (let i = 0; i < fixtures.length; i++) {\n    const f = fixtures[i];\n    const response = f.response;\n\n    // Skip response-shape validation for function responses — they are\n    // evaluated at runtime so we cannot statically inspect them.\n    if (typeof response === \"function\") {\n      // Still validate match fields and numeric options below.\n    } else {\n      // --- Error checks ---\n\n      // Response type recognition\n      // Note: isContentWithToolCallsResponse must be checked before isTextResponse\n      // and isToolCallResponse since it is a structural superset of both.\n      if (\n        !isContentWithToolCallsResponse(response) &&\n        !isTextResponse(response) &&\n        !isToolCallResponse(response) &&\n        !isErrorResponse(response) &&\n        !isEmbeddingResponse(response) &&\n        !isImageResponse(response) &&\n        !isAudioResponse(response) &&\n        !isTranscriptionResponse(response) &&\n        !isVideoResponse(response) &&\n        !isJSONResponse(response)\n      ) {\n        results.push({\n          severity: \"error\",\n          fixtureIndex: i,\n          message:\n            \"response is not a recognized type (must have content, toolCalls, error, embedding, image, audio, transcription, video, or json)\",\n        });\n      }\n\n      // Text response checks\n      if (isTextResponse(response)) {\n        if (response.content === \"\") {\n          results.push({\n            severity: \"error\",\n            fixtureIndex: i,\n            message: \"content is empty string\",\n          });\n        }\n        validateReasoning(response, i, results);\n        validateWebSearches(response, i, results);\n      }\n\n      // ContentWithToolCalls response checks\n      if (isContentWithToolCallsResponse(response)) {\n        if (response.content === \"\") {\n          results.push({\n            severity: \"error\",\n            fixtureIndex: i,\n            message: \"content is empty string\",\n          });\n        }\n        if (response.toolCalls.length === 0) {\n          results.push({\n            severity: \"warning\",\n            fixtureIndex: i,\n            message: \"toolCalls array is empty — fixture will never produce tool calls\",\n          });\n        }\n        for (let j = 0; j < response.toolCalls.length; j++) {\n          const tc = response.toolCalls[j];\n          if (!tc.name) {\n            results.push({\n              severity: \"error\",\n              fixtureIndex: i,\n              message: `toolCalls[${j}].name is empty`,\n            });\n          }\n          try {\n            JSON.parse(tc.arguments);\n          } catch {\n            results.push({\n              severity: \"error\",\n              fixtureIndex: i,\n              message: `toolCalls[${j}].arguments is not valid JSON: ${tc.arguments}`,\n            });\n          }\n        }\n        validateReasoning(response, i, results);\n        validateWebSearches(response, i, results);\n      }\n\n      // Tool call response checks\n      if (isToolCallResponse(response)) {\n        if (response.toolCalls.length === 0) {\n          results.push({\n            severity: \"warning\",\n            fixtureIndex: i,\n            message: \"toolCalls array is empty — fixture will never produce tool calls\",\n          });\n        }\n        for (let j = 0; j < response.toolCalls.length; j++) {\n          const tc = response.toolCalls[j];\n          if (!tc.name) {\n            results.push({\n              severity: \"error\",\n              fixtureIndex: i,\n              message: `toolCalls[${j}].name is empty`,\n            });\n          }\n          try {\n            JSON.parse(tc.arguments);\n          } catch {\n            results.push({\n              severity: \"error\",\n              fixtureIndex: i,\n              message: `toolCalls[${j}].arguments is not valid JSON: ${tc.arguments}`,\n            });\n          }\n        }\n        validateWebSearches(response, i, results);\n      }\n\n      // Error response checks\n      if (isErrorResponse(response)) {\n        if (!response.error.message) {\n          results.push({\n            severity: \"error\",\n            fixtureIndex: i,\n            message: \"error.message is empty\",\n          });\n        }\n        if (response.status !== undefined && (response.status < 100 || response.status > 599)) {\n          results.push({\n            severity: \"error\",\n            fixtureIndex: i,\n            message: `error status ${response.status} is not a valid HTTP status code`,\n          });\n        }\n      }\n\n      // Embedding response checks\n      if (isEmbeddingResponse(response)) {\n        if (response.embedding.length === 0) {\n          results.push({\n            severity: \"error\",\n            fixtureIndex: i,\n            message: \"embedding array is empty\",\n          });\n        }\n        for (let j = 0; j < response.embedding.length; j++) {\n          if (typeof response.embedding[j] !== \"number\") {\n            results.push({\n              severity: \"error\",\n              fixtureIndex: i,\n              message: `embedding[${j}] is not a number`,\n            });\n            break; // one error is enough\n          }\n        }\n      }\n\n      // Audio response checks — validate object-form audio\n      if (isAudioResponse(response) && typeof response.audio === \"object\") {\n        const audioObj = response.audio;\n        if (typeof audioObj.b64Json !== \"string\" || audioObj.b64Json === \"\") {\n          results.push({\n            severity: \"error\",\n            fixtureIndex: i,\n            message: \"audio.b64Json must be a non-empty string\",\n          });\n        }\n        if (audioObj.contentType !== undefined && typeof audioObj.contentType !== \"string\") {\n          results.push({\n            severity: \"error\",\n            fixtureIndex: i,\n            message: `audio.contentType must be a string, got ${typeof audioObj.contentType}`,\n          });\n        }\n      }\n\n      // Validate ResponseOverrides fields\n      if (\n        isTextResponse(response) ||\n        isToolCallResponse(response) ||\n        isContentWithToolCallsResponse(response)\n      ) {\n        const r = response as ResponseOverrides;\n        if (r.id !== undefined && typeof r.id !== \"string\") {\n          results.push({\n            severity: \"error\",\n            fixtureIndex: i,\n            message: `override \"id\" must be a string, got ${typeof r.id}`,\n          });\n        }\n        if (r.created !== undefined && (typeof r.created !== \"number\" || r.created < 0)) {\n          results.push({\n            severity: \"error\",\n            fixtureIndex: i,\n            message: `override \"created\" must be a non-negative number`,\n          });\n        }\n        if (r.model !== undefined && typeof r.model !== \"string\") {\n          results.push({\n            severity: \"error\",\n            fixtureIndex: i,\n            message: `override \"model\" must be a string, got ${typeof r.model}`,\n          });\n        }\n        if (r.finishReason !== undefined && typeof r.finishReason !== \"string\") {\n          results.push({\n            severity: \"error\",\n            fixtureIndex: i,\n            message: `override \"finishReason\" must be a string, got ${typeof r.finishReason}`,\n          });\n        }\n        if (r.role !== undefined && typeof r.role !== \"string\") {\n          results.push({\n            severity: \"error\",\n            fixtureIndex: i,\n            message: `override \"role\" must be a string, got ${typeof r.role}`,\n          });\n        }\n        if (r.systemFingerprint !== undefined && typeof r.systemFingerprint !== \"string\") {\n          results.push({\n            severity: \"error\",\n            fixtureIndex: i,\n            message: `override \"systemFingerprint\" must be a string, got ${typeof r.systemFingerprint}`,\n          });\n        }\n        if (r.usage !== undefined) {\n          if (typeof r.usage !== \"object\" || r.usage === null || Array.isArray(r.usage)) {\n            results.push({\n              severity: \"error\",\n              fixtureIndex: i,\n              message: `override \"usage\" must be an object`,\n            });\n          } else {\n            // Check all known usage fields are numbers if present\n            for (const key of Object.keys(r.usage)) {\n              const val = (r.usage as Record<string, unknown>)[key];\n              if (val !== undefined && typeof val !== \"number\") {\n                results.push({\n                  severity: \"error\",\n                  fixtureIndex: i,\n                  message: `override \"usage.${key}\" must be a number, got ${typeof val}`,\n                });\n              }\n            }\n          }\n        }\n      }\n    } // end: skip response-shape validation for function responses\n\n    // Numeric sanity checks\n    if (f.latency !== undefined && f.latency < 0) {\n      results.push({\n        severity: \"error\",\n        fixtureIndex: i,\n        message: \"latency must be >= 0\",\n      });\n    }\n    if (f.chunkSize !== undefined && f.chunkSize < 1) {\n      results.push({\n        severity: \"error\",\n        fixtureIndex: i,\n        message: \"chunkSize must be >= 1\",\n      });\n    }\n    if (f.truncateAfterChunks !== undefined && f.truncateAfterChunks < 1) {\n      results.push({\n        severity: \"error\",\n        fixtureIndex: i,\n        message: \"truncateAfterChunks must be >= 1\",\n      });\n    }\n    if (f.disconnectAfterMs !== undefined && f.disconnectAfterMs < 0) {\n      results.push({\n        severity: \"error\",\n        fixtureIndex: i,\n        message: \"disconnectAfterMs must be >= 0\",\n      });\n    }\n    if (f.streamingProfile !== undefined) {\n      const sp = f.streamingProfile;\n      if (sp.ttft !== undefined && sp.ttft < 0) {\n        results.push({\n          severity: \"error\",\n          fixtureIndex: i,\n          message: \"streamingProfile.ttft must be >= 0\",\n        });\n      }\n      if (sp.tps !== undefined && sp.tps <= 0) {\n        results.push({\n          severity: \"error\",\n          fixtureIndex: i,\n          message: \"streamingProfile.tps must be > 0\",\n        });\n      }\n      if (sp.jitter !== undefined && (sp.jitter < 0 || sp.jitter > 1)) {\n        results.push({\n          severity: \"error\",\n          fixtureIndex: i,\n          message: \"streamingProfile.jitter must be between 0 and 1\",\n        });\n      }\n    }\n    if (f.chaos !== undefined) {\n      const ch = f.chaos;\n      if (ch.dropRate !== undefined && (ch.dropRate < 0 || ch.dropRate > 1)) {\n        results.push({\n          severity: \"error\",\n          fixtureIndex: i,\n          message: \"chaos.dropRate must be between 0 and 1\",\n        });\n      }\n      if (ch.malformedRate !== undefined && (ch.malformedRate < 0 || ch.malformedRate > 1)) {\n        results.push({\n          severity: \"error\",\n          fixtureIndex: i,\n          message: \"chaos.malformedRate must be between 0 and 1\",\n        });\n      }\n      if (ch.disconnectRate !== undefined && (ch.disconnectRate < 0 || ch.disconnectRate > 1)) {\n        results.push({\n          severity: \"error\",\n          fixtureIndex: i,\n          message: \"chaos.disconnectRate must be between 0 and 1\",\n        });\n      }\n    }\n\n    // Match field type checks\n    if (f.match.turnIndex !== undefined) {\n      if (\n        typeof f.match.turnIndex !== \"number\" ||\n        f.match.turnIndex < 0 ||\n        !Number.isInteger(f.match.turnIndex)\n      ) {\n        results.push({\n          severity: \"error\",\n          fixtureIndex: i,\n          message: \"match.turnIndex must be a non-negative integer\",\n        });\n      }\n    }\n    if (f.match.sequenceIndex !== undefined) {\n      if (\n        typeof f.match.sequenceIndex !== \"number\" ||\n        f.match.sequenceIndex < 0 ||\n        !Number.isInteger(f.match.sequenceIndex)\n      ) {\n        results.push({\n          severity: \"error\",\n          fixtureIndex: i,\n          message: \"match.sequenceIndex must be a non-negative integer\",\n        });\n      }\n    }\n    if (f.match.hasToolResult !== undefined && typeof f.match.hasToolResult !== \"boolean\") {\n      results.push({\n        severity: \"error\",\n        fixtureIndex: i,\n        message: `match.hasToolResult must be a boolean, got ${typeof f.match.hasToolResult}`,\n      });\n    }\n    if (f.match.systemMessage !== undefined) {\n      const sm = f.match.systemMessage;\n      if (typeof sm === \"string\") {\n        // ok\n      } else if (Array.isArray(sm)) {\n        if (sm.length === 0) {\n          results.push({\n            severity: \"error\",\n            fixtureIndex: i,\n            message: `match.systemMessage array must contain at least one substring`,\n          });\n        } else {\n          for (let j = 0; j < sm.length; j++) {\n            if (typeof sm[j] !== \"string\") {\n              results.push({\n                severity: \"error\",\n                fixtureIndex: i,\n                message: `match.systemMessage[${j}] must be a string, got ${typeof sm[j]}`,\n              });\n            }\n          }\n        }\n      } else {\n        results.push({\n          severity: \"error\",\n          fixtureIndex: i,\n          message: `match.systemMessage must be a string or string[], got ${typeof sm}`,\n        });\n      }\n    }\n    if (f.match.context !== undefined && typeof f.match.context !== \"string\") {\n      results.push({\n        severity: \"error\",\n        fixtureIndex: i,\n        message: `match.context must be a string, got ${typeof f.match.context}`,\n      });\n    }\n\n    // --- Warning checks ---\n\n    // Duplicate userMessage shadowing — include turnIndex, hasToolResult, and\n    // sequenceIndex in the dedup key so that fixtures which share a userMessage\n    // but differ on those fields are NOT considered duplicates.\n    const um = f.match.userMessage;\n    if (typeof um === \"string\" && um) {\n      const dedupKey = `${um}|${f.match.turnIndex}|${f.match.hasToolResult}|${f.match.sequenceIndex}|${f.match.context}`;\n      const prev = seenUserMessages.get(dedupKey);\n      if (prev !== undefined) {\n        results.push({\n          severity: \"warning\",\n          fixtureIndex: i,\n          message: `duplicate userMessage '${um}' — shadows fixture ${prev}`,\n        });\n      } else {\n        seenUserMessages.set(dedupKey, i);\n      }\n    }\n\n    // Catch-all not in last position\n    const match = f.match;\n    const hasDiscriminator =\n      match.endpoint !== undefined ||\n      match.context !== undefined ||\n      match.userMessage !== undefined ||\n      match.systemMessage !== undefined ||\n      match.inputText !== undefined ||\n      match.responseFormat !== undefined ||\n      match.toolCallId !== undefined ||\n      match.toolName !== undefined ||\n      match.model !== undefined ||\n      match.predicate !== undefined ||\n      match.turnIndex !== undefined ||\n      match.sequenceIndex !== undefined ||\n      match.hasToolResult !== undefined;\n\n    if (!hasDiscriminator && i < fixtures.length - 1) {\n      results.push({\n        severity: \"warning\",\n        fixtureIndex: i,\n        message: `empty match acts as catch-all but is not the last fixture — shadows fixtures ${i + 1}+`,\n      });\n    }\n  }\n\n  return results;\n}\n"],"mappings":"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"}