{"version":3,"sources":["../src/pricing.ts","../src/content.ts","../src/capabilities.ts","../src/fingerprint.ts","../src/adapter.ts"],"names":["ContentBlockUnsupportedError","blocks","createCapabilityLearner","fs","dirname","emitRetryEvent","OpenAI","validateImageBlocks","throwIfAborted","computeChatCost","mergeTokenUsage","EmptyResponseError","extractJSON","attemptValidationRepair","failValidation","readStreamCompleteCallback","tryParsePartialJSON","resurrectOperationContext","emitAgentStepStarted","emitAgentStepCompleted","emitAgentToolCalled","sha256Hex","emitAgentToolReturned","wrapProviderError","computeEmbeddingCost","zodToJsonSchema"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\r\n * OpenAI model pricing (USD per 1M tokens).\r\n *\r\n * Source: https://openai.com/api/pricing/\r\n * Last verified: 2026-06-18 by @baabakk\r\n *\r\n * Update process: edit this file, bump the \"Last verified\" date, open a PR\r\n * with the source URL referenced. Changeset patch bump on adapter-openai.\r\n *\r\n * Users can override these via the registry's `pricingOverrides` option,\r\n * which is the daily-use escape hatch when prices change between releases\r\n * or when an enterprise has negotiated rates.\r\n *\r\n * Note: This same adapter serves OpenAI-compatible providers (Groq, Together\r\n * AI, Fireworks, DeepInfra, Perplexity, Cerebras, LiteLLM proxy, etc.) via\r\n * the `baseURL` option. Those providers have their own pricing — supply it\r\n * via `pricingOverrides`, OR rely on the curated bundled entries below for\r\n * the compat models the team has actively verified (alpha.21+ section).\r\n */\r\n\r\nimport type { ModelPricing } from \"@llm-ports/core\";\r\n\r\n// Note: this table contains pricing only — no capability flags.\r\n//\r\n// Why no hardcoded capabilities: OpenAI does not expose programmatic\r\n// capability discovery (the `/v1/models` endpoint returns names + ownership,\r\n// no schema for \"which params does this model accept\"). A hardcoded list of\r\n// \"gpt-5-nano is reasoning, gpt-4o is standard\" goes stale every time\r\n// OpenAI ships a new model. Instead, the adapter discovers constraints at\r\n// runtime: it catches the specific OpenAI error (e.g. `unsupported_value`\r\n// for `temperature`), learns the constraint, and remembers it for the rest\r\n// of the process so subsequent calls don't pay the discovery cost.\r\n//\r\n// Users who already know their model's constraints and want to skip\r\n// discovery can still supply `capabilities` via pricingOverrides — that's\r\n// what the field is for.\r\n\r\nexport const OPENAI_PRICING: Record<string, ModelPricing> = {\r\n  // GPT-5 family\r\n  \"gpt-5\": {\r\n    inputPer1M: 2.5,\r\n    outputPer1M: 10.0,\r\n    cacheReadPer1M: 0.25,\r\n  },\r\n  \"gpt-5-mini\": {\r\n    inputPer1M: 0.15,\r\n    outputPer1M: 0.6,\r\n    cacheReadPer1M: 0.075,\r\n  },\r\n  \"gpt-5-nano\": {\r\n    inputPer1M: 0.05,\r\n    outputPer1M: 0.2,\r\n    cacheReadPer1M: 0.025,\r\n  },\r\n\r\n  // GPT-4o family\r\n  \"gpt-4o\": {\r\n    inputPer1M: 2.5,\r\n    outputPer1M: 10.0,\r\n    cacheReadPer1M: 1.25,\r\n  },\r\n  \"gpt-4o-mini\": {\r\n    inputPer1M: 0.15,\r\n    outputPer1M: 0.6,\r\n    cacheReadPer1M: 0.075,\r\n  },\r\n  \"gpt-4o-audio-preview\": {\r\n    inputPer1M: 2.5,\r\n    outputPer1M: 10.0,\r\n  },\r\n\r\n  // o-series reasoning models\r\n  \"o3\": {\r\n    inputPer1M: 15.0,\r\n    outputPer1M: 60.0,\r\n    cacheReadPer1M: 7.5,\r\n  },\r\n  \"o3-mini\": {\r\n    inputPer1M: 1.1,\r\n    outputPer1M: 4.4,\r\n    cacheReadPer1M: 0.55,\r\n  },\r\n\r\n  // Embeddings\r\n  \"text-embedding-3-small\": {\r\n    inputPer1M: 0,\r\n    outputPer1M: 0,\r\n    embeddingPer1M: 0.02,\r\n  },\r\n  \"text-embedding-3-large\": {\r\n    inputPer1M: 0,\r\n    outputPer1M: 0,\r\n    embeddingPer1M: 0.13,\r\n  },\r\n\r\n  // ─── Curated compat-provider entries (alpha.21+) ────────────────────\r\n  //\r\n  // These three models are bundled because they're in active production\r\n  // use against the verified-OK provider matrix and shipping their rates\r\n  // here means consumers don't have to maintain a parallel pricingOverrides\r\n  // table for them. Source per #48. No cacheReadPer1M because neither\r\n  // DeepInfra nor Parasail publish a discounted cache-read tier.\r\n\r\n  // DeepInfra — verified 2026-06-18 via https://deepinfra.com/deepseek-ai/DeepSeek-V4-Flash\r\n  \"deepseek-ai/DeepSeek-V4-Flash\": {\r\n    inputPer1M: 0.10,\r\n    outputPer1M: 0.20,\r\n  },\r\n  // DeepInfra — verified 2026-06-18 via https://deepinfra.com/google/gemma-4-31B-it\r\n  \"google/gemma-4-31B-it\": {\r\n    inputPer1M: 0.10,\r\n    outputPer1M: 0.20,\r\n  },\r\n  // Parasail — verified 2026-06-18 via https://parasail.io/pricing\r\n  \"XiaomiMiMo/MiMo-V2.5\": {\r\n    inputPer1M: 0.14,\r\n    outputPer1M: 0.28,\r\n  },\r\n\r\n  // ─── Cerebras entries (alpha.24+) ─────────────────────────────────────\r\n  //\r\n  // Added 2026-06-24 after empirical research (see\r\n  // docs/research/reasoning-models-survey-2026-06.md). Cerebras's public\r\n  // catalog has shrunk to two production models as of June 2026; both are\r\n  // bundled here so users routing to Cerebras don't need pricingOverrides.\r\n\r\n  // Cerebras — gpt-oss-120b. Pricing verified 2026-06-24 via\r\n  // https://inference-docs.cerebras.ai/models/openai-oss (primary)\r\n  // and corroborated by Morph + Artificial Analysis (third-party).\r\n  // No documented cache-read tier; prompt caching is a listed capability\r\n  // but no separate cached_input rate is published.\r\n  \"gpt-oss-120b\": {\r\n    inputPer1M: 0.35,\r\n    outputPer1M: 0.75,\r\n  },\r\n  // Cerebras — zai-glm-4.7. Pricing per Morph + Artificial Analysis\r\n  // (third-party only; Cerebras's model page redirects pricing to a\r\n  // generic page rather than displaying the per-token rate). MEDIUM\r\n  // confidence — verify directly against Cerebras invoicing before\r\n  // relying on these numbers in cost-sensitive routing.\r\n  \"zai-glm-4.7\": {\r\n    inputPer1M: 2.25,\r\n    outputPer1M: 2.75,\r\n  },\r\n};\r\n\r\nexport function lookupOpenAIPricing(modelId: string): ModelPricing | undefined {\r\n  return OPENAI_PRICING[modelId] ?? OPENAI_PRICING[modelId.toLowerCase()];\r\n}\r\n","/**\r\n * Convert llm-ports ContentBlock[] to/from OpenAI's chat completions format.\r\n *\r\n * OpenAI message structure:\r\n *   - User/system: content can be `string` or array of typed parts\r\n *     - { type: \"text\", text: string }\r\n *     - { type: \"image_url\", image_url: { url: string, detail?: \"auto\"|\"low\"|\"high\" } }\r\n *     - { type: \"input_audio\", input_audio: { data, format: \"wav\"|\"mp3\" } }\r\n *   - Assistant: content + tool_calls separately\r\n *     - tool_calls: [{ id, type: \"function\", function: { name, arguments: JSON-string } }]\r\n *   - Tool: { role: \"tool\", tool_call_id, content }\r\n *\r\n * Notable differences from Anthropic:\r\n *   - Tool calls live in `tool_calls` field, not as content blocks\r\n *   - Tool results are separate messages (role: \"tool\"), not blocks\r\n *   - Image URLs use \"image_url\" wrapper; base64 encoded as data URI\r\n */\r\n\r\nimport {\r\n  ContentBlockUnsupportedError,\r\n  type ContentBlock,\r\n  type LLMMessage,\r\n  type MessageContent,\r\n  type ToolUseBlock,\r\n} from \"@llm-ports/core\";\r\n\r\nconst ADAPTER_NAME = \"openai\";\r\n\r\n// ─── OpenAI message shapes (just enough for translation) ─────────────\r\n\r\nexport type OpenAIRole = \"system\" | \"user\" | \"assistant\" | \"tool\";\r\n\r\nexport interface OpenAITextPart {\r\n  type: \"text\";\r\n  text: string;\r\n}\r\nexport interface OpenAIImagePart {\r\n  type: \"image_url\";\r\n  image_url: { url: string; detail?: \"auto\" | \"low\" | \"high\" };\r\n}\r\nexport interface OpenAIAudioPart {\r\n  type: \"input_audio\";\r\n  input_audio: { data: string; format: \"wav\" | \"mp3\" };\r\n}\r\nexport type OpenAIContentPart = OpenAITextPart | OpenAIImagePart | OpenAIAudioPart;\r\n\r\nexport interface OpenAIToolCall {\r\n  id: string;\r\n  type: \"function\";\r\n  function: { name: string; arguments: string };\r\n}\r\n\r\nexport interface OpenAISystemMessage {\r\n  role: \"system\";\r\n  content: string;\r\n}\r\nexport interface OpenAIUserMessage {\r\n  role: \"user\";\r\n  content: string | OpenAIContentPart[];\r\n}\r\nexport interface OpenAIAssistantMessage {\r\n  role: \"assistant\";\r\n  content: string | null;\r\n  tool_calls?: OpenAIToolCall[];\r\n}\r\nexport interface OpenAIToolMessage {\r\n  role: \"tool\";\r\n  tool_call_id: string;\r\n  content: string;\r\n}\r\nexport type OpenAIMessage =\r\n  | OpenAISystemMessage\r\n  | OpenAIUserMessage\r\n  | OpenAIAssistantMessage\r\n  | OpenAIToolMessage;\r\n\r\n// ─── Outgoing: ContentBlock[] / LLMMessage[] → OpenAI ────────────────\r\n\r\n/**\r\n * Convert MessageContent (string or ContentBlock[]) to OpenAI's content shape.\r\n * For user messages: returns string when content is text-only, otherwise the\r\n * typed parts array. Throws on tool_use / tool_result (those become separate\r\n * messages via toOpenAIMessages).\r\n */\r\nexport function toOpenAIUserContent(content: MessageContent): string | OpenAIContentPart[] {\r\n  if (typeof content === \"string\") return content;\r\n  // If every block is text, collapse to a string for simpler payloads\r\n  if (content.every((b) => b.type === \"text\")) {\r\n    return content.map((b) => (b as { type: \"text\"; text: string }).text).join(\"\");\r\n  }\r\n  return content.map((block) => toOpenAIContentPart(block));\r\n}\r\n\r\nfunction toOpenAIContentPart(block: ContentBlock): OpenAIContentPart {\r\n  switch (block.type) {\r\n    case \"text\":\r\n      return { type: \"text\", text: block.text };\r\n    case \"image\": {\r\n      const url =\r\n        block.source.kind === \"url\"\r\n          ? block.source.url\r\n          : `data:${block.source.mediaType};base64,${block.source.data}`;\r\n      // detail is optional on both ImageSource variants; forward only when set\r\n      // so we don't override OpenAI's per-account default (\"auto\") on calls\r\n      // that didn't request a specific mode.\r\n      const image_url: { url: string; detail?: \"auto\" | \"low\" | \"high\" } = { url };\r\n      if (block.source.detail !== undefined) {\r\n        image_url.detail = block.source.detail;\r\n      }\r\n      return { type: \"image_url\", image_url };\r\n    }\r\n    case \"audio\": {\r\n      // OpenAI only accepts base64-encoded audio; URL audio is not supported\r\n      if (block.source.kind === \"url\") {\r\n        throw new ContentBlockUnsupportedError(ADAPTER_NAME, \"audio (url; OpenAI requires base64)\");\r\n      }\r\n      const format = mapAudioFormat(block.source.mediaType);\r\n      return { type: \"input_audio\", input_audio: { data: block.source.data, format } };\r\n    }\r\n    case \"tool_use\":\r\n    case \"tool_result\":\r\n      throw new Error(\r\n        `tool_use and tool_result blocks must be promoted to top-level messages; use toOpenAIMessages.`,\r\n      );\r\n  }\r\n}\r\n\r\nfunction mapAudioFormat(mediaType: string): \"wav\" | \"mp3\" {\r\n  if (mediaType === \"audio/wav\") return \"wav\";\r\n  if (mediaType === \"audio/mp3\") return \"mp3\";\r\n  // Ogg not supported by OpenAI today\r\n  throw new ContentBlockUnsupportedError(ADAPTER_NAME, `audio format \"${mediaType}\"`);\r\n}\r\n\r\n/**\r\n * Translate a llm-ports message list to OpenAI messages, promoting tool_use\r\n * blocks in assistant messages to `tool_calls` and tool_result blocks in\r\n * user/tool messages to standalone `role: \"tool\"` messages.\r\n */\r\nexport function toOpenAIMessages(messages: LLMMessage[]): OpenAIMessage[] {\r\n  const out: OpenAIMessage[] = [];\r\n\r\n  for (const msg of messages) {\r\n    if (msg.role === \"system\") {\r\n      const text =\r\n        typeof msg.content === \"string\"\r\n          ? msg.content\r\n          : extractTextFromBlocks(msg.content);\r\n      out.push({ role: \"system\", content: text });\r\n      continue;\r\n    }\r\n\r\n    if (msg.role === \"assistant\") {\r\n      const blocks = typeof msg.content === \"string\" ? [{ type: \"text\" as const, text: msg.content }] : msg.content;\r\n      const textParts = blocks\r\n        .filter((b): b is { type: \"text\"; text: string } => b.type === \"text\")\r\n        .map((b) => b.text)\r\n        .join(\"\");\r\n      const toolUses = blocks.filter((b): b is ToolUseBlock => b.type === \"tool_use\");\r\n      const message: OpenAIAssistantMessage = {\r\n        role: \"assistant\",\r\n        content: textParts.length > 0 ? textParts : null,\r\n      };\r\n      if (toolUses.length > 0) {\r\n        message.tool_calls = toolUses.map((tu) => ({\r\n          id: tu.id,\r\n          type: \"function\",\r\n          function: {\r\n            name: tu.name,\r\n            arguments: typeof tu.input === \"string\" ? tu.input : JSON.stringify(tu.input),\r\n          },\r\n        }));\r\n      }\r\n      out.push(message);\r\n      continue;\r\n    }\r\n\r\n    // user or tool roles\r\n    const blocks = typeof msg.content === \"string\" ? [{ type: \"text\" as const, text: msg.content }] : msg.content;\r\n\r\n    // Promote any tool_result blocks to standalone tool messages\r\n    const toolResults = blocks.filter(\r\n      (b): b is { type: \"tool_result\"; toolUseId: string; content: string | ContentBlock[]; isError?: boolean } =>\r\n        b.type === \"tool_result\",\r\n    );\r\n    for (const tr of toolResults) {\r\n      out.push({\r\n        role: \"tool\",\r\n        tool_call_id: tr.toolUseId,\r\n        content:\r\n          typeof tr.content === \"string\" ? tr.content : extractTextFromBlocks(tr.content as ContentBlock[]),\r\n      });\r\n    }\r\n\r\n    // Anything left becomes a user message\r\n    const userBlocks = blocks.filter((b) => b.type !== \"tool_result\");\r\n    if (userBlocks.length > 0) {\r\n      out.push({\r\n        role: \"user\",\r\n        content: toOpenAIUserContent(userBlocks),\r\n      });\r\n    }\r\n  }\r\n\r\n  return out;\r\n}\r\n\r\nfunction extractTextFromBlocks(blocks: ContentBlock[]): string {\r\n  return blocks\r\n    .filter((b): b is { type: \"text\"; text: string } => b.type === \"text\")\r\n    .map((b) => b.text)\r\n    .join(\"\\n\");\r\n}\r\n\r\n// ─── Harmony tool-call extraction (alpha.23+) ────────────────────────\r\n//\r\n// gpt-oss-* models from OpenAI use the \"harmony\" output format where a tool\r\n// call is encoded as a structured channel:\r\n//\r\n//   <|channel|>commentary to=functions.write_file<|constrain|>json<|message|>\r\n//   {\"path\":\"x.ts\",\"content\":\"...\"}\r\n//\r\n// Some providers (Cerebras, Groq) translate harmony channels into the\r\n// standard `tool_calls` array on the response before sending it back. Others\r\n// (DeepInfra at the time of writing) pass the raw harmony channel through as\r\n// `message.reasoning_content`, leaving `tool_calls` empty. Without\r\n// extraction, runAgent terminates the agentic loop on what looks like an\r\n// empty assistant turn.\r\n//\r\n// This parser handles the \"raw harmony\" case by extracting one or more\r\n// tool calls from a reasoning_content string. It returns null in three cases:\r\n//   - reasoning_content is empty or missing\r\n//   - reasoning_content does not contain any parseable harmony tool call\r\n//     (just chain-of-thought prose, or a bare JSON fragment with no tool\r\n//     name — the latter is the case the alpha.23 zero-tool-call rescue\r\n//     handles via a corrective retry instead)\r\n//   - the matched JSON arguments are unparseable\r\n//\r\n// Returning null lets the caller fall through to the zero-tool-call rescue\r\n// path (ASK 2 in alpha.23), so this parser is the surgical fast path: when\r\n// the model emitted a complete tool call but in the wrong channel, hoist\r\n// it; otherwise stay out of the way.\r\n//\r\n// See llm-ports#46 / discussion #50, and ADW's 2026-06-19 diagnostic\r\n// transcript for the empirical evidence motivating this addition.\r\n\r\n/**\r\n * Best-effort parse of one or more tool calls out of a harmony-formatted\r\n * reasoning_content string. Returns null when no parseable harmony tool\r\n * call is found (so the caller can fall through to corrective rescue).\r\n */\r\nexport function parseHarmonyToolCalls(\r\n  reasoningContent: string | null | undefined,\r\n): OpenAIToolCall[] | null {\r\n  if (!reasoningContent || reasoningContent.length === 0) return null;\r\n\r\n  // Match: <|channel|>commentary|tool ... to=functions.NAME [<|constrain|>json] <|message|>{...JSON...}\r\n  //\r\n  // The non-greedy `[\\s\\S]*?` between the tool name and `<|message|>` allows\r\n  // for an optional `<|constrain|>json` segment per the harmony spec (some\r\n  // providers pass it through, others don't). The lookahead at the end\r\n  // bounds the JSON before the next harmony marker or end-of-string. Tool\r\n  // name is restricted to identifier characters to avoid false matches\r\n  // inside JSON bodies.\r\n  const HARMONY_TOOL_PATTERN =\r\n    /<\\|channel\\|>(?:commentary|tool)[\\s\\S]*?to=functions\\.([A-Za-z_][A-Za-z0-9_]*)[\\s\\S]*?<\\|message\\|>(\\{[\\s\\S]*?\\})(?=<\\||$)/g;\r\n\r\n  const calls: OpenAIToolCall[] = [];\r\n  let match: RegExpExecArray | null;\r\n  while ((match = HARMONY_TOOL_PATTERN.exec(reasoningContent)) !== null) {\r\n    const toolName = match[1]!;\r\n    const argsJson = match[2]!;\r\n    // Validate the JSON before synthesizing the tool_call so we don't pass\r\n    // along garbage that would fail downstream when the consumer's tool\r\n    // executor tries to parse it.\r\n    try {\r\n      JSON.parse(argsJson);\r\n    } catch {\r\n      continue;\r\n    }\r\n    calls.push({\r\n      id: `harmony-${Math.random().toString(36).slice(2, 14)}`,\r\n      type: \"function\",\r\n      function: { name: toolName, arguments: argsJson },\r\n    });\r\n  }\r\n\r\n  return calls.length > 0 ? calls : null;\r\n}\r\n\r\n// ─── Incoming: OpenAI assistant message → ContentBlock[] ─────────────\r\n\r\n/**\r\n * Convert an OpenAI assistant response (`message.content` + `message.tool_calls`)\r\n * back into a llm-ports ContentBlock[].\r\n *\r\n * Alpha.23+: accepts an optional `reasoning_content` field. When `tool_calls`\r\n * is empty/missing and `reasoning_content` contains harmony-formatted tool\r\n * calls (DeepInfra-style gpt-oss serving), the harmony tool calls are\r\n * extracted and merged into the result. See `parseHarmonyToolCalls`.\r\n */\r\nexport function fromOpenAIAssistantMessage(message: {\r\n  content: string | null | OpenAIContentPart[];\r\n  tool_calls?: OpenAIToolCall[];\r\n  reasoning_content?: string | null;\r\n}): ContentBlock[] {\r\n  const blocks: ContentBlock[] = [];\r\n  if (typeof message.content === \"string\" && message.content.length > 0) {\r\n    blocks.push({ type: \"text\", text: message.content });\r\n  } else if (Array.isArray(message.content)) {\r\n    for (const part of message.content) {\r\n      if (part.type === \"text\") {\r\n        blocks.push({ type: \"text\", text: part.text });\r\n      } else if (part.type === \"image_url\") {\r\n        // Decode assistant-emitted image_url back into an ImageBlock so\r\n        // callers don't silently lose data when a vision model emits an\r\n        // image in its response. Detects data: URIs vs http(s) and routes\r\n        // them to the correct ImageSource kind. (Gap 5 / issue #20.)\r\n        const decoded = decodeAssistantImageUrl(part.image_url.url);\r\n        if (decoded) blocks.push(decoded);\r\n      }\r\n      // input_audio: still rare in assistant responses; OpenAI exposes\r\n      // output audio via a separate `audio` field on the message, not as\r\n      // an `input_audio` content part. Skip until a real use case shows.\r\n    }\r\n  }\r\n  // Alpha.23+: when standard tool_calls is empty/missing AND a non-empty\r\n  // reasoning_content is present, try the harmony extraction path. This\r\n  // recovers tool calls emitted by DeepInfra-served gpt-oss into the\r\n  // reasoning channel rather than the standard tool_calls array. Falls\r\n  // through silently when no harmony tool calls are parseable, leaving\r\n  // the zero-tool-call rescue (ASK 2) to handle the prose-only case.\r\n  const standardToolCalls = message.tool_calls && message.tool_calls.length > 0\r\n    ? message.tool_calls\r\n    : (parseHarmonyToolCalls(message.reasoning_content) ?? undefined);\r\n\r\n  if (standardToolCalls) {\r\n    for (const tc of standardToolCalls) {\r\n      let parsed: unknown;\r\n      try {\r\n        parsed = JSON.parse(tc.function.arguments);\r\n      } catch {\r\n        parsed = tc.function.arguments;\r\n      }\r\n      blocks.push({\r\n        type: \"tool_use\",\r\n        id: tc.id,\r\n        name: tc.function.name,\r\n        input: parsed,\r\n      });\r\n    }\r\n  }\r\n  return blocks;\r\n}\r\n\r\n/**\r\n * Decode an assistant-emitted `image_url.url` back into an llm-ports\r\n * `ImageBlock`. Returns null when the URL is malformed.\r\n *\r\n * Routing rule:\r\n *   - `data:<mediaType>;base64,<payload>` → `{ kind: \"base64\", mediaType, data }`\r\n *   - `http(s)://...`                       → `{ kind: \"url\", url }`\r\n *   - Anything else (file://, missing scheme, etc.) → null\r\n *\r\n * The mediaType union is constrained to the four formats `ImageBlock`\r\n * supports. If a model emits an exotic type (svg+xml, bmp, tiff), the\r\n * decoder returns null and the assistant message is treated as if the\r\n * image part wasn't there. That's preferred to a structurally-invalid\r\n * ImageBlock that downstream code would crash on.\r\n */\r\nfunction decodeAssistantImageUrl(url: string): ContentBlock | null {\r\n  if (typeof url !== \"string\" || url.length === 0) return null;\r\n\r\n  // data: URI form\r\n  const dataMatch = url.match(/^data:([^;]+);base64,(.+)$/);\r\n  if (dataMatch && dataMatch[1] && dataMatch[2]) {\r\n    const mediaType = dataMatch[1];\r\n    const data = dataMatch[2];\r\n    if (\r\n      mediaType === \"image/jpeg\" ||\r\n      mediaType === \"image/png\" ||\r\n      mediaType === \"image/gif\" ||\r\n      mediaType === \"image/webp\"\r\n    ) {\r\n      return { type: \"image\", source: { kind: \"base64\", mediaType, data } };\r\n    }\r\n    return null;\r\n  }\r\n\r\n  // URL form\r\n  if (url.startsWith(\"http://\") || url.startsWith(\"https://\")) {\r\n    return { type: \"image\", source: { kind: \"url\", url } };\r\n  }\r\n\r\n  return null;\r\n}\r\n\r\n/** Best-effort: extract just the assistant's text response. */\r\nexport function extractAssistantText(message: {\r\n  content: string | null | OpenAIContentPart[];\r\n}): string {\r\n  if (typeof message.content === \"string\") return message.content;\r\n  if (message.content === null) return \"\";\r\n  return message.content\r\n    .filter((p): p is OpenAITextPart => p.type === \"text\")\r\n    .map((p) => p.text)\r\n    .join(\"\");\r\n}\r\n","/**\r\n * Runtime capability discovery for OpenAI-shaped APIs.\r\n *\r\n * OpenAI does not expose programmatic capability discovery (no API endpoint\r\n * tells you \"this model rejects custom temperature\" or \"this model doesn't\r\n * support response_format: json_object\"). Hardcoded capability tables go\r\n * stale every time a new model ships.\r\n *\r\n * Strategy: catch the specific OpenAI error codes that signal a constraint,\r\n * learn the constraint, remember it for the rest of the process. Subsequent\r\n * calls don't re-discover; they apply the learned constraint up front.\r\n *\r\n * Constraints we discover:\r\n *   - temperatureLocked: model rejects custom `temperature` value\r\n *   - jsonModeUnsupported: model rejects `response_format: { type: \"json_object\" }`\r\n *   - systemMessageInUserOnly: model rejects a separate `system` message\r\n *\r\n * Users who already know their model's constraints can supply them via\r\n * `ModelCapabilities` in pricingOverrides — that takes precedence over\r\n * discovery (no first-call learning round-trip).\r\n *\r\n * The learner instance + Map machinery is shared across all adapters via\r\n * `createCapabilityLearner` from `@llm-ports/core`. This file contributes\r\n * the OpenAI-specific error classifiers.\r\n */\r\n\r\nimport { createCapabilityLearner } from \"@llm-ports/core\";\r\nimport type { KnownModelConstraint, ModelCapabilities } from \"@llm-ports/core\";\r\n\r\n// ─── Model-ID normalization (alpha.22+) ──────────────────────────────\r\n//\r\n// OpenAI-compat providers expose models under HuggingFace-style namespaced\r\n// IDs: DeepInfra uses `openai/gpt-oss-120b`, `deepseek-ai/DeepSeek-V4-Flash`,\r\n// `google/gemma-4-31B-it`; Parasail uses `XiaomiMiMo/MiMo-V2.5`; Groq uses\r\n// `openai/gpt-oss-120b`. The same canonical model served by different\r\n// providers shows up with different prefixes (Cerebras's `gpt-oss-120b`\r\n// is the same model as DeepInfra's `openai/gpt-oss-120b`, but the catalog\r\n// patterns are anchored at `^` and don't match the prefixed form).\r\n//\r\n// Architecture choice: rather than maintain a per-(model × provider) regex\r\n// matrix, normalize every model ID to its canonical name (the part after\r\n// the last `/`) before any catalog or learner lookup. The catalog stays a\r\n// small list of anchored patterns against canonical names; new providers\r\n// hosting an already-known model require zero catalog edits.\r\n//\r\n// The raw model ID is still used in the SDK request body — DeepInfra\r\n// expects `openai/gpt-oss-120b`, not `gpt-oss-120b`. Normalization is\r\n// scoped to the capability-learning layer only.\r\n//\r\n// OpenAI-native IDs (`gpt-5`, `o3`, `gpt-4o-mini`) have no slash and pass\r\n// through unchanged. Anthropic + Google adapters don't use namespaced IDs.\r\n//\r\n// See llm-ports#46 / discussion #49 for the originating ADW + Dramma\r\n// findings and the architectural critique that motivated this design.\r\n\r\n/**\r\n * Strip a provider/namespace prefix from a model ID, returning the\r\n * canonical name. The canonical name is the substring after the last `/`.\r\n * Model IDs with no `/` pass through unchanged.\r\n *\r\n * Examples:\r\n *   gpt-oss-120b                       → gpt-oss-120b   (OpenAI native, unchanged)\r\n *   openai/gpt-oss-120b                → gpt-oss-120b   (DeepInfra/Groq form)\r\n *   deepseek-ai/DeepSeek-V4-Flash      → DeepSeek-V4-Flash\r\n *   XiaomiMiMo/MiMo-V2.5               → MiMo-V2.5\r\n *   google/gemma-4-31B-it              → gemma-4-31B-it\r\n *   models/gemini-2.0-flash            → gemini-2.0-flash\r\n */\r\nexport function normalizeModelId(modelId: string): string {\r\n  const lastSlash = modelId.lastIndexOf(\"/\");\r\n  return lastSlash === -1 ? modelId : modelId.slice(lastSlash + 1);\r\n}\r\n\r\n// ─── Process-wide learned constraints (one learner shared by this adapter) ─\r\n\r\nconst learner = createCapabilityLearner();\r\n\r\n/** Get the effective capabilities for a model: user-supplied OR learned at runtime. */\r\nexport function getEffectiveCapabilities(\r\n  modelId: string,\r\n  userSupplied: ModelCapabilities | undefined,\r\n): ModelCapabilities {\r\n  return learner.get(normalizeModelId(modelId), userSupplied);\r\n}\r\n\r\n/** Record a discovered constraint; used by the adapter after a fallback retry. */\r\nexport function rememberConstraint(modelId: string, constraint: Partial<ModelCapabilities>): void {\r\n  learner.remember(normalizeModelId(modelId), constraint);\r\n}\r\n\r\n/** Test-only: clear learned state. */\r\nexport function _resetLearnedConstraints(): void {\r\n  learner._reset();\r\n}\r\n\r\n// ─── Static catalog of known reasoning models ────────────────────────\r\n\r\n/**\r\n * **OPTIMIZATION SHORTCUT — NOT load-bearing for correctness (alpha.24+).**\r\n *\r\n * Pre-seeds the learner so the first call against a catalog-matched model\r\n * skips the discovery round-trip (reasoning starvation + learn-and-retry).\r\n * Without this catalog, the very first call to a reasoning model pays one\r\n * wasted round-trip; subsequent calls in the same process are fine.\r\n *\r\n * **The catalog is a perf shortcut, NOT the correctness path.** Runtime\r\n * detection (alpha.22+) catches every reasoning model by inspecting:\r\n *   - `usage.completion_tokens_details.reasoning_tokens` (OpenAI native)\r\n *   - `choices[0].message.reasoning` (Cerebras-style: Cerebras, Groq, SambaNova)\r\n *   - `choices[0].message.reasoning_content` (vLLM-style: DeepInfra, Parasail)\r\n *   - inline `<think>...</think>` in `choices[0].message.content` (legacy R1)\r\n *\r\n * Behavioral fingerprinting (alpha.24+) lets users skip even the first-call\r\n * penalty by caching observed shapes across processes — see\r\n * `FingerprintCacheBackend` in fingerprint.ts and the\r\n * `createOpenAIAdapter({ fingerprintCache })` option.\r\n *\r\n * **The catalog is FROZEN.** New reasoning models discovered in production\r\n * are NOT added here. New entries would be one more piece of code that\r\n * goes stale on its own schedule. The empirical survey at\r\n * `docs/research/reasoning-models-survey-2026-06.md` enumerated ~30+\r\n * reasoning models across 5 OpenAI-compat providers — maintaining regex\r\n * entries for all of them is exactly the unsustainable burden the\r\n * fingerprint cache solves.\r\n *\r\n * **Existing entries stay.** The well-known cases below (OpenAI o-series,\r\n * gpt-5-nano, gpt-oss family, Qwen3.6, MiniMax-M2.7, Xiaomi MiMo) are\r\n * production-grade and remove a pointless round-trip for the common case.\r\n * They're cheap to keep and their patterns are stable.\r\n *\r\n * **For all the cases below + everything else:** runtime detection\r\n * (correctness) + fingerprint cache (optimization) is the architecture.\r\n * See `docs/concepts/capability-detection.md` for the three-tier design.\r\n *\r\n * Patterns are case-insensitive and tolerate underscore-vs-hyphen +\r\n * dot-vs-underscore variation, since OpenAI-compat providers normalize\r\n * model IDs inconsistently (Clarifai uses `Qwen3_6`, others use `qwen-3.6`).\r\n *\r\n * Extend this list as new reasoning models ship behind OpenAI-compat\r\n * baseURLs (Clarifai, SambaNova, Groq, Together AI, Fireworks, Cerebras,\r\n * Perplexity, DeepInfra, LiteLLM proxy, etc.).\r\n */\r\nexport const KNOWN_REASONING_MODELS: readonly KnownModelConstraint[] = [\r\n  // OpenAI o-series (already learned at runtime; pre-seed saves first call)\r\n  { pattern: /^o1(-|$)/, constraints: { reasoningModel: true } },\r\n  { pattern: /^o3(-|$)/, constraints: { reasoningModel: true } },\r\n  { pattern: /^o4(-|$)/, constraints: { reasoningModel: true } },\r\n  { pattern: /^gpt-5-nano/, constraints: { reasoningModel: true } },\r\n  // Cerebras gpt-oss reasoning lineup (via baseURL=cerebras)\r\n  { pattern: /^gpt-oss-/i, constraints: { reasoningModel: true } },\r\n  // Qwen 3.6 reasoning (Clarifai: Qwen3_6-35B-A3B-FP8; other compats may\r\n  // use qwen-3.6-* or qwen3.6-*).\r\n  { pattern: /^qwen3[._-]?6/i, constraints: { reasoningModel: true } },\r\n  // MiniMax M2.7 reasoning (SambaNova: MiniMax-M2.7).\r\n  { pattern: /^minimax[-_]?m2[._]7/i, constraints: { reasoningModel: true } },\r\n  // Xiaomi MiMo reasoning lineup — DISTINCT from MiniMax despite the name\r\n  // similarity. Parasail serves the canonical id `XiaomiMiMo/MiMo-V2.5`;\r\n  // post-alpha.22 normalization that becomes `MiMo-V2.5`. Added 2026-06-19\r\n  // after ADW production observation: mimo-parasail starved on a structured-\r\n  // output call (rescue fired via runtime detection, not catalog pre-seed,\r\n  // so the first call ate the latency). Pre-seeding lets the budget\r\n  // multiplier apply on call 1.\r\n  { pattern: /^mimo[-_]?v\\d/i, constraints: { reasoningModel: true } },\r\n];\r\n\r\n/** Seed the learner with this adapter's known-reasoning catalog for a model. */\r\nexport function seedKnownConstraints(modelId: string): void {\r\n  learner.seedFromCatalog(normalizeModelId(modelId), KNOWN_REASONING_MODELS);\r\n}\r\n\r\n// ─── Error classification (OpenAI-specific) ──────────────────────────\r\n\r\ninterface OpenAIErrorShape {\r\n  status?: number;\r\n  code?: unknown;\r\n  param?: unknown;\r\n  type?: unknown;\r\n  message?: unknown;\r\n  error?: { code?: unknown; param?: unknown; type?: unknown; message?: unknown };\r\n}\r\n\r\nfunction getErrorFields(err: unknown): OpenAIErrorShape | null {\r\n  if (!err || typeof err !== \"object\") return null;\r\n  const e = err as OpenAIErrorShape;\r\n  // OpenAI SDK errors expose these at the top level AND nest them under .error\r\n  return {\r\n    code: e.code ?? e.error?.code,\r\n    param: e.param ?? e.error?.param,\r\n    type: e.type ?? e.error?.type,\r\n    message: e.message ?? e.error?.message,\r\n    status: e.status,\r\n  };\r\n}\r\n\r\n/**\r\n * True if this error is OpenAI rejecting a custom `temperature` value.\r\n *\r\n * Observed shapes:\r\n *   { code: \"unsupported_value\", param: \"temperature\", error: { message: \"...does not support 0...\" } }\r\n *   { error: { code: \"unsupported_value\", param: \"temperature\" } }\r\n */\r\nexport function isTemperatureRejection(err: unknown): boolean {\r\n  const fields = getErrorFields(err);\r\n  if (!fields) return false;\r\n  if (fields.code === \"unsupported_value\" && fields.param === \"temperature\") {\r\n    return true;\r\n  }\r\n  // Some providers wrap the message differently; substring fallback\r\n  if (\r\n    typeof fields.message === \"string\" &&\r\n    /temperature/i.test(fields.message) &&\r\n    /(unsupported|not support|does not)/i.test(fields.message)\r\n  ) {\r\n    return true;\r\n  }\r\n  return false;\r\n}\r\n\r\n/**\r\n * True if this error is OpenAI (or an OpenAI-compatible backend) rejecting our\r\n * `response_format` field. Covers two distinct cause classes that both want the\r\n * same rescue (downgrade: drop `response_format`, fall back to prompted JSON):\r\n *\r\n *  1. **Model doesn't support native JSON mode.** Some reasoning models reject\r\n *     `response_format: { type: \"json_object\" }` outright. Error shape:\r\n *       - structured: `code: \"unsupported_value\"`, `param: \"response_format\"`\r\n *       - message: contains \"response_format\" + one of \"unsupported\" / \"not support\" / \"does not\"\r\n *     This was the original alpha.14/.15-era trigger.\r\n *\r\n *  2. **Schema is strict-incompatible.** OpenAI native validates the supplied\r\n *     JSON Schema before generation. Schemas containing open-ended dictionaries\r\n *     (`z.record(...)`), regex constraints, or other features strict mode can't\r\n *     express get rejected with errors like:\r\n *       - `\"Invalid schema for response_format... Extra required key 'X' supplied\"`\r\n *       - `\"Invalid schema for response_format... 'properties' must be specified\"`\r\n *     The rescue is the same: drop strict mode, drop the schema field, fall back\r\n *     to prompted JSON. Added alpha.21 after 2026-06-17 probe showed the rescue\r\n *     was silently dead on OpenAI native's most common structured-output failure\r\n *     mode. See issue #46.\r\n */\r\nexport function isJsonModeRejection(err: unknown): boolean {\r\n  const fields = getErrorFields(err);\r\n  if (!fields) return false;\r\n  if (\r\n    (fields.code === \"unsupported_value\" || fields.code === \"invalid_value\") &&\r\n    fields.param === \"response_format\"\r\n  ) {\r\n    return true;\r\n  }\r\n  if (\r\n    typeof fields.message === \"string\" &&\r\n    /response_format/i.test(fields.message) &&\r\n    /(unsupported|not support|does not|invalid schema|extra required|missing required)/i.test(\r\n      fields.message,\r\n    )\r\n  ) {\r\n    return true;\r\n  }\r\n  return false;\r\n}\r\n\r\n/**\r\n * True if this error is OpenAI rejecting a separate system message.\r\n * Some reasoning models require system content folded into the user message.\r\n */\r\nexport function isSystemMessageRejection(err: unknown): boolean {\r\n  const fields = getErrorFields(err);\r\n  if (!fields) return false;\r\n  if (\r\n    typeof fields.message === \"string\" &&\r\n    /system\\b/i.test(fields.message) &&\r\n    /(not support|unsupported|developer message)/i.test(fields.message)\r\n  ) {\r\n    return true;\r\n  }\r\n  return false;\r\n}\r\n","/**\n * Behavioral model fingerprinting (alpha.24+).\n *\n * Problem: maintaining a static catalog of (model × provider) → capability\n * mappings is unsustainable. Three CoT field conventions exist across the\n * OpenAI-compat ecosystem (`reasoning`, `reasoning_content`, inline-`<think>`),\n * provider naming drifts, and new reasoning models ship weekly. The empirical\n * survey at docs/research/reasoning-models-survey-2026-06.md catalogues ~30+\n * reasoning models across 5 providers; every regex entry is one more piece of\n * code that goes stale on its own schedule.\n *\n * Solution: behavioral fingerprinting. At first contact with a model, fire\n * one small probe call (\"what's 2+2\") and inspect the response shape:\n *\n *   - `message.reasoning` populated → Cerebras-style reasoning model\n *   - `message.reasoning_content` populated → vLLM-style reasoning model\n *   - `usage.completion_tokens_details.reasoning_tokens > 0` → OpenAI-native\n *     reasoning model\n *   - inline `<think>...</think>` markers in `message.content` → legacy R1\n *     style\n *\n * Cache the result by (baseURL, modelId). Next process startup reads the\n * cache and skips the probe entirely. The catalog stays as a cheap shortcut\n * for the well-known cases (OpenAI o-series, gpt-5-nano); for everything\n * else, the fingerprint cache is the answer.\n *\n * This file ships the cache backend interface, two default backends\n * (in-memory + file), the `fingerprintModel` standalone helper, and the\n * `inspectResponseForFingerprint` analyzer the adapter uses for free\n * fingerprinting on existing inflight responses (no probe call needed when\n * the model already produced a fingerprint-able response).\n */\n\nimport { promises as fs } from \"node:fs\";\nimport { dirname } from \"node:path\";\nimport type { OpenAI } from \"openai\";\nimport { normalizeModelId } from \"./capabilities.js\";\n\n// ─── Public types ────────────────────────────────────────────────────\n\n/**\n * The fingerprint we cache per (baseURL, modelId) tuple. Captures enough\n * information for the adapter to skip first-call discovery.\n */\nexport interface ModelFingerprint {\n  /** Canonical model id (after normalizeModelId — strip provider prefix). */\n  modelId: string;\n  /** Provider baseURL (or \"openai-native\" sentinel for OpenAI native). */\n  baseURL: string;\n  /** True if the model produces hidden chain-of-thought tokens. */\n  reasoningModel: boolean;\n  /**\n   * Which field exposes the chain-of-thought, when reasoningModel is true.\n   * - \"reasoning\"         → message.reasoning (Cerebras, Groq, SambaNova)\n   * - \"reasoning_content\" → message.reasoning_content (DeepInfra, Parasail)\n   * - \"reasoning_tokens\"  → usage.completion_tokens_details.reasoning_tokens\n   *                         (OpenAI native; no separate text field)\n   * - \"inline-think\"      → <think>...</think> embedded in message.content\n   *                         (legacy R1 distills on some providers)\n   * - undefined           → not a reasoning model OR couldn't determine\n   */\n  reasoningField?: \"reasoning\" | \"reasoning_content\" | \"reasoning_tokens\" | \"inline-think\";\n  /** ISO timestamp when this fingerprint was captured. */\n  fingerprintedAt: string;\n  /**\n   * Schema version. Bumped when the fingerprint shape changes so old caches\n   * are invalidated gracefully instead of crashing the loader.\n   */\n  schemaVersion: 1;\n}\n\n/**\n * Cache backend interface. Implementations are responsible for persistence\n * (file, Redis, S3, etc.). All methods may return synchronously or as a\n * Promise; the adapter awaits regardless.\n */\nexport interface FingerprintCacheBackend {\n  /** Return cached fingerprint for the key, or null when absent. */\n  get(key: string): Promise<ModelFingerprint | null> | ModelFingerprint | null;\n  /** Persist the fingerprint under the key. */\n  set(key: string, value: ModelFingerprint): Promise<void> | void;\n  /** Optional: delete a single entry. Used by test helpers and admin tools. */\n  delete?(key: string): Promise<void> | void;\n}\n\n// ─── Default backends ────────────────────────────────────────────────\n\n/**\n * Simple in-memory cache. Lifetime is the current process. Useful for\n * development, tests, and short-lived workers where re-fingerprinting on\n * restart is cheap.\n */\nexport class InMemoryFingerprintCache implements FingerprintCacheBackend {\n  private readonly store = new Map<string, ModelFingerprint>();\n\n  get(key: string): ModelFingerprint | null {\n    return this.store.get(key) ?? null;\n  }\n\n  set(key: string, value: ModelFingerprint): void {\n    this.store.set(key, value);\n  }\n\n  delete(key: string): void {\n    this.store.delete(key);\n  }\n\n  /** Test-only: clear all entries. */\n  _clear(): void {\n    this.store.clear();\n  }\n\n  /** Test-only: snapshot for inspection. */\n  _snapshot(): ReadonlyMap<string, ModelFingerprint> {\n    return this.store;\n  }\n}\n\n/**\n * File-backed cache. Stores fingerprints as JSON at the configured path.\n * Loads lazily on first `get` and writes back on every `set` (atomic via\n * temp + rename). Suitable for long-running workers and CI warm-starts.\n *\n * NOT suitable for concurrent multi-process writers; if you need that,\n * supply your own backend (Redis, S3, etc.) that handles the locking.\n */\nexport class FileFingerprintCache implements FingerprintCacheBackend {\n  private cache: Map<string, ModelFingerprint> | null = null;\n  private loadPromise: Promise<void> | null = null;\n\n  constructor(public readonly path: string) {}\n\n  private async ensureLoaded(): Promise<void> {\n    if (this.cache) return;\n    if (this.loadPromise) {\n      await this.loadPromise;\n      return;\n    }\n    this.loadPromise = (async (): Promise<void> => {\n      try {\n        const text = await fs.readFile(this.path, \"utf8\");\n        const parsed = JSON.parse(text) as Record<string, ModelFingerprint>;\n        this.cache = new Map(Object.entries(parsed));\n      } catch (err) {\n        const code = (err as NodeJS.ErrnoException).code;\n        // First-time use: no file yet. Initialize empty cache.\n        if (code === \"ENOENT\") {\n          this.cache = new Map();\n          return;\n        }\n        // Malformed JSON: treat as empty and let the next write overwrite.\n        // Don't crash the adapter on a corrupt cache file.\n        if (err instanceof SyntaxError) {\n          this.cache = new Map();\n          return;\n        }\n        throw err;\n      }\n    })();\n    await this.loadPromise;\n  }\n\n  async get(key: string): Promise<ModelFingerprint | null> {\n    await this.ensureLoaded();\n    const cached = this.cache!.get(key) ?? null;\n    if (cached && cached.schemaVersion !== 1) return null;\n    return cached;\n  }\n\n  async set(key: string, value: ModelFingerprint): Promise<void> {\n    await this.ensureLoaded();\n    this.cache!.set(key, value);\n    await this.persist();\n  }\n\n  async delete(key: string): Promise<void> {\n    await this.ensureLoaded();\n    if (this.cache!.delete(key)) await this.persist();\n  }\n\n  private async persist(): Promise<void> {\n    if (!this.cache) return;\n    const serialized = JSON.stringify(Object.fromEntries(this.cache), null, 2);\n    // Atomic write via temp + rename. Avoids leaving a partial file if the\n    // process is killed mid-write.\n    const tmpPath = `${this.path}.tmp`;\n    await fs.mkdir(dirname(this.path), { recursive: true });\n    await fs.writeFile(tmpPath, serialized, \"utf8\");\n    await fs.rename(tmpPath, this.path);\n  }\n}\n\n// ─── Key builder ─────────────────────────────────────────────────────\n\n/**\n * Build the cache key for a (baseURL, modelId) tuple. Normalizes the\n * baseURL by stripping trailing slashes and the modelId by stripping the\n * provider namespace prefix (alpha.22 normalization).\n *\n * Examples:\n *   buildFingerprintKey(undefined, \"gpt-5\")\n *     → \"openai-native::gpt-5\"\n *   buildFingerprintKey(\"https://api.deepinfra.com/v1/openai\", \"openai/gpt-oss-120b\")\n *     → \"https://api.deepinfra.com/v1/openai::gpt-oss-120b\"\n *   buildFingerprintKey(\"https://api.cerebras.ai/v1/\", \"gpt-oss-120b\")\n *     → \"https://api.cerebras.ai/v1::gpt-oss-120b\"\n */\nexport function buildFingerprintKey(\n  baseURL: string | undefined,\n  modelId: string,\n): string {\n  const normalizedBase = baseURL ? baseURL.replace(/\\/+$/, \"\") : \"openai-native\";\n  return `${normalizedBase}::${normalizeModelId(modelId)}`;\n}\n\n// ─── Response shape analyzer ─────────────────────────────────────────\n\n/**\n * Inspect a chat-completion response and derive a fingerprint. Used by the\n * adapter to fingerprint for free on every inflight response — no separate\n * probe call needed when the model already produced something we can read.\n *\n * Returns a partial fingerprint (the shape-derivable fields). The caller is\n * responsible for adding modelId, baseURL, fingerprintedAt, schemaVersion.\n *\n * Detection priority (first match wins):\n *   1. `usage.completion_tokens_details.reasoning_tokens > 0` →\n *      reasoningModel=true, reasoningField=\"reasoning_tokens\"\n *      (OpenAI native; the reasoning tokens are billed but not text-exposed)\n *   2. `message.reasoning_content` populated string →\n *      reasoningModel=true, reasoningField=\"reasoning_content\"\n *      (vLLM-style: DeepInfra, Parasail)\n *   3. `message.reasoning` populated string →\n *      reasoningModel=true, reasoningField=\"reasoning\"\n *      (Cerebras-style: Cerebras, Groq, SambaNova)\n *   4. `message.content` contains `<think>...</think>` markers →\n *      reasoningModel=true, reasoningField=\"inline-think\"\n *      (legacy R1 distills emitted raw)\n *   5. Otherwise: reasoningModel=false (no signal observed)\n *\n * A \"no signal\" verdict is NOT cached — it could be a non-reasoning prompt\n * to a reasoning model. The caller decides whether to cache negatives.\n */\nexport function inspectResponseForFingerprint(\n  response: unknown,\n): Pick<ModelFingerprint, \"reasoningModel\" | \"reasoningField\"> {\n  if (!response || typeof response !== \"object\") {\n    return { reasoningModel: false };\n  }\n  const r = response as {\n    choices?: Array<{\n      message?: {\n        content?: string | null;\n        reasoning?: string | null;\n        reasoning_content?: string | null;\n      };\n    }>;\n    usage?: { completion_tokens_details?: { reasoning_tokens?: number } };\n  };\n  const reasoningTokens = r.usage?.completion_tokens_details?.reasoning_tokens ?? 0;\n  if (reasoningTokens > 0) {\n    return { reasoningModel: true, reasoningField: \"reasoning_tokens\" };\n  }\n  const msg = r.choices?.[0]?.message;\n  if (typeof msg?.reasoning_content === \"string\" && msg.reasoning_content.length > 0) {\n    return { reasoningModel: true, reasoningField: \"reasoning_content\" };\n  }\n  if (typeof msg?.reasoning === \"string\" && msg.reasoning.length > 0) {\n    return { reasoningModel: true, reasoningField: \"reasoning\" };\n  }\n  if (typeof msg?.content === \"string\" && /<think>[\\s\\S]*?<\\/think>/.test(msg.content)) {\n    return { reasoningModel: true, reasoningField: \"inline-think\" };\n  }\n  return { reasoningModel: false };\n}\n\n// ─── Standalone fingerprint helper ───────────────────────────────────\n\n/**\n * Fire one small probe call against the given client + modelId and produce\n * a fingerprint. Useful for CI warm-start scripts that want to populate the\n * cache before production traffic starts.\n *\n * @param client  An initialized OpenAI client.\n * @param modelId Provider-native model id (raw; will be normalized internally).\n * @param opts    Optional baseURL override (recorded in the key). If\n *                undefined, the client's own baseURL is read; if both are\n *                absent, the \"openai-native\" sentinel is used.\n */\nexport async function fingerprintModel(\n  client: OpenAI,\n  modelId: string,\n  opts?: { baseURL?: string },\n): Promise<ModelFingerprint> {\n  const baseURL = opts?.baseURL ?? (client as unknown as { baseURL?: string }).baseURL;\n  // Small probe: ask the model for a one-word response, low max_tokens so\n  // the call resolves quickly. We're inspecting response shape, not content.\n  // The reasoning_effort hint helps reasoning models surface their CoT.\n  const response = await client.chat.completions.create({\n    model: modelId,\n    messages: [\n      { role: \"user\", content: \"What is 2+2? Reply with just the number.\" },\n    ],\n    max_tokens: 200, // generous enough for reasoning models to surface CoT\n    temperature: 0,\n  } as never);\n\n  const shape = inspectResponseForFingerprint(response);\n  return {\n    modelId: normalizeModelId(modelId),\n    baseURL: baseURL ?? \"openai-native\",\n    reasoningModel: shape.reasoningModel,\n    ...(shape.reasoningField ? { reasoningField: shape.reasoningField } : {}),\n    fingerprintedAt: new Date().toISOString(),\n    schemaVersion: 1,\n  };\n}\n","/**\r\n * OpenAI adapter implementing LLMPort + EmbeddingsPort.\r\n *\r\n * Wraps the openai npm package's chat completions and embeddings APIs.\r\n * The same adapter serves OpenAI plus 10+ OpenAI-compatible providers\r\n * via the `baseURL` option (Azure OpenAI, Groq, Together AI, Fireworks AI,\r\n * DeepInfra, Perplexity, Cerebras, LiteLLM proxy, Ollama compat-mode, etc.).\r\n */\r\n\r\nimport OpenAI from \"openai\";\r\nimport { zodToJsonSchema } from \"zod-to-json-schema\";\r\nimport {\r\n  attemptValidationRepair,\r\n  computeChatCost,\r\n  computeEmbeddingCost,\r\n  emitAgentStepCompleted,\r\n  emitAgentStepStarted,\r\n  emitAgentToolCalled,\r\n  emitAgentToolReturned,\r\n  emitRetryEvent,\r\n  EmptyResponseError,\r\n  extractJSON,\r\n  failValidation,\r\n  mergeTokenUsage,\r\n  readStreamCompleteCallback,\r\n  resurrectOperationContext,\r\n  sha256Hex,\r\n  throwIfAborted,\r\n  tryParsePartialJSON,\r\n  validateImageBlocks,\r\n  wrapProviderError,\r\n  type AgentResult,\r\n  type BatchEmbeddingOptions,\r\n  type BatchEmbeddingResult,\r\n  type ContentBlock,\r\n  type CostUsage,\r\n  type MessageContent,\r\n  type EmbeddingOptions,\r\n  type EmbeddingResult,\r\n  type EmbeddingsPort,\r\n  type GenerateStructuredOptions,\r\n  type GenerateStructuredResult,\r\n  type GenerateTextOptions,\r\n  type GenerateTextResult,\r\n  type LLMPort,\r\n  type ModelPricing,\r\n  type OnRetry,\r\n  type ProviderModelInfo,\r\n  type RetryEvent,\r\n  type RunAgentOptions,\r\n  type StreamStructuredOptions,\r\n  type StreamTextOptions,\r\n  type ToolDefinition,\r\n  type TokenUsage,\r\n  type ValidationStrategy,\r\n} from \"@llm-ports/core\";\r\nimport { OPENAI_PRICING } from \"./pricing.js\";\r\nimport {\r\n  fromOpenAIAssistantMessage,\r\n  parseHarmonyToolCalls,\r\n  toOpenAIMessages,\r\n  type OpenAIMessage,\r\n} from \"./content.js\";\r\nimport type { ChatStreamEvent, LLMMessage, StreamChatOptions } from \"@llm-ports/core\";\r\nimport {\r\n  getEffectiveCapabilities,\r\n  isJsonModeRejection,\r\n  isSystemMessageRejection,\r\n  isTemperatureRejection,\r\n  normalizeModelId,\r\n  rememberConstraint,\r\n  seedKnownConstraints,\r\n} from \"./capabilities.js\";\r\nimport {\r\n  buildFingerprintKey,\r\n  inspectResponseForFingerprint,\r\n  type FingerprintCacheBackend,\r\n  type ModelFingerprint,\r\n} from \"./fingerprint.js\";\r\n\r\n// ─── Adapter options ─────────────────────────────────────────────────\r\n\r\nexport interface OpenAIAdapterOptions {\r\n  apiKey: string;\r\n  /**\r\n   * Override the API base URL. Use this for OpenAI-compatible providers:\r\n   *   - Azure OpenAI: `https://<resource>.openai.azure.com/openai/deployments/<deployment>`\r\n   *   - Groq: `https://api.groq.com/openai/v1`\r\n   *   - Together AI: `https://api.together.xyz/v1`\r\n   *   - Fireworks AI: `https://api.fireworks.ai/inference/v1`\r\n   *   - DeepInfra: `https://api.deepinfra.com/v1/openai`\r\n   *   - Perplexity: `https://api.perplexity.ai`\r\n   *   - Cerebras: `https://api.cerebras.ai/v1`\r\n   *   - LiteLLM proxy: self-hosted, e.g. `http://localhost:4000`\r\n   *   - Ollama compat-mode: `http://localhost:11434/v1` (prefer adapter-ollama)\r\n   */\r\n  baseURL?: string;\r\n  /** Inject a custom fetch (used for tests / proxies). */\r\n  fetch?: typeof fetch;\r\n  /** Default validation strategy if the registry doesn't override per-call. */\r\n  validationStrategy?: ValidationStrategy;\r\n  /** Override pricing for any model id. Falls back to bundled OPENAI_PRICING. */\r\n  pricingOverrides?: Record<string, ModelPricing>;\r\n  /**\r\n   * Friendly name for the adapter to use in error messages and providerAlias\r\n   * default. Useful when you point this adapter at a non-OpenAI baseURL and\r\n   * want errors to say \"groq\" instead of \"openai\". The adapter token in env\r\n   * config still says \"openai\" because that's the SDK shape.\r\n   */\r\n  displayName?: string;\r\n  /**\r\n   * Number of retries the OpenAI SDK performs internally for retriable HTTP\r\n   * errors (408, 409, 429, 500+). Defaults to 2 (the SDK's own default). The\r\n   * SDK does NOT retry 401s; that's handled separately in this adapter — see\r\n   * {@link OpenAIAdapterOptions.transientAuthRetries}.\r\n   */\r\n  maxRetries?: number;\r\n  /**\r\n   * Number of retries to attempt on transient 401 responses. OpenAI project\r\n   * keys (sk-proj-*) have burst-protection that occasionally returns\r\n   * 401 \"Incorrect API key\" when too many requests arrive in a short window,\r\n   * even though the key is valid. The adapter only retries 401s if a prior\r\n   * request on this same client previously succeeded — that's how it\r\n   * distinguishes a transient burst-protection 401 from a real auth failure.\r\n   * Defaults to 2 retries with exponential backoff (500ms, 1500ms).\r\n   * Set to 0 to disable.\r\n   */\r\n  transientAuthRetries?: number;\r\n  /**\r\n   * Override the backoff delay between transient-401 retries. Receives the\r\n   * 0-indexed retry attempt (0 = first retry) and returns the delay in\r\n   * milliseconds. Default is `(attempt) => 500 * Math.pow(3, attempt)` —\r\n   * 500ms, 1500ms, 4500ms... Tests inject `() => 0` to skip the wait.\r\n   */\r\n  transientAuthBackoffMs?: (attempt: number) => number;\r\n  /**\r\n   * Maximum bytes per base64 image. Defaults to 20MB (OpenAI's per-image\r\n   * limit). Set to 0 or a negative number to disable size validation.\r\n   */\r\n  imageSizeLimitBytes?: number;\r\n  /**\r\n   * Set to `true` to allow the OpenAI SDK to run in a browser environment.\r\n   * The SDK refuses by default to prevent accidental exposure of API keys.\r\n   *\r\n   * Only enable this when you understand the risk and have a mitigation in\r\n   * place: a server-side proxy that strips keys from the request before\r\n   * forwarding, a \"bring your own API key\" UI where users supply their own\r\n   * key, or an internal tool exposed only to trusted users. Forwarded to\r\n   * `new OpenAI({ dangerouslyAllowBrowser })` verbatim.\r\n   *\r\n   * Available since `0.1.0-alpha.9`.\r\n   */\r\n  dangerouslyAllowBrowser?: boolean;\r\n  /**\r\n   * Use OpenAI-style strict `response_format: { type: \"json_schema\", strict: true }`\r\n   * for `generateStructured` instead of classic `response_format: { type: \"json_object\" }`.\r\n   * With strict mode the provider constrains decoding to the exact schema\r\n   * before tokens are produced, so invalid JSON or missing fields are\r\n   * impossible (modulo provider bugs). The Zod schema is converted to\r\n   * JSON Schema via `zod-to-json-schema`, then post-processed to add\r\n   * `additionalProperties: false` on every object (a hard requirement of\r\n   * OpenAI / Cerebras / Groq strict mode).\r\n   *\r\n   * Defaults to auto-detect (alpha.14+). Auto-enabled when:\r\n   *   - `baseURL` is unset (= OpenAI native; strict json_schema has been GA\r\n   *     on gpt-4o / gpt-5 / o-series since August 2024)\r\n   *   - `baseURL` contains `api.cerebras.ai` (Cerebras's gpt-oss / Qwen3.6\r\n   *     endpoints silently ignore classic `json_object` mode; strict mode\r\n   *     is required for reliable structured output)\r\n   *   - `baseURL` contains `api.groq.com` (verified to support strict\r\n   *     `response_format: json_schema` with constrained decoding)\r\n   *   - `baseURL` contains `api.sambanova.ai` (added alpha.15+;\r\n   *     empirically verified — MiniMax-M2.7 jumped from 0/10 → 10/10 on\r\n   *     nested schemas with strict mode forced on)\r\n   *\r\n   * Stays OPT-IN (default `false`) for unverified compat providers like\r\n   * Together AI, Fireworks AI, Clarifai. Set `useStrictResponseFormat: true`\r\n   * explicitly once you've verified the provider's strict-mode support.\r\n   *\r\n   * Opt-out: set `useStrictResponseFormat: false` explicitly if your Zod\r\n   * schemas use open shapes that can't accept `additionalProperties: false`\r\n   * (e.g. `z.record(...)`, schemas with computed/optional fields the\r\n   * model is allowed to extend), or if strict mode is causing your model\r\n   * to reject the request.\r\n   *\r\n   * Available since `0.1.0-alpha.9`; default expanded to OpenAI native +\r\n   * Groq in `0.1.0-alpha.14`; SambaNova added `0.1.0-alpha.15`.\r\n   */\r\n  useStrictResponseFormat?: boolean;\r\n  /**\r\n   * Observability hook fired whenever the adapter retries an in-flight\r\n   * request for a known transient reason. Sync or async; called\r\n   * fire-and-forget. Throwing from the hook does NOT cancel the retry.\r\n   * Fires for: transient-auth (project-key burst-protection 401),\r\n   * capability-fallback (temperature/json_object/system-message rejection),\r\n   * reasoning-starvation (model used full budget on hidden reasoning),\r\n   * validation-feedback (structured output failed schema; retry with feedback).\r\n   */\r\n  onRetry?: OnRetry;\r\n  /**\r\n   * Streamed cost surfacing (alpha.25+). When `true` (default), the adapter\r\n   * adds `stream_options: { include_usage: true }` to streaming requests so\r\n   * the provider returns a final chunk with usage counts, which the adapter\r\n   * uses to compute cost and fire the Registry's stream-complete callback.\r\n   *\r\n   * Set to `false` when the underlying compat provider rejects the\r\n   * `stream_options` field. The stream itself still works; only the\r\n   * post-completion `onCost` / `onTokenUsage` events are suppressed for\r\n   * that provider (matches alpha.24 behavior).\r\n   */\r\n  streamUsage?: boolean;\r\n  /**\r\n   * Behavioral fingerprint cache (alpha.24+). When supplied, the adapter\r\n   * seeds the capability learner from this cache before each call and\r\n   * writes back the observed fingerprint after each successful call. This\r\n   * skips the first-call discovery penalty for known models AND avoids\r\n   * the static catalog being load-bearing for novel reasoning models.\r\n   *\r\n   * The cache is keyed by `(baseURL, modelId)`. Different providers serving\r\n   * the same canonical model get separate entries (correctly — they may\r\n   * expose different response shapes for the same weights). The same model\r\n   * served by the same provider across multiple processes shares state when\r\n   * the cache backend persists.\r\n   *\r\n   * Two bundled backends:\r\n   *   - `InMemoryFingerprintCache` — Map; lifetime is the current process.\r\n   *     Useful for dev, tests, short workers.\r\n   *   - `FileFingerprintCache(path)` — atomic JSON file. Useful for\r\n   *     long-running workers and CI warm-starts.\r\n   *\r\n   * Bring your own backend (Redis, S3, etc.) by implementing\r\n   * `FingerprintCacheBackend`.\r\n   *\r\n   * Default: undefined (no cache). Static catalog + runtime detection\r\n   * (alpha.22) handle correctness without fingerprinting; the fingerprint\r\n   * cache is purely an optimization to skip the first-call penalty.\r\n   */\r\n  fingerprintCache?: FingerprintCacheBackend;\r\n}\r\n\r\n// ─── Internal context ────────────────────────────────────────────────\r\n\r\ninterface AdapterContext {\r\n  client: OpenAI;\r\n  validationStrategy: ValidationStrategy;\r\n  pricingOverrides: Record<string, ModelPricing>;\r\n  /**\r\n   * Set true after the first successful response on this client. Used to\r\n   * distinguish OpenAI project-key burst-protection 401s (transient; key\r\n   * is valid) from real auth failures (the key never worked).\r\n   * Boxed so AdapterContext stays a value type while `hasSucceeded` mutates.\r\n   */\r\n  hasSucceeded: { value: boolean };\r\n  transientAuthRetries: number;\r\n  transientAuthBackoffMs: (attempt: number) => number;\r\n  /** 0 means \"no size check\"; positive number is the per-image byte limit. */\r\n  imageSizeLimitBytes: number;\r\n  /** Whether generateStructured should emit `response_format: { type: \"json_schema\", strict: true }`. */\r\n  useStrictResponseFormat: boolean;\r\n  /** Observability hook for transient retries. Optional; no-op when unset. */\r\n  onRetry?: OnRetry;\r\n  /** Behavioral fingerprint cache (alpha.24+). Optional. */\r\n  fingerprintCache?: FingerprintCacheBackend;\r\n  /** Adapter's configured baseURL — used for fingerprint cache key construction. */\r\n  baseURL: string | undefined;\r\n  /** Enable streamed cost surfacing via `stream_options: { include_usage: true }`. Defaults to true. (alpha.25+) */\r\n  streamUsage: boolean;\r\n}\r\n\r\n/**\r\n * Auto-detect whether to default `useStrictResponseFormat` to true based on\r\n * the `baseURL`. See the option's docstring for the rationale per provider.\r\n *\r\n * Exported for testability and for users who want to reuse the same default\r\n * logic when constructing multiple adapter instances programmatically.\r\n */\r\nexport function autoDetectStrictResponseFormat(baseURL: string | undefined): boolean {\r\n  // OpenAI native: no baseURL set, or explicit api.openai.com host (some\r\n  // users redundantly point at the default). Strict json_schema GA on\r\n  // gpt-4o / gpt-5 / o-series since August 2024.\r\n  if (!baseURL) return true;\r\n  if (baseURL.includes(\"api.openai.com\")) return true;\r\n  // Cerebras: classic json_object is silently ignored on gpt-oss / Qwen3.6\r\n  // tiers; strict mode is the only reliable path.\r\n  if (baseURL.includes(\"api.cerebras.ai\")) return true;\r\n  // Groq: verified to support strict `response_format: json_schema` with\r\n  // constrained decoding (per Groq docs, May 2026).\r\n  if (baseURL.includes(\"api.groq.com\")) return true;\r\n  // SambaNova: empirically verified 2026-05-27 — MiniMax-M2.7 with explicit\r\n  // `useStrictResponseFormat: true` jumped from 0/10 → 10/10 schema-valid\r\n  // on a nested production scoring schema (BEPA A/B harness). Docs were\r\n  // ambiguous; the probe is the source of truth.\r\n  if (baseURL.includes(\"api.sambanova.ai\")) return true;\r\n  // DeepInfra: empirically verified 2026-06-17 — deepseek-flash + gemma-31b\r\n  // jumped from 2/8 + 8/8 validation retries (json_object default) to 0/8 + 0/8\r\n  // with strict mode (ADW 04-Structured-Output-Reliability.md). DeepInfra's\r\n  // own docs explicitly recommend strict `json_schema` with `strict: true`\r\n  // for production schemas. Added alpha.21 per llm-ports#47.\r\n  if (baseURL.includes(\"api.deepinfra.com\")) return true;\r\n  // Parasail: empirically verified 2026-06-17 — mimo-parasail (MiMo-V2.5)\r\n  // dropped from 3/8 validation retries to 0/8 with strict mode (same ADW\r\n  // sweep). Added alpha.21 per llm-ports#47.\r\n  if (baseURL.includes(\"api.parasail.io\")) return true;\r\n  // Unknown compat provider — stay opt-in.\r\n  return false;\r\n}\r\n\r\n/** Fire the onRetry hook fire-and-forget. Delegates to the shared `emitRetryEvent`\r\n *  helper from @llm-ports/core so semantics stay consistent across adapters. */\r\nfunction emitRetry(ctx: AdapterContext, event: RetryEvent): void {\r\n  emitRetryEvent(ctx.onRetry, event);\r\n}\r\n\r\nfunction makeClient(opts: OpenAIAdapterOptions): OpenAI {\r\n  return new OpenAI({\r\n    apiKey: opts.apiKey,\r\n    ...(opts.baseURL ? { baseURL: opts.baseURL } : {}),\r\n    ...(opts.fetch ? { fetch: opts.fetch as OpenAI[\"fetch\"] } : {}),\r\n    ...(opts.maxRetries !== undefined ? { maxRetries: opts.maxRetries } : {}),\r\n    ...(opts.dangerouslyAllowBrowser ? { dangerouslyAllowBrowser: true } : {}),\r\n  });\r\n}\r\n\r\nfunction pricingFor(ctx: AdapterContext, modelId: string): ModelPricing {\r\n  const pricing = ctx.pricingOverrides[modelId] ?? OPENAI_PRICING[modelId];\r\n  if (!pricing) {\r\n    throw new Error(\r\n      `No pricing entry for OpenAI model \"${modelId}\". Provide pricingOverrides or update src/pricing.ts.`,\r\n    );\r\n  }\r\n  return pricing;\r\n}\r\n\r\n// ─── Public factory ──────────────────────────────────────────────────\r\n\r\nexport interface OpenAIAdapter {\r\n  name: \"openai\";\r\n  pricing: Record<string, ModelPricing>;\r\n  createLLMPort: (modelId: string, alias: string) => LLMPort;\r\n  createEmbeddingsPort: (modelId: string, alias: string) => EmbeddingsPort;\r\n}\r\n\r\nexport function createOpenAIAdapter(opts: OpenAIAdapterOptions): OpenAIAdapter {\r\n  // Merge user-supplied pricingOverrides into the adapter's exposed pricing\r\n  // table so the registry's pricing check sees them. Without this merge,\r\n  // models that aren't in the bundled OPENAI_PRICING (e.g. compat-provider\r\n  // models like Groq's llama-3.3-70b-versatile or Cerebras's llama-4-scout)\r\n  // would be rejected by the registry as \"no pricing entry\".\r\n  const mergedPricing: Record<string, ModelPricing> = {\r\n    ...OPENAI_PRICING,\r\n    ...(opts.pricingOverrides ?? {}),\r\n  };\r\n\r\n  const ctx: AdapterContext = {\r\n    client: makeClient(opts),\r\n    validationStrategy: opts.validationStrategy ?? {\r\n      kind: \"retry-with-feedback\",\r\n      maxAttempts: 2,\r\n      includeOriginalError: true,\r\n    },\r\n    pricingOverrides: opts.pricingOverrides ?? {},\r\n    hasSucceeded: { value: false },\r\n    transientAuthRetries: opts.transientAuthRetries ?? 2,\r\n    transientAuthBackoffMs:\r\n      opts.transientAuthBackoffMs ?? ((attempt) => 500 * Math.pow(3, attempt)),\r\n    imageSizeLimitBytes: opts.imageSizeLimitBytes ?? 20 * 1024 * 1024,\r\n    useStrictResponseFormat:\r\n      opts.useStrictResponseFormat ?? autoDetectStrictResponseFormat(opts.baseURL),\r\n    baseURL: opts.baseURL,\r\n    streamUsage: opts.streamUsage ?? true,\r\n    ...(opts.onRetry ? { onRetry: opts.onRetry } : {}),\r\n    ...(opts.fingerprintCache ? { fingerprintCache: opts.fingerprintCache } : {}),\r\n  };\r\n\r\n  return {\r\n    name: \"openai\",\r\n    pricing: mergedPricing,\r\n    createLLMPort: (modelId, alias) => createPort(ctx, modelId, alias),\r\n    createEmbeddingsPort: (modelId, alias) => createEmbeddings(ctx, modelId, alias),\r\n  };\r\n}\r\n\r\n/**\r\n * Apply a cached fingerprint to the capability learner (alpha.24+).\r\n *\r\n * Called once when the fingerprint cache yields a hit for the (baseURL,\r\n * modelId) tuple. Translates the recorded `reasoningField` into the\r\n * `reasoningModel: true` constraint the learner consumes.\r\n */\r\nfunction seedFromFingerprint(modelId: string, fp: ModelFingerprint): void {\r\n  if (fp.reasoningModel) {\r\n    rememberConstraint(modelId, { reasoningModel: true });\r\n  }\r\n  // Non-reasoning fingerprints are also informative — they tell us NOT to\r\n  // apply the headroom multiplier. The learner today only stores positive\r\n  // constraints, so we don't write a negative; the absence-as-default\r\n  // behavior preserves correctness.\r\n}\r\n\r\n/**\r\n * Persist a fingerprint observation to the cache (alpha.24+).\r\n *\r\n * Fire-and-forget: writes back asynchronously without blocking the inflight\r\n * call. Cache backend errors are swallowed — a failed write is observability\r\n * loss, not a correctness issue (next process startup will just re-discover).\r\n */\r\nfunction writeFingerprint(\r\n  cache: FingerprintCacheBackend,\r\n  baseURL: string | undefined,\r\n  modelId: string,\r\n  response: unknown,\r\n): void {\r\n  const shape = inspectResponseForFingerprint(response);\r\n  // Don't cache \"no signal\" verdicts. They could be a non-reasoning prompt\r\n  // against a reasoning model (e.g., \"what's 2+2\" against gpt-oss-120b at\r\n  // reasoning_effort: \"none\"). Wait for an observation that tells us\r\n  // something definitive.\r\n  if (!shape.reasoningModel) return;\r\n  const fp: ModelFingerprint = {\r\n    modelId: normalizeModelId(modelId),\r\n    baseURL: baseURL ?? \"openai-native\",\r\n    reasoningModel: shape.reasoningModel,\r\n    ...(shape.reasoningField ? { reasoningField: shape.reasoningField } : {}),\r\n    fingerprintedAt: new Date().toISOString(),\r\n    schemaVersion: 1,\r\n  };\r\n  const key = buildFingerprintKey(baseURL, modelId);\r\n  // Fire-and-forget; backend errors silently dropped.\r\n  Promise.resolve(cache.set(key, fp)).catch(() => {\r\n    /* swallow — fingerprint write is observability, not correctness */\r\n  });\r\n}\r\n\r\n// ─── LLMPort implementation ──────────────────────────────────────────\r\n\r\n/**\r\n * Resolve the canonical `messages` + `instructions` pair from the alpha.26\r\n * dual-shape call options. The Registry normalizes `{ instructions, prompt }`\r\n * into `messages` before dispatch, so in practice this helper mostly reads\r\n * `options.messages`. When called directly (bypassing the Registry, e.g.\r\n * consumer holds a raw port), it also honors the legacy fields.\r\n *\r\n * Semantics:\r\n *   - If `options.messages` is set (Registry-normalized path), extract the\r\n *     LEADING contiguous system-role messages into a concatenated\r\n *     `instructions` string (Anthropic + Google adapters use a separate\r\n *     system field; the OpenAI shape keeps system inline but the adapter\r\n *     centralizes the transform for consistency). Remaining messages become\r\n *     OpenAI-shape messages.\r\n *   - Non-contiguous system messages (system in the middle of a\r\n *     conversation) are passed through inline unchanged — OpenAI supports\r\n *     mid-conversation system messages natively as boundary markers.\r\n */\r\nfunction resolveMessagesFromCallOptions(options: {\r\n  messages: LLMMessage[];\r\n}): { messages: OpenAIMessage[]; instructions: string | undefined } {\r\n  const arr = options.messages;\r\n  const leadingSystem: string[] = [];\r\n  let i = 0;\r\n  while (i < arr.length && arr[i]!.role === \"system\") {\r\n    const content = arr[i]!.content;\r\n    if (typeof content === \"string\") {\r\n      leadingSystem.push(content);\r\n    } else {\r\n      // Multimodal system content — flatten text blocks; other blocks\r\n      // fall through inline (unusual case).\r\n      const textFragments: string[] = [];\r\n      let hasNonText = false;\r\n      for (const block of content) {\r\n        if ((block as { type: string }).type === \"text\") {\r\n          textFragments.push((block as { text: string }).text);\r\n        } else {\r\n          hasNonText = true;\r\n        }\r\n      }\r\n      if (hasNonText) break; // fall through with system inline; abort concatenation\r\n      leadingSystem.push(textFragments.join(\"\"));\r\n    }\r\n    i++;\r\n  }\r\n  const instructions = leadingSystem.length > 0 ? leadingSystem.join(\"\\n\\n\") : undefined;\r\n  const remaining = arr.slice(i);\r\n  const openaiMessages = remaining.length > 0 ? toOpenAIMessages(remaining) : [];\r\n  // If we consumed all messages as system content, fall back to a single\r\n  // empty user message so the provider has SOMETHING to respond to. This\r\n  // is a defensive edge case — most callers wouldn't do this deliberately.\r\n  if (openaiMessages.length === 0) {\r\n    openaiMessages.push({ role: \"user\", content: \"\" });\r\n  }\r\n  return { messages: openaiMessages, instructions };\r\n}\r\n\r\nfunction createPort(ctx: AdapterContext, modelId: string, alias: string): LLMPort {\r\n  const pricing = pricingFor(ctx, modelId);\r\n  // Seed known-reasoning catalog so first calls on o-series / gpt-5-nano /\r\n  // gpt-oss / Qwen3.6 / MiniMax-M2.7 / MiMo-V skip the first-call penalty.\r\n  // The catalog is a shortcut, not a correctness layer — runtime detection\r\n  // (alpha.22) handles models the catalog doesn't know, and behavioral\r\n  // fingerprinting (alpha.24) handles them without the wasted first call\r\n  // when a cache is configured.\r\n  seedKnownConstraints(modelId);\r\n\r\n  // Behavioral fingerprint cache (alpha.24+): if a cache is configured AND\r\n  // contains a fingerprint for this (baseURL, modelId) tuple, seed the\r\n  // learner from it. This skips the first-call discovery for models the\r\n  // catalog doesn't know but that have been previously fingerprinted\r\n  // (either via the standalone `fingerprintModel()` helper or by an\r\n  // earlier call against this cache).\r\n  //\r\n  // Fire-and-forget on the read side: don't block port construction on a\r\n  // potentially-slow cache backend (Redis, S3 reads). The next call against\r\n  // an unseeded model just pays the usual first-call learning penalty\r\n  // (already handled by runtime detection); not a correctness issue.\r\n  if (ctx.fingerprintCache) {\r\n    const key = buildFingerprintKey(ctx.baseURL, modelId);\r\n    Promise.resolve(ctx.fingerprintCache.get(key))\r\n      .then((fp) => {\r\n        if (fp) seedFromFingerprint(modelId, fp);\r\n      })\r\n      .catch(() => {\r\n        /* swallow — fingerprint cache read is best-effort */\r\n      });\r\n  }\r\n\r\n  // Validate image content blocks at the adapter boundary. Throws typed\r\n  // ImageTooLargeError or InvalidImageUrlError if a base64 image exceeds\r\n  // the size limit or a URL-form image has a bad scheme.\r\n  const validateContent = (content: MessageContent): void => {\r\n    if (Array.isArray(content)) {\r\n      validateImageBlocks(content, {\r\n        alias,\r\n        ...(ctx.imageSizeLimitBytes > 0 ? { limitBytes: ctx.imageSizeLimitBytes } : {}),\r\n      });\r\n    }\r\n  };\r\n  const validateMessages = (messages: ReadonlyArray<{ content: MessageContent }>): void => {\r\n    for (const msg of messages) validateContent(msg.content);\r\n  };\r\n\r\n  return {\r\n    async generateText(options: GenerateTextOptions): Promise<GenerateTextResult> {\r\n      throwIfAborted(options.signal);\r\n      // alpha.27+: validation happens in resolveMessagesFromCallOptions via message content check;\r\n      const start = Date.now();\r\n      const { messages: chatMessages, instructions } = resolveMessagesFromCallOptions(options);\r\n      const { response } = await executeChatRequest(ctx.client, ctx, alias, pricing, {\r\n        modelId,\r\n        messages: chatMessages,\r\n        ...(instructions !== undefined ? { instructions } : {}),\r\n        ...(options.temperature !== undefined ? { temperature: options.temperature } : {}),\r\n        ...(options.maxOutputTokens !== undefined ? { maxOutputTokens: options.maxOutputTokens } : {}),\r\n        ...(options.signal ? { signal: options.signal } : {}),\r\n        ...(options.reasoningEffort ? { reasoningEffort: options.reasoningEffort } : {}),\r\n        ...(options.providerExtras ? { providerExtras: options.providerExtras } : {}),\r\n        stream: false,\r\n      });\r\n      const r = response as {\r\n        model?: string;\r\n        choices: Array<{ message: { content: string | null } }>;\r\n        usage?: { prompt_tokens?: number; completion_tokens?: number; prompt_tokens_details?: { cached_tokens?: number } };\r\n      };\r\n      const usage = parseUsage(r);\r\n      const text = r.choices[0]?.message.content ?? \"\";\r\n      return {\r\n        text,\r\n        usage,\r\n        cost: computeChatCost(usage, pricing),\r\n        modelId: r.model ?? modelId,\r\n        providerAlias: alias,\r\n        latencyMs: Date.now() - start,\r\n      };\r\n    },\r\n\r\n    async generateStructured<T>(\r\n      options: GenerateStructuredOptions<T>,\r\n    ): Promise<GenerateStructuredResult<T>> {\r\n      throwIfAborted(options.signal);\r\n      const start = Date.now();\r\n      let attempts = 0;\r\n      const maxAttempts =\r\n        ctx.validationStrategy.kind === \"retry-with-feedback\"\r\n          ? ctx.validationStrategy.maxAttempts\r\n          : 1;\r\n\r\n      let correctionPrompt: string | null = null;\r\n      let lastUsage: TokenUsage = { inputTokens: 0, outputTokens: 0, totalTokens: 0 };\r\n      let lastModelId = modelId;\r\n\r\n      // alpha.27+: canonical messages input. Caller supplies their own JSON\r\n      // instruction OR relies on strict-mode response_format. Correction\r\n      // prompts on retry rounds append as trailing user messages.\r\n      const {\r\n        messages: baseMessages,\r\n        instructions: baseInstructions,\r\n      } = resolveMessagesFromCallOptions(options);\r\n\r\n      while (attempts < maxAttempts) {\r\n        attempts++;\r\n        const requestMessages: OpenAIMessage[] = [...baseMessages];\r\n        if (correctionPrompt) {\r\n          requestMessages.push({ role: \"user\", content: correctionPrompt });\r\n        }\r\n\r\n        // When strict mode is enabled, build the JSON Schema for the call.\r\n        // The schema is reused across retry-with-feedback rounds so we only\r\n        // build it once.\r\n        //\r\n        // Precedence (alpha.21+):\r\n        //   1. options.strict (per-call override; takes priority)\r\n        //   2. ctx.useStrictResponseFormat (adapter-level, set at construction)\r\n        //   3. autoDetectStrictResponseFormat(baseURL) (default, applied to (2)\r\n        //      at construction time if the user didn't pass useStrictResponseFormat)\r\n        //\r\n        // See llm-ports#46 for the empirical case driving the per-call hook:\r\n        // a registry with one adapter alias per provider needs to flip strict\r\n        // on/off per call based on the schema shape (closed-shape → strict,\r\n        // `z.record(...)` → json_object).\r\n        const effectiveStrict = options.strict ?? ctx.useStrictResponseFormat;\r\n        const strictResponseSchema = effectiveStrict\r\n          ? {\r\n              name: options.schemaName ?? \"structured_output\",\r\n              schema: buildStrictJsonSchema(options.schema),\r\n            }\r\n          : undefined;\r\n\r\n        // executeChatRequest handles error wrapping and capability fallback.\r\n        // Don't double-wrap here — let ProviderUnavailableError propagate, and\r\n        // let failValidation throw ValidationError directly.\r\n        const { response } = await executeChatRequest(ctx.client, ctx, alias, pricing, {\r\n          modelId,\r\n          messages: requestMessages,\r\n          ...(baseInstructions !== undefined ? { instructions: baseInstructions } : {}),\r\n          temperature: options.temperature ?? 0,\r\n          ...(options.maxOutputTokens !== undefined\r\n            ? { maxOutputTokens: options.maxOutputTokens }\r\n            : {}),\r\n          ...(options.signal ? { signal: options.signal } : {}),\r\n          ...(options.reasoningEffort ? { reasoningEffort: options.reasoningEffort } : {}),\r\n        ...(options.providerExtras ? { providerExtras: options.providerExtras } : {}),\r\n          ...(strictResponseSchema ? { strictResponseSchema } : { jsonMode: true }),\r\n          stream: false,\r\n        });\r\n        const r = response as {\r\n          model?: string;\r\n          choices: Array<{ message: { content: string | null } }>;\r\n          usage?: { prompt_tokens?: number; completion_tokens?: number; prompt_tokens_details?: { cached_tokens?: number } };\r\n        };\r\n        // Accumulate usage across retry-with-feedback rounds so cost\r\n        // reporting reflects every SDK call, not just the final one.\r\n        // Matches runAgent's mergeTokenUsage pattern.\r\n        lastUsage = mergeTokenUsage(lastUsage, parseUsage(r));\r\n        lastModelId = r.model ?? modelId;\r\n        const raw = r.choices[0]?.message.content ?? \"\";\r\n        // If the response is empty after the executeChatRequest starvation\r\n        // retry, the model produced no JSON to parse. Throw a typed\r\n        // EmptyResponseError so the registry can route to a fallback model\r\n        // instead of seeing JSON.parse(\"\") raise SyntaxError wrapped as\r\n        // ProviderUnavailableError. Mirrors @llm-ports/adapter-vercel.\r\n        if (raw.trim().length === 0) {\r\n          throw new EmptyResponseError(\r\n            alias,\r\n            lastModelId,\r\n            \"generateStructured needs a JSON body to parse. Increase maxOutputTokens or route to a fallback model.\",\r\n          );\r\n        }\r\n        const decoded = extractJSON(raw);\r\n        let parsed = options.schema.safeParse(decoded);\r\n        if (!parsed.success) {\r\n          // Programmatic repair pass — catches the 6 common LLM output\r\n          // quirks (null where not expected, \"9\" vs 9, \"true\" vs true, etc.)\r\n          // before paying for a retry-with-feedback round-trip.\r\n          const repaired = attemptValidationRepair(decoded, parsed.error);\r\n          const reparsed = options.schema.safeParse(repaired);\r\n          if (reparsed.success) parsed = reparsed;\r\n        }\r\n        if (parsed.success) {\r\n          return {\r\n            data: parsed.data as T,\r\n            usage: lastUsage,\r\n            cost: computeChatCost(lastUsage, pricing),\r\n            modelId: lastModelId,\r\n            providerAlias: alias,\r\n            latencyMs: Date.now() - start,\r\n            validationAttempts: attempts,\r\n          };\r\n        }\r\n        if (\r\n          ctx.validationStrategy.kind === \"retry-with-feedback\" &&\r\n          attempts < maxAttempts\r\n        ) {\r\n          const issues = parsed.error.issues\r\n            .map((i) => `- ${i.path.join(\".\") || \"<root>\"}: ${i.message}`)\r\n            .join(\"\\n\");\r\n          correctionPrompt = `Your previous response failed validation:\\n${issues}\\n\\nReply with a single corrected JSON object only.`;\r\n          emitRetry(ctx, {\r\n            reason: \"validation-feedback\",\r\n            attempt: attempts - 1,\r\n            modelId: lastModelId,\r\n            providerAlias: alias,\r\n            delayMs: 0,\r\n            cause: parsed.error,\r\n          });\r\n          continue;\r\n        }\r\n        failValidation(parsed.error.issues, attempts);\r\n      }\r\n      throw new Error(\"generateStructured exhausted attempts\");\r\n    },\r\n\r\n    async *streamText(options: StreamTextOptions): AsyncIterable<string> {\r\n      throwIfAborted(options.signal);\r\n      // alpha.27+: validation happens in resolveMessagesFromCallOptions via message content check;\r\n      const { messages: chatMessages, instructions } = resolveMessagesFromCallOptions(options);\r\n      const streamStart = Date.now();\r\n      const streamCompleteCallback = readStreamCompleteCallback(options);\r\n      const stream = await executeChatStream(ctx.client, ctx, alias, pricing, {\r\n        modelId,\r\n        messages: chatMessages,\r\n        ...(instructions !== undefined ? { instructions } : {}),\r\n        ...(options.temperature !== undefined ? { temperature: options.temperature } : {}),\r\n        ...(options.maxOutputTokens !== undefined ? { maxOutputTokens: options.maxOutputTokens } : {}),\r\n        ...(options.signal ? { signal: options.signal } : {}),\r\n        ...(options.reasoningEffort ? { reasoningEffort: options.reasoningEffort } : {}),\r\n        ...(options.providerExtras ? { providerExtras: options.providerExtras } : {}),\r\n        stream: true,\r\n        streamUsage: ctx.streamUsage,\r\n      });\r\n      let finalUsageChunk: OpenAIStreamChunk | undefined;\r\n      for await (const chunk of stream) {\r\n        // Alpha.25+: watch for the final usage-only chunk (choices=[] + usage\r\n        // populated) that `stream_options: { include_usage: true }` produces.\r\n        // The final chunk usually has no delta, so we intercept and stash it\r\n        // for post-loop cost emission instead of yielding.\r\n        if (chunk.usage && (!chunk.choices || chunk.choices.length === 0)) {\r\n          finalUsageChunk = chunk;\r\n          continue;\r\n        }\r\n        const delta = chunk.choices[0]?.delta?.content;\r\n        if (typeof delta === \"string\" && delta.length > 0) {\r\n          yield delta;\r\n        }\r\n      }\r\n      // Natural completion: fire the Registry-attached stream-complete\r\n      // callback with usage + cost. Mid-stream errors and consumer aborts\r\n      // bypass this block (the for-await throws upward instead).\r\n      if (streamCompleteCallback && finalUsageChunk?.usage) {\r\n        emitStreamComplete({\r\n          usage: finalUsageChunk.usage,\r\n          modelId,\r\n          providerAlias: alias,\r\n          pricing,\r\n          streamStart,\r\n          callback: streamCompleteCallback,\r\n        });\r\n      }\r\n    },\r\n\r\n    /**\r\n     * Alpha.32+. One streamed turn with tool calls surfaced, never\r\n     * executed. See `LLMPort.streamChat`.\r\n     *\r\n     * ## Tool schemas are converted here, per call\r\n     *\r\n     * `toOpenAITools(options.tools)` runs inside this method, which the\r\n     * Registry invokes once per provider attempt. So a fallback provider\r\n     * always converts the caller's tool definitions itself rather than\r\n     * inheriting a dialect prepared for the provider that just failed.\r\n     *\r\n     * That ordering is the whole guarantee. Hoisting conversion above the\r\n     * attempt boundary is the defect that makes a fallback model reject\r\n     * the primary model's tool definitions, and `tool-schema-per-attempt`\r\n     * in the test suite fails if this line ever moves.\r\n     */\r\n    async *streamChat(options: StreamChatOptions): AsyncIterable<ChatStreamEvent> {\r\n      throwIfAborted(options.signal);\r\n      const { messages: chatMessages, instructions } = resolveMessagesFromCallOptions(options);\r\n      const streamStart = Date.now();\r\n      const streamCompleteCallback = readStreamCompleteCallback(options);\r\n      const tools = toOpenAITools(options.tools);\r\n\r\n      const stream = await executeChatStream(ctx.client, ctx, alias, pricing, {\r\n        modelId,\r\n        messages: chatMessages,\r\n        ...(instructions !== undefined ? { instructions } : {}),\r\n        ...(options.temperature !== undefined ? { temperature: options.temperature } : {}),\r\n        ...(options.maxOutputTokens !== undefined\r\n          ? { maxOutputTokens: options.maxOutputTokens }\r\n          : {}),\r\n        ...(options.signal ? { signal: options.signal } : {}),\r\n        ...(options.reasoningEffort ? { reasoningEffort: options.reasoningEffort } : {}),\r\n        // `toolChoice` maps onto OpenAI's own `tool_choice` vocabulary,\r\n        // whose three values happen to match ours exactly. It goes\r\n        // through providerExtras rather than a new typed field so\r\n        // compat providers that reject the parameter can be handled by\r\n        // the caller without a core change.\r\n        ...(options.toolChoice && tools.length > 0\r\n          ? {\r\n              providerExtras: {\r\n                ...(options.providerExtras ?? {}),\r\n                tool_choice: options.toolChoice,\r\n              },\r\n            }\r\n          : options.providerExtras\r\n            ? { providerExtras: options.providerExtras }\r\n            : {}),\r\n        ...(tools.length > 0 ? { tools } : {}),\r\n        stream: true,\r\n        streamUsage: ctx.streamUsage,\r\n      });\r\n\r\n      // Index-keyed accumulation. A tool call is not emittable until the\r\n      // provider stops appending to it, so calls are held here and\r\n      // flushed when a finish_reason arrives or the stream ends.\r\n      const pending = new Map<number, { id: string; name: string; args: string }>();\r\n      let finalUsageChunk: OpenAIStreamChunk | undefined;\r\n      let stopReason: string | undefined;\r\n\r\n      for await (const chunk of stream) {\r\n        // Alpha.25+: the final usage-only chunk (choices=[] + usage) that\r\n        // `stream_options: { include_usage: true }` produces.\r\n        if (chunk.usage && (!chunk.choices || chunk.choices.length === 0)) {\r\n          finalUsageChunk = chunk;\r\n          continue;\r\n        }\r\n\r\n        const choice = chunk.choices[0];\r\n        const delta = choice?.delta;\r\n\r\n        const text = delta?.content;\r\n        if (typeof text === \"string\" && text.length > 0) {\r\n          // Never emit an empty delta: a zero-length span is noise every\r\n          // consumer would otherwise have to filter.\r\n          yield { type: \"text-delta\", text };\r\n        }\r\n\r\n        if (delta?.tool_calls) {\r\n          for (const fragment of delta.tool_calls) {\r\n            const existing = pending.get(fragment.index);\r\n            if (existing) {\r\n              if (fragment.id) existing.id = fragment.id;\r\n              if (fragment.function?.name) existing.name = fragment.function.name;\r\n              if (fragment.function?.arguments) {\r\n                existing.args += fragment.function.arguments;\r\n              }\r\n            } else {\r\n              pending.set(fragment.index, {\r\n                id: fragment.id ?? `call_${fragment.index}`,\r\n                name: fragment.function?.name ?? \"\",\r\n                args: fragment.function?.arguments ?? \"\",\r\n              });\r\n            }\r\n          }\r\n        }\r\n\r\n        if (choice?.finish_reason) {\r\n          stopReason = choice.finish_reason;\r\n          yield* flushPendingToolCalls(pending);\r\n          yield { type: \"step-finish\", stopReason: choice.finish_reason };\r\n        }\r\n      }\r\n\r\n      // A provider that ended without a finish_reason still must not\r\n      // swallow assembled calls.\r\n      yield* flushPendingToolCalls(pending);\r\n      if (stopReason === undefined) {\r\n        yield { type: \"step-finish\", stopReason: \"stop\" };\r\n      }\r\n\r\n      if (finalUsageChunk?.usage) {\r\n        const usage = parseUsage({ usage: finalUsageChunk.usage });\r\n        const cost = computeChatCost(usage, pricing);\r\n        if (streamCompleteCallback) {\r\n          emitStreamComplete({\r\n            usage: finalUsageChunk.usage,\r\n            modelId,\r\n            providerAlias: alias,\r\n            pricing,\r\n            streamStart,\r\n            callback: streamCompleteCallback,\r\n          });\r\n        }\r\n        yield {\r\n          type: \"finish\",\r\n          usage,\r\n          cost,\r\n          modelId,\r\n          providerAlias: alias,\r\n        };\r\n      }\r\n    },\r\n\r\n    async *streamStructured<T>(options: StreamStructuredOptions<T>): AsyncIterable<Partial<T>> {\r\n      throwIfAborted(options.signal);\r\n      // alpha.21+: mirror generateStructured's strict-mode precedence chain\r\n      // so streamStructured callers can also opt into strict json_schema\r\n      // mode per call.\r\n      const effectiveStrict = options.strict ?? ctx.useStrictResponseFormat;\r\n      const strictResponseSchema = effectiveStrict\r\n        ? {\r\n            name: options.schemaName ?? \"structured_output\",\r\n            schema: buildStrictJsonSchema(options.schema),\r\n          }\r\n        : undefined;\r\n      const streamStart = Date.now();\r\n      const streamCompleteCallback = readStreamCompleteCallback(options);\r\n      // alpha.27+: canonical messages input.\r\n      const {\r\n        messages: chatMessages,\r\n        instructions: baseInstructions,\r\n      } = resolveMessagesFromCallOptions(options);\r\n      const stream = await executeChatStream(ctx.client, ctx, alias, pricing, {\r\n        modelId,\r\n        messages: chatMessages,\r\n        ...(baseInstructions !== undefined ? { instructions: baseInstructions } : {}),\r\n        temperature: options.temperature ?? 0,\r\n        ...(options.maxOutputTokens !== undefined ? { maxOutputTokens: options.maxOutputTokens } : {}),\r\n        ...(options.signal ? { signal: options.signal } : {}),\r\n        ...(options.reasoningEffort ? { reasoningEffort: options.reasoningEffort } : {}),\r\n        ...(options.providerExtras ? { providerExtras: options.providerExtras } : {}),\r\n        ...(strictResponseSchema ? { strictResponseSchema } : { jsonMode: true }),\r\n        stream: true,\r\n        streamUsage: ctx.streamUsage,\r\n      });\r\n      let buffer = \"\";\r\n      let finalUsageChunk: OpenAIStreamChunk | undefined;\r\n      for await (const chunk of stream) {\r\n        // Alpha.25+: intercept the final usage-only chunk (see streamText).\r\n        if (chunk.usage && (!chunk.choices || chunk.choices.length === 0)) {\r\n          finalUsageChunk = chunk;\r\n          continue;\r\n        }\r\n        const delta = chunk.choices[0]?.delta?.content;\r\n        if (typeof delta !== \"string\") continue;\r\n        buffer += delta;\r\n        const partial = tryParsePartialJSON(buffer) as Partial<T> | null;\r\n        if (partial !== null) yield partial;\r\n      }\r\n      if (streamCompleteCallback && finalUsageChunk?.usage) {\r\n        emitStreamComplete({\r\n          usage: finalUsageChunk.usage,\r\n          modelId,\r\n          providerAlias: alias,\r\n          pricing,\r\n          streamStart,\r\n          callback: streamCompleteCallback,\r\n        });\r\n      }\r\n    },\r\n\r\n    async runAgent(this: LLMPort, options: RunAgentOptions): Promise<AgentResult> {\r\n      throwIfAborted(options.signal);\r\n      validateMessages(options.messages);\r\n      // Defensive default: absent tools = no tools. The public options\r\n      // type declares tools as required, but consumers occasionally omit\r\n      // it (see toOpenAITools' equivalent guard). Alpha.28 pre-work\r\n      // TD-LLMP-17.\r\n      const toolsMap: Record<string, ToolDefinition> = options.tools ?? {};\r\n      const start = Date.now();\r\n      const maxSteps = options.maxSteps ?? 10;\r\n      const conversation = [...options.messages];\r\n      const toolCalls: AgentResult[\"toolCalls\"] = [];\r\n      let stepsTaken = 0;\r\n      let totalUsage: TokenUsage = { inputTokens: 0, outputTokens: 0, totalTokens: 0 };\r\n      let finalText = \"\";\r\n      let lastModelId = modelId;\r\n      let terminationReason: AgentResult[\"terminationReason\"] = \"max_steps\";\r\n\r\n      // Alpha.30+ §2.5: resurrect the outer OperationContext threaded down\r\n      // by the Registry (or a direct-caller `withObservabilityContext`) so\r\n      // per-step + per-tool events on this run correlate with the outer\r\n      // `operation_id`. No-op when observability is off — the four\r\n      // `emitAgent*` helpers safely skip when `outerOpCtx` is undefined.\r\n      const outerOpCtx = resurrectOperationContext(this);\r\n\r\n      try {\r\n        for (let step = 0; step < maxSteps; step++) {\r\n          // Re-check on each loop iteration so cancellation between steps\r\n          // also propagates; mid-step in-flight cancellation comes from the\r\n          // signal threaded into the SDK call.\r\n          throwIfAborted(options.signal);\r\n          stepsTaken = step + 1;\r\n          const turnMessages = toOpenAIMessages(conversation);\r\n          const tools = toOpenAITools(toolsMap);\r\n\r\n          const llmStepStart = Date.now();\r\n          emitAgentStepStarted(outerOpCtx, { stepIndex: stepsTaken, stepType: \"llm\" });\r\n\r\n          const { response } = await executeChatRequest(ctx.client, ctx, alias, pricing, {\r\n            modelId,\r\n            messages: turnMessages,\r\n            ...(options.instructions ? { instructions: options.instructions } : {}),\r\n            ...(options.temperature !== undefined ? { temperature: options.temperature } : {}),\r\n            ...(options.maxOutputTokens !== undefined ? { maxOutputTokens: options.maxOutputTokens } : {}),\r\n            ...(tools.length > 0 ? { tools } : {}),\r\n            ...(options.signal ? { signal: options.signal } : {}),\r\n            ...(options.reasoningEffort ? { reasoningEffort: options.reasoningEffort } : {}),\r\n        ...(options.providerExtras ? { providerExtras: options.providerExtras } : {}),\r\n            stream: false,\r\n          });\r\n          const r = response as {\r\n            model?: string;\r\n            choices: Array<{\r\n              message: {\r\n                content: string | null;\r\n                tool_calls?: Array<{ id: string; type: \"function\"; function: { name: string; arguments: string } }>;\r\n                reasoning_content?: string | null;\r\n              };\r\n            }>;\r\n            usage?: { prompt_tokens?: number; completion_tokens?: number; prompt_tokens_details?: { cached_tokens?: number } };\r\n          };\r\n          const stepUsage = parseUsage(r);\r\n          totalUsage = mergeTokenUsage(totalUsage, stepUsage);\r\n          lastModelId = r.model ?? modelId;\r\n\r\n          emitAgentStepCompleted(outerOpCtx, {\r\n            stepIndex: stepsTaken,\r\n            durationMs: Date.now() - llmStepStart,\r\n            usage: stepUsage,\r\n            cost: computeChatCost(stepUsage, pricing),\r\n          });\r\n\r\n          const aMsg = r.choices[0]?.message;\r\n          if (!aMsg) {\r\n            terminationReason = \"completed\";\r\n            break;\r\n          }\r\n          // Alpha.23+: harmony tool-call extraction. When the standard\r\n          // tool_calls array is empty AND a non-empty reasoning_content is\r\n          // present, try to parse harmony-encoded tool calls out of it. The\r\n          // parser returns null when no parseable harmony call is found;\r\n          // otherwise it returns synthesized tool_calls entries that the\r\n          // loop executes the same way as standard ones.\r\n          let effectiveToolCalls = aMsg.tool_calls ?? [];\r\n          if (effectiveToolCalls.length === 0 && aMsg.reasoning_content) {\r\n            const extracted = parseHarmonyToolCalls(aMsg.reasoning_content);\r\n            if (extracted && extracted.length > 0) {\r\n              effectiveToolCalls = extracted as typeof effectiveToolCalls;\r\n              emitRetry(ctx, {\r\n                reason: \"harmony-tool-call-extracted\",\r\n                attempt: 0,\r\n                modelId: lastModelId,\r\n                providerAlias: alias,\r\n                delayMs: 0,\r\n              });\r\n            }\r\n          }\r\n\r\n          // Append the assistant message to the conversation\r\n          conversation.push({\r\n            role: \"assistant\",\r\n            content: fromOpenAIAssistantMessage({\r\n              content: aMsg.content,\r\n              ...(effectiveToolCalls.length > 0 ? { tool_calls: effectiveToolCalls as never } : {}),\r\n              ...(aMsg.reasoning_content !== undefined ? { reasoning_content: aMsg.reasoning_content } : {}),\r\n            }),\r\n          });\r\n\r\n          finalText = aMsg.content ?? \"\";\r\n\r\n          const calls = effectiveToolCalls;\r\n          if (calls.length === 0) {\r\n            terminationReason = \"completed\";\r\n            break;\r\n          }\r\n\r\n          const toolResults: ContentBlock[] = [];\r\n          for (const tc of calls) {\r\n            const def = toolsMap[tc.function.name];\r\n            if (!def) {\r\n              toolResults.push({\r\n                type: \"tool_result\",\r\n                toolUseId: tc.id,\r\n                content: `Tool \"${tc.function.name}\" not found.`,\r\n                isError: true,\r\n              });\r\n              continue;\r\n            }\r\n            const toolStart = Date.now();\r\n            const rawArgs = tc.function.arguments ?? \"\";\r\n            emitAgentToolCalled(outerOpCtx, {\r\n              toolName: tc.function.name,\r\n              toolCallId: tc.id,\r\n              argumentsDigest: sha256Hex(rawArgs),\r\n            });\r\n            try {\r\n              const args = tc.function.arguments\r\n                ? JSON.parse(tc.function.arguments)\r\n                : {};\r\n              const output = await def.execute(args as never);\r\n              toolCalls.push({\r\n                name: tc.function.name,\r\n                input: args as Record<string, unknown>,\r\n                output,\r\n              });\r\n              const text = typeof output === \"string\" ? output : JSON.stringify(output);\r\n              const truncated =\r\n                def.maxOutputBytes !== undefined && text.length > def.maxOutputBytes\r\n                  ? `${text.slice(0, def.maxOutputBytes)}\\n[truncated]`\r\n                  : text;\r\n              emitAgentToolReturned(outerOpCtx, {\r\n                toolName: tc.function.name,\r\n                toolCallId: tc.id,\r\n                resultDigest: sha256Hex(truncated),\r\n                durationMs: Date.now() - toolStart,\r\n              });\r\n              toolResults.push({\r\n                type: \"tool_result\",\r\n                toolUseId: tc.id,\r\n                content: truncated,\r\n              });\r\n            } catch (toolErr) {\r\n              const errText = toolErr instanceof Error ? toolErr.message : String(toolErr);\r\n              emitAgentToolReturned(outerOpCtx, {\r\n                toolName: tc.function.name,\r\n                toolCallId: tc.id,\r\n                resultDigest: sha256Hex(errText),\r\n                durationMs: Date.now() - toolStart,\r\n                error: {\r\n                  error_type: toolErr instanceof Error ? toolErr.name : \"UnknownError\",\r\n                  message: errText,\r\n                  cause_category: \"port_internal\",\r\n                  retryable: false,\r\n                  fallback_worthy: false,\r\n                },\r\n              });\r\n              toolResults.push({\r\n                type: \"tool_result\",\r\n                toolUseId: tc.id,\r\n                content: errText,\r\n                isError: true,\r\n              });\r\n            }\r\n          }\r\n          // Tool results go in via the standard tool role conversion\r\n          conversation.push({ role: \"user\", content: toolResults });\r\n        }\r\n      } catch (err) {\r\n        throw wrapProviderError(alias, err, lastModelId);\r\n      }\r\n\r\n      return {\r\n        text: finalText,\r\n        messages: conversation,\r\n        toolCalls,\r\n        usage: totalUsage,\r\n        cost: computeChatCost(totalUsage, pricing),\r\n        modelId: lastModelId,\r\n        providerAlias: alias,\r\n        latencyMs: Date.now() - start,\r\n        stepsTaken,\r\n        terminationReason,\r\n      };\r\n    },\r\n\r\n    async listModels(): Promise<ProviderModelInfo[]> {\r\n      try {\r\n        const out: ProviderModelInfo[] = [];\r\n        const page = await ctx.client.models.list();\r\n        // The OpenAI SDK returns a paginator; iterate to flatten.\r\n        for await (const m of page) {\r\n          const model = m as { id: string; owned_by?: string; created?: number };\r\n          out.push({\r\n            id: model.id,\r\n            ...(model.owned_by ? { metadata: { owned_by: model.owned_by, created: model.created } } : {}),\r\n          });\r\n        }\r\n        return out;\r\n      } catch (err) {\r\n        throw wrapProviderError(alias, err);\r\n      }\r\n    },\r\n  };\r\n}\r\n\r\n// ─── EmbeddingsPort implementation ───────────────────────────────────\r\n\r\nfunction createEmbeddings(\r\n  ctx: AdapterContext,\r\n  modelId: string,\r\n  alias: string,\r\n): EmbeddingsPort {\r\n  const pricing = pricingFor(ctx, modelId);\r\n\r\n  return {\r\n    async generateEmbedding(options: EmbeddingOptions): Promise<EmbeddingResult> {\r\n      const start = Date.now();\r\n      try {\r\n        const response = await withTransientAuthRetry(\r\n          ctx,\r\n          alias,\r\n          () =>\r\n            ctx.client.embeddings.create({\r\n              model: modelId,\r\n              input: options.input,\r\n            }),\r\n          modelId,\r\n        );\r\n        const inputTokens = response.usage?.prompt_tokens ?? 0;\r\n        const vector = response.data[0]?.embedding ?? [];\r\n        return {\r\n          vector,\r\n          dimensions: vector.length,\r\n          modelId: response.model ?? modelId,\r\n          providerAlias: alias,\r\n          usage: { inputTokens },\r\n          cost: computeEmbeddingCost(inputTokens, pricing),\r\n          latencyMs: Date.now() - start,\r\n        };\r\n      } catch (err) {\r\n        throw wrapProviderError(alias, err, modelId);\r\n      }\r\n    },\r\n\r\n    async generateEmbeddings(options: BatchEmbeddingOptions): Promise<BatchEmbeddingResult> {\r\n      const start = Date.now();\r\n      try {\r\n        const response = await withTransientAuthRetry(\r\n          ctx,\r\n          alias,\r\n          () =>\r\n            ctx.client.embeddings.create({\r\n              model: modelId,\r\n              input: options.inputs,\r\n            }),\r\n          modelId,\r\n        );\r\n        const inputTokens = response.usage?.prompt_tokens ?? 0;\r\n        const vectors = response.data.map((d) => d.embedding);\r\n        return {\r\n          vectors,\r\n          dimensions: vectors[0]?.length ?? 0,\r\n          modelId: response.model ?? modelId,\r\n          providerAlias: alias,\r\n          usage: { inputTokens },\r\n          cost: computeEmbeddingCost(inputTokens, pricing),\r\n          latencyMs: Date.now() - start,\r\n        };\r\n      } catch (err) {\r\n        throw wrapProviderError(alias, err, modelId);\r\n      }\r\n    },\r\n  };\r\n}\r\n\r\n// ─── Capability-aware request building ───────────────────────────────\r\n\r\n/**\r\n * Logical chat-completion request. Adapter methods build one of these and\r\n * hand it to {@link executeChatRequest}, which materializes it for the SDK\r\n * — applying any model capability constraints learned (or supplied via\r\n * pricingOverrides), retrying once on capability rejection.\r\n */\r\ninterface LogicalChatRequest {\r\n  modelId: string;\r\n  messages: OpenAIMessage[];\r\n  /** Optional system instructions. Folded into user message if model rejects system. */\r\n  instructions?: string;\r\n  /** User-supplied temperature. Skipped when model has temperatureLocked capability. */\r\n  temperature?: number;\r\n  /** User-supplied output cap. Always honored when set. */\r\n  maxOutputTokens?: number;\r\n  /** Set true to request native JSON mode. Falls back to plain text on rejection. */\r\n  jsonMode?: boolean;\r\n  /**\r\n   * When set, generateStructured uses `response_format: { type: \"json_schema\",\r\n   * strict: true }` with this JSON Schema instead of classic\r\n   * `response_format: { type: \"json_object\" }`. The schema must already have\r\n   * `additionalProperties: false` on every nested object and `required: [...]`\r\n   * on every property — those are caller-enforced via `buildStrictJsonSchema`.\r\n   */\r\n  strictResponseSchema?: { name: string; schema: Record<string, unknown> };\r\n  /** Stream the response or not. */\r\n  stream: boolean;\r\n  /**\r\n   * When streaming, add `stream_options: { include_usage: true }` to the\r\n   * request so the provider sends a final chunk with a usage summary.\r\n   * Enables the alpha.25+ streamed cost surfacing path. Set to `false` on\r\n   * compat providers that reject the field (rare). Ignored when\r\n   * `stream: false`. (alpha.25+)\r\n   */\r\n  streamUsage?: boolean;\r\n  /** Tools when this is an agent step. */\r\n  tools?: ReturnType<typeof toOpenAITools>;\r\n  /** Mid-flight cancellation: threaded as the 2nd arg to client.chat.completions.create. */\r\n  signal?: AbortSignal;\r\n  /**\r\n   * Reasoning effort. Forwarded as `reasoning_effort` on the SDK call when\r\n   * the model is a known reasoning model (o-series, gpt-5-nano, etc.) OR\r\n   * the user explicitly opts in via this field. Non-reasoning models on\r\n   * OpenAI native ignore the parameter; some compat providers (notably\r\n   * Groq's `openai/gpt-oss-120b`) honor it.\r\n   */\r\n  reasoningEffort?: \"low\" | \"medium\" | \"high\";\r\n  /**\r\n   * Per-call escape hatch for provider-specific request fields. Shallow-\r\n   * merged into the SDK request body AFTER all typed port fields are set —\r\n   * so a caller passing `providerExtras: { reasoning_effort: \"high\" }` would\r\n   * override the alpha.12 typed field. Use this for knobs the port doesn't\r\n   * model: vLLM `chat_template_kwargs`, SGLang `regex`, vLLM `guided_json`\r\n   * (when not using strict mode), Together `repetition_penalty`, etc.\r\n   * (alpha.16+)\r\n   */\r\n  providerExtras?: Record<string, unknown>;\r\n}\r\n\r\n/** Build the SDK's request object from a logical request and the model's effective capabilities. */\r\nfunction materializeRequest(\r\n  req: LogicalChatRequest,\r\n  caps: ModelCapsCompact,\r\n): Record<string, unknown> {\r\n  // Compose messages, optionally folding instructions into the user message\r\n  // if the model rejects standalone system messages.\r\n  const messages: OpenAIMessage[] = [];\r\n  if (req.instructions !== undefined) {\r\n    if (caps.systemMessageInUserOnly) {\r\n      // Prepend instructions to the first user-role message; if there is\r\n      // none, synthesize one.\r\n      const cloned = [...req.messages];\r\n      const firstUserIdx = cloned.findIndex((m) => m.role === \"user\");\r\n      const annotation = `<instructions>\\n${req.instructions}\\n</instructions>\\n\\n`;\r\n      if (firstUserIdx >= 0) {\r\n        const u = cloned[firstUserIdx]!;\r\n        if (typeof (u as { content: unknown }).content === \"string\") {\r\n          cloned[firstUserIdx] = { role: \"user\", content: annotation + ((u as { content: string }).content) };\r\n        } else {\r\n          cloned[firstUserIdx] = {\r\n            role: \"user\",\r\n            content: [\r\n              { type: \"text\", text: annotation } as never,\r\n              ...((u as { content: unknown[] }).content as never[]),\r\n            ] as never,\r\n          };\r\n        }\r\n      } else {\r\n        cloned.unshift({ role: \"user\", content: annotation });\r\n      }\r\n      messages.push(...cloned);\r\n    } else {\r\n      messages.push({ role: \"system\", content: req.instructions });\r\n      messages.push(...req.messages);\r\n    }\r\n  } else {\r\n    messages.push(...req.messages);\r\n  }\r\n\r\n  const out: Record<string, unknown> = {\r\n    model: req.modelId,\r\n    messages,\r\n    stream: req.stream,\r\n  };\r\n  // Streamed cost surfacing (alpha.25+). When the caller requested streaming\r\n  // AND opted into usage inclusion, ask the provider to emit a final chunk\r\n  // with prompt/completion token counts. OpenAI natively supports this;\r\n  // compat providers that don't implement it either ignore the field or\r\n  // reject at stream-creation time (in which case `streamUsage: false` is\r\n  // the escape hatch for callers to opt out).\r\n  if (req.stream && req.streamUsage) {\r\n    out[\"stream_options\"] = { include_usage: true };\r\n  }\r\n  // Temperature: only set if user requested AND model accepts it\r\n  if (req.temperature !== undefined && !caps.temperatureLocked) {\r\n    out[\"temperature\"] = req.temperature;\r\n  }\r\n  if (req.maxOutputTokens !== undefined) {\r\n    // For reasoning models, OpenAI's max_completion_tokens caps reasoning\r\n    // tokens + visible output. Apply the headroom multiplier so the model\r\n    // has room to think AND emit visible output. Discovered at runtime\r\n    // (see executeChatRequest learning from usage.reasoningTokens) or\r\n    // supplied via pricingOverrides.capabilities.reasoningModel.\r\n    out[\"max_completion_tokens\"] = caps.reasoningModel\r\n      ? req.maxOutputTokens * caps.reasoningHeadroomMultiplier\r\n      : req.maxOutputTokens;\r\n  }\r\n  if (req.strictResponseSchema && !caps.jsonModeUnsupported) {\r\n    // OpenAI / Cerebras strict JSON Schema mode: provider constrains\r\n    // decoding to the schema before tokens are produced. Overrides plain\r\n    // json_object when present.\r\n    out[\"response_format\"] = {\r\n      type: \"json_schema\",\r\n      json_schema: {\r\n        name: req.strictResponseSchema.name,\r\n        schema: req.strictResponseSchema.schema,\r\n        strict: true,\r\n      },\r\n    };\r\n  } else if (req.jsonMode && !caps.jsonModeUnsupported) {\r\n    out[\"response_format\"] = { type: \"json_object\" };\r\n  }\r\n  if (req.reasoningEffort !== undefined) {\r\n    // OpenAI o-series + gpt-5-nano + Groq `openai/gpt-oss-120b` accept\r\n    // `reasoning_effort: \"low\" | \"medium\" | \"high\"`. Compat providers\r\n    // that don't honor it generally just ignore the field. We pass it\r\n    // through verbatim; no per-model gating in v0.1.\r\n    out[\"reasoning_effort\"] = req.reasoningEffort;\r\n  }\r\n  if (req.tools && req.tools.length > 0) {\r\n    out[\"tools\"] = req.tools;\r\n  }\r\n  // providerExtras: shallow merge LAST so callers can override our typed\r\n  // defaults if they need to (e.g. `providerExtras: { reasoning_effort:\r\n  // \"high\" }` overrides the alpha.12 typed field). Generic escape hatch for\r\n  // vLLM chat_template_kwargs, SGLang regex, vLLM guided_json, Together\r\n  // repetition_penalty, etc. Field semantics are provider-specific; we\r\n  // don't validate. (alpha.16+)\r\n  if (req.providerExtras) {\r\n    Object.assign(out, req.providerExtras);\r\n  }\r\n  return out;\r\n}\r\n\r\ninterface ModelCapsCompact {\r\n  temperatureLocked?: boolean;\r\n  jsonModeUnsupported?: boolean;\r\n  systemMessageInUserOnly?: boolean;\r\n  reasoningModel?: boolean;\r\n  reasoningHeadroomMultiplier: number;\r\n}\r\n\r\nfunction readCaps(modelId: string, pricing: ModelPricing): ModelCapsCompact {\r\n  const eff = getEffectiveCapabilities(modelId, pricing.capabilities);\r\n  return {\r\n    temperatureLocked: eff.temperatureLocked === true,\r\n    // jsonMode default is true; only treat as unsupported if explicitly false\r\n    jsonModeUnsupported: eff.jsonMode === false,\r\n    systemMessageInUserOnly: eff.systemMessageInUserOnly === true,\r\n    reasoningModel: eff.reasoningModel === true,\r\n    reasoningHeadroomMultiplier: eff.reasoningHeadroomMultiplier ?? 10,\r\n  };\r\n}\r\n\r\n/**\r\n * Inspect an SDK error and, if it matches a known capability constraint,\r\n * record the constraint against this model. Returns true if at least one\r\n * constraint was learned from this error (so the caller knows a retry might\r\n * succeed).\r\n */\r\nfunction learnConstraintsFromError(err: unknown, req: LogicalChatRequest): boolean {\r\n  let learned = false;\r\n  if (isTemperatureRejection(err) && req.temperature !== undefined) {\r\n    rememberConstraint(req.modelId, { temperatureLocked: true });\r\n    learned = true;\r\n  }\r\n  // `response_format` rejection covers BOTH paths:\r\n  //   - legacy `{ type: \"json_object\" }` (req.jsonMode)\r\n  //   - alpha.9+ strict `{ type: \"json_schema\", strict: true }` (req.strictResponseSchema)\r\n  // Either way, the model has told us it doesn't accept any `response_format`\r\n  // shape we know how to send — so flip `jsonModeUnsupported` and the next\r\n  // call will omit the field entirely.\r\n  if (isJsonModeRejection(err) && (req.jsonMode || req.strictResponseSchema)) {\r\n    rememberConstraint(req.modelId, { jsonMode: false });\r\n    learned = true;\r\n  }\r\n  if (isSystemMessageRejection(err) && req.instructions !== undefined) {\r\n    rememberConstraint(req.modelId, { systemMessageInUserOnly: true });\r\n    learned = true;\r\n  }\r\n  return learned;\r\n}\r\n\r\n/**\r\n * Inspect a successful response and remember any newly-observed model behavior.\r\n * Marks the model as reasoning if any of these signals is present:\r\n *   - `usage.completion_tokens_details.reasoning_tokens > 0` (OpenAI o-series, gpt-5-nano)\r\n *   - `choices[0].message.reasoning` populated (Cerebras gpt-oss-*, vLLM, some\r\n *     OpenAI-compat providers that expose CoT as a separate field)\r\n *   - `choices[0].message.reasoning_content` populated (DeepInfra's gpt-oss\r\n *     harmony serving — the tool-call / reasoning intent lands here when the\r\n *     provider hasn't translated harmony channels into standard `tool_calls`).\r\n *     Added alpha.22 after ADW empirical findings.\r\n * Future calls to this model will get an expanded max_completion_tokens budget\r\n * via the headroom multiplier so visible output has room after reasoning.\r\n */\r\nfunction learnFromResponse(modelId: string, response: unknown): void {\r\n  if (!response || typeof response !== \"object\") return;\r\n  const r = response as {\r\n    choices?: Array<{ message?: { reasoning?: string | null; reasoning_content?: string | null } }>;\r\n    usage?: { completion_tokens_details?: { reasoning_tokens?: number } };\r\n  };\r\n  const reasoningTokens = r.usage?.completion_tokens_details?.reasoning_tokens;\r\n  const reasoningField = r.choices?.[0]?.message?.reasoning;\r\n  const reasoningContent = r.choices?.[0]?.message?.reasoning_content;\r\n  const isReasoning =\r\n    (reasoningTokens !== undefined && reasoningTokens > 0) ||\r\n    (typeof reasoningField === \"string\" && reasoningField.length > 0) ||\r\n    (typeof reasoningContent === \"string\" && reasoningContent.length > 0);\r\n  if (isReasoning) {\r\n    rememberConstraint(modelId, { reasoningModel: true });\r\n  }\r\n}\r\n\r\n/**\r\n * Detect the \"all budget consumed by reasoning\" pattern: empty visible text +\r\n * no tool_calls + any signal that the model is reasoning. This tells the\r\n * caller to retry with the now-learned reasoning multiplier so the model has\r\n * budget for visible output.\r\n *\r\n * Different providers expose reasoning differently:\r\n *   - OpenAI o-series + gpt-5-nano: message.content empty, usage has reasoning_tokens, finish=length\r\n *   - Cerebras gpt-oss-*: message.content missing entirely, message.reasoning has CoT, finish=length\r\n *   - DeepInfra gpt-oss (alpha.22 ADW finding): message.content empty,\r\n *     message.reasoning_content has harmony channel output (the tool-call\r\n *     intent lands here), finish=stop (not length)\r\n * All produce the same end-user symptom (empty visible text, no executable\r\n * tool_calls), so we recover the same way: expand the total budget and retry.\r\n *\r\n * The alpha.22 broadening relaxes finish_reason from `length` only to either\r\n * `length` or `stop` whenever the empty-visible-output + reasoning-signal\r\n * pattern holds. The narrow `length`-only check missed the DeepInfra gpt-oss\r\n * harmony case where the provider returns `stop` despite the reasoning channel\r\n * holding the intended output. See llm-ports#46 / discussion #49 for the\r\n * empirical evidence motivating the broadening.\r\n *\r\n * Note: this detection rescues the same call once with an expanded budget;\r\n * it does NOT yet parse the reasoning_content channel for tool-call intent.\r\n * Full harmony-channel parsing (so DeepInfra-served gpt-oss tool calls become\r\n * executable) is a separate workstream tracked in a follow-up issue — that\r\n * requires design work across provider serving formats. This change makes\r\n * the failure observable and budget-correct; it does not auto-recover the\r\n * harmony tool-call case.\r\n */\r\nfunction reasoningStarvedResponse(response: unknown, req: LogicalChatRequest): boolean {\r\n  if (!response || typeof response !== \"object\") return false;\r\n  if (req.maxOutputTokens === undefined) return false;\r\n  const r = response as {\r\n    choices?: Array<{\r\n      message?: {\r\n        content?: string | null;\r\n        reasoning?: string | null;\r\n        reasoning_content?: string | null;\r\n        tool_calls?: Array<unknown> | null;\r\n      };\r\n      finish_reason?: string;\r\n    }>;\r\n    usage?: { completion_tokens_details?: { reasoning_tokens?: number } };\r\n  };\r\n  const choice = r.choices?.[0];\r\n  const text = choice?.message?.content ?? \"\";\r\n  const finishReason = choice?.finish_reason;\r\n  const toolCalls = choice?.message?.tool_calls;\r\n  const reasoningTokens = r.usage?.completion_tokens_details?.reasoning_tokens ?? 0;\r\n  const reasoningField = choice?.message?.reasoning;\r\n  const reasoningContent = choice?.message?.reasoning_content;\r\n  const hasReasoningSignal =\r\n    reasoningTokens > 0 ||\r\n    (typeof reasoningField === \"string\" && reasoningField.length > 0) ||\r\n    (typeof reasoningContent === \"string\" && reasoningContent.length > 0);\r\n  // Empty visible output = no content text AND no executable tool_calls. A\r\n  // response with valid tool_calls is not starved — the model successfully\r\n  // produced output, even if content is empty.\r\n  const noVisibleOutput =\r\n    text === \"\" && (!Array.isArray(toolCalls) || toolCalls.length === 0);\r\n  // alpha.22+: accept both finish_reason values. Pre-alpha.22 required\r\n  // `length` only (OpenAI native + Cerebras pattern); DeepInfra's gpt-oss\r\n  // harmony serving returns `stop`. The reasoning-signal + no-visible-output\r\n  // conjunction is sufficient to discriminate from genuine completion.\r\n  const finishStarvable = finishReason === \"length\" || finishReason === \"stop\";\r\n  return noVisibleOutput && finishStarvable && hasReasoningSignal;\r\n}\r\n\r\n/**\r\n * Detect the \"model emitted prose, didn't call any tool\" pattern. (alpha.23+)\r\n *\r\n * Empirical motivation: ADW 2026-06-19 — mimo-parasail in the multi-team\r\n * agentic build loop returned `finish_reason: \"stop\"` with ~69 tokens of\r\n * prose, zero `tool_calls`, no `reasoning_content`. The agentic loop saw\r\n * no executable output and terminated as \"completed\" — false success.\r\n *\r\n * Predicate: there were tools available in the request AND the response\r\n * was a clean completion (length or stop) with no tool_calls AND there\r\n * was visible prose content. The model SHOULD have called a tool but\r\n * answered with text instead.\r\n *\r\n * Discriminators that prevent false positives:\r\n *   - tool_calls populated → model actually called something; not this case\r\n *   - no tools in request → text response is legitimate\r\n *   - finish_reason is `tool_calls` → standard tool-use success path\r\n *   - empty content → likely reasoning starvation, not prose response\r\n *     (handled by reasoningStarvedResponse instead)\r\n *   - reasoning_content populated AND tool_calls empty → harmony case,\r\n *     handled by ASK 1 extraction before this predicate is checked\r\n *\r\n * When true, the caller mirrors the reasoning-starvation rescue: retry once\r\n * with a corrective system message asking the model to use the standard\r\n * `tool_calls` format rather than describing its intent in prose.\r\n */\r\nfunction zeroToolCallProseResponse(response: unknown, req: LogicalChatRequest): boolean {\r\n  if (!response || typeof response !== \"object\") return false;\r\n  // The request must have included a tools array. Without tools, a prose\r\n  // response is the only correct response shape.\r\n  if (!Array.isArray(req.tools) || req.tools.length === 0) return false;\r\n  // Don't rescue when the conversation already includes tool results. The\r\n  // model may legitimately be summarizing tool execution output rather than\r\n  // failing to call a tool. This discriminator scopes the rescue to the\r\n  // \"model failed to use tools on its first agentic turn\" case rather than\r\n  // firing on every subsequent loop iteration where the model is wrapping up.\r\n  // In a runAgent loop, tool results come back as role: \"tool\" messages.\r\n  const hasToolResults = req.messages.some((m) => m.role === \"tool\");\r\n  if (hasToolResults) return false;\r\n  const r = response as {\r\n    choices?: Array<{\r\n      message?: {\r\n        content?: string | null;\r\n        tool_calls?: Array<unknown> | null;\r\n        reasoning_content?: string | null;\r\n      };\r\n      finish_reason?: string;\r\n    }>;\r\n  };\r\n  const choice = r.choices?.[0];\r\n  const text = choice?.message?.content ?? \"\";\r\n  const finishReason = choice?.finish_reason;\r\n  const toolCalls = choice?.message?.tool_calls;\r\n  // ASK 1 extracts harmony calls before this predicate runs in runAgent, but\r\n  // executeChatRequest doesn't have that context — be defensive and skip when\r\n  // reasoning_content looks harmony-shaped to avoid double-firing. The starvation\r\n  // rescue (reasoningStarvedResponse) handles non-harmony reasoning emissions.\r\n  const reasoningContent = choice?.message?.reasoning_content;\r\n  if (typeof reasoningContent === \"string\" && reasoningContent.length > 0) {\r\n    return false;\r\n  }\r\n  // Tool calls populated → success path, not prose\r\n  if (Array.isArray(toolCalls) && toolCalls.length > 0) return false;\r\n  // No visible prose → covered by reasoning starvation, not this\r\n  if (text.length === 0) return false;\r\n  // Must be a clean completion (length or stop), not an error\r\n  const finishStop = finishReason === \"stop\" || finishReason === \"length\";\r\n  if (!finishStop) return false;\r\n  // Don't rescue on finish_reason=tool_calls — that's the standard success path\r\n  // (the OpenAI spec uses `tool_calls` as a finish_reason variant; if it's\r\n  // present, the model intended tool use). Already excluded by the tool_calls\r\n  // population check above, but explicit guard for clarity.\r\n  return true;\r\n}\r\n\r\n/**\r\n * True if this error is OpenAI's project-key burst-protection 401 (transient,\r\n * key is valid) rather than a real auth failure. Distinguishable only when a\r\n * prior request on the same client already succeeded — otherwise indistinguishable\r\n * from a bad key, in which case we fall through to the normal error path.\r\n *\r\n * OpenAI sk-proj-* keys briefly return 401 \"Incorrect API key\" when too many\r\n * requests arrive in a short window, even though the key works. The OpenAI SDK\r\n * does not retry 401 internally because for most users a 401 is a permanent\r\n * config issue. The adapter handles this provider-specific quirk so callers\r\n * don't need to know about it.\r\n */\r\nfunction isTransientAuthError(err: unknown, ctx: AdapterContext): boolean {\r\n  if (!ctx.hasSucceeded.value) return false;\r\n  if (!err || typeof err !== \"object\") return false;\r\n  const e = err as {\r\n    status?: number;\r\n    message?: unknown;\r\n    code?: unknown;\r\n    error?: { code?: unknown; message?: unknown };\r\n  };\r\n  if (e.status !== 401) return false;\r\n  const code = e.code ?? e.error?.code;\r\n  const message = String(e.message ?? e.error?.message ?? \"\");\r\n  if (code === \"invalid_api_key\") return true;\r\n  if (/incorrect api key/i.test(message)) return true;\r\n  return false;\r\n}\r\n\r\n/** Wait helper for transient retry backoff. */\r\nfunction sleep(ms: number): Promise<void> {\r\n  return new Promise((resolve) => setTimeout(resolve, ms));\r\n}\r\n\r\n/**\r\n * Generic transient-401 retry wrapper for non-chat operations (embeddings, etc.).\r\n * Same logic as the transient branch of executeChatRequest but as a standalone\r\n * helper. Used by EmbeddingsPort methods. Marks ctx.hasSucceeded on success so\r\n * subsequent calls' transient detection works.\r\n */\r\nasync function withTransientAuthRetry<T>(\r\n  ctx: AdapterContext,\r\n  alias: string,\r\n  fn: () => Promise<T>,\r\n  modelId: string,\r\n): Promise<T> {\r\n  let attempt = 0;\r\n  // eslint-disable-next-line no-constant-condition -- intentional retry loop; exits via return/throw/break\r\n  while (true) {\r\n    try {\r\n      const result = await fn();\r\n      ctx.hasSucceeded.value = true;\r\n      return result;\r\n    } catch (err) {\r\n      if (\r\n        isTransientAuthError(err, ctx) &&\r\n        attempt < ctx.transientAuthRetries\r\n      ) {\r\n        const delayMs = ctx.transientAuthBackoffMs(attempt);\r\n        emitRetry(ctx, {\r\n          reason: \"transient-auth\",\r\n          attempt,\r\n          modelId,\r\n          providerAlias: alias,\r\n          delayMs,\r\n          cause: err,\r\n        });\r\n        await sleep(delayMs);\r\n        attempt++;\r\n        continue;\r\n      }\r\n      throw err;\r\n    }\r\n  }\r\n}\r\n\r\n/**\r\n * Execute a non-streaming chat completion with capability awareness AND\r\n * transient-401 resilience. Single retry loop with three decision branches:\r\n *\r\n *   1. Success  → mark client as proven-good; learn from usage; return.\r\n *      (If the response is reasoning-starved, do one expanded-budget retry.)\r\n *   2. Transient 401 (project-key burst protection)  → backoff + retry,\r\n *      up to ctx.transientAuthRetries.\r\n *   3. Capability rejection (temperature, json_object, system message)  →\r\n *      learn the constraint, retry once with offending param dropped.\r\n *\r\n * Anything else propagates as ProviderUnavailableError via {@link wrapProviderError}.\r\n */\r\nasync function executeChatRequest(\r\n  client: OpenAI,\r\n  ctx: AdapterContext,\r\n  alias: string,\r\n  pricing: ModelPricing,\r\n  req: LogicalChatRequest,\r\n): Promise<{ response: unknown; modelId: string }> {\r\n  const attempt = async (): Promise<unknown> => {\r\n    const caps = readCaps(req.modelId, pricing);\r\n    const sdkReq = materializeRequest(req, caps);\r\n    // Thread the AbortSignal as the SDK's 2nd-arg request options; the OpenAI\r\n    // SDK uses this to cancel the in-flight fetch on abort.\r\n    const reqOpts = req.signal ? { signal: req.signal } : undefined;\r\n    return await client.chat.completions.create(sdkReq as never, reqOpts);\r\n  };\r\n\r\n  let triedCapabilityFallback = false;\r\n  let transientRetries = 0;\r\n\r\n  // eslint-disable-next-line no-constant-condition -- intentional retry loop; exits via return/throw/break\r\n  while (true) {\r\n    try {\r\n      const response = await attempt();\r\n      ctx.hasSucceeded.value = true;\r\n      learnFromResponse(req.modelId, response);\r\n      // Behavioral fingerprint write (alpha.24+): inspect every successful\r\n      // response and persist a fingerprint when one is derivable. Free\r\n      // observability — no extra probe call required.\r\n      if (ctx.fingerprintCache) {\r\n        writeFingerprint(ctx.fingerprintCache, ctx.baseURL, req.modelId, response);\r\n      }\r\n\r\n      // If the response shows the model spent all its budget on reasoning and\r\n      // produced no visible text, retry once with the now-learned reasoning\r\n      // multiplier applied to max_completion_tokens. This is the recovery path\r\n      // for first-call interactions with unknown reasoning models.\r\n      if (reasoningStarvedResponse(response, req)) {\r\n        emitRetry(ctx, {\r\n          reason: \"reasoning-starvation\",\r\n          attempt: 0,\r\n          modelId: req.modelId,\r\n          providerAlias: alias,\r\n          delayMs: 0,\r\n        });\r\n        try {\r\n          const retried = await attempt();\r\n          ctx.hasSucceeded.value = true;\r\n          learnFromResponse(req.modelId, retried);\r\n          return { response: retried, modelId: req.modelId };\r\n        } catch (retryErr) {\r\n          throw wrapProviderError(alias, retryErr, req.modelId);\r\n        }\r\n      }\r\n\r\n      // ASK 2 (alpha.23+): the model emitted prose without calling any tool\r\n      // despite the request providing a tools array. Retry once with a\r\n      // corrective system message asking it to use the standard tool_calls\r\n      // format. Single-shot; if the retry also responds with prose-only,\r\n      // return that response and let the consumer's orchestration handle it.\r\n      if (zeroToolCallProseResponse(response, req)) {\r\n        emitRetry(ctx, {\r\n          reason: \"zero-tool-call-prose-retry\",\r\n          attempt: 0,\r\n          modelId: req.modelId,\r\n          providerAlias: alias,\r\n          delayMs: 0,\r\n        });\r\n        try {\r\n          // Build a corrective system message and prepend it to the messages\r\n          // array for the retry. Modifying req.messages in place would leak\r\n          // into the calling code's view of the request; shallow-clone instead.\r\n          const correctiveMessage = {\r\n            role: \"system\" as const,\r\n            content:\r\n              \"Your previous response did not include a tool call. Tools are \" +\r\n              \"available — call them via the standard tool_calls array to \" +\r\n              \"perform the work. Do not describe what you would do; do it.\",\r\n          };\r\n          const retryReq: LogicalChatRequest = {\r\n            ...req,\r\n            messages: [...req.messages, correctiveMessage],\r\n          };\r\n          const retryAttempt = async (): Promise<unknown> => {\r\n            const caps = readCaps(retryReq.modelId, pricing);\r\n            const sdkReq = materializeRequest(retryReq, caps);\r\n            const reqOpts = retryReq.signal ? { signal: retryReq.signal } : undefined;\r\n            return await client.chat.completions.create(sdkReq as never, reqOpts);\r\n          };\r\n          const retried = await retryAttempt();\r\n          ctx.hasSucceeded.value = true;\r\n          learnFromResponse(req.modelId, retried);\r\n          return { response: retried, modelId: req.modelId };\r\n        } catch (retryErr) {\r\n          throw wrapProviderError(alias, retryErr, req.modelId);\r\n        }\r\n      }\r\n\r\n      return { response, modelId: req.modelId };\r\n    } catch (err) {\r\n      if (\r\n        isTransientAuthError(err, ctx) &&\r\n        transientRetries < ctx.transientAuthRetries\r\n      ) {\r\n        // Exponential backoff: 500ms, 1500ms, 4500ms... up to maxRetries\r\n        const delayMs = ctx.transientAuthBackoffMs(transientRetries);\r\n        emitRetry(ctx, {\r\n          reason: \"transient-auth\",\r\n          attempt: transientRetries,\r\n          modelId: req.modelId,\r\n          providerAlias: alias,\r\n          delayMs,\r\n          cause: err,\r\n        });\r\n        await sleep(delayMs);\r\n        transientRetries++;\r\n        continue;\r\n      }\r\n      if (!triedCapabilityFallback && learnConstraintsFromError(err, req)) {\r\n        emitRetry(ctx, {\r\n          reason: \"capability-fallback\",\r\n          attempt: 0,\r\n          modelId: req.modelId,\r\n          providerAlias: alias,\r\n          delayMs: 0,\r\n          cause: err,\r\n        });\r\n        triedCapabilityFallback = true;\r\n        continue;\r\n      }\r\n      throw wrapProviderError(alias, err, req.modelId);\r\n    }\r\n  }\r\n}\r\n\r\n/**\r\n * Chunk shape from a streaming chat completion. `choices` is empty on the\r\n * final `include_usage: true` chunk; `usage` is populated only on the final\r\n * chunk when streamUsage was requested.\r\n */\r\ninterface OpenAIStreamChunk {\r\n  choices: Array<{\r\n    delta?: {\r\n      content?: string;\r\n      /**\r\n       * Alpha.32+: streamed tool calls, consumed by `streamChat`.\r\n       *\r\n       * OpenAI emits these as fragments keyed by `index`. The first\r\n       * fragment for an index carries `id` and `function.name`; later\r\n       * fragments append a few characters at a time to\r\n       * `function.arguments`. Reassembly is therefore index-keyed\r\n       * accumulation, and a call is only complete once the stream moves\r\n       * on or finishes. That is why `streamChat` buffers rather than\r\n       * forwarding fragments.\r\n       */\r\n      tool_calls?: Array<{\r\n        index: number;\r\n        id?: string;\r\n        function?: { name?: string; arguments?: string };\r\n      }>;\r\n    };\r\n    finish_reason?: string | null;\r\n  }>;\r\n  usage?: {\r\n    prompt_tokens?: number;\r\n    completion_tokens?: number;\r\n    total_tokens?: number;\r\n    prompt_tokens_details?: { cached_tokens?: number };\r\n    completion_tokens_details?: { reasoning_tokens?: number };\r\n  };\r\n}\r\n\r\n/**\r\n * Execute a streaming chat completion with capability awareness AND\r\n * transient-401 resilience. Mirrors executeChatRequest but returns the SDK's\r\n * async iterable. Both retry kinds (capability rejection, transient 401)\r\n * happen at stream-creation time. Mid-stream errors propagate as-is to the\r\n * consumer's iteration loop.\r\n */\r\nasync function executeChatStream(\r\n  client: OpenAI,\r\n  ctx: AdapterContext,\r\n  alias: string,\r\n  pricing: ModelPricing,\r\n  req: LogicalChatRequest,\r\n): Promise<AsyncIterable<OpenAIStreamChunk>> {\r\n  const streamReq = { ...req, stream: true };\r\n  const attempt = async (): Promise<AsyncIterable<OpenAIStreamChunk>> => {\r\n    const caps = readCaps(streamReq.modelId, pricing);\r\n    const sdkReq = materializeRequest(streamReq, caps);\r\n    const reqOpts = streamReq.signal ? { signal: streamReq.signal } : undefined;\r\n    return (await client.chat.completions.create(sdkReq as never, reqOpts)) as never;\r\n  };\r\n\r\n  let triedCapabilityFallback = false;\r\n  let transientRetries = 0;\r\n\r\n  // eslint-disable-next-line no-constant-condition -- intentional retry loop; exits via return/throw/break\r\n  while (true) {\r\n    try {\r\n      const stream: AsyncIterable<OpenAIStreamChunk> = await attempt();\r\n      ctx.hasSucceeded.value = true;\r\n      return stream;\r\n    } catch (err) {\r\n      if (\r\n        isTransientAuthError(err, ctx) &&\r\n        transientRetries < ctx.transientAuthRetries\r\n      ) {\r\n        const delayMs = ctx.transientAuthBackoffMs(transientRetries);\r\n        emitRetry(ctx, {\r\n          reason: \"transient-auth\",\r\n          attempt: transientRetries,\r\n          modelId: streamReq.modelId,\r\n          providerAlias: alias,\r\n          delayMs,\r\n          cause: err,\r\n        });\r\n        await sleep(delayMs);\r\n        transientRetries++;\r\n        continue;\r\n      }\r\n      if (!triedCapabilityFallback && learnConstraintsFromError(err, streamReq)) {\r\n        emitRetry(ctx, {\r\n          reason: \"capability-fallback\",\r\n          attempt: 0,\r\n          modelId: streamReq.modelId,\r\n          providerAlias: alias,\r\n          delayMs: 0,\r\n          cause: err,\r\n        });\r\n        triedCapabilityFallback = true;\r\n        continue;\r\n      }\r\n      throw wrapProviderError(alias, err, streamReq.modelId);\r\n    }\r\n  }\r\n}\r\n\r\n// ─── Helpers ─────────────────────────────────────────────────────────\r\n\r\nfunction parseUsage(response: {\r\n  usage?: {\r\n    prompt_tokens?: number;\r\n    completion_tokens?: number;\r\n    prompt_tokens_details?: { cached_tokens?: number };\r\n    completion_tokens_details?: { reasoning_tokens?: number };\r\n  };\r\n}): TokenUsage {\r\n  const inputTokens = response.usage?.prompt_tokens ?? 0;\r\n  const outputTokens = response.usage?.completion_tokens ?? 0;\r\n  const cached = response.usage?.prompt_tokens_details?.cached_tokens;\r\n  const reasoning = response.usage?.completion_tokens_details?.reasoning_tokens;\r\n  return {\r\n    inputTokens,\r\n    outputTokens,\r\n    totalTokens: inputTokens + outputTokens,\r\n    ...(cached !== undefined && cached > 0 ? { cacheReadTokens: cached } : {}),\r\n    ...(reasoning !== undefined && reasoning > 0 ? { reasoningTokens: reasoning } : {}),\r\n  };\r\n}\r\n\r\n/**\r\n * Fire the Registry-attached stream-complete callback with usage + cost\r\n * derived from the final `include_usage: true` chunk. (alpha.25+)\r\n *\r\n * Called at natural stream completion by `streamText` and `streamStructured`.\r\n * Mid-stream errors and consumer aborts bypass this path; no cost or\r\n * observability events are emitted on failure paths (matches the alpha.24\r\n * non-streaming contract of \"cost recorded only on success\").\r\n *\r\n * Errors from the callback are NOT caught here — the callback contract\r\n * (via {@link readStreamCompleteCallback}) already documents that the\r\n * Registry-side callback wraps its own emit calls fire-and-forget. If a\r\n * future consumer of the callback wants error isolation, that's their\r\n * responsibility.\r\n */\r\n/**\r\n * Emit every fully-assembled tool call, then clear the buffer.\r\n *\r\n * Arguments arrive as a character stream, so JSON.parse can only be\r\n * attempted once the provider stops appending. A call whose arguments do\r\n * not parse is still emitted, with `args` undefined and `rawArguments`\r\n * carrying the original text: one malformed call must not kill a live\r\n * conversation, and a caller who can salvage the raw string should be\r\n * given the chance.\r\n *\r\n * Calls with no name are dropped. A nameless tool call is not actionable\r\n * by any caller, and forwarding it would only push the same decision one\r\n * layer out.\r\n */\r\nfunction* flushPendingToolCalls(\r\n  pending: Map<number, { id: string; name: string; args: string }>,\r\n): Generator<ChatStreamEvent> {\r\n  if (pending.size === 0) return;\r\n  const calls = [...pending.entries()].sort((a, b) => a[0] - b[0]);\r\n  pending.clear();\r\n  for (const [, call] of calls) {\r\n    if (!call.name) continue;\r\n    let parsed: unknown;\r\n    let ok = true;\r\n    try {\r\n      parsed = call.args.trim() === \"\" ? {} : JSON.parse(call.args);\r\n    } catch {\r\n      ok = false;\r\n    }\r\n    yield {\r\n      type: \"tool-call\",\r\n      toolCallId: call.id,\r\n      toolName: call.name,\r\n      ...(ok ? { args: parsed } : {}),\r\n      rawArguments: call.args,\r\n    };\r\n  }\r\n}\r\n\r\nfunction emitStreamComplete(args: {\r\n  usage: NonNullable<OpenAIStreamChunk[\"usage\"]>;\r\n  modelId: string;\r\n  providerAlias: string;\r\n  pricing: ModelPricing;\r\n  streamStart: number;\r\n  callback: (meta: {\r\n    usage: TokenUsage;\r\n    cost: CostUsage;\r\n    modelId: string;\r\n    providerAlias: string;\r\n    latencyMs: number;\r\n  }) => void;\r\n}): void {\r\n  const usage = parseUsage({ usage: args.usage });\r\n  const cost = computeChatCost(usage, args.pricing);\r\n  const latencyMs = Date.now() - args.streamStart;\r\n  args.callback({\r\n    usage,\r\n    cost,\r\n    modelId: args.modelId,\r\n    providerAlias: args.providerAlias,\r\n    latencyMs,\r\n  });\r\n}\r\n\r\ninterface OpenAITool {\r\n  type: \"function\";\r\n  function: {\r\n    name: string;\r\n    description: string;\r\n    parameters: { type: \"object\"; properties: Record<string, unknown>; required?: string[] };\r\n  };\r\n}\r\n\r\nfunction toOpenAITools(\r\n  tools: Record<string, ToolDefinition> | undefined | null,\r\n): OpenAITool[] {\r\n  // Defensive normalization: `runAgent`'s public options type declares\r\n  // `tools` as required, but consumers occasionally pass `undefined`\r\n  // explicitly or omit the field. Treating absent tools as \"no tools\" is\r\n  // the natural reading of the type signature (matches the behavior of\r\n  // `tools: {}` which already works). Added in alpha.28 pre-work\r\n  // (TD-LLMP-17). Prior to this defense, `Object.entries(undefined)`\r\n  // threw a raw TypeError which then got misclassified as\r\n  // ServiceUnavailableError, triggering futile chain-wide failover.\r\n  if (!tools) return [];\r\n  return Object.entries(tools).map(([name, def]) => ({\r\n    type: \"function\",\r\n    function: {\r\n      name,\r\n      description: def.description,\r\n      parameters: zodToParameters(def.inputSchema),\r\n    },\r\n  }));\r\n}\r\n\r\n/**\r\n * Convert a Zod schema to the JSON Schema shape OpenAI's tool-use API\r\n * expects (`parameters: { type: \"object\", properties: { ... }, required: [...] }`).\r\n *\r\n * Uses `zod-to-json-schema` with the OpenAI target so output is the\r\n * exact dialect OpenAI accepts (no draft-07 `$schema` header, no\r\n * `additionalProperties` injected unless the schema declares it, etc.).\r\n *\r\n * Falls back to the `{ type: \"object\", properties: {} }` shape if the\r\n * schema is not a Zod schema or if conversion fails — defensive\r\n * fallback so a malformed tool definition doesn't crash the agent loop.\r\n */\r\nfunction zodToParameters(schema: unknown): {\r\n  type: \"object\";\r\n  properties: Record<string, unknown>;\r\n  required?: string[];\r\n} {\r\n  try {\r\n    const json = zodToJsonSchema(schema as never, {\r\n      target: \"openAi\",\r\n      $refStrategy: \"none\",\r\n    }) as Record<string, unknown>;\r\n    if (json && typeof json === \"object\" && json[\"type\"] === \"object\") {\r\n      return {\r\n        type: \"object\",\r\n        properties: (json[\"properties\"] as Record<string, unknown>) ?? {},\r\n        ...(Array.isArray(json[\"required\"])\r\n          ? { required: json[\"required\"] as string[] }\r\n          : {}),\r\n      };\r\n    }\r\n  } catch {\r\n    // fall through to the safe default\r\n  }\r\n  return { type: \"object\", properties: {} };\r\n}\r\n\r\n/**\r\n * Build the JSON Schema for OpenAI / Cerebras strict response_format mode\r\n * from a Zod schema. Strict mode requires:\r\n *   - Every object: `additionalProperties: false`\r\n *   - Every object: ALL declared properties listed in `required` (no optionals)\r\n *   - No unsupported JSON Schema features (oneOf is supported as anyOf,\r\n *     allOf must be flattened, $ref must be inlined)\r\n *\r\n * We use `$refStrategy: \"none\"` to inline refs, then post-process to add\r\n * the `additionalProperties: false` invariant on every nested object. The\r\n * `required` field is left as-is — Zod-emitted JSON Schema marks every\r\n * required field correctly. Optional Zod fields stay optional; callers\r\n * who hit Cerebras's \"all-fields-required\" enforcement should either\r\n * mark fields required in Zod or use `.default()`.\r\n */\r\nfunction buildStrictJsonSchema(schema: unknown): Record<string, unknown> {\r\n  let json: Record<string, unknown>;\r\n  try {\r\n    json = zodToJsonSchema(schema as never, {\r\n      target: \"openAi\",\r\n      $refStrategy: \"none\",\r\n    }) as Record<string, unknown>;\r\n  } catch {\r\n    return { type: \"object\", properties: {}, additionalProperties: false };\r\n  }\r\n  return enforceStrictDialect(json);\r\n}\r\n\r\nfunction enforceStrictDialect(input: unknown): Record<string, unknown> {\r\n  if (!input || typeof input !== \"object\" || Array.isArray(input)) {\r\n    return { type: \"object\", properties: {}, additionalProperties: false };\r\n  }\r\n  const out: Record<string, unknown> = {};\r\n  for (const [key, value] of Object.entries(input as Record<string, unknown>)) {\r\n    if (key === \"$schema\") continue;\r\n    if (key === \"properties\" && value && typeof value === \"object\") {\r\n      const props: Record<string, unknown> = {};\r\n      for (const [k, v] of Object.entries(value as Record<string, unknown>)) {\r\n        props[k] = enforceStrictDialect(v);\r\n      }\r\n      out[key] = props;\r\n      continue;\r\n    }\r\n    if (key === \"items\" && value && typeof value === \"object\" && !Array.isArray(value)) {\r\n      out[key] = enforceStrictDialect(value);\r\n      continue;\r\n    }\r\n    if (key === \"anyOf\" && Array.isArray(value)) {\r\n      out[key] = value.map((v) => enforceStrictDialect(v));\r\n      continue;\r\n    }\r\n    out[key] = value;\r\n  }\r\n  if (out[\"type\"] === \"object\" && out[\"additionalProperties\"] === undefined) {\r\n    out[\"additionalProperties\"] = false;\r\n  }\r\n  return out;\r\n}\r\n"]}