{"version":3,"file":"ollama.cjs","names":["flattenHeaders","getContext","getTestId","matchFixtureDiagnostic","recordMatchOptions","applyChaos","resolveStrictMode","strictNoMatchMessage","strictNoMatchLogLine","strictOverrideField","proxyAndRecord","resolveResponse","isErrorResponse","serializeErrorResponse","isContentWithToolCallsResponse","resolveReasoningForModel","createInterruptionSignal","writeNDJSONStream","isTextResponse","isToolCallResponse","isEmbeddingResponse","generateDeterministicEmbedding"],"sources":["../src/ollama.ts"],"sourcesContent":["/**\n * Ollama API endpoint support.\n *\n * Translates incoming /api/chat, /api/generate, and /api/embeddings requests\n * into the ChatCompletionRequest format used by the fixture router, and converts\n * fixture responses back into Ollama's NDJSON streaming or non-streaming format.\n *\n * Key differences from OpenAI:\n * - Ollama defaults to stream: true (opposite of OpenAI)\n * - Streaming uses NDJSON, not SSE\n * - Tool call arguments are objects, not JSON strings\n * - Tool calls have no id field\n * - Embeddings return a single `embedding` array, not an array of objects\n */\n\nimport type * as http from \"node:http\";\nimport type {\n  ChatCompletionRequest,\n  ChatMessage,\n  Fixture,\n  HandlerDefaults,\n  ToolCall,\n  ToolDefinition,\n} from \"./types.js\";\nimport {\n  isTextResponse,\n  isToolCallResponse,\n  isContentWithToolCallsResponse,\n  isErrorResponse,\n  isEmbeddingResponse,\n  serializeErrorResponse,\n  generateDeterministicEmbedding,\n  flattenHeaders,\n  getTestId,\n  resolveResponse,\n  resolveStrictMode,\n  resolveReasoningForModel,\n  strictOverrideField,\n  getContext,\n  strictNoMatchMessage,\n  strictNoMatchLogLine,\n} from \"./helpers.js\";\nimport { matchFixtureDiagnostic, recordMatchOptions } from \"./router.js\";\nimport { writeErrorResponse } from \"./sse-writer.js\";\nimport { writeNDJSONStream } from \"./ndjson-writer.js\";\nimport { createInterruptionSignal } from \"./interruption.js\";\nimport type { Journal } from \"./journal.js\";\nimport type { Logger } from \"./logger.js\";\nimport { applyChaos } from \"./chaos.js\";\nimport { proxyAndRecord } from \"./recorder.js\";\n\n// ─── Ollama request types ────────────────────────────────────────────────────\n\ninterface OllamaMessage {\n  role: \"system\" | \"user\" | \"assistant\" | \"tool\";\n  content: string;\n  tool_calls?: Array<{ function: { name: string; arguments: unknown } }>;\n  images?: string[];\n}\n\ninterface OllamaToolDef {\n  type: string;\n  function: {\n    name: string;\n    description?: string;\n    parameters?: object;\n  };\n}\n\ninterface OllamaRequest {\n  model: string;\n  messages: OllamaMessage[];\n  stream?: boolean; // default true!\n  options?: { temperature?: number; num_predict?: number };\n  tools?: OllamaToolDef[];\n}\n\ninterface OllamaGenerateRequest {\n  model: string;\n  prompt: string;\n  stream?: boolean; // default true!\n  options?: { temperature?: number; num_predict?: number };\n  system?: string;\n  images?: string[];\n}\n\n// ─── Duration fields (zeroed, required on final/non-streaming responses) ────\n\nconst DURATION_FIELDS = {\n  done_reason: \"stop\" as const,\n  total_duration: 0,\n  load_duration: 0,\n  prompt_eval_count: 0,\n  prompt_eval_duration: 0,\n  eval_count: 0,\n  eval_duration: 0,\n};\n\n// ─── Input conversion: Ollama → ChatCompletionRequest ────────────────────────\n\nexport function ollamaToCompletionRequest(req: OllamaRequest): ChatCompletionRequest {\n  const messages: ChatMessage[] = [];\n\n  for (const msg of req.messages) {\n    const chatMsg: ChatMessage = {\n      role: msg.role as ChatMessage[\"role\"],\n      content: msg.content,\n    };\n\n    // Map inbound tool_calls on assistant messages to the internal format\n    if (msg.tool_calls && msg.tool_calls.length > 0) {\n      chatMsg.tool_calls = msg.tool_calls.map((tc, i) => ({\n        id: `call_${i}`,\n        type: \"function\" as const,\n        function: {\n          name: tc.function.name,\n          arguments:\n            typeof tc.function.arguments === \"string\"\n              ? tc.function.arguments\n              : JSON.stringify(tc.function.arguments),\n        },\n      }));\n    }\n\n    messages.push(chatMsg);\n  }\n\n  // Convert tools\n  let tools: ToolDefinition[] | undefined;\n  if (req.tools && req.tools.length > 0) {\n    tools = req.tools.map((t) => ({\n      type: \"function\" as const,\n      function: {\n        name: t.function.name,\n        description: t.function.description,\n        parameters: t.function.parameters,\n      },\n    }));\n  }\n\n  return {\n    model: req.model,\n    messages,\n    stream: req.stream ?? true,\n    temperature: req.options?.temperature,\n    max_tokens: req.options?.num_predict,\n    tools,\n  };\n}\n\nfunction ollamaGenerateToCompletionRequest(req: OllamaGenerateRequest): ChatCompletionRequest {\n  const messages: ChatMessage[] = [];\n\n  // Prepend system message if present\n  if (req.system) {\n    messages.push({ role: \"system\", content: req.system });\n  }\n\n  messages.push({ role: \"user\", content: req.prompt });\n\n  return {\n    model: req.model,\n    messages,\n    stream: req.stream ?? true,\n    temperature: req.options?.temperature,\n    max_tokens: req.options?.num_predict,\n  };\n}\n\n// ─── Response builders: /api/chat ────────────────────────────────────────────\n\nfunction buildOllamaChatTextChunks(\n  content: string,\n  model: string,\n  chunkSize: number,\n  reasoning?: string,\n): object[] {\n  const chunks: object[] = [];\n  const createdAt = new Date().toISOString();\n\n  // Reasoning chunks (before content)\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        model,\n        created_at: createdAt,\n        message: { role: \"assistant\", content: \"\", reasoning_content: slice },\n        done: false,\n      });\n    }\n  }\n\n  for (let i = 0; i < content.length; i += chunkSize) {\n    const slice = content.slice(i, i + chunkSize);\n    chunks.push({\n      model,\n      created_at: createdAt,\n      message: { role: \"assistant\", content: slice },\n      done: false,\n    });\n  }\n\n  // Final chunk with done: true and all duration fields\n  chunks.push({\n    model,\n    created_at: createdAt,\n    message: { role: \"assistant\", content: \"\" },\n    done: true,\n    ...DURATION_FIELDS,\n  });\n\n  return chunks;\n}\n\nfunction buildOllamaChatTextResponse(content: string, model: string, reasoning?: string): object {\n  return {\n    model,\n    created_at: new Date().toISOString(),\n    message: {\n      role: \"assistant\",\n      content,\n      ...(reasoning ? { reasoning_content: reasoning } : {}),\n    },\n    done: true,\n    ...DURATION_FIELDS,\n  };\n}\n\nfunction buildOllamaChatToolCallChunks(\n  toolCalls: ToolCall[],\n  model: string,\n  chunkSize: number,\n  logger: Logger,\n  reasoning?: string,\n): object[] {\n  const ollamaToolCalls = toolCalls.map((tc) => {\n    let argsObj: unknown;\n    try {\n      argsObj = JSON.parse(tc.arguments || \"{}\");\n    } catch {\n      logger.warn(\n        `Malformed JSON in fixture tool call arguments for \"${tc.name}\": ${tc.arguments}`,\n      );\n      argsObj = {};\n    }\n    return {\n      function: {\n        name: tc.name,\n        arguments: argsObj,\n      },\n    };\n  });\n\n  // Tool calls are sent in a single chunk (no streaming of individual args)\n  const chunks: object[] = [];\n  const createdAt = new Date().toISOString();\n\n  // Reasoning chunks (before tool calls)\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        model,\n        created_at: createdAt,\n        message: { role: \"assistant\", content: \"\", reasoning_content: slice },\n        done: false,\n      });\n    }\n  }\n\n  chunks.push({\n    model,\n    created_at: createdAt,\n    message: {\n      role: \"assistant\",\n      content: \"\",\n      tool_calls: ollamaToolCalls,\n    },\n    done: false,\n  });\n\n  // Final chunk\n  chunks.push({\n    model,\n    created_at: createdAt,\n    message: { role: \"assistant\", content: \"\" },\n    done: true,\n    ...DURATION_FIELDS,\n  });\n\n  return chunks;\n}\n\nfunction buildOllamaChatToolCallResponse(\n  toolCalls: ToolCall[],\n  model: string,\n  logger: Logger,\n  reasoning?: string,\n): object {\n  const ollamaToolCalls = toolCalls.map((tc) => {\n    let argsObj: unknown;\n    try {\n      argsObj = JSON.parse(tc.arguments || \"{}\");\n    } catch {\n      logger.warn(\n        `Malformed JSON in fixture tool call arguments for \"${tc.name}\": ${tc.arguments}`,\n      );\n      argsObj = {};\n    }\n    return {\n      function: {\n        name: tc.name,\n        arguments: argsObj,\n      },\n    };\n  });\n\n  return {\n    model,\n    created_at: new Date().toISOString(),\n    message: {\n      role: \"assistant\",\n      content: \"\",\n      ...(reasoning ? { reasoning_content: reasoning } : {}),\n      tool_calls: ollamaToolCalls,\n    },\n    done: true,\n    ...DURATION_FIELDS,\n  };\n}\n\n// ─── Response builders: /api/chat — content + tool calls ────────────────────\n\nfunction buildOllamaChatContentWithToolCallsChunks(\n  content: string,\n  toolCalls: ToolCall[],\n  model: string,\n  chunkSize: number,\n  logger: Logger,\n  reasoning?: string,\n): object[] {\n  const chunks: object[] = [];\n  const createdAt = new Date().toISOString();\n\n  // Reasoning chunks (before content)\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        model,\n        created_at: createdAt,\n        message: { role: \"assistant\", content: \"\", reasoning_content: slice },\n        done: false,\n      });\n    }\n  }\n\n  // Content chunks first\n  for (let i = 0; i < content.length; i += chunkSize) {\n    const slice = content.slice(i, i + chunkSize);\n    chunks.push({\n      model,\n      created_at: createdAt,\n      message: { role: \"assistant\", content: slice },\n      done: false,\n    });\n  }\n\n  // Tool calls in a single chunk (same as tool-call-only path)\n  const ollamaToolCalls = toolCalls.map((tc) => {\n    let argsObj: unknown;\n    try {\n      argsObj = JSON.parse(tc.arguments || \"{}\");\n    } catch {\n      logger.warn(\n        `Malformed JSON in fixture tool call arguments for \"${tc.name}\": ${tc.arguments}`,\n      );\n      argsObj = {};\n    }\n    return {\n      function: {\n        name: tc.name,\n        arguments: argsObj,\n      },\n    };\n  });\n\n  chunks.push({\n    model,\n    created_at: createdAt,\n    message: {\n      role: \"assistant\",\n      content: \"\",\n      tool_calls: ollamaToolCalls,\n    },\n    done: false,\n  });\n\n  // Final chunk\n  chunks.push({\n    model,\n    created_at: createdAt,\n    message: { role: \"assistant\", content: \"\" },\n    done: true,\n    ...DURATION_FIELDS,\n  });\n\n  return chunks;\n}\n\nfunction buildOllamaChatContentWithToolCallsResponse(\n  content: string,\n  toolCalls: ToolCall[],\n  model: string,\n  logger: Logger,\n  reasoning?: string,\n): object {\n  const ollamaToolCalls = toolCalls.map((tc) => {\n    let argsObj: unknown;\n    try {\n      argsObj = JSON.parse(tc.arguments || \"{}\");\n    } catch {\n      logger.warn(\n        `Malformed JSON in fixture tool call arguments for \"${tc.name}\": ${tc.arguments}`,\n      );\n      argsObj = {};\n    }\n    return {\n      function: {\n        name: tc.name,\n        arguments: argsObj,\n      },\n    };\n  });\n\n  return {\n    model,\n    created_at: new Date().toISOString(),\n    message: {\n      role: \"assistant\",\n      content,\n      ...(reasoning ? { reasoning_content: reasoning } : {}),\n      tool_calls: ollamaToolCalls,\n    },\n    done: true,\n    ...DURATION_FIELDS,\n  };\n}\n\n// ─── Response builders: /api/generate ────────────────────────────────────────\n\nfunction buildOllamaGenerateTextChunks(\n  content: string,\n  model: string,\n  chunkSize: number,\n  reasoning?: string,\n): object[] {\n  const chunks: object[] = [];\n  const createdAt = new Date().toISOString();\n\n  // Reasoning chunks (before content)\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        model,\n        created_at: createdAt,\n        response: \"\",\n        reasoning_content: slice,\n        done: false,\n      });\n    }\n  }\n\n  for (let i = 0; i < content.length; i += chunkSize) {\n    const slice = content.slice(i, i + chunkSize);\n    chunks.push({\n      model,\n      created_at: createdAt,\n      response: slice,\n      done: false,\n    });\n  }\n\n  // Final chunk\n  chunks.push({\n    model,\n    created_at: createdAt,\n    response: \"\",\n    done: true,\n    ...DURATION_FIELDS,\n    context: [],\n  });\n\n  return chunks;\n}\n\nfunction buildOllamaGenerateTextResponse(\n  content: string,\n  model: string,\n  reasoning?: string,\n): object {\n  return {\n    model,\n    created_at: new Date().toISOString(),\n    response: content,\n    ...(reasoning ? { reasoning_content: reasoning } : {}),\n    done: true,\n    ...DURATION_FIELDS,\n    context: [],\n  };\n}\n\n// ─── Request handler: /api/chat ──────────────────────────────────────────────\n\nexport async function handleOllama(\n  req: http.IncomingMessage,\n  res: http.ServerResponse,\n  raw: string,\n  fixtures: Fixture[],\n  journal: Journal,\n  defaults: HandlerDefaults,\n  setCorsHeaders: (res: http.ServerResponse) => void,\n): Promise<void> {\n  const { logger } = defaults;\n  setCorsHeaders(res);\n\n  const urlPath = req.url ?? \"/api/chat\";\n\n  let ollamaReq: OllamaRequest;\n  try {\n    ollamaReq = JSON.parse(raw) as OllamaRequest;\n  } catch (parseErr) {\n    const detail = parseErr instanceof Error ? parseErr.message : \"unknown\";\n    journal.add({\n      method: req.method ?? \"POST\",\n      path: urlPath,\n      headers: flattenHeaders(req.headers),\n      body: null,\n      response: { status: 400, fixture: null },\n    });\n    writeErrorResponse(\n      res,\n      400,\n      JSON.stringify({\n        error: {\n          message: `Malformed JSON body: ${detail}`,\n          type: \"invalid_request_error\",\n        },\n      }),\n    );\n    return;\n  }\n\n  if (!ollamaReq.messages || !Array.isArray(ollamaReq.messages)) {\n    journal.add({\n      method: req.method ?? \"POST\",\n      path: urlPath,\n      headers: flattenHeaders(req.headers),\n      body: null,\n      response: { status: 400, fixture: null },\n    });\n    writeErrorResponse(\n      res,\n      400,\n      JSON.stringify({\n        error: {\n          message: \"Invalid request: messages array is required\",\n          type: \"invalid_request_error\",\n        },\n      }),\n    );\n    return;\n  }\n\n  // Convert to ChatCompletionRequest for fixture matching\n  const completionReq = ollamaToCompletionRequest(ollamaReq);\n  completionReq._endpointType = \"chat\";\n  completionReq._context = getContext(req);\n\n  const testId = getTestId(req);\n  const { fixture, skippedBySequenceOrTurn } = matchFixtureDiagnostic(\n    fixtures,\n    completionReq,\n    journal.getFixtureMatchCountsForTest(testId),\n    defaults.requestTransform,\n    // Record mode proxies on a miss to capture a fresh turn (see record gate\n    // below), so keep turnIndex strict to prevent an earlier-turn fixture from\n    // shadowing a longer request and skipping the new turn's recording.\n    recordMatchOptions(!!defaults.record, defaults.logger),\n  );\n\n  if (fixture) {\n    journal.incrementFixtureMatchCount(fixture, fixtures, testId);\n    logger.debug(`Fixture matched: ${JSON.stringify(fixture.match).slice(0, 120)}`);\n  } else {\n    logger.debug(`No fixture matched for request`);\n  }\n\n  if (\n    applyChaos(\n      res,\n      fixture,\n      defaults.chaos,\n      req.headers,\n      journal,\n      {\n        method: req.method ?? \"POST\",\n        path: urlPath,\n        headers: flattenHeaders(req.headers),\n        body: completionReq,\n      },\n      fixture ? \"fixture\" : \"proxy\",\n      defaults.registry,\n      defaults.logger,\n    )\n  )\n    return;\n\n  if (!fixture) {\n    const effectiveStrict = resolveStrictMode(defaults.strict, req.headers);\n    if (effectiveStrict) {\n      const strictStatus = 503;\n      const strictMessage = strictNoMatchMessage(skippedBySequenceOrTurn);\n      logger.error(strictNoMatchLogLine(req.method ?? \"POST\", urlPath, skippedBySequenceOrTurn));\n      journal.add({\n        method: req.method ?? \"POST\",\n        path: urlPath,\n        headers: flattenHeaders(req.headers),\n        body: completionReq,\n        response: {\n          status: strictStatus,\n          fixture: null,\n          ...strictOverrideField(defaults.strict, req.headers),\n        },\n      });\n      writeErrorResponse(\n        res,\n        strictStatus,\n        JSON.stringify({\n          error: {\n            message: strictMessage,\n            type: \"invalid_request_error\",\n          },\n        }),\n      );\n      return;\n    }\n    if (defaults.record) {\n      const outcome = await proxyAndRecord(\n        req,\n        res,\n        completionReq,\n        \"ollama\",\n        urlPath,\n        fixtures,\n        defaults,\n        raw,\n      );\n      if (outcome === \"handled_by_hook\") return;\n      if (outcome !== \"not_configured\") {\n        journal.add({\n          method: req.method ?? \"POST\",\n          path: urlPath,\n          headers: flattenHeaders(req.headers),\n          body: completionReq,\n          response: { status: res.statusCode ?? 200, fixture: null, source: \"proxy\" },\n        });\n        return;\n      }\n    }\n    journal.add({\n      method: req.method ?? \"POST\",\n      path: urlPath,\n      headers: flattenHeaders(req.headers),\n      body: completionReq,\n      response: {\n        status: 404,\n        fixture: null,\n        ...strictOverrideField(defaults.strict, req.headers),\n      },\n    });\n    writeErrorResponse(\n      res,\n      404,\n      JSON.stringify({\n        error: {\n          message: \"No fixture matched\",\n          type: \"invalid_request_error\",\n        },\n      }),\n    );\n    return;\n  }\n\n  const response = await resolveResponse(fixture, completionReq);\n  const latency = fixture.latency ?? defaults.latency;\n  const chunkSize = Math.max(1, fixture.chunkSize ?? defaults.chunkSize);\n\n  // Ollama defaults to streaming when stream is absent or true\n  const streaming = ollamaReq.stream !== false;\n\n  // Error response\n  if (isErrorResponse(response)) {\n    const status = response.status ?? 500;\n    journal.add({\n      method: req.method ?? \"POST\",\n      path: urlPath,\n      headers: flattenHeaders(req.headers),\n      body: completionReq,\n      response: { status, fixture },\n    });\n    writeErrorResponse(res, status, serializeErrorResponse(response), {\n      retryAfter: response.retryAfter,\n    });\n    return;\n  }\n\n  // Content + tool calls response (must be checked before text/tool-only branches)\n  if (isContentWithToolCallsResponse(response)) {\n    if (response.webSearches?.length) {\n      logger.warn(\"webSearches in fixture response are not supported for Ollama API -- ignoring\");\n    }\n    const journalEntry = journal.add({\n      method: req.method ?? \"POST\",\n      path: urlPath,\n      headers: flattenHeaders(req.headers),\n      body: completionReq,\n      response: { status: 200, fixture },\n    });\n    // Gate reasoning emission on the requested model's capability (aimock#254).\n    const effectiveStrict = resolveStrictMode(defaults.strict, req.headers);\n    const effReasoning = resolveReasoningForModel(\n      response.reasoning,\n      completionReq.model,\n      effectiveStrict,\n      logger,\n    );\n    if (!streaming) {\n      const body = buildOllamaChatContentWithToolCallsResponse(\n        response.content,\n        response.toolCalls,\n        completionReq.model,\n        logger,\n        effReasoning,\n      );\n      res.writeHead(200, { \"Content-Type\": \"application/json\" });\n      res.end(JSON.stringify(body));\n    } else {\n      const chunks = buildOllamaChatContentWithToolCallsChunks(\n        response.content,\n        response.toolCalls,\n        completionReq.model,\n        chunkSize,\n        logger,\n        effReasoning,\n      );\n      const interruption = createInterruptionSignal(fixture);\n      const completed = await writeNDJSONStream(res, chunks, {\n        latency,\n        streamingProfile: fixture.streamingProfile,\n        recordedTimings: fixture.recordedTimings,\n        replaySpeed: fixture.replaySpeed ?? defaults.replaySpeed,\n        signal: interruption?.signal,\n        onChunkSent: interruption?.tick,\n      });\n      if (!completed) {\n        if (!res.writableEnded) res.destroy();\n        journalEntry.response.interrupted = true;\n        journalEntry.response.interruptReason = interruption?.reason();\n      }\n      interruption?.cleanup();\n    }\n    return;\n  }\n\n  // Text response\n  if (isTextResponse(response)) {\n    if (response.webSearches?.length) {\n      logger.warn(\"webSearches in fixture response are not supported for Ollama API -- ignoring\");\n    }\n    const journalEntry = journal.add({\n      method: req.method ?? \"POST\",\n      path: urlPath,\n      headers: flattenHeaders(req.headers),\n      body: completionReq,\n      response: { status: 200, fixture },\n    });\n    // Gate reasoning emission on the requested model's capability (aimock#254).\n    const effectiveStrict = resolveStrictMode(defaults.strict, req.headers);\n    const effReasoning = resolveReasoningForModel(\n      response.reasoning,\n      completionReq.model,\n      effectiveStrict,\n      logger,\n    );\n    if (!streaming) {\n      const body = buildOllamaChatTextResponse(response.content, completionReq.model, effReasoning);\n      res.writeHead(200, { \"Content-Type\": \"application/json\" });\n      res.end(JSON.stringify(body));\n    } else {\n      const chunks = buildOllamaChatTextChunks(\n        response.content,\n        completionReq.model,\n        chunkSize,\n        effReasoning,\n      );\n      const interruption = createInterruptionSignal(fixture);\n      const completed = await writeNDJSONStream(res, chunks, {\n        latency,\n        streamingProfile: fixture.streamingProfile,\n        recordedTimings: fixture.recordedTimings,\n        replaySpeed: fixture.replaySpeed ?? defaults.replaySpeed,\n        signal: interruption?.signal,\n        onChunkSent: interruption?.tick,\n      });\n      if (!completed) {\n        if (!res.writableEnded) res.destroy();\n        journalEntry.response.interrupted = true;\n        journalEntry.response.interruptReason = interruption?.reason();\n      }\n      interruption?.cleanup();\n    }\n    return;\n  }\n\n  // Tool call response\n  if (isToolCallResponse(response)) {\n    if (response.webSearches?.length) {\n      logger.warn(\"webSearches in fixture response are not supported for Ollama API — ignoring\");\n    }\n    const journalEntry = journal.add({\n      method: req.method ?? \"POST\",\n      path: urlPath,\n      headers: flattenHeaders(req.headers),\n      body: completionReq,\n      response: { status: 200, fixture },\n    });\n    // Gate reasoning emission on the requested model's capability (aimock#254).\n    const effectiveStrict = resolveStrictMode(defaults.strict, req.headers);\n    const effReasoning = resolveReasoningForModel(\n      response.reasoning,\n      completionReq.model,\n      effectiveStrict,\n      logger,\n    );\n    if (!streaming) {\n      const body = buildOllamaChatToolCallResponse(\n        response.toolCalls,\n        completionReq.model,\n        logger,\n        effReasoning,\n      );\n      res.writeHead(200, { \"Content-Type\": \"application/json\" });\n      res.end(JSON.stringify(body));\n    } else {\n      const chunks = buildOllamaChatToolCallChunks(\n        response.toolCalls,\n        completionReq.model,\n        chunkSize,\n        logger,\n        effReasoning,\n      );\n      const interruption = createInterruptionSignal(fixture);\n      const completed = await writeNDJSONStream(res, chunks, {\n        latency,\n        streamingProfile: fixture.streamingProfile,\n        recordedTimings: fixture.recordedTimings,\n        replaySpeed: fixture.replaySpeed ?? defaults.replaySpeed,\n        signal: interruption?.signal,\n        onChunkSent: interruption?.tick,\n      });\n      if (!completed) {\n        if (!res.writableEnded) res.destroy();\n        journalEntry.response.interrupted = true;\n        journalEntry.response.interruptReason = interruption?.reason();\n      }\n      interruption?.cleanup();\n    }\n    return;\n  }\n\n  // Unknown response type\n  journal.add({\n    method: req.method ?? \"POST\",\n    path: urlPath,\n    headers: flattenHeaders(req.headers),\n    body: completionReq,\n    response: { status: 500, fixture },\n  });\n  writeErrorResponse(\n    res,\n    500,\n    JSON.stringify({\n      error: {\n        message: \"Fixture response did not match any known type\",\n        type: \"server_error\",\n      },\n    }),\n  );\n}\n\n// ─── Request handler: /api/generate ──────────────────────────────────────────\n\nexport async function handleOllamaGenerate(\n  req: http.IncomingMessage,\n  res: http.ServerResponse,\n  raw: string,\n  fixtures: Fixture[],\n  journal: Journal,\n  defaults: HandlerDefaults,\n  setCorsHeaders: (res: http.ServerResponse) => void,\n): Promise<void> {\n  setCorsHeaders(res);\n\n  const urlPath = req.url ?? \"/api/generate\";\n\n  let generateReq: OllamaGenerateRequest;\n  try {\n    generateReq = JSON.parse(raw) as OllamaGenerateRequest;\n  } catch (parseErr) {\n    const detail = parseErr instanceof Error ? parseErr.message : \"unknown\";\n    journal.add({\n      method: req.method ?? \"POST\",\n      path: urlPath,\n      headers: flattenHeaders(req.headers),\n      body: null,\n      response: { status: 400, fixture: null },\n    });\n    writeErrorResponse(\n      res,\n      400,\n      JSON.stringify({\n        error: {\n          message: `Malformed JSON body: ${detail}`,\n          type: \"invalid_request_error\",\n        },\n      }),\n    );\n    return;\n  }\n\n  if (!generateReq.prompt || typeof generateReq.prompt !== \"string\") {\n    journal.add({\n      method: req.method ?? \"POST\",\n      path: urlPath,\n      headers: flattenHeaders(req.headers),\n      body: null,\n      response: { status: 400, fixture: null },\n    });\n    writeErrorResponse(\n      res,\n      400,\n      JSON.stringify({\n        error: {\n          message: \"Invalid request: prompt field is required\",\n          type: \"invalid_request_error\",\n        },\n      }),\n    );\n    return;\n  }\n\n  // Convert to ChatCompletionRequest for fixture matching\n  const completionReq = ollamaGenerateToCompletionRequest(generateReq);\n  completionReq._endpointType = \"chat\";\n  completionReq._context = getContext(req);\n\n  const testId = getTestId(req);\n  const { fixture, skippedBySequenceOrTurn } = matchFixtureDiagnostic(\n    fixtures,\n    completionReq,\n    journal.getFixtureMatchCountsForTest(testId),\n    defaults.requestTransform,\n    // Record mode proxies on a miss to capture a fresh turn (see record gate\n    // below), so keep turnIndex strict to prevent an earlier-turn fixture from\n    // shadowing a longer request and skipping the new turn's recording.\n    recordMatchOptions(!!defaults.record, defaults.logger),\n  );\n\n  if (fixture) {\n    journal.incrementFixtureMatchCount(fixture, fixtures, testId);\n    defaults.logger.debug(`Fixture matched: ${JSON.stringify(fixture.match).slice(0, 120)}`);\n  } else {\n    defaults.logger.debug(`No fixture matched for request`);\n  }\n\n  if (\n    applyChaos(\n      res,\n      fixture,\n      defaults.chaos,\n      req.headers,\n      journal,\n      {\n        method: req.method ?? \"POST\",\n        path: urlPath,\n        headers: flattenHeaders(req.headers),\n        body: completionReq,\n      },\n      fixture ? \"fixture\" : \"proxy\",\n      defaults.registry,\n      defaults.logger,\n    )\n  )\n    return;\n\n  if (!fixture) {\n    const effectiveStrict = resolveStrictMode(defaults.strict, req.headers);\n    if (effectiveStrict) {\n      const strictStatus = 503;\n      const strictMessage = strictNoMatchMessage(skippedBySequenceOrTurn);\n      defaults.logger.error(\n        strictNoMatchLogLine(req.method ?? \"POST\", urlPath, skippedBySequenceOrTurn),\n      );\n      journal.add({\n        method: req.method ?? \"POST\",\n        path: urlPath,\n        headers: flattenHeaders(req.headers),\n        body: completionReq,\n        response: {\n          status: strictStatus,\n          fixture: null,\n          ...strictOverrideField(defaults.strict, req.headers),\n        },\n      });\n      writeErrorResponse(\n        res,\n        strictStatus,\n        JSON.stringify({\n          error: {\n            message: strictMessage,\n            type: \"invalid_request_error\",\n          },\n        }),\n      );\n      return;\n    }\n    if (defaults.record) {\n      const outcome = await proxyAndRecord(\n        req,\n        res,\n        completionReq,\n        \"ollama\",\n        urlPath,\n        fixtures,\n        defaults,\n        raw,\n      );\n      if (outcome === \"handled_by_hook\") return;\n      if (outcome !== \"not_configured\") {\n        journal.add({\n          method: req.method ?? \"POST\",\n          path: urlPath,\n          headers: flattenHeaders(req.headers),\n          body: completionReq,\n          response: { status: res.statusCode ?? 200, fixture: null, source: \"proxy\" },\n        });\n        return;\n      }\n    }\n    journal.add({\n      method: req.method ?? \"POST\",\n      path: urlPath,\n      headers: flattenHeaders(req.headers),\n      body: completionReq,\n      response: {\n        status: 404,\n        fixture: null,\n        ...strictOverrideField(defaults.strict, req.headers),\n      },\n    });\n    writeErrorResponse(\n      res,\n      404,\n      JSON.stringify({\n        error: {\n          message: \"No fixture matched\",\n          type: \"invalid_request_error\",\n        },\n      }),\n    );\n    return;\n  }\n\n  const response = await resolveResponse(fixture, completionReq);\n  const latency = fixture.latency ?? defaults.latency;\n  const chunkSize = Math.max(1, fixture.chunkSize ?? defaults.chunkSize);\n\n  // Ollama defaults to streaming when stream is absent or true\n  const streaming = generateReq.stream !== false;\n\n  // Error response\n  if (isErrorResponse(response)) {\n    const status = response.status ?? 500;\n    journal.add({\n      method: req.method ?? \"POST\",\n      path: urlPath,\n      headers: flattenHeaders(req.headers),\n      body: completionReq,\n      response: { status, fixture },\n    });\n    writeErrorResponse(res, status, serializeErrorResponse(response), {\n      retryAfter: response.retryAfter,\n    });\n    return;\n  }\n\n  // Text response (only type supported for /api/generate)\n  if (isTextResponse(response)) {\n    const journalEntry = journal.add({\n      method: req.method ?? \"POST\",\n      path: urlPath,\n      headers: flattenHeaders(req.headers),\n      body: completionReq,\n      response: { status: 200, fixture },\n    });\n    // Gate reasoning emission on the requested model's capability (aimock#254).\n    const effectiveStrict = resolveStrictMode(defaults.strict, req.headers);\n    const effReasoning = resolveReasoningForModel(\n      response.reasoning,\n      completionReq.model,\n      effectiveStrict,\n      defaults.logger,\n    );\n    if (!streaming) {\n      const body = buildOllamaGenerateTextResponse(\n        response.content,\n        completionReq.model,\n        effReasoning,\n      );\n      res.writeHead(200, { \"Content-Type\": \"application/json\" });\n      res.end(JSON.stringify(body));\n    } else {\n      const chunks = buildOllamaGenerateTextChunks(\n        response.content,\n        completionReq.model,\n        chunkSize,\n        effReasoning,\n      );\n      const interruption = createInterruptionSignal(fixture);\n      const completed = await writeNDJSONStream(res, chunks, {\n        latency,\n        streamingProfile: fixture.streamingProfile,\n        recordedTimings: fixture.recordedTimings,\n        replaySpeed: fixture.replaySpeed ?? defaults.replaySpeed,\n        signal: interruption?.signal,\n        onChunkSent: interruption?.tick,\n      });\n      if (!completed) {\n        if (!res.writableEnded) res.destroy();\n        journalEntry.response.interrupted = true;\n        journalEntry.response.interruptReason = interruption?.reason();\n      }\n      interruption?.cleanup();\n    }\n    return;\n  }\n\n  // Tool call fixtures matched but not supported on /api/generate\n  if (isToolCallResponse(response) || isContentWithToolCallsResponse(response)) {\n    journal.add({\n      method: req.method ?? \"POST\",\n      path: urlPath,\n      headers: flattenHeaders(req.headers),\n      body: completionReq,\n      response: { status: 400, fixture },\n    });\n    writeErrorResponse(\n      res,\n      400,\n      JSON.stringify({\n        error: {\n          message: \"Tool call fixtures are not supported on /api/generate — use /api/chat instead\",\n          type: \"invalid_request_error\",\n        },\n      }),\n    );\n    return;\n  }\n\n  // Unknown response type\n  journal.add({\n    method: req.method ?? \"POST\",\n    path: urlPath,\n    headers: flattenHeaders(req.headers),\n    body: completionReq,\n    response: { status: 500, fixture },\n  });\n  writeErrorResponse(\n    res,\n    500,\n    JSON.stringify({\n      error: {\n        message: \"Fixture response did not match any known type\",\n        type: \"server_error\",\n      },\n    }),\n  );\n}\n\n// ─── Ollama embeddings request type ─────────────────────────────────────────\n\ninterface OllamaEmbeddingsRequest {\n  model: string;\n  prompt?: string;\n  input?: string | string[];\n}\n\n// ─── Request handler: /api/embeddings ───────────────────────────────────────\n\nexport async function handleOllamaEmbeddings(\n  req: http.IncomingMessage,\n  res: http.ServerResponse,\n  raw: string,\n  fixtures: Fixture[],\n  journal: Journal,\n  defaults: HandlerDefaults,\n  setCorsHeaders: (res: http.ServerResponse) => void,\n): Promise<void> {\n  const { logger } = defaults;\n  setCorsHeaders(res);\n\n  const urlPath = req.url ?? \"/api/embeddings\";\n\n  let embReq: OllamaEmbeddingsRequest;\n  try {\n    embReq = JSON.parse(raw) as OllamaEmbeddingsRequest;\n  } catch (parseErr) {\n    const detail = parseErr instanceof Error ? parseErr.message : \"unknown\";\n    journal.add({\n      method: req.method ?? \"POST\",\n      path: urlPath,\n      headers: flattenHeaders(req.headers),\n      body: null,\n      response: { status: 400, fixture: null },\n    });\n    writeErrorResponse(\n      res,\n      400,\n      JSON.stringify({\n        error: {\n          message: `Malformed JSON body: ${detail}`,\n          type: \"invalid_request_error\",\n        },\n      }),\n    );\n    return;\n  }\n\n  // Ollama accepts either \"prompt\" or \"input\" for the text to embed\n  const inputText =\n    embReq.prompt ??\n    (typeof embReq.input === \"string\" ? embReq.input : undefined) ??\n    (Array.isArray(embReq.input) ? embReq.input.join(\" \") : undefined);\n\n  if (!embReq.model) {\n    journal.add({\n      method: req.method ?? \"POST\",\n      path: urlPath,\n      headers: flattenHeaders(req.headers),\n      body: null,\n      response: { status: 400, fixture: null },\n    });\n    writeErrorResponse(\n      res,\n      400,\n      JSON.stringify({\n        error: {\n          message: \"Invalid request: model field is required\",\n          type: \"invalid_request_error\",\n        },\n      }),\n    );\n    return;\n  }\n\n  if (!inputText) {\n    journal.add({\n      method: req.method ?? \"POST\",\n      path: urlPath,\n      headers: flattenHeaders(req.headers),\n      body: null,\n      response: { status: 400, fixture: null },\n    });\n    writeErrorResponse(\n      res,\n      400,\n      JSON.stringify({\n        error: {\n          message: \"Invalid request: prompt or input field is required\",\n          type: \"invalid_request_error\",\n        },\n      }),\n    );\n    return;\n  }\n\n  // Build synthetic ChatCompletionRequest for the fixture router\n  const syntheticReq: ChatCompletionRequest = {\n    model: embReq.model,\n    messages: [],\n    embeddingInput: inputText,\n    _endpointType: \"embedding\",\n    _context: getContext(req),\n  };\n\n  const testId = getTestId(req);\n  const { fixture, skippedBySequenceOrTurn } = matchFixtureDiagnostic(\n    fixtures,\n    syntheticReq,\n    journal.getFixtureMatchCountsForTest(testId),\n    defaults.requestTransform,\n    // Record mode proxies on a miss to capture a fresh turn (see record gate\n    // below), so keep turnIndex strict to prevent an earlier-turn fixture from\n    // shadowing a longer request and skipping the new turn's recording.\n    recordMatchOptions(!!defaults.record, defaults.logger),\n  );\n\n  if (fixture) {\n    journal.incrementFixtureMatchCount(fixture, fixtures, testId);\n    logger.debug(`Fixture matched: ${JSON.stringify(fixture.match).slice(0, 120)}`);\n  } else {\n    logger.debug(`No fixture matched for request`);\n  }\n\n  if (\n    applyChaos(\n      res,\n      fixture,\n      defaults.chaos,\n      req.headers,\n      journal,\n      {\n        method: req.method ?? \"POST\",\n        path: urlPath,\n        headers: flattenHeaders(req.headers),\n        body: syntheticReq,\n      },\n      fixture ? \"fixture\" : \"proxy\",\n      defaults.registry,\n      defaults.logger,\n    )\n  )\n    return;\n\n  if (fixture) {\n    const response = await resolveResponse(fixture, syntheticReq);\n\n    // Error response\n    if (isErrorResponse(response)) {\n      const status = response.status ?? 500;\n      journal.add({\n        method: req.method ?? \"POST\",\n        path: urlPath,\n        headers: flattenHeaders(req.headers),\n        body: syntheticReq,\n        response: { status, fixture },\n      });\n      writeErrorResponse(res, status, serializeErrorResponse(response), {\n        retryAfter: response.retryAfter,\n      });\n      return;\n    }\n\n    // Embedding response — use the fixture's embedding\n    if (isEmbeddingResponse(response)) {\n      journal.add({\n        method: req.method ?? \"POST\",\n        path: urlPath,\n        headers: flattenHeaders(req.headers),\n        body: syntheticReq,\n        response: { status: 200, fixture },\n      });\n      const body = {\n        model: embReq.model,\n        embedding: [...response.embedding],\n      };\n      res.writeHead(200, { \"Content-Type\": \"application/json\" });\n      res.end(JSON.stringify(body));\n      return;\n    }\n\n    // Fixture matched but response type is not compatible with embeddings\n    journal.add({\n      method: req.method ?? \"POST\",\n      path: urlPath,\n      headers: flattenHeaders(req.headers),\n      body: syntheticReq,\n      response: { status: 500, fixture },\n    });\n    writeErrorResponse(\n      res,\n      500,\n      JSON.stringify({\n        error: {\n          message:\n            \"Fixture response did not match any known embedding type (must have embedding or error)\",\n          type: \"server_error\",\n        },\n      }),\n    );\n    return;\n  }\n\n  // No fixture match — check strict mode first, then try proxy\n  const effectiveStrict = resolveStrictMode(defaults.strict, req.headers);\n  if (effectiveStrict) {\n    const strictMessage = strictNoMatchMessage(skippedBySequenceOrTurn);\n    logger.error(strictNoMatchLogLine(req.method ?? \"POST\", urlPath, skippedBySequenceOrTurn));\n    journal.add({\n      method: req.method ?? \"POST\",\n      path: urlPath,\n      headers: flattenHeaders(req.headers),\n      body: syntheticReq,\n      response: {\n        status: 503,\n        fixture: null,\n        ...strictOverrideField(defaults.strict, req.headers),\n      },\n    });\n    writeErrorResponse(\n      res,\n      503,\n      JSON.stringify({\n        error: {\n          message: strictMessage,\n          type: \"invalid_request_error\",\n        },\n      }),\n    );\n    return;\n  }\n\n  if (defaults.record) {\n    const outcome = await proxyAndRecord(\n      req,\n      res,\n      syntheticReq,\n      \"ollama\",\n      urlPath,\n      fixtures,\n      defaults,\n      raw,\n    );\n    if (outcome === \"handled_by_hook\") return;\n    if (outcome !== \"not_configured\") {\n      journal.add({\n        method: req.method ?? \"POST\",\n        path: urlPath,\n        headers: flattenHeaders(req.headers),\n        body: syntheticReq,\n        response: { status: res.statusCode ?? 200, fixture: null, source: \"proxy\" },\n      });\n      return;\n    }\n  }\n\n  // No fixture match — generate deterministic embedding from input text\n  logger.warn(\n    `No embedding fixture matched for \"${inputText.slice(0, 80)}\" — returning deterministic fallback`,\n  );\n  const embedding = generateDeterministicEmbedding(inputText);\n\n  journal.add({\n    method: req.method ?? \"POST\",\n    path: urlPath,\n    headers: flattenHeaders(req.headers),\n    body: syntheticReq,\n    response: { status: 200, fixture: null },\n  });\n\n  const body = {\n    model: embReq.model,\n    embedding,\n  };\n  res.writeHead(200, { \"Content-Type\": \"application/json\" });\n  res.end(JSON.stringify(body));\n}\n"],"mappings":"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"}