{"version":3,"sources":["../src/index.ts","../src/errors.ts","../src/providers/anthropic.ts","../src/utils/event-stream.ts","../src/utils/zod-to-json-schema.ts","../src/providers/reasoning-field.ts","../src/providers/transform.ts","../src/utils/json.ts","../src/providers/openai.ts","../src/providers/prompt-cache-key.ts","../src/utils/diag.ts","../src/providers/moonshot-video.ts","../src/utils/env.ts","../src/providers/openai-codex.ts","../src/utils/sse.ts","../src/utils/request-id.ts","../src/providers/gemini.ts","../src/provider-registry.ts","../src/utils/well-formed.ts","../src/stream.ts","../src/error-classification.ts","../src/redaction.ts","../src/providers/palsu.ts"],"sourcesContent":["// Core entry point\nexport { stream, localWireModelId } from \"./stream.js\";\n\n// Provider registry\nexport { providerRegistry } from \"./provider-registry.js\";\nexport type { ProviderStreamFn, ProviderEntry } from \"./provider-registry.js\";\n\n// Types\nexport type {\n  Provider,\n  ThinkingLevel,\n  CacheRetention,\n  TextContent,\n  ThinkingContent,\n  ImageContent,\n  VideoContent,\n  ToolCall,\n  ToolResult,\n  ToolResultContent,\n  ServerToolCall,\n  ServerToolResult,\n  ServerToolDefinition,\n  RawContent,\n  ContentPart,\n  MessageProvenanceSource,\n  MessageProvenanceKind,\n  MessageProvenanceVisibility,\n  MessageProvenance,\n  SystemMessage,\n  UserMessage,\n  AssistantMessage,\n  ToolResultMessage,\n  Message,\n  Tool,\n  ToolChoice,\n  TextDeltaEvent,\n  ThinkingDeltaEvent,\n  ToolCallDeltaEvent,\n  ToolCallDoneEvent,\n  ServerToolCallEvent,\n  ServerToolResultEvent,\n  DoneEvent,\n  ErrorEvent,\n  StreamEvent,\n  StopReason,\n  StreamResponse,\n  Usage,\n  StreamOptions,\n} from \"./types.js\";\n\n// Classes\nexport { StreamResult, EventStream } from \"./utils/event-stream.js\";\nexport {\n  GGAIError,\n  ProviderError,\n  formatError,\n  formatErrorForDisplay,\n  isUsageLimitError,\n  isHardBillingMessage,\n} from \"./errors.js\";\nexport type { ErrorSource, FormattedError } from \"./errors.js\";\nexport { classifyProviderError } from \"./error-classification.js\";\nexport { REDACTION_MARKER, environmentSecrets, redactText, redactValue } from \"./redaction.js\";\nexport type { RedactionOptions } from \"./redaction.js\";\n\n// UTF-16 well-formedness: providers reject request bodies holding lone surrogates.\nexport {\n  hasLoneSurrogate,\n  sanitizeMessagesForWire,\n  sliceHead,\n  sliceTail,\n  toWellFormedText,\n} from \"./utils/well-formed.js\";\n\n// Provider-level diagnostics (raw SSE event types, etc.)\nexport { setProviderDiagnostic } from \"./utils/diag.js\";\nexport type { ProviderDiagnosticFn } from \"./utils/diag.js\";\n\n// Tool schema serialization — the exact encoding every provider request uses\n// (rawInputSchema passthrough for MCP tools, zodToJsonSchema otherwise).\nexport { resolveToolSchema } from \"./utils/zod-to-json-schema.js\";\n\n// Provider request transforms (exposed for request-building + verification)\nexport {\n  clampProviderContextImages,\n  toAnthropicMessages,\n  toOpenAIMessages,\n} from \"./providers/transform.js\";\n\n// Cache pre-warming (Anthropic — fires a max_tokens:1 warm-up to prime the KV cache)\nexport { prewarmAnthropicCache } from \"./providers/anthropic.js\";\n\n// Palsu provider (testing)\nexport {\n  registerPalsuProvider,\n  palsuText,\n  palsuThinking,\n  palsuToolCall,\n  palsuAssistantMessage,\n} from \"./providers/palsu.js\";\nexport type {\n  PalsuProviderHandle,\n  PalsuProviderConfig,\n  PalsuProviderState,\n  PalsuResponse,\n  PalsuResponseFactory,\n  PalsuModelConfig,\n  PalsuModelHandle,\n} from \"./providers/palsu.js\";\n","/**\n * Error model for gg-ai and downstream consumers.\n *\n * Every error users see should answer one question: \"is this me or them?\"\n * That answer drives whether they retry, switch model, log in, or report a\n * GG Coder bug. The `FormattedError` shape captures it in plain English:\n *\n *   ✗ OpenAI returned an error.\n *     An error occurred while processing your request...\n *     → This is an OpenAI issue, not GG Coder. Retry — if it persists, check status.openai.com.\n *\n *   ✗ GG Coder hit an unexpected error.\n *     Cannot read property 'foo' of undefined\n *     → This is a GG Coder bug — please report it.\n */\n\nexport type ErrorSource = \"provider\" | \"ggcoder\" | \"network\" | \"auth\" | \"capability\";\n\n/**\n * Probe a web `Headers` object or a plain header record for the first present\n * header among `names`. Case-insensitive for plain records. Returns the value\n * of the first name that resolves to a string, or `undefined`.\n */\nexport function readHeader(headers: unknown, ...names: string[]): string | undefined {\n  if (!headers) return undefined;\n  const getter =\n    typeof (headers as { get?: unknown }).get === \"function\"\n      ? (name: string): string | undefined => (headers as Headers).get(name) ?? undefined\n      : typeof headers === \"object\"\n        ? (name: string): string | undefined => {\n            const rec = headers as Record<string, unknown>;\n            const value = rec[name] ?? rec[name.toLowerCase()];\n            return typeof value === \"string\" ? value : undefined;\n          }\n        : undefined;\n  if (!getter) return undefined;\n  for (const name of names) {\n    const value = getter(name);\n    if (value != null) return value;\n  }\n  return undefined;\n}\n\nexport interface FormattedError {\n  /** Plain-English headline, e.g. \"OpenAI returned an error.\" */\n  headline: string;\n  /** Machine-readable classification. */\n  source: ErrorSource;\n  /** Detailed message body from the underlying error (no JSON, no tag prefix). */\n  message: string;\n  /** Action line — tells the user whether to retry, switch model, log in, or report a bug. */\n  guidance: string;\n  /** Provider name when source === \"provider\". */\n  provider?: string;\n  /** HTTP status code if known. */\n  statusCode?: number;\n  /** Provider request ID, kept for telemetry / debug — not shown by default. */\n  requestId?: string;\n  /** Unix seconds when a usage/rate limit resets, when the provider reports it. */\n  resetsAt?: number;\n}\n\nexport class GGAIError extends Error {\n  readonly source: ErrorSource;\n  readonly requestId?: string;\n  readonly hint?: string;\n\n  constructor(\n    message: string,\n    options?: {\n      source?: ErrorSource;\n      requestId?: string;\n      hint?: string;\n      cause?: unknown;\n    },\n  ) {\n    super(message, { cause: options?.cause });\n    this.name = \"GGAIError\";\n    this.source = options?.source ?? \"ggcoder\";\n    this.requestId = options?.requestId;\n    this.hint = options?.hint;\n  }\n}\n\n/**\n * The active model can't handle some content in the request (e.g. a video block\n * left in history after switching from a video model to a text-only one). A\n * clean, user-facing capability error — not a bug, not a provider outage.\n */\nexport class VideoUnsupportedError extends GGAIError {\n  constructor() {\n    super(\"This model can't analyze video.\", { source: \"capability\" });\n    this.name = \"VideoUnsupportedError\";\n  }\n}\n\nexport class ProviderError extends GGAIError {\n  readonly provider: string;\n  readonly statusCode?: number;\n  /** Unix seconds when a usage/rate limit resets, when the provider reports it. */\n  readonly resetsAt?: number;\n\n  constructor(\n    provider: string,\n    message: string,\n    options?: {\n      statusCode?: number;\n      requestId?: string;\n      hint?: string;\n      cause?: unknown;\n      resetsAt?: number;\n    },\n  ) {\n    super(message, {\n      source: \"provider\",\n      requestId: options?.requestId,\n      hint: options?.hint,\n      cause: options?.cause,\n    });\n    this.name = \"ProviderError\";\n    this.provider = provider;\n    this.statusCode = options?.statusCode;\n    this.resetsAt = options?.resetsAt;\n  }\n}\n\n/**\n * Display names for every provider we support. Used in headlines so users\n * see \"OpenAI returned an error.\" rather than the slug \"openai\".\n */\nconst PROVIDER_DISPLAY: Record<string, string> = {\n  openai: \"OpenAI\",\n  anthropic: \"Anthropic\",\n  gemini: \"Gemini\",\n  glm: \"Z.AI (GLM)\",\n  moonshot: \"Moonshot\",\n  deepseek: \"DeepSeek\",\n  openrouter: \"OpenRouter\",\n  sakana: \"Sakana\",\n  xai: \"xAI (Grok)\",\n  huggingface: \"Hugging Face\",\n  xiaomi: \"Xiaomi (MiMo)\",\n  minimax: \"MiniMax\",\n};\n\n/** Status pages for providers that publish one. */\nconst PROVIDER_STATUS_URL: Record<string, string> = {\n  openai: \"status.openai.com\",\n  anthropic: \"status.anthropic.com\",\n  xai: \"status.x.ai\",\n};\n\nfunction providerDisplayName(provider: string): string {\n  return PROVIDER_DISPLAY[provider] ?? provider;\n}\n\n/**\n * Normalise any thrown value into a structured display object. Always returns\n * a non-empty `headline` and `guidance` so the UI never has to second-guess\n * what to show the user.\n */\n/**\n * Is this a subscription/plan usage-window exhaustion error (as opposed to a\n * transient per-minute throttle)? These don't clear with a quick retry — the\n * user has to wait for the window to reset — so callers must surface them as a\n * hard stop, not silently retry for minutes. Detected from the canonical\n * \"usage limit reached\" message gg-ai stamps onto the ProviderError.\n */\nexport function isUsageLimitError(err: unknown): boolean {\n  if (!(err instanceof Error)) return false;\n  return /usage limit reached/i.test(err.message);\n}\n\n/**\n * Substrings that mark a hard, non-retriable billing/quota stop on ANY provider\n * (credit exhaustion, balance too low, plan quota spent). Single source of truth\n * shared across the OpenAI-compatible and Anthropic provider boundaries and the\n * agent-loop retry classifier, so the lists can't drift. Matched case-insensitively.\n */\nexport function isHardBillingMessage(message: string): boolean {\n  const lower = message.toLowerCase();\n  return (\n    lower.includes(\"insufficient balance\") ||\n    lower.includes(\"insufficient credits\") ||\n    lower.includes(\"more credits\") ||\n    lower.includes(\"insufficient_quota\") ||\n    lower.includes(\"exceeded your current quota\") ||\n    lower.includes(\"quota exceeded\") ||\n    lower.includes(\"no resource package\") ||\n    lower.includes(\"recharge\") ||\n    lower.includes(\"balance is too low\") ||\n    lower.includes(\"out of credits\") ||\n    lower.includes(\"arrears\") ||\n    lower.includes(\"arrearage\") ||\n    lower.includes(\"token quota\") ||\n    lower.includes(\"exceeded_current_quota_error\") ||\n    lower.includes(\"check your account balance\") ||\n    lower.includes(\"does not yet include access\") ||\n    lower.includes(\"subscription plan\") ||\n    lower.includes(\"billing\")\n  );\n}\n\n/** Format a unix-seconds reset timestamp for display, e.g. \"3:45 PM\". */\nfunction formatResetTime(resetsAt: number): string {\n  const when = new Date(resetsAt * 1000);\n  const sameDay = when.toDateString() === new Date().toDateString();\n  return sameDay\n    ? when.toLocaleTimeString(undefined, { hour: \"numeric\", minute: \"2-digit\" })\n    : when.toLocaleString(undefined, {\n        weekday: \"short\",\n        hour: \"numeric\",\n        minute: \"2-digit\",\n      });\n}\n\n/**\n * Anthropic's Claude Mythos models are invitation-only (Project Glasswing) —\n * unapproved accounts get a bare `not_found_error` from the API. Detect that\n * case so we can explain the access model instead of echoing the raw error.\n */\nfunction isMythosAccessError(message: string): boolean {\n  const lower = message.toLowerCase();\n  return (\n    lower.includes(\"mythos\") &&\n    (lower.includes(\"not_found\") || lower.includes(\"not found\") || lower.includes(\"no access\"))\n  );\n}\n\n/**\n * The OpenAI and Anthropic SDKs both build `err.message` by JSON-stringifying\n * the raw error body whenever it has no usable string `message` field (e.g.\n * `{\"code\":\"400\",\"message\":\"\",\"param\":\"\",\"type\":\"\"}` from a provider that\n * returned an empty/malformed error) — producing an unreadable blob like\n * `400 {\"code\":\"400\",\"message\":\"\",\"param\":\"\",\"type\":\"\"}`. Detect that shape so\n * provider wrappers can swap in a clean, honest fallback instead of echoing raw\n * JSON at the user. The original is never lost — it survives on `err.cause` for\n * anyone who needs to inspect the raw provider response.\n */\nexport function isRawJsonErrorEcho(message: string): boolean {\n  const trimmed = message.trim();\n  const jsonStart = trimmed.indexOf(\"{\");\n  if (jsonStart === -1) return false;\n  // The SDKs only ever prefix the JSON with \"<status> \" or nothing at all.\n  const prefix = trimmed.slice(0, jsonStart).trim();\n  if (prefix && !/^\\d+$/.test(prefix)) return false;\n  try {\n    const parsed: unknown = JSON.parse(trimmed.slice(jsonStart));\n    return typeof parsed === \"object\" && parsed !== null;\n  } catch {\n    return false;\n  }\n}\n\n/**\n * Detect a raw HTML document returned by a provider edge, proxy, or status page.\n * SDKs preserve non-JSON response bodies in `err.message`, sometimes prefixed by\n * the HTTP status. HTML is diagnostic transport debris, not a user-facing error.\n */\nexport function isRawHtmlErrorEcho(message: string): boolean {\n  const withoutStatus = message\n    .trimStart()\n    .replace(/^\\d{3}\\s+/, \"\")\n    .trimStart();\n  return /^<!doctype\\s+html(?:\\s|>)/i.test(withoutStatus) || /^<html(?:\\s|>)/i.test(withoutStatus);\n}\n\n/** Clean fallback when an API endpoint returned an HTML page instead of API JSON. */\nexport function providerHtmlErrorMessage(statusCode: number | undefined): string {\n  return statusCode\n    ? `The provider returned an HTML error page (HTTP ${statusCode}) instead of an API response.`\n    : \"The provider returned an HTML error page instead of an API response.\";\n}\n\n/** Clean fallback message when a provider's error body carried no usable text. */\nexport function emptyProviderErrorMessage(statusCode: number | undefined): string {\n  return statusCode\n    ? `The provider returned an empty error response (HTTP ${statusCode}), with no further detail.`\n    : \"The provider returned an empty error response, with no further detail.\";\n}\n\nexport function formatError(err: unknown): FormattedError {\n  if (err instanceof ProviderError) {\n    const name = providerDisplayName(err.provider);\n    const cleanMessage = cleanProviderMessage(err.message, err.statusCode);\n    if (isMythosAccessError(cleanMessage)) {\n      return {\n        headline: \"Claude Mythos 5 is invitation-only.\",\n        source: \"provider\",\n        message:\n          \"Your Anthropic account isn't approved for Project Glasswing, so the API reports the model as not found.\",\n        provider: err.provider,\n        statusCode: err.statusCode,\n        ...(err.requestId ? { requestId: err.requestId } : {}),\n        guidance:\n          \"Request access via your Anthropic account team (see platform.claude.com/docs/en/about-claude/models/overview), or switch to Claude Fable 5 via the model selector — same underlying model, generally available.\",\n      };\n    }\n    if (isUsageLimitError(err)) {\n      const resetClause = err.resetsAt ? ` It resets at ${formatResetTime(err.resetsAt)}.` : \"\";\n      return {\n        headline: `${name} usage limit reached.`,\n        source: \"provider\",\n        message: `Your ${name} usage is finished.${resetClause}`,\n        provider: err.provider,\n        statusCode: err.statusCode,\n        ...(err.requestId ? { requestId: err.requestId } : {}),\n        ...(err.resetsAt ? { resetsAt: err.resetsAt } : {}),\n        guidance: \"Try again once it's back. Your conversation is preserved.\",\n      };\n    }\n    return {\n      headline: `${name} returned an error.`,\n      source: \"provider\",\n      message: cleanMessage,\n      provider: err.provider,\n      statusCode: err.statusCode,\n      requestId: err.requestId,\n      guidance: err.hint ?? providerGuidance(err.provider, cleanMessage, err.statusCode),\n    };\n  }\n\n  if (err instanceof GGAIError) {\n    return finaliseBySource(err.source, err.message, err.requestId, err.hint);\n  }\n\n  if (err instanceof Error) {\n    const source = inferSource(err);\n    return finaliseBySource(source, err.message, undefined, undefined);\n  }\n\n  return finaliseBySource(\"ggcoder\", String(err), undefined, undefined);\n}\n\nfunction finaliseBySource(\n  source: ErrorSource,\n  message: string,\n  requestId: string | undefined,\n  hint: string | undefined,\n): FormattedError {\n  switch (source) {\n    case \"network\":\n      return {\n        headline: \"Network error — couldn't reach the provider.\",\n        source,\n        message,\n        guidance: hint ?? \"Check your internet connection. Not a GG Coder issue — retry shortly.\",\n        ...(requestId ? { requestId } : {}),\n      };\n    case \"auth\":\n      return {\n        headline: \"Authentication issue.\",\n        source,\n        message,\n        guidance: hint ?? \"Re-authenticate to refresh your credentials.\",\n        ...(requestId ? { requestId } : {}),\n      };\n    case \"provider\":\n      // Provider source with no ProviderError instance — best effort.\n      return {\n        headline: \"Provider returned an error.\",\n        source,\n        message,\n        guidance: hint ?? providerGuidance(undefined, message, undefined),\n        ...(requestId ? { requestId } : {}),\n      };\n    case \"capability\":\n      return {\n        headline: message,\n        source,\n        message: \"\",\n        guidance:\n          hint ??\n          \"Only Kimi, Gemini, MiniMax, and MiMo-V2.5 can analyze video. Switch to one of those via the model selector.\",\n        ...(requestId ? { requestId } : {}),\n      };\n    case \"ggcoder\":\n      return {\n        headline: \"GG Coder hit an unexpected error.\",\n        source,\n        message,\n        guidance:\n          hint ?? \"This looks like a GG Coder bug — please report it to the developer (see /help).\",\n        ...(requestId ? { requestId } : {}),\n      };\n  }\n}\n\n/**\n * Render a FormattedError as a multi-line string for terminal display.\n *\n * Format:\n *   <headline>\n *     <message>\n *     → <guidance>\n */\nexport function formatErrorForDisplay(err: unknown): string {\n  const f = formatError(err);\n  const lines = [f.headline];\n  if (f.message && f.message !== f.headline) lines.push(`  ${f.message}`);\n  lines.push(`  → ${f.guidance}`);\n  return lines.join(\"\\n\");\n}\n\n/**\n * Strip legacy `[provider]` / `[provider:name]` prefix from a message body,\n * so older ProviderError messages render cleanly under the new headline\n * system without doubling up.\n */\nfunction cleanProviderMessage(message: string, statusCode?: number): string {\n  const clean = message.replace(/^\\[[^\\]]+\\]\\s*/, \"\").trim();\n  return isRawHtmlErrorEcho(clean) ? providerHtmlErrorMessage(statusCode) : clean;\n}\n\nfunction inferSource(err: Error): ErrorSource {\n  const msg = err.message.toLowerCase();\n  const code = (err as { code?: string }).code ?? \"\";\n  if (\n    code === \"ECONNREFUSED\" ||\n    code === \"ETIMEDOUT\" ||\n    code === \"ENOTFOUND\" ||\n    code === \"ECONNRESET\" ||\n    msg.includes(\"fetch failed\") ||\n    msg.includes(\"network request failed\")\n  ) {\n    return \"network\";\n  }\n  if (\n    msg.includes(\"not logged in\") ||\n    msg.includes(\"token exchange failed\") ||\n    msg.includes(\"token refresh failed\") ||\n    msg.includes(\"invalid_grant\")\n  ) {\n    return \"auth\";\n  }\n  return \"ggcoder\";\n}\n\n/**\n * Build the action line for a provider error: tells the user whether to\n * retry, switch model, check billing, or whether it's serious enough to\n * report. Always frames the source plainly (\"This is an OpenAI issue\") so\n * the user knows to NOT report it to the GG Coder dev.\n */\nfunction providerGuidance(\n  provider: string | undefined,\n  message: string,\n  statusCode: number | undefined,\n): string {\n  const name = provider ? providerDisplayName(provider) : \"the provider\";\n  const status = provider ? PROVIDER_STATUS_URL[provider] : undefined;\n  const lower = message.toLowerCase();\n\n  if (statusCode === 401 || lower.includes(\"unauthorized\") || lower.includes(\"invalid api key\")) {\n    return `Authentication failed with ${name}. Re-authenticate to refresh your credentials.`;\n  }\n  if (lower.includes(\"overloaded\") || lower.includes(\"engine_overloaded\")) {\n    return `${name}'s servers are overloaded right now. Retry in a moment — not a GG Coder issue.`;\n  }\n  if (\n    lower.includes(\"insufficient balance\") ||\n    lower.includes(\"quota exceeded\") ||\n    lower.includes(\"recharge\") ||\n    lower.includes(\"no resource package\")\n  ) {\n    return `Your ${name} account has a billing or quota issue — check your balance. Not a GG Coder issue.`;\n  }\n  if (statusCode === 429 || lower.includes(\"rate limit\") || lower.includes(\"too many requests\")) {\n    return `${name} rate limit hit. Wait a moment then retry — not a GG Coder issue.`;\n  }\n  if (statusCode === 502 || lower.includes(\"bad gateway\")) {\n    return `${name} returned a bad gateway. Retry — this is on their side, not GG Coder.`;\n  }\n  if (statusCode === 503 || lower.includes(\"service unavailable\")) {\n    return `${name} is temporarily unavailable. Retry shortly — not a GG Coder issue.`;\n  }\n  if (\n    statusCode === 507 ||\n    lower.includes(\"exceeded request buffer limit while retrying upstream\")\n  ) {\n    return `${name}'s proxy could not retry this large request. GG Coder already retried automatically — compact the conversation, then retry.`;\n  }\n  if (\n    statusCode === 500 ||\n    lower.includes(\"server_error\") ||\n    (lower.includes(\"500\") && lower.includes(\"internal server error\"))\n  ) {\n    return status\n      ? `This is an error from ${name}, not GG Coder. Retry — if it keeps happening, check ${status}.`\n      : `This is an error from ${name}, not GG Coder. Retry — if it keeps happening, try a different model via the model selector.`;\n  }\n  if (lower.includes(\"timeout\") || lower.includes(\"timed out\")) {\n    return `Request to ${name} timed out. Their servers may be slow — retry. Not a GG Coder issue.`;\n  }\n  if (\n    lower.includes(\"does not recognize the requested model\") ||\n    (lower.includes(\"model\") &&\n      (lower.includes(\"not exist\") || lower.includes(\"not found\") || lower.includes(\"no access\")))\n  ) {\n    return `${name} doesn't recognise this model on your account. Switch to a different model via the model selector, or check your subscription tier.`;\n  }\n  if (lower.includes(\"context_length_exceeded\") || lower.includes(\"prompt is too long\")) {\n    return `Context window for this ${name} model is full. Compact the conversation to shrink history, or start a new session.`;\n  }\n  if (\n    lower.includes(\"many-image request\") ||\n    (lower.includes(\"image dimensions\") && lower.includes(\"max allowed size\"))\n  ) {\n    return `An image in conversation history exceeds ${name}'s many-image limit. Restart GG Coder so restored images are resized, then retry; if it persists, start a new session.`;\n  }\n  // Anthropic HTTP 413: the request BODY (not the token count) exceeds the\n  // provider's max size. Retrying the same request fails identically — the fix\n  // is to shrink history, same as a context overflow.\n  if (\n    statusCode === 413 ||\n    lower.includes(\"request_too_large\") ||\n    lower.includes(\"request exceeds the maximum size\")\n  ) {\n    return `The request to ${name} is too large. Compact the conversation to shrink history, or start a new session.`;\n  }\n  return status\n    ? `This is an error from ${name}, not GG Coder. Retry — if it persists, check ${status}.`\n    : `This is an error from ${name}, not GG Coder. Retry — if it persists, try a different model via the model selector.`;\n}\n","import Anthropic from \"@anthropic-ai/sdk\";\nimport type {\n  ContentPart,\n  ServerToolCall,\n  ServerToolResult,\n  StreamEvent,\n  StreamOptions,\n  StreamResponse,\n  ToolCall,\n} from \"../types.js\";\nimport {\n  ProviderError,\n  readHeader,\n  isHardBillingMessage,\n  isRawJsonErrorEcho,\n  isRawHtmlErrorEcho,\n  emptyProviderErrorMessage,\n  providerHtmlErrorMessage,\n} from \"../errors.js\";\nimport { StreamResult } from \"../utils/event-stream.js\";\nimport {\n  downgradeUnsupportedImages,\n  normalizeAnthropicStopReason,\n  toAnthropicCacheControl,\n  toAnthropicMessages,\n  downgradeUnsupportedVideos,\n  toAnthropicThinking,\n  toAnthropicToolChoice,\n  toAnthropicTools,\n  isAdaptiveThinkingModel,\n} from \"./transform.js\";\nimport { isJsonObject } from \"../utils/json.js\";\n\n/**\n * Client cache — avoids re-instantiating the SDK on every stream() call.\n * The SDK constructor parses config, computes auth headers, and sets up the\n * fetch dispatcher. Node's undici pool already reuses TCP connections, but\n * the SDK overhead itself (config parsing, header computation) repeats on\n * every call. Keyed by the identity-relevant fields (apiKey, baseUrl,\n * userAgent) so a mid-session model switch (which may change the UA) gets a\n * fresh client.\n */\nconst anthropicClientCache = new Map<string, Anthropic>();\n\n/**\n * Upper HTTP timeout for the non-streaming fallback request.\n *\n * The Anthropic SDK refuses any non-streaming `messages.create` whose\n * `max_tokens` implies a >10-minute worst case — it throws \"Streaming is\n * required for operations that may take longer than 10 minutes\" *client-side*,\n * before any network call (see `calculateNonstreamingTimeout`: the throw fires\n * when `(60*60*max_tokens)/128000 > 600s`, i.e. any `max_tokens > ~21333`).\n * Adaptive-thinking Opus/Sonnet models set `max_tokens` to their full output\n * ceiling (~32K), so the fallback tripped this every time. The SDK only runs\n * that pre-flight check when the *client* carries no explicit `timeout`, so we\n * set one here to bypass it. The agent loop already bounds this call with its\n * own abort signal (NON_STREAMING_HARD_TIMEOUT_MS), so this is just a ceiling.\n */\nconst NON_STREAMING_REQUEST_TIMEOUT_MS = 600_000;\n\n/**\n * Fine-grained (eager) tool-input streaming is OFF by default.\n *\n * With `eager_input_streaming` + the `fine-grained-tool-streaming-2025-05-14`\n * beta, Anthropic streams tool arguments token-by-token WITHOUT server-side\n * buffering/validation. If the SSE stream is truncated (large `edit` payloads\n * are the usual victim), the accumulated `argsJson` is incomplete and\n * `JSON.parse` throws — historically we swallowed that and emitted a phantom\n * `args:{}` call, which the tool layer rejected with \"Invalid arguments\".\n * Claude Code itself gates this behind a default-false flag\n * (`CLAUDE_CODE_ENABLE_FINE_GRAINED_TOOL_STREAMING` / the `tengu_fgts`\n * experiment); we mirror that. Opt in with `GG_FINE_GRAINED_TOOL_STREAMING=1`\n * (or the Claude Code env var, for parity).\n */\nexport function fineGrainedToolStreamingEnabled(): boolean {\n  const raw =\n    process.env.GG_FINE_GRAINED_TOOL_STREAMING ??\n    process.env.CLAUDE_CODE_ENABLE_FINE_GRAINED_TOOL_STREAMING;\n  if (!raw) return false;\n  const v = raw.trim().toLowerCase();\n  return v === \"1\" || v === \"true\" || v === \"yes\" || v === \"on\";\n}\n\nfunction createClient(options: StreamOptions): Anthropic {\n  const isOAuth = options.apiKey?.startsWith(\"sk-ant-oat\");\n  const userAgent = isOAuth ? (options.userAgent ?? \"claude-cli/2.1.75 (external, cli)\") : \"\";\n  const cacheKey = `${options.apiKey ?? \"\"}|${options.baseUrl ?? \"\"}|${userAgent}`;\n\n  // Skip cache when a custom fetch is provided (tests, React Native, etc.) —\n  // the cached client would carry the wrong fetch implementation.\n  if (!options.fetch) {\n    const cached = anthropicClientCache.get(cacheKey);\n    if (cached) return cached;\n  }\n\n  const client = new Anthropic({\n    ...(isOAuth\n      ? { apiKey: null as unknown as string, authToken: options.apiKey }\n      : { apiKey: options.apiKey }),\n    ...(options.baseUrl ? { baseURL: options.baseUrl } : {}),\n    ...(options.fetch ? { fetch: options.fetch } : {}),\n    maxRetries: 0,\n    ...(isOAuth\n      ? {\n          defaultHeaders: {\n            \"user-agent\": userAgent,\n            \"x-app\": \"cli\",\n          },\n        }\n      : {}),\n  });\n\n  // Only cache production clients (no custom fetch override).\n  if (!options.fetch) {\n    if (anthropicClientCache.size >= 8) {\n      const oldest = anthropicClientCache.keys().next().value;\n      if (oldest) anthropicClientCache.delete(oldest);\n    }\n    anthropicClientCache.set(cacheKey, client);\n  }\n  return client;\n}\n\n/**\n * Fire a minimal `max_tokens: 1` request that populates the Anthropic prompt\n * cache with the system prompt + tools prefix, so the first real user turn is\n * a cache read instead of a cold cache write. Best-effort: any error is\n * swallowed so a failed pre-warm never blocks the session.\n *\n * Called by AgentSession when speedProfile is \"optimized\", before the first\n * real agent-loop turn. The cache TTL follows the `cacheRetention` option —\n * pass \"long\" (1 h) so the pre-warm survives until the user's first message.\n */\nexport async function prewarmAnthropicCache(options: {\n  apiKey: string;\n  model: string;\n  system: string;\n  tools?: StreamOptions[\"tools\"];\n  serverTools?: StreamOptions[\"serverTools\"];\n  baseUrl?: string;\n  userAgent?: string;\n  cacheRetention?: StreamOptions[\"cacheRetention\"];\n  signal?: AbortSignal;\n}): Promise<void> {\n  try {\n    const client = createClient({\n      apiKey: options.apiKey,\n      baseUrl: options.baseUrl,\n      userAgent: options.userAgent,\n    } as StreamOptions);\n    const cacheControl = toAnthropicCacheControl(options.cacheRetention ?? \"long\", options.baseUrl);\n    const { system, messages } = toAnthropicMessages(\n      [\n        { role: \"system\", content: options.system },\n        { role: \"user\", content: \".\" },\n      ],\n      cacheControl,\n    );\n    const isOAuth = options.apiKey.startsWith(\"sk-ant-oat\");\n    const fullSystem = isOAuth\n      ? [\n          {\n            type: \"text\" as const,\n            text: \"You are Claude Code, Anthropic's official CLI for Claude.\",\n          },\n          ...(system ?? []),\n        ]\n      : system;\n    const tools = options.tools?.length\n      ? toAnthropicTools(options.tools, {\n          cacheControl,\n          // Keep the serialized tool bytes identical to runStream so the\n          // prewarmed prompt cache actually hits — both are gated by the flag.\n          enableFineGrainedToolStreaming: fineGrainedToolStreamingEnabled(),\n        })\n      : undefined;\n    await client.messages.create(\n      {\n        model: options.model,\n        max_tokens: 1,\n        messages,\n        ...(fullSystem ? { system: fullSystem as Anthropic.MessageCreateParams[\"system\"] } : {}),\n        ...(tools\n          ? {\n              tools: [\n                ...tools,\n                ...(options.serverTools ?? []),\n              ] as Anthropic.MessageCreateParams[\"tools\"],\n            }\n          : {}),\n      } as Anthropic.MessageCreateParamsNonStreaming,\n      {\n        signal: options.signal ?? undefined,\n        ...(() => {\n          // Mirror runStream's beta headers for the parts that affect caching:\n          // OAuth identity betas + the extended-cache-ttl beta, without which a\n          // 1-h pre-warm silently writes a 5-min cache and expires before the\n          // user's first turn.\n          const betas = [\n            ...(isOAuth ? [\"claude-code-20250219\", \"oauth-2025-04-20\"] : []),\n            ...(cacheControl?.ttl === \"1h\" ? [\"extended-cache-ttl-2025-04-11\"] : []),\n          ];\n          return betas.length ? { headers: { \"anthropic-beta\": betas.join(\",\") } } : {};\n        })(),\n      },\n    );\n  } catch {\n    // Best-effort — prewarm failure should never block the session.\n  }\n}\n\nexport function streamAnthropic(options: StreamOptions): StreamResult {\n  return new StreamResult(runStream(options), options.signal);\n}\n\nasync function* runStream(options: StreamOptions): AsyncGenerator<StreamEvent, StreamResponse> {\n  const client = createClient(options);\n  const isOAuth = options.apiKey?.startsWith(\"sk-ant-oat\");\n  const useStreaming = options.streaming !== false;\n\n  const cacheControl = toAnthropicCacheControl(options.cacheRetention, options.baseUrl);\n  const supportsFirstPartyToolExtras =\n    !options.baseUrl || options.baseUrl.includes(\"api.anthropic.com\");\n  const downgradedImages = downgradeUnsupportedImages(options.messages, options.supportsImages);\n  const downgradedMessages = downgradeUnsupportedVideos(downgradedImages, options.supportsVideo);\n  const { system: rawSystem, messages } = toAnthropicMessages(downgradedMessages, cacheControl);\n\n  // OAuth tokens require Claude Code identity in the system prompt\n  const system = isOAuth\n    ? [\n        {\n          type: \"text\" as const,\n          text: \"You are Claude Code, Anthropic's official CLI for Claude.\",\n        },\n        ...(rawSystem ?? []),\n      ]\n    : rawSystem;\n\n  let maxTokens = options.maxTokens ?? 4096;\n  let thinking: Anthropic.ThinkingConfigParam | undefined;\n  let outputConfig: Record<string, unknown> | undefined;\n\n  if (options.thinking) {\n    const t = toAnthropicThinking(options.thinking, maxTokens, options.model);\n    thinking = t.thinking;\n    maxTokens = t.maxTokens;\n    if (t.outputConfig) {\n      outputConfig = t.outputConfig;\n    }\n  }\n\n  const params: Anthropic.MessageCreateParams = {\n    model: options.model,\n    max_tokens: maxTokens,\n    messages,\n    ...(system ? { system: system as Anthropic.MessageCreateParams[\"system\"] } : {}),\n    ...(thinking ? { thinking } : {}),\n    ...(outputConfig\n      ? { output_config: outputConfig as unknown as Anthropic.MessageCreateParams[\"output_config\"] }\n      : {}),\n    ...(options.temperature != null && !thinking ? { temperature: options.temperature } : {}),\n    ...(options.topP != null ? { top_p: options.topP } : {}),\n    ...(options.stop ? { stop_sequences: options.stop } : {}),\n    ...(options.tools?.length || options.serverTools?.length || options.webSearch\n      ? (() => {\n          // Build the tools array with server-side tools taking precedence over\n          // client tools that share their name. Anthropic rejects duplicate tool\n          // names with a 400, so when both a client `web_search` (from a non-\n          // anthropic provider's tool list left over after a /model switch) and\n          // the native server-side web_search are present, drop the client one.\n          const reservedServerNames = new Set<string>();\n          if (options.webSearch) reservedServerNames.add(\"web_search\");\n          for (const t of options.serverTools ?? []) {\n            const name = (t as { name?: string }).name;\n            if (name) reservedServerNames.add(name);\n          }\n          const clientTools = options.tools?.length\n            ? toAnthropicTools(\n                options.tools.filter((t) => !reservedServerNames.has(t.name)),\n                {\n                  ...(supportsFirstPartyToolExtras && cacheControl ? { cacheControl } : {}),\n                  ...(supportsFirstPartyToolExtras && fineGrainedToolStreamingEnabled()\n                    ? { enableFineGrainedToolStreaming: true }\n                    : {}),\n                },\n              )\n            : [];\n          return {\n            tools: [\n              ...clientTools,\n              ...(options.serverTools ?? []),\n              ...(options.webSearch ? [{ type: \"web_search_20250305\", name: \"web_search\" }] : []),\n            ] as Anthropic.MessageCreateParams[\"tools\"],\n          };\n        })()\n      : {}),\n    ...(options.toolChoice && options.tools?.length\n      ? { tool_choice: toAnthropicToolChoice(options.toolChoice) }\n      : {}),\n    ...(() => {\n      const contextEdits = [\n        ...(options.compaction ? [{ type: \"compact_20260112\" }] : []),\n        ...(options.clearToolUses ? [{ type: \"clear_tool_uses_20250919\" }] : []),\n      ];\n      return contextEdits.length ? { context_management: { edits: contextEdits } } : {};\n    })(),\n    stream: useStreaming,\n  } as Anthropic.MessageCreateParams;\n\n  // Adaptive thinking models (Opus 5, Opus 4.8/4.7/4.6, Sonnet 5, Fable 5)\n  // don't need the interleaved-thinking beta — they have it built in.\n  const hasAdaptiveThinking = isAdaptiveThinkingModel(options.model);\n\n  const betaHeaders = [\n    ...(isOAuth ? [\"claude-code-20250219\", \"oauth-2025-04-20\"] : []),\n    ...(options.compaction ? [\"compact-2026-01-12\"] : []),\n    ...(options.clearToolUses ? [\"context-management-2025-06-27\"] : []),\n    // Eager tool-input streaming beta — opt-in only (see\n    // fineGrainedToolStreamingEnabled). Off by default: the un-buffered stream\n    // truncates large tool payloads into malformed JSON → phantom empty calls.\n    ...(fineGrainedToolStreamingEnabled() ? [\"fine-grained-tool-streaming-2025-05-14\"] : []),\n    ...(!hasAdaptiveThinking ? [\"interleaved-thinking-2025-05-14\"] : []),\n    // The 1-h cache TTL (cacheRetention \"long\") is gated behind this beta. Without\n    // it Anthropic silently ignores ttl:\"1h\" and falls back to the 5-min default,\n    // so a pre-warmed cache expires before the user's first turn. cacheControl.ttl\n    // is only \"1h\" on the first-party endpoint (see toAnthropicCacheControl).\n    ...(cacheControl?.ttl === \"1h\" ? [\"extended-cache-ttl-2025-04-11\"] : []),\n  ];\n\n  const requestOptions = {\n    signal: options.signal ?? undefined,\n    ...(betaHeaders.length ? { headers: { \"anthropic-beta\": betaHeaders.join(\",\") } } : {}),\n  };\n\n  // Non-streaming fallback: issue a single request/response and synthesize\n  // stream events from the final Message. Used by the agent loop after the\n  // SSE stream has stalled repeatedly -- broken streaming connections often\n  // recover when the request is replayed over a plain HTTP response.\n  if (!useStreaming) {\n    try {\n      // withOptions() clones the client (sharing auth state) with an explicit\n      // timeout set, which suppresses the SDK's bogus \"Streaming is required…\"\n      // pre-flight throw for large max_tokens. See NON_STREAMING_REQUEST_TIMEOUT_MS.\n      const nonStreamingClient = client.withOptions({\n        timeout: NON_STREAMING_REQUEST_TIMEOUT_MS,\n      });\n      const message = (await nonStreamingClient.messages.create(\n        { ...params, stream: false } as Anthropic.MessageCreateParamsNonStreaming,\n        requestOptions,\n      )) as Anthropic.Message;\n      yield* synthesizeEventsFromMessage(message);\n      return messageToResponse(message);\n    } catch (err) {\n      throw toError(err);\n    }\n  }\n\n  // ── Accumulation state ──────────────────────────────────\n  const contentParts: ContentPart[] = [];\n\n  // Per-block accumulators indexed by content_block_start index\n  const blocks = new Map<\n    number,\n    {\n      type: string;\n      text: string;\n      thinking: string;\n      signature: string;\n      toolId: string;\n      toolName: string;\n      argsJson: string;\n      input: unknown;\n      raw: Record<string, unknown> | null;\n    }\n  >();\n\n  let inputTokens = 0;\n  let outputTokens = 0;\n  let cacheRead: number | undefined;\n  let cacheWrite: number | undefined;\n  let stopReason: string | null = null;\n\n  const keepalive = { type: \"keepalive\" as const };\n  let receivedAnyEvent = false;\n\n  try {\n    // Use the low-level streaming request instead of the SDK's `messages.stream()`\n    // helper. The helper starts its request immediately; if Anthropic rejects the\n    // request before our async iterator attaches listeners, its iterator can miss\n    // the already-emitted error/end event and wait forever. That surfaced as the\n    // CLI sitting on \"Working...\" when an OAuth account ran out of usage.\n    const stream = (await client.messages.create(\n      params as Anthropic.MessageCreateParamsStreaming,\n      requestOptions,\n    )) as AsyncIterable<Anthropic.MessageStreamEvent>;\n\n    for await (const event of stream) {\n      receivedAnyEvent = true;\n      switch (event.type) {\n        case \"message_start\": {\n          const usage = event.message.usage;\n          inputTokens = usage.input_tokens;\n          const usageAny = usage as unknown as Record<string, unknown>;\n          if (usageAny.cache_read_input_tokens != null) {\n            cacheRead = usageAny.cache_read_input_tokens as number;\n          }\n          if (usageAny.cache_creation_input_tokens != null) {\n            cacheWrite = usageAny.cache_creation_input_tokens as number;\n          }\n          yield keepalive;\n          break;\n        }\n\n        case \"content_block_start\": {\n          const block = event.content_block;\n          const idx = event.index;\n          const accum = {\n            type: block.type,\n            text: \"\",\n            thinking: \"\",\n            signature: \"\",\n            toolId: \"\",\n            toolName: \"\",\n            argsJson: \"\",\n            input: undefined as unknown,\n            raw: null as Record<string, unknown> | null,\n          };\n\n          if (block.type === \"tool_use\") {\n            accum.toolId = block.id;\n            accum.toolName = block.name;\n            accum.input = (block as unknown as { input?: unknown }).input;\n          } else if (block.type === \"server_tool_use\") {\n            accum.toolId = (block as unknown as { id: string }).id;\n            accum.toolName = (block as unknown as { name: string }).name;\n            accum.input = (block as unknown as { input: unknown }).input;\n          } else if (block.type !== \"text\" && block.type !== \"thinking\") {\n            // Preserve unknown/encrypted blocks from their start event. We no longer\n            // use the SDK MessageStream helper's `currentMessage` snapshot because\n            // it can miss early request errors and hang its iterator.\n            accum.raw = block as unknown as Record<string, unknown>;\n          }\n\n          blocks.set(idx, accum);\n          // Surface \"reasoning started\" as an empty thinking_delta the moment\n          // a thinking content block opens, so the UI flips to the thinking\n          // phase before the first delta with real content arrives.\n          if (block.type === \"thinking\") {\n            yield { type: \"thinking_delta\", text: \"\" };\n          } else {\n            yield keepalive;\n          }\n          break;\n        }\n\n        case \"content_block_delta\": {\n          const accum = blocks.get(event.index);\n          if (!accum) break;\n\n          const delta = event.delta as unknown as Record<string, unknown>;\n          const deltaType = delta.type as string;\n\n          if (deltaType === \"text_delta\") {\n            const text = delta.text as string;\n            accum.text += text;\n            yield { type: \"text_delta\", text };\n          } else if (deltaType === \"thinking_delta\") {\n            const text = delta.thinking as string;\n            accum.thinking += text;\n            yield { type: \"thinking_delta\", text };\n          } else if (deltaType === \"input_json_delta\") {\n            const partialJson = delta.partial_json as string;\n            accum.argsJson += partialJson;\n            yield {\n              type: \"toolcall_delta\",\n              id: accum.toolId,\n              name: accum.toolName,\n              argsJson: partialJson,\n            };\n          } else if (deltaType === \"signature_delta\") {\n            accum.signature = delta.signature as string;\n          }\n          break;\n        }\n\n        case \"content_block_stop\": {\n          const accum = blocks.get(event.index);\n          if (!accum) break;\n\n          if (accum.type === \"text\") {\n            contentParts.push({ type: \"text\", text: accum.text });\n          } else if (accum.type === \"thinking\") {\n            contentParts.push({\n              type: \"thinking\",\n              text: accum.thinking,\n              signature: accum.signature,\n            });\n            yield keepalive;\n          } else if (accum.type === \"tool_use\") {\n            let args: Record<string, unknown> = isJsonObject(accum.input) ? accum.input : {};\n            if (accum.argsJson) {\n              try {\n                const parsed = JSON.parse(accum.argsJson) as unknown;\n                args = isJsonObject(parsed) ? parsed : {};\n              } catch (parseErr) {\n                // The streamed tool-input JSON arrived truncated/malformed. Do\n                // NOT silently fall back to {} — that emits a phantom empty\n                // tool call (e.g. `edit` with no file_path/edits) which the\n                // tool layer rejects with \"Invalid arguments\" and the model\n                // then has to guess how to recover from. Instead surface it as\n                // a malformed-stream failure.\n                //\n                // Deliberately NO statusCode: a 5xx would make classifyOverload()\n                // treat this as a transient provider error and replay in the\n                // SAME streaming mode (which just re-truncates). Leaving it\n                // status-less keeps classifyOverload() null, so agent-loop falls\n                // through to isMalformedStream() — which walks the SyntaxError\n                // `cause` and routes the retry into the non-streaming fallback\n                // that returns the complete tool input.\n                // Keep the raw partial JSON on the error (bounded so a large\n                // truncated `edit` payload can't bloat logs) for debugging.\n                const rawPartial = accum.argsJson;\n                const snippet =\n                  rawPartial.length > 200 ? `${rawPartial.slice(0, 200)}\\u2026` : rawPartial;\n                throw new ProviderError(\n                  \"anthropic\",\n                  `Tool \"${accum.toolName}\" input JSON was truncated in the stream ` +\n                    `(${rawPartial.length} bytes): ${snippet}; ${(parseErr as Error).message}`,\n                  { cause: parseErr },\n                );\n              }\n            }\n            const tc: ToolCall = {\n              type: \"tool_call\",\n              id: accum.toolId,\n              name: accum.toolName,\n              args,\n            };\n            contentParts.push(tc);\n            yield {\n              type: \"toolcall_done\",\n              id: tc.id,\n              name: tc.name,\n              args: tc.args,\n            };\n          } else if (accum.type === \"server_tool_use\") {\n            // Server tools (e.g. native web_search) stream their input via\n            // input_json_delta the same way client tool_use does. The block-start\n            // `input` is empty `{}` and only the accumulated `argsJson` carries\n            // the real arguments (e.g. the search query). Prefer the parsed\n            // streamed JSON, falling back to the block-start input only when\n            // argsJson is absent/malformed -- otherwise the query is dropped and\n            // Anthropic rejects the call with `invalid_tool_input`.\n            let input: unknown = accum.input;\n            if (accum.argsJson) {\n              try {\n                input = JSON.parse(accum.argsJson);\n              } catch {\n                // malformed JSON -- keep the block-start input fallback\n              }\n            }\n            const stc: ServerToolCall = {\n              type: \"server_tool_call\",\n              id: accum.toolId,\n              name: accum.toolName,\n              input,\n            };\n            contentParts.push(stc);\n            yield {\n              type: \"server_toolcall\",\n              id: stc.id,\n              name: stc.name,\n              input: stc.input,\n            };\n          } else if (accum.type === \"redacted_thinking\" && accum.raw) {\n            contentParts.push({ type: \"raw\", data: accum.raw });\n            yield keepalive;\n          } else {\n            const rawBlock = accum.raw;\n            if (rawBlock) {\n              const blockType = rawBlock.type as string;\n              if (blockType === \"web_search_tool_result\") {\n                const str: ServerToolResult = {\n                  type: \"server_tool_result\",\n                  toolUseId: rawBlock.tool_use_id as string,\n                  resultType: blockType,\n                  data: rawBlock,\n                };\n                contentParts.push(str);\n                yield {\n                  type: \"server_toolresult\",\n                  toolUseId: str.toolUseId,\n                  resultType: str.resultType,\n                  data: str.data,\n                };\n              } else {\n                // Preserve unknown blocks (e.g. compaction) for round-tripping\n                contentParts.push({ type: \"raw\", data: rawBlock });\n              }\n            }\n          }\n\n          blocks.delete(event.index);\n          break;\n        }\n\n        case \"message_delta\": {\n          const delta = event.delta as unknown as Record<string, unknown>;\n          if (delta.stop_reason) {\n            stopReason = delta.stop_reason as string;\n          }\n          const usage = event.usage as unknown as Record<string, unknown> | undefined;\n          if (usage?.output_tokens != null) {\n            outputTokens = usage.output_tokens as number;\n          }\n          yield keepalive;\n          break;\n        }\n\n        // message_stop — loop exits naturally.\n        //\n        // Deliberately NOT breaking early here. Breaking makes the SDK iterator\n        // run `if (!done) controller.abort()` in its `finally`\n        // (core/streaming.js:97), which tears the connection down instead of\n        // returning it to the keep-alive pool — every turn would then pay a\n        // fresh TLS handshake. Draining to the end is what every other Anthropic\n        // client does, and the stall it guards against is handled by the agent\n        // loop's idle timeout.\n        default:\n          // Unhandled event types (e.g. \"ping\" heartbeats) — yield keepalive\n          // so the idle timer in the agent loop resets on any API activity.\n          yield keepalive;\n          break;\n      }\n    }\n  } catch (err) {\n    throw toError(err);\n  }\n\n  // Race-condition safety: if the SDK's stream ended (or error'd) before the\n  // first event was yielded, the loop exits silently with an empty response.\n  // Treat that as a transport failure so the agent loop retries instead of\n  // presenting a phantom empty reply.\n  if (!receivedAnyEvent) {\n    throw new ProviderError(\"anthropic\", \"Stream ended without producing any events.\", {\n      statusCode: 504,\n    });\n  }\n\n  // Silent-partial guard: a complete Anthropic stream always emits `message_delta`\n  // (carrying stop_reason) *before* `message_stop`. So consuming events but never\n  // seeing a stop_reason means the stream was truncated mid-flight — a clean TCP\n  // close with no terminal events. Without this guard, normalizeAnthropicStopReason\n  // maps the null stop into \"end_turn\", making a truncated turn indistinguishable\n  // from a finished one. Throw a 504 so the agent loop treats it as a retryable\n  // transport failure (same bucket as a mid-stream socket destroy). The partial\n  // body is surfaced on `cause` for debugging, never silently returned.\n  if (stopReason === null) {\n    throw new ProviderError(\"anthropic\", \"Stream ended before completion (no stop_reason).\", {\n      statusCode: 504,\n      cause: { partialContent: contentParts, outputTokens },\n    });\n  }\n\n  const normalizedStop = normalizeAnthropicStopReason(stopReason);\n\n  const response: StreamResponse = {\n    message: {\n      role: \"assistant\",\n      content: contentParts.length > 0 ? contentParts : \"\",\n    },\n    stopReason: normalizedStop,\n    usage: {\n      inputTokens,\n      outputTokens,\n      ...(cacheRead != null && { cacheRead }),\n      ...(cacheWrite != null && { cacheWrite }),\n    },\n  };\n\n  yield { type: \"done\", stopReason: normalizedStop };\n  return response;\n}\n\n/**\n * Walk a non-streaming Anthropic Message and yield the same StreamEvents\n * that the streaming path would produce. Emits one large delta per block\n * rather than token-by-token -- the agent loop consumer doesn't care about\n * granularity, only completeness.\n */\nfunction* synthesizeEventsFromMessage(message: Anthropic.Message): Generator<StreamEvent, void> {\n  for (const block of message.content) {\n    const blk = block as unknown as Record<string, unknown>;\n    const type = blk.type as string;\n\n    if (type === \"text\") {\n      const text = blk.text as string;\n      if (text) yield { type: \"text_delta\", text };\n    } else if (type === \"thinking\") {\n      const text = blk.thinking as string;\n      if (text) yield { type: \"thinking_delta\", text };\n    } else if (type === \"tool_use\") {\n      const argsJson = JSON.stringify(blk.input ?? {});\n      yield {\n        type: \"toolcall_delta\",\n        id: blk.id as string,\n        name: blk.name as string,\n        argsJson,\n      };\n      yield {\n        type: \"toolcall_done\",\n        id: blk.id as string,\n        name: blk.name as string,\n        args: (blk.input as Record<string, unknown> | undefined) ?? {},\n      };\n    } else if (type === \"server_tool_use\") {\n      yield {\n        type: \"server_toolcall\",\n        id: blk.id as string,\n        name: blk.name as string,\n        input: blk.input,\n      };\n    } else if (type === \"web_search_tool_result\") {\n      yield {\n        type: \"server_toolresult\",\n        toolUseId: blk.tool_use_id as string,\n        resultType: type,\n        data: blk,\n      };\n    }\n    // Other block types (redacted_thinking, compaction blocks) are preserved\n    // in the response via messageToResponse but don't emit events.\n  }\n  yield { type: \"done\", stopReason: normalizeAnthropicStopReason(message.stop_reason) };\n}\n\n/** Convert a non-streaming Anthropic Message into our StreamResponse shape. */\nfunction messageToResponse(message: Anthropic.Message): StreamResponse {\n  const contentParts: ContentPart[] = [];\n  for (const block of message.content) {\n    const blk = block as unknown as Record<string, unknown>;\n    const type = blk.type as string;\n\n    if (type === \"text\") {\n      contentParts.push({ type: \"text\", text: blk.text as string });\n    } else if (type === \"thinking\") {\n      contentParts.push({\n        type: \"thinking\",\n        text: blk.thinking as string,\n        signature: (blk.signature as string) ?? \"\",\n      });\n    } else if (type === \"tool_use\") {\n      contentParts.push({\n        type: \"tool_call\",\n        id: blk.id as string,\n        name: blk.name as string,\n        args: (blk.input as Record<string, unknown> | undefined) ?? {},\n      });\n    } else if (type === \"server_tool_use\") {\n      contentParts.push({\n        type: \"server_tool_call\",\n        id: blk.id as string,\n        name: blk.name as string,\n        input: blk.input,\n      });\n    } else if (type === \"web_search_tool_result\") {\n      contentParts.push({\n        type: \"server_tool_result\",\n        toolUseId: blk.tool_use_id as string,\n        resultType: type,\n        data: blk,\n      });\n    } else {\n      // Preserve unknown blocks (redacted_thinking, compaction) for round-tripping\n      contentParts.push({ type: \"raw\", data: blk });\n    }\n  }\n\n  const usage = message.usage as unknown as Record<string, unknown>;\n  const inputTokens = (usage.input_tokens as number) ?? 0;\n  const outputTokens = (usage.output_tokens as number) ?? 0;\n  const cacheRead = usage.cache_read_input_tokens as number | undefined;\n  const cacheWrite = usage.cache_creation_input_tokens as number | undefined;\n\n  return {\n    message: {\n      role: \"assistant\",\n      content: contentParts.length > 0 ? contentParts : \"\",\n    },\n    stopReason: normalizeAnthropicStopReason(message.stop_reason),\n    usage: {\n      inputTokens,\n      outputTokens,\n      ...(cacheRead != null && { cacheRead }),\n      ...(cacheWrite != null && { cacheWrite }),\n    },\n  };\n}\n\n/**\n * Read Anthropic's unified rate-limit headers — the subscription (OAuth) quota\n * signal. `anthropic-ratelimit-unified-status: rejected` means the usage window\n * is spent (not a transient per-minute throttle); `-reset` is the unix-seconds\n * reset time. Works against a web `Headers` object or a plain header record.\n */\nfunction readUnifiedRateLimit(headers: unknown): { rejected: boolean; resetsAt?: number } {\n  const status = readHeader(headers, \"anthropic-ratelimit-unified-status\");\n  const resetRaw = readHeader(\n    headers,\n    \"anthropic-ratelimit-unified-reset\",\n    \"anthropic-ratelimit-unified-5h-reset\",\n    \"anthropic-ratelimit-unified-7d-reset\",\n  );\n  const resetNum = resetRaw != null ? Number(resetRaw) : Number.NaN;\n  const resetsAt = Number.isFinite(resetNum) && resetNum > 0 ? resetNum : undefined;\n  return { rejected: status === \"rejected\", ...(resetsAt ? { resetsAt } : {}) };\n}\n\nfunction toError(err: unknown): ProviderError {\n  // Already normalized (e.g. the truncated-tool-JSON guard in runStream throws a\n  // ProviderError whose cause is the SyntaxError). Pass it through untouched so\n  // its statusCode and cause chain survive for agent-loop's retry classifiers\n  // (isMalformedStream walks one level of `.cause`).\n  if (err instanceof ProviderError) return err;\n  if (err instanceof Anthropic.APIError) {\n    // Anthropic exposes request IDs as `requestID` in current SDKs, `request_id`\n    // in older/compat shapes, and sometimes inside the streamed error body.\n    const errorBody = err.error as Record<string, unknown> | undefined;\n    const nestedError = errorBody?.error as Record<string, unknown> | undefined;\n    const requestId =\n      (err as unknown as { requestID?: string | null }).requestID ??\n      (err as unknown as { request_id?: string | null }).request_id ??\n      (typeof errorBody?.request_id === \"string\" ? errorBody.request_id : undefined) ??\n      (typeof nestedError?.request_id === \"string\" ? nestedError.request_id : undefined) ??\n      undefined;\n    // Guard against an empty-string message (e.g. MiniMax's Anthropic-transport\n    // path returning `{ message: \"\" }`) counting as \"usable\" — that would win\n    // over the raw-JSON-echo fallback below and surface a blank error instead.\n    const bodyMessage =\n      typeof nestedError?.message === \"string\" && nestedError.message.trim()\n        ? nestedError.message.trim()\n        : typeof errorBody?.message === \"string\" && errorBody.message.trim()\n          ? errorBody.message.trim()\n          : undefined;\n    const bodyType =\n      typeof nestedError?.type === \"string\"\n        ? nestedError.type\n        : typeof errorBody?.type === \"string\"\n          ? errorBody.type\n          : typeof (err as unknown as { type?: unknown }).type === \"string\"\n            ? ((err as unknown as { type: string }).type as string)\n            : undefined;\n    // The SDK may expose raw JSON or a whole HTML edge/proxy page through either\n    // the parsed body or err.message. Preserve the original on `cause`, but never\n    // send transport markup to the user.\n    const fallbackMessage = isRawJsonErrorEcho(err.message)\n      ? emptyProviderErrorMessage(err.status)\n      : err.message;\n    const messageCandidate = bodyMessage ?? err.message;\n    const message = isRawHtmlErrorEcho(messageCandidate)\n      ? providerHtmlErrorMessage(err.status)\n      : bodyType && bodyMessage\n        ? `${bodyType}: ${bodyMessage}`\n        : (bodyMessage ?? fallbackMessage);\n\n    // Subscription (OAuth) usage-window exhaustion. Anthropic returns 429 with\n    // the unified rate-limit headers; a \"rejected\" status — or a reset stamp\n    // meaningfully in the future — means the plan's usage is spent, not a\n    // transient per-minute throttle. Stamp a canonical message so downstream\n    // retry logic stops instead of burning minutes retrying.\n    if (err.status === 429) {\n      const limit = readUnifiedRateLimit(err.headers);\n      const farOff = limit.resetsAt != null && limit.resetsAt * 1000 - Date.now() > 60_000;\n      if (limit.rejected || farOff) {\n        return new ProviderError(\"anthropic\", \"Claude usage limit reached\", {\n          statusCode: 429,\n          ...(requestId ? { requestId } : {}),\n          ...(limit.resetsAt ? { resetsAt: limit.resetsAt } : {}),\n          cause: err,\n        });\n      }\n    }\n\n    // Hard billing/quota stop, regardless of status code. MiniMax (Anthropic\n    // transport) returns these as HTTP 500 `api_error` \"insufficient balance\";\n    // the Anthropic API key path returns a 400 \"credit balance is too low\".\n    // Both would otherwise be treated as transient and retried — stamp the\n    // canonical \"usage limit reached\" token so the loop surfaces it once.\n    if (isHardBillingMessage(message)) {\n      const usageMessage = /usage limit reached/i.test(message)\n        ? message\n        : `usage limit reached: ${message}`;\n      return new ProviderError(\"anthropic\", usageMessage, {\n        statusCode: err.status,\n        ...(requestId ? { requestId } : {}),\n        cause: err,\n      });\n    }\n\n    return new ProviderError(\"anthropic\", message, {\n      statusCode: err.status,\n      ...(requestId ? { requestId } : {}),\n      cause: err,\n    });\n  }\n  if (err instanceof Error) {\n    return new ProviderError(\"anthropic\", err.message, { cause: err });\n  }\n  return new ProviderError(\"anthropic\", String(err));\n}\n","import type { StreamEvent, StreamResponse } from \"../types.js\";\n\n/**\n * Push-based async iterable. Producers push events, consumers\n * iterate with `for await`. Also supports thenable so you can\n * `await stream(...)` directly to get the final response.\n */\nexport class EventStream<T = StreamEvent> implements AsyncIterable<T> {\n  private queue: T[] = [];\n  private resolve: (() => void) | null = null;\n  private done = false;\n  private error: Error | null = null;\n\n  push(event: T): void {\n    // Safety valve: if queue grows beyond 10k unconsumed events, drop oldest\n    // to prevent OOM when consumer is blocked/slow\n    if (this.queue.length > 10_000) {\n      this.queue.splice(0, this.queue.length - 5_000);\n    }\n    this.queue.push(event);\n    this.resolve?.();\n    this.resolve = null;\n  }\n\n  close(): void {\n    this.done = true;\n    this.resolve?.();\n    this.resolve = null;\n  }\n\n  abort(error: Error): void {\n    this.error = error;\n    this.done = true;\n    this.resolve?.();\n    this.resolve = null;\n  }\n\n  async *[Symbol.asyncIterator](): AsyncIterator<T> {\n    let index = 0;\n    while (true) {\n      while (index < this.queue.length) {\n        yield this.queue[index++]!;\n      }\n      // Reset to avoid holding references to already-yielded events\n      this.queue.splice(0, index);\n      index = 0;\n      if (this.error) throw this.error;\n      if (this.done) return;\n      await new Promise<void>((r) => {\n        this.resolve = r;\n      });\n    }\n  }\n}\n\n/**\n * Pull-based stream result. Wraps an async generator that yields\n * StreamEvents and returns a StreamResponse. Also thenable so:\n *\n *   const msg = await stream({...})          // awaits response\n *   for await (const e of stream({...})) {}  // iterates events\n *\n * The generator is pumped eagerly — events flow into an internal\n * buffer regardless of whether a consumer is iterating. This avoids\n * the push-based EventStream's stall bugs (lost wakeups, single\n * resolve field, iterator starvation).\n */\nexport class StreamResult implements AsyncIterable<StreamEvent> {\n  readonly response: Promise<StreamResponse>;\n  private buffer: StreamEvent[] = [];\n  private done = false;\n  private error: Error | null = null;\n  private resolveResponse!: (r: StreamResponse) => void;\n  private rejectResponse!: (e: Error) => void;\n  private resolveWait: (() => void) | null = null;\n  /**\n   * High-water mark: when the buffer exceeds this many unconsumed events,\n   * the pump pauses until the consumer drains below the low-water mark.\n   * Prevents unbounded memory growth when a consumer is slow.\n   * Only active when someone IS iterating — if nobody iterates (the `then()`\n   * path), backpressure is skipped so the pump can complete and resolve.\n   */\n  private static readonly HIGH_WATER = 5_000;\n  private static readonly LOW_WATER = 1_000;\n  private iterating = false;\n  private paused = false;\n  private resolveDrain: (() => void) | null = null;\n\n  constructor(generator: AsyncGenerator<StreamEvent, StreamResponse>, signal?: AbortSignal) {\n    this.response = new Promise<StreamResponse>((resolve, reject) => {\n      this.resolveResponse = resolve;\n      this.rejectResponse = reject;\n    });\n    this.pump(generator, signal);\n  }\n\n  private async pump(\n    generator: AsyncGenerator<StreamEvent, StreamResponse>,\n    signal?: AbortSignal,\n  ): Promise<void> {\n    try {\n      let next = await this._nextWithAbort(generator, signal);\n      while (!next.done) {\n        this.buffer.push(next.value);\n        this.resolveWait?.();\n        this.resolveWait = null;\n\n        // Backpressure: only apply when a consumer IS iterating but falling\n        // behind. If nobody is iterating (the `await stream()` without\n        // `for await` path), skip backpressure so the pump completes and the\n        // response promise resolves.\n        if (this.iterating && this.buffer.length > StreamResult.HIGH_WATER) {\n          this.paused = true;\n          await new Promise<void>((r) => {\n            this.resolveDrain = r;\n          });\n          this.paused = false;\n        }\n\n        next = await this._nextWithAbort(generator, signal);\n      }\n      this.done = true;\n      this.resolveResponse(next.value);\n      this.resolveWait?.();\n      this.resolveWait = null;\n    } catch (err) {\n      const error = err instanceof Error ? err : new Error(String(err));\n      this.error = error;\n      this.done = true;\n      this.rejectResponse(error);\n      this.resolveWait?.();\n      this.resolveWait = null;\n    }\n  }\n\n  private async _nextWithAbort(\n    generator: AsyncGenerator<StreamEvent, StreamResponse>,\n    signal?: AbortSignal,\n  ): Promise<IteratorResult<StreamEvent, StreamResponse>> {\n    if (!signal) {\n      return generator.next();\n    }\n    if (signal.aborted) {\n      return Promise.reject(new DOMException(\"Aborted\", \"AbortError\"));\n    }\n    let onAbort: (() => void) | undefined;\n    const abortPromise = new Promise<IteratorResult<StreamEvent, StreamResponse>>((_, reject) => {\n      onAbort = () => {\n        generator.return?.(undefined as unknown as StreamResponse).catch(() => {});\n        reject(new DOMException(\"Aborted\", \"AbortError\"));\n      };\n      signal.addEventListener(\"abort\", onAbort, { once: true });\n    });\n    try {\n      return await Promise.race([generator.next(), abortPromise]);\n    } finally {\n      if (onAbort) signal.removeEventListener(\"abort\", onAbort);\n    }\n  }\n\n  async *[Symbol.asyncIterator](): AsyncIterator<StreamEvent> {\n    this.iterating = true;\n    let index = 0;\n    while (true) {\n      while (index < this.buffer.length) {\n        yield this.buffer[index++]!;\n      }\n      // If the pump is paused waiting for us to drain, signal it.\n      if (this.paused && index > StreamResult.LOW_WATER) {\n        this.resolveDrain?.();\n        this.resolveDrain = null;\n      }\n      // Trim already-yielded events to free memory (they're consumed).\n      if (index > 0 && !this.paused) {\n        this.buffer.splice(0, index);\n        index = 0;\n      }\n      if (this.error) throw this.error;\n      if (this.done) return;\n      await new Promise<void>((r) => {\n        this.resolveWait = r;\n        // Guard against race: pump may have advanced between the while-check\n        // and this promise registration. Re-check and resolve immediately.\n        if (this.buffer.length > index || this.done || this.error) {\n          this.resolveWait = null;\n          r();\n        }\n      });\n    }\n  }\n\n  then<TResult1 = StreamResponse, TResult2 = never>(\n    onfulfilled?: ((value: StreamResponse) => TResult1 | PromiseLike<TResult1>) | null,\n    onrejected?: ((reason: unknown) => TResult2 | PromiseLike<TResult2>) | null,\n  ): Promise<TResult1 | TResult2> {\n    // Release backpressure: if someone calls then(), they want the response\n    // resolved ASAP. Clear any pending pause so the pump can complete.\n    if (this.paused) {\n      this.paused = false;\n      this.resolveDrain?.();\n      this.resolveDrain = null;\n    }\n    return this.response.then(onfulfilled, onrejected);\n  }\n}\n","import { z } from \"zod\";\nimport type { Tool } from \"../types.js\";\n\n/**\n * Converts a Zod schema to a JSON Schema object suitable for provider tool\n * parameter definitions.\n *\n * Anthropic's `input_schema` validator is strict in two ways:\n *\n *   1. The root must be `type: \"object\"`. Returns 400 with\n *      `tools.N.custom.input_schema.type: Field required` otherwise.\n *\n *   2. The root must NOT contain `oneOf`, `anyOf`, or `allOf`. Returns 400 with\n *      `input_schema does not support oneOf, allOf, or anyOf at the top level`.\n *\n * Both rules trip whenever a tool's parameters are defined via\n * `z.discriminatedUnion(...)` or `z.union(...)` — Zod 4's\n * `z.toJSONSchema` emits `{oneOf: [...]}` at the root with no `type`.\n *\n * The fix is to collapse the union into a single flat object schema:\n *\n *   - properties = union of all branch properties (later branches win on\n *     conflict; that's fine because the model only uses these for hints —\n *     Zod's actual `tool.parameters.parse(args)` is the real validator)\n *   - required = intersection of branch `required` arrays (a field is only\n *     required if EVERY branch requires it)\n *   - if the union has a discriminator field (every branch has the same\n *     property as a `const`), we replace the discriminator's per-branch\n *     `const` with an `enum` listing every literal — the model gets a clear\n *     hint of the valid action values without needing oneOf\n *\n * The flattening is lossy for *schema-level* constraints (e.g. \"if action=X,\n * then field Y is required\") — Zod still enforces those at parse time. For\n * the model's purposes this is identical to a single object with optional\n * fields and a discriminator enum, which is exactly how Anthropic-supported\n * tools are typically authored anyway.\n */\n\ntype JsonSchema = Record<string, unknown>;\n\n/**\n * Memoize the Zod → JSON Schema conversion. Tool schemas are immutable within\n * a session, but `toAnthropicTools` / `toOpenAITools` call this on every turn.\n * For ~15-20 tools with complex nested schemas, `z.toJSONSchema` can take\n * 5-20ms total per turn — pure wasted CPU on an unchanged schema.\n * Keyed by the Zod schema object identity (WeakMap so schemas can GC).\n */\nconst schemaCache = new WeakMap<z.ZodType, JsonSchema>();\n\nexport function zodToJsonSchema(schema: z.ZodType): JsonSchema {\n  const cached = schemaCache.get(schema);\n  if (cached) return cached;\n  const jsonSchema = z.toJSONSchema(schema) as JsonSchema;\n  const { $schema: _schema, ...rest } = jsonSchema;\n  const normalized = normalizeRootForAnthropic(rest);\n  schemaCache.set(schema, normalized);\n  return normalized;\n}\n\n/**\n * Resolve a tool's JSON Schema for provider tool definitions: prefer the\n * tool's pre-built `rawInputSchema`, otherwise convert its Zod `parameters`.\n */\nexport function resolveToolSchema(tool: Tool): JsonSchema {\n  return tool.rawInputSchema ?? zodToJsonSchema(tool.parameters);\n}\n\n/**\n * Recursively flatten a root discriminated/plain union into a single object\n * schema. Only operates at the ROOT — nested unions inside properties are\n * left intact (Anthropic accepts those just fine; only the top-level\n * input_schema is restricted).\n */\nfunction normalizeRootForAnthropic(schema: JsonSchema): JsonSchema {\n  const branches = (schema.oneOf ?? schema.anyOf) as JsonSchema[] | undefined;\n  if (!branches || branches.length === 0) {\n    // Already an object root or a primitive — Anthropic only sees object\n    // params, so primitive roots will fail elsewhere; that's not our bug.\n    return schema;\n  }\n\n  // All branches must be object schemas to flatten. If any isn't, fall\n  // back to wrapping with type:\"object\" — better than failing outright.\n  const allObjects = branches.every((b) => b.type === \"object\");\n  if (!allObjects) {\n    return { type: \"object\", ...schema };\n  }\n\n  const mergedProps: Record<string, JsonSchema> = {};\n  const requiredCounts: Record<string, number> = {};\n  const enumCandidate: Record<string, Set<string | number | boolean>> = {};\n  const everyBranchHas: Record<string, number> = {};\n\n  for (const branch of branches) {\n    const props = (branch.properties ?? {}) as Record<string, JsonSchema>;\n    const required = (branch.required ?? []) as string[];\n\n    for (const [key, prop] of Object.entries(props)) {\n      everyBranchHas[key] = (everyBranchHas[key] ?? 0) + 1;\n      // Last-wins merge — fine, since these are model hints only.\n      mergedProps[key] = { ...mergedProps[key], ...prop };\n\n      // Track const candidates for discriminator collapse.\n      if (prop && typeof prop === \"object\" && \"const\" in prop) {\n        const v = prop.const as string | number | boolean;\n        enumCandidate[key] = enumCandidate[key] ?? new Set();\n        enumCandidate[key].add(v);\n      }\n    }\n    for (const r of required) {\n      requiredCounts[r] = (requiredCounts[r] ?? 0) + 1;\n    }\n  }\n\n  // For any property where every branch had a `const` of the same primitive\n  // type, replace that property's `const` with an `enum` listing all\n  // observed literals. This is the discriminator collapse.\n  for (const [key, values] of Object.entries(enumCandidate)) {\n    if (everyBranchHas[key] === branches.length && values.size > 1) {\n      const list = [...values];\n      // Drop `const` (mutually exclusive with enum), keep type from one branch.\n      const { const: _const, ...rest } = mergedProps[key];\n      mergedProps[key] = { ...rest, enum: list };\n    }\n  }\n\n  // A field is required only if EVERY branch lists it as required.\n  const required = Object.entries(requiredCounts)\n    .filter(([, count]) => count === branches.length)\n    .map(([key]) => key);\n\n  // Pull through any non-conflicting metadata from the union root\n  // (description, title, etc.) — drop oneOf/anyOf/allOf themselves.\n  const {\n    oneOf: _o,\n    anyOf: _a,\n    allOf: _all,\n    type: _t,\n    properties: _p,\n    required: _r,\n    ...meta\n  } = schema;\n\n  const out: JsonSchema = {\n    ...meta,\n    type: \"object\",\n    properties: mergedProps,\n  };\n  if (required.length > 0) out.required = required;\n  return out;\n}\n","/**\n * OpenAI-compatible endpoints disagree on what to call the reasoning field.\n * DeepSeek, GLM, Moonshot and Xiaomi use `reasoning_content`; newer vLLM builds\n * and several gateways use `reasoning`. Reading only one name loses 100% of the\n * thinking content on the others — silently, since the turn still succeeds.\n *\n * Order matters: `reasoning_content` stays first so every endpoint we ship today\n * behaves byte-identically.\n */\nexport const REASONING_FIELD_ALIASES = [\n  \"reasoning_content\",\n  \"reasoning\",\n  \"reasoning_text\",\n] as const;\n\nexport const DEFAULT_REASONING_FIELD = REASONING_FIELD_ALIASES[0];\n\n/** Read the first reasoning alias present as a non-empty string. */\nexport function readReasoning(\n  obj: Record<string, unknown> | undefined | null,\n): { field: string; text: string } | undefined {\n  if (!obj) return undefined;\n  for (const field of REASONING_FIELD_ALIASES) {\n    const value = obj[field];\n    if (typeof value === \"string\" && value) return { field, text: value };\n  }\n  return undefined;\n}\n\n/** Stable cache key for one endpoint (provider + base URL + model). */\nexport function reasoningFieldKey(\n  provider: string,\n  baseUrl: string | undefined,\n  model: string,\n): string {\n  return `${provider}|${baseUrl ?? \"\"}|${model}`;\n}\n\n/** Bounded so a long-lived sidecar can't grow it without limit. */\nconst MAX_REMEMBERED_ENDPOINTS = 64;\nconst detectedFields = new Map<string, string>();\n\nexport function rememberReasoningField(key: string, field: string): void {\n  if (detectedFields.get(key) === field) return;\n  detectedFields.set(key, field);\n  while (detectedFields.size > MAX_REMEMBERED_ENDPOINTS) {\n    const oldest = detectedFields.keys().next();\n    if (oldest.done) break;\n    detectedFields.delete(oldest.value);\n  }\n}\n\n/**\n * The field this endpoint was last seen using. Falls back to\n * `reasoning_content` — a first turn has no history to echo back, so there is\n * no ordering hazard in defaulting.\n */\nexport function getReasoningField(key: string): string {\n  return detectedFields.get(key) ?? DEFAULT_REASONING_FIELD;\n}\n\n/** Test-only: drop all remembered endpoints. */\nexport function resetReasoningFieldCache(): void {\n  detectedFields.clear();\n}\n","import type Anthropic from \"@anthropic-ai/sdk\";\nimport type OpenAI from \"openai\";\nimport type {\n  CacheRetention,\n  ContentPart,\n  ImageContent,\n  Message,\n  Provider,\n  StopReason,\n  TextContent,\n  ThinkingContent,\n  ThinkingLevel,\n  VideoContent,\n  Tool,\n  ToolChoice,\n  ToolResultContent,\n} from \"../types.js\";\nimport { resolveToolSchema, zodToJsonSchema } from \"../utils/zod-to-json-schema.js\";\nimport { DEFAULT_REASONING_FIELD } from \"./reasoning-field.js\";\n\n// ── Shared helpers ─────────────────────────────────────────\n\n/**\n * A thinking block is only safe to round-trip to Anthropic as a real `thinking`\n * block when it carries a genuinely non-empty signature. Empty or whitespace-\n * only signatures (e.g. from an interrupted stream that never received its\n * `signature_delta`, or from non-Anthropic providers) would be rejected with\n * \"thinking ... blocks cannot be modified\", so they are downgraded to text.\n */\nfunction hasValidThinkingSignature(part: ThinkingContent): boolean {\n  return typeof part.signature === \"string\" && part.signature.trim().length > 0;\n}\n\n/** True for `raw` parts that wrap a thinking / redacted_thinking wire block. */\nfunction isRawThinking(part: ContentPart): boolean {\n  if (part.type !== \"raw\") return false;\n  const t = part.data.type;\n  return t === \"thinking\" || t === \"redacted_thinking\";\n}\n\n/**\n * Content block `type`s Anthropic accepts as message input. A `raw` part can\n * originate from another provider (e.g. the OpenAI Codex provider round-trips its\n * encrypted reasoning item as `{ type: \"raw\", data: { type: \"reasoning\", … } }`).\n * Switching such a session to an Anthropic model would otherwise forward that\n * foreign block verbatim and Anthropic rejects it (\"Input tag 'reasoning' … does\n * not match any of the expected tags\"). Raw blocks whose wire type isn't in this\n * set are dropped on the way out.\n */\nconst ANTHROPIC_INPUT_BLOCK_TYPES = new Set<string>([\n  \"bash_code_execution_tool_result\",\n  \"code_execution_tool_result\",\n  \"connector_text\",\n  \"container_upload\",\n  \"document\",\n  \"image\",\n  \"mid_conv_system\",\n  \"redacted_thinking\",\n  \"search_result\",\n  \"server_tool_use\",\n  \"text\",\n  \"text_editor_code_execution_tool_result\",\n  \"thinking\",\n  \"tool_result\",\n  \"tool_search_tool_result\",\n  \"tool_use\",\n  \"web_fetch_tool_result\",\n  \"web_search_tool_result\",\n]);\n\n/** True for a `raw` part Anthropic will accept as an input content block. */\nfunction isAnthropicCompatibleRaw(part: Extract<ContentPart, { type: \"raw\" }>): boolean {\n  return ANTHROPIC_INPUT_BLOCK_TYPES.has(part.data.type as string);\n}\n\n/**\n * True for content parts that Anthropic treats as position-sensitive reasoning\n * blocks in the latest assistant message: SIGNED `thinking` blocks and\n * `redacted_thinking` blocks (round-tripped as opaque `raw`). Unsigned thinking\n * (e.g. from GLM/OpenAI or an aborted stream) is excluded — it is converted to a\n * text block on the way out, so it carries no signature for Anthropic to validate\n * and imposes no positional constraint.\n */\nfunction isPositionSensitiveThinking(part: ContentPart): boolean {\n  if (part.type === \"thinking\") return hasValidThinkingSignature(part);\n  return isRawThinking(part);\n}\n\n/** Map a single assistant content part to its Anthropic wire block (or null to drop). */\nfunction toAnthropicAssistantPart(\n  part: ContentPart,\n  idMap: Map<string, string>,\n): Anthropic.ContentBlockParam | null {\n  if (part.type === \"text\") return { type: \"text\", text: part.text };\n  if (part.type === \"thinking\") {\n    // Signed thinking round-trips verbatim. Unsigned/invalid-signature thinking\n    // (GLM/OpenAI, or an aborted Anthropic stream) has nothing for Anthropic to\n    // validate and would be rejected as a thinking block, so preserve its\n    // reasoning as a text block instead of discarding it.\n    const sig = part.signature;\n    return sig && sig.trim().length > 0\n      ? { type: \"thinking\", thinking: part.text, signature: sig }\n      : { type: \"text\", text: part.text };\n  }\n  if (part.type === \"tool_call\")\n    return {\n      type: \"tool_use\",\n      id: remapAnthropicToolCallId(part.id, idMap),\n      name: part.name,\n      input: part.args,\n    };\n  if (part.type === \"server_tool_call\")\n    return {\n      type: \"server_tool_use\",\n      id: part.id,\n      name: part.name,\n      input: part.input,\n    } as unknown as Anthropic.ContentBlockParam;\n  if (part.type === \"server_tool_result\")\n    return part.data as unknown as Anthropic.ContentBlockParam;\n  if (part.type === \"raw\")\n    return isAnthropicCompatibleRaw(part)\n      ? (part.data as unknown as Anthropic.ContentBlockParam)\n      : null;\n  // Unknown content type (e.g. image in assistant message) — drop it.\n  return null;\n}\n\n/**\n * Build an assistant message's Anthropic content blocks.\n *\n * Anthropic requires thinking blocks to be preserved for the duration of the\n * ACTIVE trajectory — every assistant turn from the last real user message\n * forward (a multi-step tool loop has no user message between steps, so each\n * read/grep/edit turn is part of the same trajectory). The cookbook is explicit:\n * a final assistant message must start with a thinking block preceding the\n * lastmost tool_use/tool_result set, and previous-turn thinking should be kept.\n * Stripping reasoning from earlier in-trajectory turns leaves the model with a\n * bare tool_use → result chain and no reasoning anchor, which can degenerate the\n * next turn's leading token.\n *\n * For SETTLED turns (before the last user message), keeping signed thinking just\n * makes history fragile — any later edit, compaction, or reorder invalidates the\n * signature and triggers \"thinking ... blocks cannot be modified\". So thinking\n * and redacted_thinking are stripped there (tool_use and text survive). Within\n * the active trajectory they are preserved byte-identical (signed) or downgraded\n * to text (unsigned).\n */\nfunction toAnthropicAssistantContent(\n  content: ContentPart[],\n  preserveThinking: boolean,\n  idMap: Map<string, string>,\n): Anthropic.ContentBlockParam[] {\n  if (!preserveThinking) {\n    return content\n      .filter((part) => {\n        if (part.type === \"thinking\" || isRawThinking(part)) return false;\n        // Anthropic rejects empty text content blocks.\n        if (part.type === \"text\" && !part.text) return false;\n        return true;\n      })\n      .map((part) => toAnthropicAssistantPart(part, idMap))\n      .filter((b): b is Anthropic.ContentBlockParam => b !== null);\n  }\n\n  // Active-trajectory assistant turn: thinking/redacted_thinking blocks are byte-identical\n  // AND position-sensitive (interleaved-thinking-2025-05-14). Dropping a block\n  // that PRECEDES a thinking block shifts that block's index, which the API\n  // rejects, so empty text blocks before the last thinking block are kept;\n  // empty text after it can be dropped safely.\n  const lastThinkingIdx = content.reduce(\n    (last, part, idx) => (isPositionSensitiveThinking(part) ? idx : last),\n    -1 as number,\n  );\n  return content\n    .filter((part, idx) => {\n      // Drop empty, signature-less thinking blocks — nothing to preserve.\n      if (part.type === \"thinking\" && !hasValidThinkingSignature(part) && !part.text) return false;\n      if (part.type === \"text\" && !part.text && idx > lastThinkingIdx) return false;\n      return true;\n    })\n    .map((part) => toAnthropicAssistantPart(part, idMap))\n    .filter((b): b is Anthropic.ContentBlockParam => b !== null);\n}\n\nconst PROVIDER_IMAGE_LIMIT_PLACEHOLDER = \"[image omitted: provider image limit]\";\n\nconst PROVIDER_IMAGE_BUDGETS: Partial<Record<Provider, number>> = {\n  anthropic: 90,\n  minimax: 90,\n  openai: 200,\n  gemini: 200,\n  openrouter: 90,\n};\n\nfunction countContextImages(messages: Message[]): number {\n  let count = 0;\n  for (const message of messages) {\n    if (message.role === \"user\" && Array.isArray(message.content)) {\n      count += message.content.filter((part) => part.type === \"image\").length;\n    } else if (message.role === \"tool\") {\n      for (const result of message.content) {\n        if (Array.isArray(result.content)) {\n          count += result.content.filter((part) => part.type === \"image\").length;\n        }\n      }\n    }\n  }\n  return count;\n}\n\n/**\n * Cap historical images before provider dispatch, removing the oldest first.\n * The persisted/live conversation is never mutated; only modified messages and\n * tool results are cloned for the outgoing request.\n */\nexport function clampProviderContextImages(\n  messages: Message[],\n  provider: Provider,\n  supportsImages: boolean | undefined,\n): Message[] {\n  if (supportsImages === false) return messages;\n  const budget = PROVIDER_IMAGE_BUDGETS[provider] ?? 5;\n  let remainingToRemove = countContextImages(messages) - budget;\n  if (remainingToRemove <= 0) return messages;\n\n  return messages.map((message): Message => {\n    if (message.role === \"user\" && Array.isArray(message.content)) {\n      const content = message.content.filter((part) => {\n        if (part.type !== \"image\" || remainingToRemove <= 0) return true;\n        remainingToRemove--;\n        return false;\n      });\n      return {\n        ...message,\n        content:\n          content.length > 0\n            ? content\n            : [{ type: \"text\" as const, text: PROVIDER_IMAGE_LIMIT_PLACEHOLDER }],\n      };\n    }\n    if (message.role === \"tool\") {\n      return {\n        ...message,\n        content: message.content.map((result) => {\n          if (!Array.isArray(result.content)) return result;\n          const content = result.content.filter((part) => {\n            if (part.type !== \"image\" || remainingToRemove <= 0) return true;\n            remainingToRemove--;\n            return false;\n          });\n          return {\n            ...result,\n            content:\n              content.length > 0\n                ? content\n                : [{ type: \"text\" as const, text: PROVIDER_IMAGE_LIMIT_PLACEHOLDER }],\n          };\n        }),\n      };\n    }\n    return message;\n  });\n}\n\nconst NON_VISION_USER_IMAGE_PLACEHOLDER = \"(image omitted: model does not support images)\";\nconst NON_VISION_TOOL_IMAGE_PLACEHOLDER = \"(tool image omitted: model does not support images)\";\nconst NON_VIDEO_USER_PLACEHOLDER = \"(video omitted: model does not support video)\";\n\n/** Replace image blocks with a text placeholder (deduping consecutive placeholders). */\nfunction stripImages<T extends TextContent | ImageContent | VideoContent>(\n  content: T[],\n  placeholder: string,\n): (Exclude<T, ImageContent> | TextContent)[] {\n  const out: (Exclude<T, ImageContent> | TextContent)[] = [];\n  let lastWasPlaceholder = false;\n  for (const block of content) {\n    if (block.type === \"image\") {\n      if (!lastWasPlaceholder) out.push({ type: \"text\", text: placeholder });\n      lastWasPlaceholder = true;\n      continue;\n    }\n    out.push(block as Exclude<T, ImageContent>);\n    lastWasPlaceholder = block.type === \"text\" && block.text === placeholder;\n  }\n  return out;\n}\n\n/** Replace video blocks with a text placeholder (deduping consecutive placeholders). */\nfunction stripVideos(\n  content: (TextContent | ImageContent | VideoContent)[],\n  placeholder: string,\n): (TextContent | ImageContent)[] {\n  const out: (TextContent | ImageContent)[] = [];\n  let lastWasPlaceholder = false;\n  for (const block of content) {\n    if (block.type === \"video\") {\n      if (!lastWasPlaceholder) out.push({ type: \"text\", text: placeholder });\n      lastWasPlaceholder = true;\n      continue;\n    }\n    out.push(block);\n    lastWasPlaceholder = block.type === \"text\" && block.text === placeholder;\n  }\n  return out;\n}\n\n/**\n * Pre-transform pass: when the target model doesn't support video, replace\n * video blocks in user messages with a text placeholder. Tool results never\n * carry video, so only user messages are scanned.\n */\nexport function downgradeUnsupportedVideos(\n  messages: Message[],\n  supportsVideo: boolean | undefined,\n): Message[] {\n  if (supportsVideo === true) return messages;\n  return messages.map((msg) => {\n    if (msg.role === \"user\" && Array.isArray(msg.content)) {\n      return { ...msg, content: stripVideos(msg.content, NON_VIDEO_USER_PLACEHOLDER) };\n    }\n    return msg;\n  });\n}\n\n/**\n * Pre-transform pass: when the target model doesn't support images, replace\n * image blocks in user messages and tool_result messages with a text placeholder.\n * Called before provider-specific transforms.\n */\nexport function downgradeUnsupportedImages(\n  messages: Message[],\n  supportsImages: boolean | undefined,\n): Message[] {\n  if (supportsImages !== false) return messages;\n  return messages.map((msg) => {\n    if (msg.role === \"user\" && Array.isArray(msg.content)) {\n      return { ...msg, content: stripImages(msg.content, NON_VISION_USER_IMAGE_PLACEHOLDER) };\n    }\n    if (msg.role === \"tool\") {\n      return {\n        ...msg,\n        content: msg.content.map((tr) =>\n          Array.isArray(tr.content)\n            ? {\n                ...tr,\n                content: stripImages(tr.content, NON_VISION_TOOL_IMAGE_PLACEHOLDER),\n              }\n            : tr,\n        ),\n      };\n    }\n    return msg;\n  });\n}\n\n/** Extract concatenated text from tool_result content (array or string). */\nexport function toolResultText(content: ToolResultContent): string {\n  if (typeof content === \"string\") return content;\n  return content\n    .filter((b): b is TextContent => b.type === \"text\")\n    .map((b) => b.text)\n    .join(\"\\n\");\n}\n\n/** Extract image blocks from tool_result content. Returns empty array for string content. */\nfunction toolResultImages(content: ToolResultContent): ImageContent[] {\n  if (typeof content === \"string\") return [];\n  return content.filter((b): b is ImageContent => b.type === \"image\");\n}\n\n/** Extract video blocks from tool_result content. Returns empty array for string content. */\nfunction toolResultVideos(content: ToolResultContent): VideoContent[] {\n  if (typeof content === \"string\") return [];\n  return content.filter((b): b is VideoContent => b.type === \"video\");\n}\n\n// ── Anthropic Transforms ───────────────────────────────────\n\nexport function toAnthropicCacheControl(\n  retention: CacheRetention | undefined,\n  baseUrl: string | undefined,\n): { type: \"ephemeral\"; ttl?: \"1h\" } | undefined {\n  const resolved = retention ?? \"short\";\n  if (resolved === \"none\") return undefined;\n  const ttl =\n    resolved === \"long\" && (!baseUrl || baseUrl.includes(\"api.anthropic.com\")) ? \"1h\" : undefined;\n  return { type: \"ephemeral\", ...(ttl && { ttl }) } as { type: \"ephemeral\"; ttl?: \"1h\" };\n}\n\ntype AnthropicImageSource = {\n  type: \"base64\";\n  media_type: \"image/jpeg\" | \"image/png\" | \"image/gif\" | \"image/webp\";\n  data: string;\n};\n\n/**\n * Convert tool_result content to Anthropic's wire format. Strings pass through;\n * arrays are mapped to Anthropic's (text | image) block format, which\n * tool_result.content accepts natively.\n */\ntype AnthropicToolResultBlock =\n  | { type: \"text\"; text: string }\n  | { type: \"image\"; source: AnthropicImageSource }\n  | { type: \"video\"; source: { type: \"base64\"; media_type: string; data: string } };\n\nfunction toAnthropicToolResultContent(\n  content: ToolResultContent,\n): string | AnthropicToolResultBlock[] {\n  if (typeof content === \"string\") return content;\n  return content.map((block): AnthropicToolResultBlock => {\n    if (block.type === \"text\") return { type: \"text\" as const, text: block.text };\n    // Video blocks (e.g. read on a .mp4 for MiniMax) use the same base64 video\n    // shape as inline user content. Real Anthropic models are supportsVideo:false\n    // so they never reach here; this serves the Anthropic-compatible MiniMax API.\n    if (block.type === \"video\") {\n      return {\n        type: \"video\" as const,\n        source: { type: \"base64\" as const, media_type: block.mediaType, data: block.data },\n      };\n    }\n    return {\n      type: \"image\" as const,\n      source: {\n        type: \"base64\" as const,\n        media_type: block.mediaType as AnthropicImageSource[\"media_type\"],\n        data: block.data,\n      },\n    };\n  });\n}\n\n/**\n * Anthropic requires tool_use IDs to match `^[a-zA-Z0-9_-]+$`. Codex tool IDs\n * are composite (`callId|itemId`) and other providers may include dots/colons.\n * Replace any disallowed characters with `_` and memoize so the assistant's\n * tool_use ID matches the corresponding tool_result.tool_use_id.\n */\nfunction remapAnthropicToolCallId(id: string, idMap: Map<string, string>): string {\n  if (/^[a-zA-Z0-9_-]+$/.test(id)) return id;\n  const existing = idMap.get(id);\n  if (existing) return existing;\n  const mapped = id.replace(/[^a-zA-Z0-9_-]/g, \"_\");\n  idMap.set(id, mapped);\n  return mapped;\n}\n\nexport function toAnthropicMessages(\n  messages: Message[],\n  cacheControl?: { type: \"ephemeral\"; ttl?: \"1h\" },\n): {\n  system: Anthropic.TextBlockParam[] | undefined;\n  messages: Anthropic.MessageParam[];\n} {\n  let systemText: string | undefined;\n  const out: Anthropic.MessageParam[] = [];\n  const idMap = new Map<string, string>();\n\n  // Thinking is preserved across the ACTIVE trajectory: every assistant turn\n  // after the last real user message (tool results are role \"tool\", not \"user\",\n  // so this is simply the last role===\"user\" index). Earlier, settled turns have\n  // thinking stripped to keep history robust against signature invalidation.\n  const trajectoryStartIdx = messages.reduce(\n    (last, m, i) => (m.role === \"user\" ? i : last),\n    -1 as number,\n  );\n\n  let msgIdx = -1;\n  for (const msg of messages) {\n    msgIdx++;\n    if (msg.role === \"system\") {\n      systemText = msg.content;\n      continue;\n    }\n    if (msg.role === \"user\") {\n      // Drop empty-string text parts: Anthropic rejects empty text blocks with a\n      // 400 (\"text content blocks must be non-empty\"). A string content of \"\"\n      // and an all-empty content array are both degenerate — skip the whole\n      // message rather than send a guaranteed-400 body. Whitespace-only text is\n      // left intact (it is non-empty and the API accepts it). Baseline #20 A/B.\n      if (typeof msg.content === \"string\") {\n        if (msg.content === \"\") continue;\n      } else if (!msg.content.some((p) => !(p.type === \"text\" && p.text === \"\"))) {\n        continue;\n      }\n      out.push({\n        role: \"user\",\n        content:\n          typeof msg.content === \"string\"\n            ? msg.content\n            : msg.content\n                .filter((part) => !(part.type === \"text\" && part.text === \"\"))\n                .map((part) => {\n                  if (part.type === \"text\") return { type: \"text\" as const, text: part.text };\n                  if (part.type === \"video\") {\n                    // MiniMax-M3 rides the Anthropic transport and accepts native\n                    // video blocks. Non-video models never reach here — video is\n                    // downgraded to text by downgradeUnsupportedVideos first.\n                    return {\n                      type: \"video\" as const,\n                      source: {\n                        type: \"base64\" as const,\n                        media_type: part.mediaType,\n                        data: part.data,\n                      },\n                    } as unknown as Anthropic.ContentBlockParam;\n                  }\n                  return {\n                    type: \"image\" as const,\n                    source: {\n                      type: \"base64\" as const,\n                      media_type: part.mediaType as\n                        | \"image/jpeg\"\n                        | \"image/png\"\n                        | \"image/gif\"\n                        | \"image/webp\",\n                      data: part.data,\n                    },\n                  };\n                }),\n      });\n      continue;\n    }\n    if (msg.role === \"assistant\") {\n      // A settled assistant turn with string content \"\" bypasses the array\n      // filter below and would reach the wire as an empty string — Anthropic\n      // 400s on it just like an empty text block. Drop it (baseline #20 D).\n      if (typeof msg.content === \"string\" && msg.content === \"\") continue;\n      const content =\n        typeof msg.content === \"string\"\n          ? msg.content\n          : toAnthropicAssistantContent(msg.content, msgIdx > trajectoryStartIdx, idMap);\n      // Skip assistant messages with no content blocks (can happen when all\n      // blocks are filtered — e.g. thinking-only responses from non-Anthropic\n      // providers where signature is missing and text is empty)\n      if (Array.isArray(content) && content.length === 0) continue;\n      out.push({ role: \"assistant\", content });\n      continue;\n    }\n    if (msg.role === \"tool\") {\n      out.push({\n        role: \"user\",\n        // Cast covers the video block (used by the Anthropic-compatible MiniMax\n        // API), which isn't in the first-party Anthropic tool_result types.\n        content: msg.content.map((result) => ({\n          type: \"tool_result\" as const,\n          tool_use_id: remapAnthropicToolCallId(result.toolCallId, idMap),\n          content: toAnthropicToolResultContent(result.content),\n          is_error: result.isError,\n        })) as unknown as Anthropic.ContentBlockParam[],\n      });\n    }\n  }\n\n  // Add cache_control to the last user message to cache conversation history\n  if (cacheControl && out.length > 0) {\n    for (let i = out.length - 1; i >= 0; i--) {\n      if (out[i].role === \"user\") {\n        const content = out[i].content;\n        if (typeof content === \"string\") {\n          out[i] = {\n            role: \"user\",\n            content: [\n              {\n                type: \"text\",\n                text: content,\n                cache_control: cacheControl,\n              } as Anthropic.TextBlockParam,\n            ],\n          };\n        } else if (Array.isArray(content) && content.length > 0) {\n          const last = content[content.length - 1];\n          content[content.length - 1] = {\n            ...last,\n            cache_control: cacheControl,\n          } as (typeof content)[number];\n        }\n        break;\n      }\n    }\n  }\n\n  // Anthropic supports block-level cache_control. GG Coder keeps reusable prompt\n  // content before the \"<!-- uncached -->\" marker and volatile text (currently\n  // the date) after it, so only the reusable prefix receives cache_control.\n  let system: Anthropic.TextBlockParam[] | undefined;\n  if (systemText) {\n    const marker = \"<!-- uncached -->\";\n    const markerIdx = systemText.indexOf(marker);\n    if (markerIdx !== -1 && cacheControl) {\n      const cachedPart = systemText.slice(0, markerIdx).trimEnd();\n      const uncachedPart = systemText.slice(markerIdx + marker.length).trimStart();\n      system = [\n        { type: \"text\" as const, text: cachedPart, cache_control: cacheControl },\n        ...(uncachedPart ? [{ type: \"text\" as const, text: uncachedPart }] : []),\n      ];\n    } else {\n      system = [\n        {\n          type: \"text\" as const,\n          text: systemText,\n          ...(cacheControl && { cache_control: cacheControl }),\n        },\n      ];\n    }\n  }\n\n  return { system, messages: out };\n}\n\nexport function toAnthropicTools(\n  tools: Tool[],\n  options?: {\n    cacheControl?: { type: \"ephemeral\"; ttl?: \"1h\" };\n    enableFineGrainedToolStreaming?: boolean;\n  },\n): Anthropic.Tool[] {\n  return tools.map((tool, index) => {\n    const anthropicTool: Anthropic.Tool & {\n      cache_control?: { type: \"ephemeral\"; ttl?: \"1h\" };\n      eager_input_streaming?: boolean;\n    } = {\n      name: tool.name,\n      description: tool.description,\n      input_schema: (tool.rawInputSchema ??\n        zodToJsonSchema(tool.parameters)) as Anthropic.Tool[\"input_schema\"],\n      ...(options?.enableFineGrainedToolStreaming ? { eager_input_streaming: true } : {}),\n    };\n    if (options?.cacheControl && index === tools.length - 1) {\n      anthropicTool.cache_control = options.cacheControl;\n    }\n    return anthropicTool;\n  });\n}\n\nexport function toAnthropicToolChoice(choice: ToolChoice): Anthropic.ToolChoice {\n  if (choice === \"auto\") return { type: \"auto\" };\n  if (choice === \"none\") return { type: \"none\" };\n  if (choice === \"required\") return { type: \"any\" };\n  return { type: \"tool\", name: choice.name };\n}\n\n/**\n * Anthropic models with built-in adaptive thinking (Fable 5, Mythos 5,\n * Opus 5, Opus 4.8/4.7/4.6, Sonnet 5). Matches both dashed (`opus-4-8`) and\n * dotted (`opus-4.8`) forms so callers don't have to enumerate variants. These\n * models don't need the `interleaved-thinking` beta header — it's built in.\n * (`opus-5` can't false-match `claude-opus-4-5-…` — the `4-` breaks the literal.)\n */\nexport function isAdaptiveThinkingModel(model: string): boolean {\n  return /opus-5|opus-4[-.]8|opus-4[-.]7|opus-4[-.]6|sonnet-5|fable-5|mythos-5/.test(model);\n}\n\nexport function toAnthropicThinking(\n  level: ThinkingLevel,\n  maxTokens: number,\n  model: string,\n): {\n  thinking: Anthropic.ThinkingConfigParam;\n  maxTokens: number;\n  outputConfig?: { effort: string };\n} {\n  if (isAdaptiveThinkingModel(model)) {\n    // Adaptive thinking — model decides when/how much to think.\n    // budget_tokens is deprecated on Opus 5 / 4.8 / 4.7 / 4.6 and Sonnet 5.\n    // Anthropic's output_config.effort accepts low, medium, high, xhigh, and max.\n    // xhigh is Opus 5 / 4.8 / 4.7-only; max is supported by every adaptive model.\n    let effort: string = level;\n    if (effort === \"xhigh\" && !/opus-5|opus-4-8|opus-4-7/.test(model)) {\n      effort = \"high\";\n    }\n    return {\n      thinking: { type: \"adaptive\" } as unknown as Anthropic.ThinkingConfigParam,\n      maxTokens,\n      outputConfig: { effort },\n    };\n  }\n\n  // Legacy budget-based thinking for older models (\"xhigh\"/\"max\" treated as\n  // \"high\"). `maxTokens` is the model's full output-token ceiling; for budget\n  // thinking `max_tokens` is the TOTAL response envelope (thinking + visible\n  // output), so it must stay ≤ the ceiling and `budget_tokens` must be strictly\n  // less than it. The previous code returned `maxTokens + budget`, which blew\n  // past the ceiling (e.g. Haiku 4.5: 64K + 64K = 128K) and could trip the\n  // provider's `max_tokens > maximum allowed` rejection. Now the ceiling is the\n  // envelope and the budget is a fraction of it with a reserved visible floor.\n  const VISIBLE_FLOOR = 1024;\n  const effectiveLevel = level === \"xhigh\" || level === \"max\" || level === \"ultra\" ? \"high\" : level;\n  const budgetMap: Record<\"low\" | \"medium\" | \"high\", number> = {\n    low: Math.max(1024, Math.floor(maxTokens * 0.2)),\n    medium: Math.max(2048, Math.floor(maxTokens * 0.45)),\n    high: Math.max(4096, Math.floor(maxTokens * 0.8)),\n  };\n  // Clamp the budget so a visible-output floor survives even at \"high\" on small\n  // ceilings, and budget_tokens stays < max_tokens (Anthropic hard requirement).\n  const budget = Math.max(0, Math.min(budgetMap[effectiveLevel], maxTokens - VISIBLE_FLOOR));\n  return {\n    thinking: { type: \"enabled\", budget_tokens: budget },\n    maxTokens,\n  };\n}\n\n// ── OpenAI Transforms ──────────────────────────────────────\n\n/**\n * Remap Anthropic `toolu_*` tool call IDs to `call_*` so OpenAI accepts them.\n * Only Anthropic IDs need remapping — IDs from OpenAI-compatible providers\n * (Moonshot, GLM, Xiaomi, MiniMax) are passed through unchanged to avoid\n * breaking the provider's own ID validation.\n */\nfunction remapToolCallId(id: string, idMap: Map<string, string>): string {\n  if (!id.startsWith(\"toolu_\")) return id;\n  const existing = idMap.get(id);\n  if (existing) return existing;\n  // Strip the full `toolu_` prefix (6 chars). `slice(5)` left the trailing\n  // underscore, producing `call__<id>` (double underscore) — lossy and not\n  // identity-reversible. `slice(6)` yields a clean `call_<id>`. Pairing still\n  // holds because both the tool_call and its result resolve through idMap.\n  const mapped = `call_${id.slice(6)}`;\n  idMap.set(id, mapped);\n  return mapped;\n}\n\nexport function toOpenAIMessages(\n  messages: Message[],\n  options?: {\n    provider?: string;\n    thinking?: boolean;\n    supportsImages?: boolean;\n    /** Wire name for reasoning on assistant messages. Defaults to `reasoning_content`. */\n    reasoningField?: string;\n  },\n): OpenAI.ChatCompletionMessageParam[] {\n  const reasoningField = options?.reasoningField || DEFAULT_REASONING_FIELD;\n  const out: OpenAI.ChatCompletionMessageParam[] = [];\n  const idMap = new Map<string, string>();\n  // GLM drops reasoning_content when a user message follows tool results.\n  // Merge user text into the last tool message to preserve thinking context.\n  const mergeToolResultText = options?.provider === \"glm\";\n\n  for (const msg of messages) {\n    if (msg.role === \"system\") {\n      // OpenAI-style APIs receive the system prompt literally. They may do\n      // provider-side prefix/key caching, but there is no Anthropic-style\n      // uncached block split here; the marker remains ordinary text.\n      out.push({ role: \"system\", content: msg.content });\n      continue;\n    }\n    if (msg.role === \"user\") {\n      // For GLM: if the previous message is a tool result, merge text into it\n      // to avoid a standalone user message that causes reasoning_content to be dropped.\n      if (mergeToolResultText && out.length > 0 && out[out.length - 1]!.role === \"tool\") {\n        const userText =\n          typeof msg.content === \"string\"\n            ? msg.content\n            : msg.content\n                .filter((p): p is TextContent => p.type === \"text\")\n                .map((p) => p.text)\n                .join(\"\");\n        if (userText) {\n          // Append text to the last tool message's content\n          const lastTool = out[out.length - 1] as OpenAI.ChatCompletionToolMessageParam;\n          lastTool.content = (lastTool.content ?? \"\") + \"\\n\\n\" + userText;\n          continue;\n        }\n      }\n      if (typeof msg.content === \"string\") {\n        out.push({ role: \"user\", content: msg.content });\n      } else {\n        out.push({\n          role: \"user\",\n          content: msg.content.map(\n            (\n              part,\n            ): OpenAI.ChatCompletionContentPartImage | OpenAI.ChatCompletionContentPartText => {\n              if (part.type === \"text\") return { type: \"text\", text: part.text };\n              if (part.type === \"video\") {\n                // Moonshot/Kimi requires video uploaded to the file service and\n                // referenced by `ms://<id>` — inline base64 is rejected. The\n                // openai provider uploads first and caches `fileId` on the part.\n                // Match Kimi's wire shape exactly: when uploaded, include both\n                // `url` and `id`. Non-video models never reach here.\n                const videoUrl = part.fileId\n                  ? { url: `ms://${part.fileId}`, id: part.fileId }\n                  : { url: `data:${part.mediaType};base64,${part.data}` };\n                return {\n                  type: \"video_url\",\n                  video_url: videoUrl,\n                } as unknown as OpenAI.ChatCompletionContentPartImage;\n              }\n              return {\n                type: \"image_url\",\n                image_url: {\n                  url: `data:${part.mediaType};base64,${part.data}`,\n                },\n              };\n            },\n          ),\n        });\n      }\n      continue;\n    }\n    if (msg.role === \"assistant\") {\n      const parts = typeof msg.content === \"string\" ? msg.content : undefined;\n      const toolCalls =\n        typeof msg.content !== \"string\"\n          ? msg.content\n              .filter(\n                (p): p is Extract<ContentPart, { type: \"tool_call\" }> => p.type === \"tool_call\",\n              )\n              .map(\n                (tc): OpenAI.ChatCompletionMessageToolCall => ({\n                  id: remapToolCallId(tc.id, idMap),\n                  type: \"function\",\n                  function: { name: tc.name, arguments: JSON.stringify(tc.args) },\n                }),\n              )\n          : undefined;\n      const textParts =\n        typeof msg.content !== \"string\"\n          ? msg.content\n              .filter((p): p is TextContent => p.type === \"text\")\n              .map((p) => p.text)\n              .join(\"\")\n          : undefined;\n      // Roundtrip thinking content as reasoning_content (GLM, Moonshot)\n      const thinkingParts =\n        typeof msg.content !== \"string\"\n          ? msg.content\n              .filter((p): p is ThinkingContent => p.type === \"thinking\")\n              .map((p) => p.text)\n              .join(\"\")\n          : undefined;\n\n      const contentValue = parts || textParts || null;\n      const hasToolCalls = toolCalls && toolCalls.length > 0;\n      // Skip assistant messages with no content and no tool_calls (can happen\n      // with thinking-only responses) — providers like Xiaomi reject these.\n      if (!contentValue && !hasToolCalls) continue;\n\n      const assistantMsg: OpenAI.ChatCompletionAssistantMessageParam = {\n        role: \"assistant\",\n        content: contentValue,\n        ...(hasToolCalls ? { tool_calls: toolCalls } : {}),\n      };\n      // Attach reasoning_content for multi-turn thinking coherence (non-standard field).\n      // When thinking content exists, always include it for round-tripping.\n      // When thinking is enabled but no content exists (e.g. after compaction),\n      // Moonshot/Kimi requires reasoning_content on assistant tool_call messages —\n      // default to empty string.  GLM silently hangs on empty values, so skip it there.\n      if (thinkingParts) {\n        (assistantMsg as unknown as Record<string, unknown>)[reasoningField] = thinkingParts;\n      } else if (options?.thinking && hasToolCalls && options.provider !== \"glm\") {\n        (assistantMsg as unknown as Record<string, unknown>)[reasoningField] = \" \";\n      }\n      out.push(assistantMsg);\n      continue;\n    }\n    if (msg.role === \"tool\") {\n      // OpenAI's `tool` role only accepts text. Emit the tool message with the\n      // text content, then (if any tool results carried images and the model\n      // supports vision) a follow-up `user` message carrying image_url blocks.\n      //\n      // Moonshot/Kimi is the exception for VIDEO: its coding endpoint accepts a\n      // `video_url` content part ONLY inside the tool message itself (not in a\n      // user message). So for moonshot we emit the tool content as an array\n      // `[{text}, {video_url}]` carrying the uploaded `ms://<id>` reference —\n      // mirroring the official Kimi read-media tool. The provider uploads the\n      // clip and stamps `fileId` before this transform runs.\n      //\n      // Every OTHER OpenAI-compatible video model (e.g. Xiaomi MiMo-V2.5)\n      // rejects video inside a `tool` message (\"`text` is not set\", verified\n      // against the live API) — it accepts `video_url` only in `user` content.\n      // So those videos are carried out the same way images are: a follow-up\n      // `user` message after the tool result. Tool results only ever carry\n      // video when the active model is video-capable (the read tool returns\n      // native video solely for such models, and `stream()` rejects stray video\n      // for text-only models), so no extra capability guard is needed here.\n      const isMoonshot = options?.provider === \"moonshot\";\n      const followUpMediaBlocks: OpenAI.ChatCompletionContentPart[] = [];\n      let followUpHasVideo = false;\n      for (const result of msg.content) {\n        const text = toolResultText(result.content);\n        const images = toolResultImages(result.content);\n        const videos = toolResultVideos(result.content);\n        const hasText = text.length > 0;\n        if (isMoonshot && videos.length > 0) {\n          const parts: OpenAI.ChatCompletionContentPartText[] = [];\n          if (hasText) parts.push({ type: \"text\", text });\n          const videoParts = videos.map((v) => {\n            const videoUrl = v.fileId\n              ? { url: `ms://${v.fileId}`, id: v.fileId }\n              : { url: `data:${v.mediaType};base64,${v.data}` };\n            return { type: \"video_url\", video_url: videoUrl };\n          });\n          out.push({\n            role: \"tool\",\n            tool_call_id: remapToolCallId(result.toolCallId, idMap),\n            content: [...parts, ...videoParts] as unknown as string,\n          });\n          continue;\n        }\n        out.push({\n          role: \"tool\",\n          tool_call_id: remapToolCallId(result.toolCallId, idMap),\n          content: hasText ? text : \"(see attached media)\",\n        });\n        if (images.length > 0 && options?.supportsImages !== false) {\n          for (const img of images) {\n            followUpMediaBlocks.push({\n              type: \"image_url\",\n              image_url: { url: `data:${img.mediaType};base64,${img.data}` },\n            });\n          }\n        }\n        // Non-Moonshot video models: deliver the clip in a follow-up user\n        // message as an inline base64 `video_url` (the shape MiMo accepts).\n        if (!isMoonshot && videos.length > 0) {\n          for (const v of videos) {\n            followUpMediaBlocks.push({\n              type: \"video_url\",\n              video_url: { url: `data:${v.mediaType};base64,${v.data}` },\n            } as unknown as OpenAI.ChatCompletionContentPart);\n            followUpHasVideo = true;\n          }\n        }\n      }\n      if (followUpMediaBlocks.length > 0) {\n        const label = followUpHasVideo\n          ? \"Attached media from tool result:\"\n          : \"Attached image(s) from tool result:\";\n        out.push({\n          role: \"user\",\n          content: [{ type: \"text\", text: label }, ...followUpMediaBlocks],\n        });\n      }\n    }\n  }\n\n  return out;\n}\n\nexport function toOpenAITools(tools: Tool[]): OpenAI.ChatCompletionTool[] {\n  return tools.map((tool) => ({\n    type: \"function\" as const,\n    function: {\n      name: tool.name,\n      description: tool.description,\n      parameters: resolveToolSchema(tool),\n    },\n  }));\n}\n\nexport function toOpenAIToolChoice(choice: ToolChoice): OpenAI.ChatCompletionToolChoiceOption {\n  if (choice === \"auto\") return \"auto\";\n  if (choice === \"none\") return \"none\";\n  if (choice === \"required\") return \"required\";\n  return { type: \"function\", function: { name: choice.name } };\n}\n\n/**\n * Reasoning effort for a locally hosted server (Ollama, LM Studio, llama.cpp,\n * vLLM). These spell the top rung **\"max\"**, not \"xhigh\" — Ollama 0.32 answers\n * `invalid reasoning value: 'xhigh' (must be \"high\", \"medium\", \"low\", \"max\", or\n * \"none\")`, so sending the OpenAI spelling is a hard 400. Like Kimi's `max`,\n * the value sits outside the OpenAI SDK's effort union, so the caller assigns\n * it through the usual escape hatch.\n */\nexport function toLocalReasoningEffort(level: ThinkingLevel): \"low\" | \"medium\" | \"high\" | \"max\" {\n  if (level === \"max\" || level === \"ultra\" || level === \"xhigh\") return \"max\";\n  return level;\n}\n\n/**\n * Reasoning effort for Z.AI's GLM endpoint. Its accepted set is declared by\n * the API itself — an unknown value 400s with `reasoning_effort must be one of:\n * none, minimal, low, medium, high, xhigh, max` (verified against glm-5.3) —\n * so every ThinkingLevel except `ultra` passes through unchanged. Crucially\n * `max` must NOT be remapped to `xhigh` the way {@link toOpenAIReasoningEffort}\n * does: GLM spells its top rung `max` and treats it as the default.\n */\nexport function toGlmReasoningEffort(\n  level: ThinkingLevel,\n): \"low\" | \"medium\" | \"high\" | \"xhigh\" | \"max\" {\n  return level === \"ultra\" ? \"max\" : level;\n}\n\nexport function toOpenAIReasoningEffort(\n  level: ThinkingLevel,\n  model: string,\n): \"low\" | \"medium\" | \"high\" | \"xhigh\" {\n  const effort = level === \"max\" || level === \"ultra\" ? \"xhigh\" : level;\n  // Sakana Fugu models reject any effort other than \"high\"/\"xhigh\", so floor a\n  // lower manual selection up to \"high\" rather than letting the API 400.\n  if (model.startsWith(\"fugu\") && (effort === \"low\" || effort === \"medium\")) {\n    return \"high\";\n  }\n  return effort;\n}\n\n// ── Response Normalization ─────────────────────────────────\n\nexport function normalizeAnthropicStopReason(reason: string | null): StopReason {\n  switch (reason) {\n    case \"tool_use\":\n      return \"tool_use\";\n    case \"max_tokens\":\n      return \"max_tokens\";\n    case \"pause_turn\":\n      return \"pause_turn\";\n    case \"stop_sequence\":\n      return \"stop_sequence\";\n    case \"refusal\":\n      return \"refusal\";\n    default:\n      return \"end_turn\";\n  }\n}\n\nexport function normalizeOpenAIStopReason(reason: string | null): StopReason {\n  switch (reason) {\n    case \"tool_calls\":\n      return \"tool_use\";\n    case \"length\":\n      return \"max_tokens\";\n    case \"stop\":\n      return \"stop_sequence\";\n    default:\n      return \"end_turn\";\n  }\n}\n","export function isJsonObject(value: unknown): value is Record<string, unknown> {\n  return value != null && typeof value === \"object\" && !Array.isArray(value);\n}\n\nexport function parseToolArguments(argsJson: string): Record<string, unknown> {\n  if (!argsJson) return {};\n  try {\n    const parsed = JSON.parse(argsJson) as unknown;\n    const unwrapped = typeof parsed === \"string\" ? (JSON.parse(parsed) as unknown) : parsed;\n    return isJsonObject(unwrapped) ? unwrapped : {};\n  } catch {\n    return {};\n  }\n}\n","import OpenAI from \"openai\";\nimport type {\n  ContentPart,\n  StreamEvent,\n  StreamOptions,\n  StreamResponse,\n  ThinkingLevel,\n  ToolCall,\n} from \"../types.js\";\nimport {\n  ProviderError,\n  readHeader,\n  isHardBillingMessage,\n  isRawJsonErrorEcho,\n  isRawHtmlErrorEcho,\n  emptyProviderErrorMessage,\n  providerHtmlErrorMessage,\n} from \"../errors.js\";\nimport { StreamResult } from \"../utils/event-stream.js\";\nimport {\n  downgradeUnsupportedImages,\n  downgradeUnsupportedVideos,\n  normalizeOpenAIStopReason,\n  toOpenAIMessages,\n  toGlmReasoningEffort,\n  toLocalReasoningEffort,\n  toOpenAIReasoningEffort,\n  toOpenAIToolChoice,\n  toOpenAITools,\n} from \"./transform.js\";\nimport { normalizePromptCacheKey } from \"./prompt-cache-key.js\";\nimport { uploadMoonshotVideos } from \"./moonshot-video.js\";\nimport {\n  getReasoningField,\n  readReasoning,\n  reasoningFieldKey,\n  rememberReasoningField,\n} from \"./reasoning-field.js\";\nimport { parseToolArguments } from \"../utils/json.js\";\nimport { getEnvironment } from \"../utils/env.js\";\n\n// Kimi K3's declared effort rungs (server-validated; anything else 400s).\n// Official alias mapping from Moonshot's K3 third-party-tools docs:\n// ultra/max/xhigh → max, high/medium → high, low → low.\ntype KimiK3Effort = \"low\" | \"high\" | \"max\";\nfunction toKimiK3Effort(level: ThinkingLevel): KimiK3Effort {\n  switch (level) {\n    case \"low\":\n      return \"low\";\n    case \"medium\":\n    case \"high\":\n      return \"high\";\n    default: // \"xhigh\" | \"max\" | \"ultra\"\n      return \"max\";\n  }\n}\n\n// Normalize OpenAI completion usage to the framework convention where\n// inputTokens excludes cache hits (matching Anthropic). Handles vendor-specific\n// cache reporting fields:\n// - Kimi K2/K2.5 / StepFun: top-level `cached_tokens`\n// - DeepSeek / SiliconFlow: `prompt_cache_hit_tokens`\n// - OpenAI / Zhipu (GLM) / MiniMax / Qwen / Mistral / xAI: standard\n//   `prompt_tokens_details.cached_tokens`\nfunction extractOpenAIUsage(usage: OpenAI.CompletionUsage): {\n  inputTokens: number;\n  outputTokens: number;\n  cacheRead: number;\n  cacheWrite: number;\n} {\n  let cacheRead = 0;\n  let cacheWrite = 0;\n  const details = usage.prompt_tokens_details;\n  if (details?.cached_tokens) {\n    cacheRead = details.cached_tokens;\n  }\n  const usageAny = usage as unknown as Record<string, unknown>;\n  const detailsAny = details as unknown as Record<string, unknown> | undefined;\n  if (typeof detailsAny?.cache_write_tokens === \"number\") {\n    cacheWrite = detailsAny.cache_write_tokens;\n  }\n  if (!cacheRead && typeof usageAny.cached_tokens === \"number\" && usageAny.cached_tokens > 0) {\n    cacheRead = usageAny.cached_tokens as number;\n  }\n  if (\n    !cacheRead &&\n    typeof usageAny.prompt_cache_hit_tokens === \"number\" &&\n    usageAny.prompt_cache_hit_tokens > 0\n  ) {\n    cacheRead = usageAny.prompt_cache_hit_tokens as number;\n  }\n  // OpenAI's prompt_tokens includes cached tokens; subtract to match\n  // Anthropic's convention where inputTokens excludes cache hits.\n  return {\n    inputTokens: usage.prompt_tokens - cacheRead - cacheWrite,\n    outputTokens: usage.completion_tokens,\n    cacheRead,\n    cacheWrite,\n  };\n}\n\n/** Client cache — avoids re-instantiating the OpenAI SDK on every call.\n *  See anthropic.ts for rationale. Keyed by identity-relevant fields. */\nconst openaiClientCache = new Map<string, OpenAI>();\n\nfunction createClient(options: StreamOptions): OpenAI {\n  const cacheKey = `${options.apiKey ?? \"\"}|${options.baseUrl ?? \"\"}|${JSON.stringify(options.defaultHeaders ?? {})}`;\n\n  // Skip cache when a custom fetch is provided (tests, React Native, etc.).\n  if (!options.fetch) {\n    const cached = openaiClientCache.get(cacheKey);\n    if (cached) return cached;\n  }\n\n  const client = new OpenAI({\n    apiKey: options.apiKey,\n    ...(options.baseUrl ? { baseURL: options.baseUrl } : {}),\n    ...(options.fetch ? { fetch: options.fetch } : {}),\n    ...(options.defaultHeaders ? { defaultHeaders: options.defaultHeaders } : {}),\n  });\n\n  if (!options.fetch) {\n    if (openaiClientCache.size >= 8) {\n      const oldest = openaiClientCache.keys().next().value;\n      if (oldest) openaiClientCache.delete(oldest);\n    }\n    openaiClientCache.set(cacheKey, client);\n  }\n  return client;\n}\n\nexport function streamOpenAI(options: StreamOptions): StreamResult {\n  return new StreamResult(runStream(options), options.signal);\n}\n\nasync function* runStream(options: StreamOptions): AsyncGenerator<StreamEvent, StreamResponse> {\n  const providerName = options.provider ?? \"openai\";\n  const useStreaming = options.streaming !== false;\n  // Endpoints disagree on the reasoning field name; remember what this one\n  // emitted so the echo-back on the next turn uses the same name.\n  const endpointKey = reasoningFieldKey(providerName, options.baseUrl, options.model);\n\n  const client = createClient(options);\n\n  // Kimi K3's effort ladder is server-declared as low/high/max on both the\n  // public API (default max) and the Kimi For Coding OAuth endpoint (default\n  // high); unlisted efforts are rejected with a 400, and thinking can be fully\n  // disabled via the nested toggle on either endpoint. The public API takes\n  // top-level `reasoning_effort`; the managed endpoint keeps the official\n  // CLI's nested shape.\n  const isLocal = options.provider === \"local\";\n  const isKimiK3 = options.provider === \"moonshot\" && options.model === \"kimi-k3\";\n  const isManagedKimiK3 =\n    isKimiK3 && options.baseUrl?.replace(/\\/+$/, \"\").endsWith(\"/coding/v1\") === true;\n  // Clamp out-of-ladder levels to the official alias rungs — the session\n  // layer already restricts choices via getSupportedThinkingLevels, this is a\n  // safety net for stale saved settings.\n  const k3Effort = options.thinking ? toKimiK3Effort(options.thinking) : undefined;\n  const isKimiK27 = options.provider === \"moonshot\" && options.model.startsWith(\"kimi-k2.7-code\");\n  const hasFixedKimiSampling = isKimiK3 || isKimiK27;\n  const usesThinkingParam =\n    options.provider === \"glm\" ||\n    (options.provider === \"moonshot\" && !isKimiK3 && !isKimiK27) ||\n    options.provider === \"xiaomi\";\n\n  const downgradedImages = downgradeUnsupportedImages(options.messages, options.supportsImages);\n  const downgradedMessages = downgradeUnsupportedVideos(downgradedImages, options.supportsVideo);\n  // Moonshot/Kimi requires video uploaded to the file service and referenced by\n  // `ms://<id>` — inline base64 is rejected. Kimi's endpoint also only accepts\n  // the resulting `video_url` part inside a tool result (not user content), so\n  // ggcoder routes attached video through the read tool. This uploads every\n  // video part (in user OR tool-result content) and caches the id so multi-turn\n  // sessions don't re-upload. Done in-place before the transform.\n  if (options.provider === \"moonshot\") {\n    try {\n      await uploadMoonshotVideos(client, downgradedMessages, options.signal);\n    } catch (err) {\n      // Surface upload failures through the same provider-error classification\n      // as the chat call (this runs before the stream try/catch below).\n      throw toError(err, providerName);\n    }\n  }\n  const messages = toOpenAIMessages(downgradedMessages, {\n    provider: options.provider,\n    // K2.7 preserves reasoning even when the user hides thinking in the UI;\n    // keep assistant tool-call history wire-valid in that display mode. A\n    // disabled K3 must NOT carry placeholder reasoning_content (mirrors the\n    // official CLI: reasoning is preserved only while thinking is enabled).\n    thinking: isKimiK27 || !!options.thinking,\n    supportsImages: options.supportsImages,\n    reasoningField: getReasoningField(endpointKey),\n  });\n\n  // GLM models default to 0.6 temperature when not in thinking mode\n  const defaultTemp = options.provider === \"glm\" ? 0.6 : undefined;\n  const effectiveTemp = options.temperature ?? defaultTemp;\n\n  const params: OpenAI.ChatCompletionCreateParams = {\n    model: options.model,\n    messages,\n    stream: useStreaming,\n    ...(options.maxTokens ? { max_completion_tokens: options.maxTokens } : {}),\n    ...(effectiveTemp != null && !options.thinking && !hasFixedKimiSampling\n      ? { temperature: effectiveTemp }\n      : {}),\n    ...(options.topP != null && !hasFixedKimiSampling ? { top_p: options.topP } : {}),\n    ...(options.stop ? { stop: options.stop } : {}),\n    ...(options.thinking && !usesThinkingParam && !isKimiK3 && !isKimiK27 && !isLocal\n      ? { reasoning_effort: toOpenAIReasoningEffort(options.thinking, options.model) }\n      : {}),\n    ...(options.tools?.length ? { tools: toOpenAITools(options.tools) } : {}),\n    ...(options.toolChoice && options.tools?.length\n      ? { tool_choice: toOpenAIToolChoice(options.toolChoice) }\n      : {}),\n    ...(useStreaming ? { stream_options: { include_usage: true } } : {}),\n  };\n\n  // Native web search is disabled for OpenAI-compatible providers — ggcoder\n  // provides its own web_search/web_fetch tools which handle results properly.\n  // Moonshot's $web_search was previously injected here but it returns opaque\n  // results and triggers reasoning_content validation errors with thinking mode.\n\n  // prompt_cache_key helps bucket similar requests for better cache hit rates.\n  // Only send to providers known to support it (OpenAI, Moonshot/Kimi) — unknown\n  // params may cause errors on other OpenAI-compatible providers like GLM or Xiaomi.\n  if (options.provider === \"openai\" || options.provider === \"moonshot\") {\n    const paramsAny = params as unknown as Record<string, unknown>;\n    paramsAny.prompt_cache_key = normalizePromptCacheKey(options.promptCacheKey ?? \"ggcoder\");\n\n    // GPT-5.6 replaced prompt_cache_retention with prompt_cache_options.\n    // Its only supported TTL is 30m; implicit mode preserves automatic latest-\n    // message breakpoints while enabling the newer reliable key+prefix matching.\n    if (options.provider === \"openai\" && options.model.startsWith(\"gpt-5.6\")) {\n      paramsAny.prompt_cache_options = { mode: \"implicit\", ttl: \"30m\" };\n    } else if (!isKimiK3 && (options.cacheRetention ?? \"short\") === \"long\") {\n      // K3 caching is automatic and its request schema does not expose a TTL.\n      paramsAny.prompt_cache_retention = \"24h\";\n    }\n  }\n\n  // Local endpoints take low/medium/high/max — `max` sits outside the OpenAI\n  // SDK's effort union (same situation as Kimi's), so assign it directly.\n  if (isLocal && options.thinking) {\n    (params as unknown as Record<string, unknown>).reasoning_effort = toLocalReasoningEffort(\n      options.thinking,\n    );\n  }\n\n  if (options.provider === \"openai\" && options.serviceTier) {\n    (params as unknown as Record<string, unknown>).service_tier = options.serviceTier;\n  }\n\n  if (isKimiK3) {\n    const paramsAny = params as unknown as Record<string, unknown>;\n    if (isManagedKimiK3) {\n      // Kimi Code's managed OAuth endpoint keeps the official CLI's Kimi wire\n      // shape: nested effort plus preserved reasoning, or an explicit disabled\n      // toggle when thinking is off.\n      paramsAny.thinking = k3Effort\n        ? { type: \"enabled\", effort: k3Effort, keep: \"all\" }\n        : { type: \"disabled\" };\n    } else if (k3Effort) {\n      // The public K3 API uses top-level reasoning_effort. The OpenAI SDK's\n      // effort union does not know Kimi's `max` value yet.\n      paramsAny.reasoning_effort = k3Effort;\n    } else {\n      // Public K3 has no reasoning_effort \"off\" — disable via the nested\n      // toggle, the shape the official CLI uses on this endpoint too.\n      paramsAny.thinking = { type: \"disabled\" };\n    }\n  }\n\n  // Inject the custom toggle for K2.6-era Kimi, GLM, and Xiaomi. Public K3 uses\n  // reasoning_effort, managed K3 has its endpoint-specific block above, and\n  // K2.7 is always-thinking and rejects an explicit disabled toggle.\n  if (usesThinkingParam) {\n    if (options.thinking) {\n      (params as unknown as Record<string, unknown>).thinking = { type: \"enabled\" };\n      // GLM pairs the toggle with a real effort ladder (verified: an unknown\n      // value 400s listing `none, minimal, low, medium, high, xhigh, max`).\n      // The toggle alone silently runs Z.AI's `max` default, which made every\n      // rung below the ceiling a lie in the UI.\n      if (options.provider === \"glm\") {\n        (params as unknown as Record<string, unknown>).reasoning_effort = toGlmReasoningEffort(\n          options.thinking,\n        );\n      }\n    } else {\n      // The providers/models routed through this block support explicit disabled.\n      // MiMo is an always-on reasoning model — without { type: \"disabled\" } it\n      // returns reasoning_content and may produce thinking-only responses with\n      // no actionable output, causing the agent loop to silently end.\n      (params as unknown as Record<string, unknown>).thinking = { type: \"disabled\" };\n    }\n  }\n\n  // Dump request body for stall diagnosis when GGAI_DUMP_REQUEST is set\n  if (getEnvironment()?.GGAI_DUMP_REQUEST) {\n    const fs = await import(\"fs\");\n    const ts = new Date().toISOString().replace(/[:.]/g, \"-\");\n    const dumpPath = `/tmp/ggai-request-${ts}.json`;\n    fs.writeFileSync(dumpPath, JSON.stringify(params, null, 2));\n    fs.appendFileSync(\n      \"/tmp/ggai-requests.log\",\n      `[${ts}] ${dumpPath} messages=${params.messages.length}\\n`,\n    );\n  }\n\n  // Non-streaming fallback: issue a single request/response and synthesize\n  // stream events from the final ChatCompletion. Used by the agent loop after\n  // the streaming transport has stalled repeatedly -- flipping to a plain\n  // request/response often recovers from broken SSE connections.\n  if (!useStreaming) {\n    try {\n      const completion = (await client.chat.completions.create(params, {\n        signal: options.signal ?? undefined,\n      })) as OpenAI.ChatCompletion;\n      yield* synthesizeEventsFromCompletion(completion, !!options.thinking, endpointKey);\n      return completionToResponse(completion, endpointKey);\n    } catch (err) {\n      throw toError(err, providerName);\n    }\n  }\n\n  let stream: AsyncIterable<OpenAI.ChatCompletionChunk>;\n  try {\n    stream = (await client.chat.completions.create(params, {\n      signal: options.signal ?? undefined,\n    })) as AsyncIterable<OpenAI.ChatCompletionChunk>;\n  } catch (err) {\n    throw toError(err, providerName);\n  }\n\n  const contentParts: ContentPart[] = [];\n  const toolCallAccum = new Map<number, { id: string; name: string; argsJson: string }>();\n  let textAccum = \"\";\n  let thinkingAccum = \"\";\n  let inputTokens = 0;\n  let outputTokens = 0;\n  let cacheRead = 0;\n  let cacheWrite = 0;\n  let finishReason: string | null = null;\n  let receivedAnyChunk = false;\n\n  try {\n    for await (const chunk of stream) {\n      receivedAnyChunk = true;\n      const choice = chunk.choices?.[0];\n\n      if (chunk.usage) {\n        ({ inputTokens, outputTokens, cacheRead, cacheWrite } = extractOpenAIUsage(chunk.usage));\n      }\n\n      if (!choice) {\n        // A frame with no `choices` key is either gateway metadata (skip) or the\n        // provider's real error smuggled inside a 200 response (raise, so the\n        // agent loop sees the true status instead of a generic transport stall).\n        const gatewayError = classifyChoicelessFrame(chunk);\n        if (gatewayError) {\n          throw new ProviderError(providerName, gatewayError.message, {\n            statusCode: gatewayError.statusCode,\n          });\n        }\n        continue;\n      }\n\n      if (choice.finish_reason) {\n        finishReason = choice.finish_reason;\n      }\n\n      const delta = choice.delta;\n\n      // Reasoning/thinking delta (GLM, Moonshot, Xiaomi MiMo, DeepSeek)\n      // Always accumulate reasoning_content for round-tripping in multi-turn\n      // conversations (models like DeepSeek Reasoner require it on assistant\n      // messages).  Only yield thinking_delta to the UI when thinking is enabled\n      // — reasoning models like MiMo always return reasoning_content even when\n      // thinking is \"off\", which would cause a permanent \"Thinking\" indicator.\n      const reasoning = readReasoning(delta as Record<string, unknown>);\n      if (reasoning) {\n        rememberReasoningField(endpointKey, reasoning.field);\n        thinkingAccum += reasoning.text;\n        if (options.thinking) {\n          yield { type: \"thinking_delta\", text: reasoning.text };\n        }\n      }\n\n      // Text delta\n      if (delta.content) {\n        textAccum += delta.content;\n        yield { type: \"text_delta\", text: delta.content };\n      }\n\n      // Tool call deltas\n      if (delta.tool_calls) {\n        for (const tc of delta.tool_calls) {\n          let accum = toolCallAccum.get(tc.index);\n          if (!accum) {\n            accum = {\n              id: tc.id ?? \"\",\n              name: tc.function?.name ?? \"\",\n              argsJson: \"\",\n            };\n            toolCallAccum.set(tc.index, accum);\n          }\n          if (tc.id) accum.id = tc.id;\n          if (tc.function?.name) accum.name = tc.function.name;\n          if (tc.function?.arguments) {\n            accum.argsJson += tc.function.arguments;\n            yield {\n              type: \"toolcall_delta\",\n              id: accum.id,\n              name: accum.name,\n              argsJson: tc.function.arguments,\n            };\n          }\n        }\n      }\n    }\n  } catch (err) {\n    throw toError(err, providerName);\n  }\n\n  if (!receivedAnyChunk) {\n    throw new ProviderError(providerName, \"Stream ended without producing any chunks.\", {\n      statusCode: 504,\n    });\n  }\n\n  // Silent-partial guard (mirror of anthropic.ts): a complete OpenAI-compatible\n  // stream always ends with a chunk carrying `finish_reason`. The OpenAI SDK does\n  // NOT throw on a clean premature close (the body iterator just ends), so\n  // consuming chunks but never seeing a finish_reason means the stream was\n  // truncated mid-flight. Without this guard, normalizeOpenAIStopReason(null)\n  // maps the missing finish into \"end_turn\", making a truncated turn look\n  // finished. Throw a 504 so the agent loop treats it as a retryable transport\n  // failure. The partial body rides on `cause` for debugging, never returned.\n  if (finishReason === null) {\n    throw new ProviderError(providerName, \"Stream ended before completion (no finish_reason).\", {\n      statusCode: 504,\n      cause: { partialText: textAccum, outputTokens },\n    });\n  }\n\n  // Finalize thinking content (GLM, Moonshot, Xiaomi reasoning_content)\n  // Always include in response for multi-turn round-tripping, even when\n  // thinking display is off — toOpenAIMessages sends it as reasoning_content.\n  if (thinkingAccum) {\n    contentParts.push({ type: \"thinking\", text: thinkingAccum });\n  }\n\n  // Finalize text content\n  if (textAccum) {\n    contentParts.push({ type: \"text\", text: textAccum });\n  }\n\n  // Finalize tool calls\n  for (const [, tc] of toolCallAccum) {\n    const args = parseToolArguments(tc.argsJson);\n    const toolCall: ToolCall = {\n      type: \"tool_call\",\n      id: tc.id,\n      name: tc.name,\n      args,\n    };\n    contentParts.push(toolCall);\n    yield {\n      type: \"toolcall_done\",\n      id: tc.id,\n      name: tc.name,\n      args,\n    };\n  }\n\n  const stopReason = normalizeOpenAIStopReason(finishReason);\n\n  const response: StreamResponse = {\n    message: {\n      role: \"assistant\",\n      content: contentParts.length > 0 ? contentParts : textAccum || \"\",\n    },\n    stopReason,\n    usage: {\n      inputTokens,\n      outputTokens,\n      ...(cacheRead > 0 && { cacheRead }),\n      ...(cacheWrite > 0 && { cacheWrite }),\n    },\n  };\n\n  yield { type: \"done\", stopReason };\n  return response;\n}\n\n/**\n * Walk a non-streaming OpenAI ChatCompletion and yield the same StreamEvents\n * that the streaming path would produce. Emits one large delta per field so\n * the agent loop consumer observes identical behaviour to streaming mode.\n */\nfunction* synthesizeEventsFromCompletion(\n  completion: OpenAI.ChatCompletion,\n  thinkingEnabled: boolean,\n  endpointKey: string,\n): Generator<StreamEvent, void> {\n  const choice = completion.choices?.[0];\n  if (!choice) {\n    yield { type: \"done\", stopReason: normalizeOpenAIStopReason(null) };\n    return;\n  }\n\n  const msg = choice.message as unknown as Record<string, unknown>;\n\n  // Reasoning / thinking content (GLM, Moonshot, DeepSeek)\n  const reasoning = readReasoning(msg);\n  if (reasoning) {\n    rememberReasoningField(endpointKey, reasoning.field);\n    if (thinkingEnabled) yield { type: \"thinking_delta\", text: reasoning.text };\n  }\n\n  // Text content\n  if (typeof msg.content === \"string\" && msg.content) {\n    yield { type: \"text_delta\", text: msg.content };\n  }\n\n  // Tool calls\n  const toolCalls = msg.tool_calls as\n    | Array<{ id: string; function: { name: string; arguments: string } }>\n    | undefined;\n  if (toolCalls) {\n    for (const tc of toolCalls) {\n      const argsJson = tc.function?.arguments ?? \"\";\n      if (argsJson) {\n        yield {\n          type: \"toolcall_delta\",\n          id: tc.id,\n          name: tc.function?.name ?? \"\",\n          argsJson,\n        };\n      }\n      const args = parseToolArguments(argsJson);\n      yield {\n        type: \"toolcall_done\",\n        id: tc.id,\n        name: tc.function?.name ?? \"\",\n        args,\n      };\n    }\n  }\n\n  yield { type: \"done\", stopReason: normalizeOpenAIStopReason(choice.finish_reason ?? null) };\n}\n\n/** Convert a non-streaming OpenAI ChatCompletion into our StreamResponse shape. */\nfunction completionToResponse(\n  completion: OpenAI.ChatCompletion,\n  endpointKey: string,\n): StreamResponse {\n  const choice = completion.choices?.[0];\n  const contentParts: ContentPart[] = [];\n  let textAccum = \"\";\n\n  if (choice) {\n    const msg = choice.message as unknown as Record<string, unknown>;\n\n    // Reasoning content -- always included for multi-turn round-tripping\n    const reasoning = readReasoning(msg);\n    if (reasoning) {\n      rememberReasoningField(endpointKey, reasoning.field);\n      contentParts.push({ type: \"thinking\", text: reasoning.text });\n    }\n\n    if (typeof msg.content === \"string\" && msg.content) {\n      textAccum = msg.content;\n      contentParts.push({ type: \"text\", text: msg.content });\n    }\n\n    const toolCalls = msg.tool_calls as\n      | Array<{ id: string; function: { name: string; arguments: string } }>\n      | undefined;\n    if (toolCalls) {\n      for (const tc of toolCalls) {\n        const args = parseToolArguments(tc.function?.arguments ?? \"\");\n        const toolCall: ToolCall = {\n          type: \"tool_call\",\n          id: tc.id,\n          name: tc.function?.name ?? \"\",\n          args,\n        };\n        contentParts.push(toolCall);\n      }\n    }\n  }\n\n  // Usage -- match streaming path accounting (inputTokens excludes cache hits).\n  let inputTokens = 0;\n  let outputTokens = 0;\n  let cacheRead = 0;\n  let cacheWrite = 0;\n  if (completion.usage) {\n    ({ inputTokens, outputTokens, cacheRead, cacheWrite } = extractOpenAIUsage(completion.usage));\n  }\n\n  const stopReason = normalizeOpenAIStopReason(choice?.finish_reason ?? null);\n\n  return {\n    message: {\n      role: \"assistant\",\n      content: contentParts.length > 0 ? contentParts : textAccum,\n    },\n    stopReason,\n    usage: {\n      inputTokens,\n      outputTokens,\n      ...(cacheRead > 0 && { cacheRead }),\n      ...(cacheWrite > 0 && { cacheWrite }),\n    },\n  };\n}\n\n/**\n * Classify a stream frame that carries no `choices` key.\n *\n * Gateways (Portkey, Azure APIM, OpenRouter, FastAPI fronts) answer HTTP 200 and\n * then deliver the real failure as an in-stream frame. The OpenAI SDK only\n * throws for frames with a top-level `error` key, so shapes like\n * `{\"statusCode\":429,...}` or `{\"detail\":[{\"msg\":...}]}` arrive here as ordinary\n * chunks. Skipping them loses the provider's status AND message: a rate limit\n * degrades into our generic 504 \"stream ended before completion\", which the\n * agent loop retries up to 10 times with blind backoff, re-billing the full\n * prompt each attempt and ignoring the server's reset time. A gateway-reported\n * context overflow is worse — `isContextOverflow` never matches, so we never\n * compact and every one of those 10 retries is guaranteed to fail.\n *\n * Returns `null` for genuine metadata (trace ids, guardrail hook results) and\n * for the standard usage-only chunk, which carries `choices: []` — an empty\n * array is not a missing `choices` key and must never be treated as an error.\n */\nexport function classifyChoicelessFrame(\n  frame: unknown,\n): { message: string; statusCode?: number } | null {\n  if (!frame || typeof frame !== \"object\" || Array.isArray(frame)) return null;\n  const rec = frame as Record<string, unknown>;\n\n  // `choices: []` is the final usage chunk, not an error frame.\n  if (Array.isArray(rec.choices)) return null;\n\n  const statusOf = (value: unknown): number | undefined => {\n    const n = typeof value === \"string\" ? Number(value) : value;\n    return typeof n === \"number\" && Number.isFinite(n) && n >= 400 && n <= 599 ? n : undefined;\n  };\n  const statusCode = statusOf(rec.status) ?? statusOf(rec.statusCode) ?? statusOf(rec.code);\n\n  const typeIsError = typeof rec.type === \"string\" && rec.type.toLowerCase() === \"error\";\n\n  // FastAPI validation/error shape: `detail` is a string or an array of {msg}.\n  let detailText: string | undefined;\n  const detail = rec.detail;\n  if (typeof detail === \"string\" && detail.trim()) {\n    detailText = detail.trim();\n  } else if (Array.isArray(detail)) {\n    const parts = detail\n      .map((d) =>\n        d && typeof d === \"object\" && typeof (d as Record<string, unknown>).msg === \"string\"\n          ? ((d as Record<string, unknown>).msg as string)\n          : typeof d === \"string\"\n            ? d\n            : \"\",\n      )\n      .filter(Boolean);\n    if (parts.length) detailText = parts.join(\"; \");\n  }\n\n  if (statusCode === undefined && !typeIsError && !detailText) return null;\n\n  const rawMessage =\n    (typeof rec.message === \"string\" && rec.message.trim() ? rec.message.trim() : undefined) ??\n    detailText ??\n    (typeof rec.error === \"string\" && rec.error.trim() ? rec.error.trim() : undefined) ??\n    (statusCode !== undefined ? `Gateway returned status ${statusCode}.` : \"Gateway error.\");\n\n  // Never hand a whole edge/proxy page or an unbounded blob to the user.\n  const message = rawMessage.slice(0, 500);\n\n  return { message, statusCode };\n}\n\n/**\n * Classify an OpenAI-compatible error as a hard usage/quota stop, a transient\n * throttle, or neither. \"hard\" stops must NOT be retried (credit/balance/quota\n * exhaustion); \"transient\" 429s are retriable (per-minute throttle).\n */\nfunction classifyOpenAICompatLimit(args: {\n  status: number | undefined;\n  code: string | undefined;\n  type: string | undefined;\n  message: string;\n}): \"hard\" | \"transient\" | null {\n  const { status, code, type, message } = args;\n  const codeType = `${code ?? \"\"} ${type ?? \"\"}`.toLowerCase();\n  const isHard =\n    status === 402 || codeType.includes(\"insufficient_quota\") || isHardBillingMessage(message);\n  if (isHard) return \"hard\";\n  if (\n    status === 429 ||\n    codeType.includes(\"rate_limit_exceeded\") ||\n    codeType.includes(\"too_many_requests\")\n  ) {\n    return \"transient\";\n  }\n  return null;\n}\n\nfunction toError(err: unknown, provider: string = \"openai\"): ProviderError {\n  // Already classified (e.g. an in-stream gateway error frame). Re-wrapping via\n  // the generic Error branch below would discard statusCode/resetsAt and demote\n  // a 429 to an unclassified failure.\n  if (err instanceof ProviderError) return err;\n  if (err instanceof OpenAI.APIError) {\n    const body = err.error as Record<string, unknown> | undefined;\n    const bodyMessage =\n      typeof body?.message === \"string\" && body.message.trim() ? body.message.trim() : undefined;\n    const modelName = typeof body?.model === \"string\" ? body.model : \"\";\n    // The SDK may expose a whole HTML edge/proxy page either as the parsed body\n    // message or as err.message. Preserve the original on `cause`, but never send\n    // transport markup to the user.\n    const messageCandidate = bodyMessage ?? err.message;\n    const cleanMessage = isRawHtmlErrorEcho(messageCandidate)\n      ? providerHtmlErrorMessage(err.status)\n      : bodyMessage\n        ? bodyMessage\n        : isRawJsonErrorEcho(err.message)\n          ? emptyProviderErrorMessage(err.status)\n          : err.message;\n\n    let hint: string | undefined;\n    if (modelName === \"codex-mini-latest\" || cleanMessage.includes(\"codex-mini-latest\")) {\n      hint =\n        \"codex-mini-latest requires an OpenAI Pro or Max subscription. \" +\n        \"Your account currently has access to GPT-5.4 and GPT-5.4 Mini.\";\n    }\n\n    const requestId =\n      (err as unknown as { request_id?: string }).request_id ??\n      (typeof body?.request_id === \"string\" ? body.request_id : undefined);\n\n    const code = typeof err.code === \"string\" ? err.code : undefined;\n    const type = typeof err.type === \"string\" ? err.type : undefined;\n    const limit = classifyOpenAICompatLimit({\n      status: err.status,\n      code,\n      type,\n      message: cleanMessage,\n    });\n\n    if (limit === \"hard\") {\n      // Stamp the canonical \"usage limit reached\" token so downstream retry\n      // logic surfaces it once instead of burning quota on doomed retries.\n      const message = /usage limit reached/i.test(cleanMessage)\n        ? cleanMessage\n        : `usage limit reached: ${cleanMessage}`;\n      return new ProviderError(provider, message, {\n        statusCode: err.status,\n        ...(requestId ? { requestId } : {}),\n        ...(hint ? { hint } : {}),\n        cause: err,\n      });\n    }\n\n    if (limit === \"transient\") {\n      // Honor a server-stated Retry-After (seconds) so the loop waits the right\n      // amount through the existing serverResetDelayMs() path.\n      const retryAfterRaw = readHeader(err.headers, \"retry-after\");\n      const retryAfterSec = retryAfterRaw != null ? Number(retryAfterRaw) : Number.NaN;\n      const resetsAt =\n        Number.isFinite(retryAfterSec) && retryAfterSec > 0\n          ? Math.floor(Date.now() / 1000) + retryAfterSec\n          : undefined;\n      return new ProviderError(provider, cleanMessage, {\n        statusCode: err.status,\n        ...(requestId ? { requestId } : {}),\n        ...(hint ? { hint } : {}),\n        ...(resetsAt ? { resetsAt } : {}),\n        cause: err,\n      });\n    }\n\n    return new ProviderError(provider, cleanMessage, {\n      statusCode: err.status,\n      ...(requestId ? { requestId } : {}),\n      ...(hint ? { hint } : {}),\n      cause: err,\n    });\n  }\n  if (err instanceof Error) {\n    return new ProviderError(provider, err.message, { cause: err });\n  }\n  return new ProviderError(provider, String(err));\n}\n","const MAX_PROMPT_CACHE_KEY_LENGTH = 64;\n\nexport function normalizePromptCacheKey(key: string): string {\n  if (key.length <= MAX_PROMPT_CACHE_KEY_LENGTH) return key;\n  const hash = fnv1aHash(key);\n  const prefixLength = MAX_PROMPT_CACHE_KEY_LENGTH - hash.length - 1;\n  return `${key.slice(0, prefixLength)}:${hash}`;\n}\n\nfunction fnv1aHash(value: string): string {\n  let hash = 0x811c9dc5;\n  for (let index = 0; index < value.length; index++) {\n    hash ^= value.charCodeAt(index);\n    hash = Math.imul(hash, 0x01000193);\n  }\n  return (hash >>> 0).toString(16).padStart(8, \"0\");\n}\n","/**\n * Provider-level diagnostic hook. Mirrors the pattern used by gg-agent's\n * setStreamDiagnostic — the host app wires a callback (typically writing to\n * a debug log) and providers call `providerDiag(...)` to record interesting\n * lifecycle events (e.g. raw SSE event types and timings).\n */\nexport type ProviderDiagnosticFn = (phase: string, data?: Record<string, unknown>) => void;\n\nlet _diagFn: ProviderDiagnosticFn | null = null;\n\n/** Register a diagnostic callback for provider-level tracing. */\nexport function setProviderDiagnostic(fn: ProviderDiagnosticFn | null): void {\n  _diagFn = fn;\n}\n\nexport function providerDiag(phase: string, data?: Record<string, unknown>): void {\n  _diagFn?.(phase, data);\n}\n","import type OpenAI from \"openai\";\nimport type { Message, VideoContent } from \"../types.js\";\nimport { providerDiag } from \"../utils/diag.js\";\n\n/**\n * Moonshot/Kimi video upload.\n *\n * Moonshot's chat API (both `api.moonshot.ai` and the Kimi For Coding endpoint\n * `api.kimi.com/coding`) rejects inline base64 `video_url` data URLs with\n * \"invalid part type: video_url\". Videos must instead be uploaded to the\n * Moonshot file service (`POST {baseUrl}/files`, `purpose=video`) and\n * referenced in the message as `ms://<file-id>`.\n *\n * This mirrors MoonshotAI/kimi-code's `KimiFiles.uploadVideo`. We upload each\n * video part once and cache the returned id on the content part (`fileId`), so\n * subsequent turns reuse it instead of re-uploading the clip.\n */\nexport async function uploadMoonshotVideos(\n  client: OpenAI,\n  messages: Message[],\n  signal?: AbortSignal,\n): Promise<void> {\n  for (const msg of messages) {\n    if (typeof msg.content === \"string\") continue;\n    for (const part of msg.content) {\n      // Direct video parts in user messages.\n      if (part.type === \"video\") {\n        await ensureUploaded(client, part as VideoContent, signal);\n        continue;\n      }\n      // Video parts nested inside tool_result content (the path Kimi's coding\n      // endpoint actually accepts: video delivered as a read-tool result).\n      if (part.type === \"tool_result\" && Array.isArray(part.content)) {\n        for (const inner of part.content) {\n          if (inner.type === \"video\") {\n            await ensureUploaded(client, inner as VideoContent, signal);\n          }\n        }\n      }\n    }\n  }\n}\n\nasync function ensureUploaded(\n  client: OpenAI,\n  video: VideoContent,\n  signal?: AbortSignal,\n): Promise<void> {\n  if (video.fileId) {\n    providerDiag(\"moonshot_video_cached\", { fileId: video.fileId });\n    return;\n  }\n  if (!video.data) {\n    providerDiag(\"moonshot_video_skipped_no_data\", {});\n    return;\n  }\n  providerDiag(\"moonshot_video_upload_start\", {\n    mediaType: video.mediaType,\n    bytes: Math.floor((video.data.length * 3) / 4),\n  });\n  video.fileId = await uploadOne(client, video, signal);\n  providerDiag(\"moonshot_video_upload_done\", { fileId: video.fileId });\n}\n\nasync function uploadOne(\n  client: OpenAI,\n  video: VideoContent,\n  signal?: AbortSignal,\n): Promise<string> {\n  const bytes = Buffer.from(video.data, \"base64\");\n  const mediaType = video.mediaType || \"video/mp4\";\n  const filename = `upload.${extForMime(mediaType)}`;\n  // `Blob`/`File` are Node 20+ globals; the OpenAI SDK's `Uploadable` accepts a\n  // File-like object. Cast `purpose` since \"video\" is a Moonshot-specific value\n  // outside the SDK's first-party purpose union.\n  const file = new File([new Uint8Array(bytes)], filename, { type: mediaType });\n  const uploaded = (await client.files.create(\n    { file: file as never, purpose: \"video\" as never },\n    signal ? { signal } : undefined,\n  )) as unknown as { id: string };\n  return uploaded.id;\n}\n\nconst MIME_TO_EXT: Record<string, string> = {\n  \"video/mp4\": \"mp4\",\n  \"video/mpeg\": \"mpeg\",\n  \"video/quicktime\": \"mov\",\n  \"video/webm\": \"webm\",\n  \"video/x-matroska\": \"mkv\",\n  \"video/x-msvideo\": \"avi\",\n  \"video/x-flv\": \"flv\",\n  \"video/3gpp\": \"3gp\",\n};\n\nfunction extForMime(mediaType: string): string {\n  return MIME_TO_EXT[mediaType.toLowerCase()] ?? \"mp4\";\n}\n","/**\n * Read the process environment without assuming a Node global exists (gg-ai\n * runs in Node, Deno, browsers, and Workers). Returns `undefined` when no\n * `process.env` is available.\n */\nexport function getEnvironment(): Record<string, string | undefined> | undefined {\n  return (globalThis as { process?: { env?: Record<string, string | undefined> } }).process?.env;\n}\n","import os from \"node:os\";\nimport * as zstd from \"@bokuweb/zstd-wasm\";\nimport type {\n  ContentPart,\n  ImageContent,\n  Message,\n  StreamEvent,\n  StreamOptions,\n  StreamResponse,\n  Tool,\n  ToolCall,\n  ToolChoice,\n} from \"../types.js\";\nimport {\n  GGAIError,\n  ProviderError,\n  isRawHtmlErrorEcho,\n  providerHtmlErrorMessage,\n  readHeader,\n} from \"../errors.js\";\nimport { StreamResult } from \"../utils/event-stream.js\";\nimport { providerDiag } from \"../utils/diag.js\";\nimport { resolveToolSchema } from \"../utils/zod-to-json-schema.js\";\nimport { normalizePromptCacheKey } from \"./prompt-cache-key.js\";\nimport {\n  downgradeUnsupportedImages,\n  downgradeUnsupportedVideos,\n  toolResultText,\n} from \"./transform.js\";\nimport { parseToolArguments } from \"../utils/json.js\";\nimport { readSseStream } from \"../utils/sse.js\";\nimport { extractRequestIdFromMessage } from \"../utils/request-id.js\";\n\nconst DEFAULT_BASE_URL = \"https://chatgpt.com/backend-api\";\nconst CODEX_CLIENT_VERSION = \"0.144.1\";\n// OpenAI's Codex CLI enables zstd request compression by default. Keep tiny\n// synthetic/API requests readable, but compress real agent payloads before they\n// hit the backend's finite Envoy retry buffer.\nconst CODEX_REQUEST_COMPRESSION_MIN_BYTES = 16 * 1024;\n\nlet zstdInitPromise: Promise<void> | undefined;\n\ninterface EncodedCodexRequest {\n  body: BodyInit;\n  compressed: boolean;\n  rawBytes: number;\n  encodedBytes: number;\n}\n\nasync function encodeCodexRequest(body: Record<string, unknown>): Promise<EncodedCodexRequest> {\n  const json = JSON.stringify(body);\n  const raw = new TextEncoder().encode(json);\n  if (raw.byteLength < CODEX_REQUEST_COMPRESSION_MIN_BYTES) {\n    return {\n      body: json,\n      compressed: false,\n      rawBytes: raw.byteLength,\n      encodedBytes: raw.byteLength,\n    };\n  }\n\n  try {\n    zstdInitPromise ??= zstd.init();\n    await zstdInitPromise;\n    const compressed = Uint8Array.from(zstd.compress(raw));\n    if (compressed.byteLength >= raw.byteLength) {\n      return {\n        body: json,\n        compressed: false,\n        rawBytes: raw.byteLength,\n        encodedBytes: raw.byteLength,\n      };\n    }\n    return {\n      body: compressed,\n      compressed: true,\n      rawBytes: raw.byteLength,\n      encodedBytes: compressed.byteLength,\n    };\n  } catch (error) {\n    // Compression is an optimization, not a reason to make the provider\n    // unreachable if the WASM asset is missing in an unusual host.\n    providerDiag(\"codex_request_compression_failed\", {\n      error: error instanceof Error ? error.message : String(error),\n      rawBytes: raw.byteLength,\n    });\n    return {\n      body: json,\n      compressed: false,\n      rawBytes: raw.byteLength,\n      encodedBytes: raw.byteLength,\n    };\n  }\n}\n\nfunction usesResponsesLite(model: string): boolean {\n  return model.startsWith(\"gpt-5.6-\");\n}\n\nfunction outputTextKey(itemId: string | undefined, contentIndex: number | undefined): string {\n  return `${itemId ?? \"\"}:${contentIndex ?? 0}`;\n}\n\nfunction isVisibleOutputItem(itemType: string | undefined): boolean {\n  return itemType === \"message\";\n}\n\nfunction toCodexToolChoice(choice: ToolChoice | undefined, tools: Tool[] | undefined): string {\n  const resolved = choice ?? \"auto\";\n  if (typeof resolved === \"object\") {\n    throw new GGAIError(\n      `OpenAI Codex does not support selecting the named tool \\`${resolved.name}\\`; use auto, none, or required.`,\n      { source: \"capability\" },\n    );\n  }\n  if (resolved === \"required\" && !tools?.length) {\n    throw new GGAIError(\"OpenAI Codex cannot require a tool call when no tools are configured.\", {\n      source: \"capability\",\n    });\n  }\n  return resolved;\n}\n\nexport function streamOpenAICodex(options: StreamOptions): StreamResult {\n  return new StreamResult(runStream(options), options.signal);\n}\n\nasync function* runStream(options: StreamOptions): AsyncGenerator<StreamEvent, StreamResponse> {\n  const baseUrl = (options.baseUrl || DEFAULT_BASE_URL).replace(/\\/+$/, \"\");\n  const url = `${baseUrl}/codex/responses`;\n\n  const downgradedImages = downgradeUnsupportedImages(options.messages, options.supportsImages);\n  // Codex (GPT OAuth) has no video support — always strip video to a placeholder.\n  const downgraded = downgradeUnsupportedVideos(downgradedImages, options.supportsVideo);\n  const { system, input } = toCodexInput(downgraded, { supportsImages: options.supportsImages });\n\n  const responsesLite = usesResponsesLite(options.model);\n  const body: Record<string, unknown> = {\n    model: options.model,\n    store: false,\n    stream: true,\n    instructions: system,\n    input,\n    tool_choice: toCodexToolChoice(options.toolChoice, options.tools),\n    parallel_tool_calls: !responsesLite,\n    include: [\"reasoning.encrypted_content\"],\n  };\n\n  if (options.tools?.length) {\n    body.tools = toCodexTools(options.tools);\n  }\n  // Always set a prompt_cache_key. OpenAI uses this key to route requests\n  // with the same prefix to the same cache shard — without it, the codex\n  // backend hashes only the request body, so cache hits for shared\n  // system+tool prefixes across separate sub-agent processes are accidental\n  // rather than guaranteed.\n  body.prompt_cache_key = normalizePromptCacheKey(options.promptCacheKey ?? \"ggcoder\");\n  // Note: prompt_cache_retention (\"24h\") is a Responses API param, not\n  // accepted by the Codex backend — it returns 400 \"Unsupported parameter\".\n  // Cache TTL on Codex is controlled server-side (~5-10 min in-memory).\n  // The session_id + x-client-request-id headers below handle cache routing.\n  if (options.temperature != null && !options.thinking) {\n    body.temperature = options.temperature;\n  }\n  body.reasoning = {\n    // `ultra` is a client orchestration preset, not a Codex API effort.\n    effort: options.thinking === \"ultra\" ? \"max\" : (options.thinking ?? \"none\"),\n    summary: \"auto\",\n    ...(responsesLite ? { context: \"all_turns\" } : {}),\n  };\n\n  const headers: Record<string, string> = {\n    \"Content-Type\": \"application/json\",\n    Accept: \"text/event-stream\",\n    Authorization: `Bearer ${options.apiKey}`,\n    \"OpenAI-Beta\": \"responses=experimental\",\n    originator: responsesLite ? \"codex_cli_rs\" : \"ggcoder\",\n    \"User-Agent\": responsesLite\n      ? `codex_cli_rs/${CODEX_CLIENT_VERSION}`\n      : `ggcoder (${os.platform()} ${os.release()}; ${os.arch()})`,\n    ...(responsesLite\n      ? {\n          version: CODEX_CLIENT_VERSION,\n          \"X-OpenAI-Internal-Codex-Responses-Lite\": \"true\",\n        }\n      : {}),\n  };\n\n  if (options.accountId) {\n    headers[\"chatgpt-account-id\"] = options.accountId;\n  }\n\n  // Match Codex CLI's identity split: prompt_cache_key controls cache routing,\n  // while these headers identify the conversation. Sub-agents may deliberately\n  // share a cache key when their static prefixes match, but each child keeps an\n  // independent transport identity so sticky session state cannot bleed across.\n  if (options.transportSessionId) {\n    const transportSessionId = normalizePromptCacheKey(options.transportSessionId);\n    headers[\"session_id\"] = transportSessionId;\n    headers[\"x-client-request-id\"] = transportSessionId;\n  }\n\n  const encodedRequest = await encodeCodexRequest(body);\n  if (encodedRequest.compressed) headers[\"Content-Encoding\"] = \"zstd\";\n  providerDiag(\"codex_request_body\", {\n    rawBytes: encodedRequest.rawBytes,\n    encodedBytes: encodedRequest.encodedBytes,\n    compressed: encodedRequest.compressed,\n  });\n\n  const response = await fetch(url, {\n    method: \"POST\",\n    headers,\n    body: encodedRequest.body,\n    signal: options.signal,\n  });\n\n  if (!response.ok) {\n    const text = await response.text().catch(() => \"\");\n    const parsed = parseCodexErrorBody(text, response.status);\n    const message = parsed.message ?? `Codex API returned HTTP ${response.status}.`;\n    const requestId =\n      parsed.requestId ??\n      readHeader(response.headers, \"x-request-id\", \"openai-request-id\", \"x-oai-request-id\");\n\n    // ChatGPT-subscription usage-window exhaustion. The codex backend returns\n    // HTTP 429 with a usage_limit_reached / usage_not_included / rate_limit_exceeded\n    // code and a reset timestamp. Stop immediately with a clear message instead\n    // of letting the agent loop retry a 429 it can't recover from.\n    const usageLimit = codexUsageLimitError(parsed.errorObj, response.status, requestId);\n    if (usageLimit) throw usageLimit;\n\n    let hint: string | undefined;\n    if (response.status === 400 && text.includes(\"not supported\")) {\n      if (options.model === \"gpt-5.5-pro\") {\n        hint = \"Use gpt-5.5 instead. OpenAI's Codex model catalog does not list gpt-5.5-pro.\";\n      } else {\n        hint =\n          \"This model is not available through Codex for the authenticated account. \" +\n          \"Switch to a model listed for OpenAI Codex via the model selector, or check your Codex usage limits.\";\n      }\n    } else if (response.status === 404 && text.includes(\"does not exist\")) {\n      hint =\n        \"This model is not in the current OpenAI Codex catalog for this account. \" +\n        \"Switch to gpt-5.6-sol, gpt-5.6-terra, gpt-5.6-luna, or gpt-5.5 via the model selector.\";\n    }\n\n    throw new ProviderError(\"openai\", message, {\n      statusCode: response.status,\n      ...(requestId ? { requestId } : {}),\n      ...(hint ? { hint } : {}),\n    });\n  }\n\n  if (!response.body) {\n    throw new ProviderError(\"openai\", \"No response body from Codex API\");\n  }\n\n  const contentParts: ContentPart[] = [];\n  let textAccum = \"\";\n  const toolCalls = new Map<string, { id: string; name: string; argsJson: string }>();\n  // Reasoning and tool-call items in true stream arrival order. Encrypted\n  // reasoning items (store:false + include reasoning.encrypted_content) are\n  // recorded inline so each one keeps its position relative to the function_call\n  // it reasoned about — preserving the reasoning anchor even for parallel tool\n  // calls (parallels the Anthropic thinking round-trip).\n  const orderedItems: ({ kind: \"reasoning\"; part: ContentPart } | { kind: \"tool\"; id: string })[] =\n    [];\n  const outputItemTypes = new Map<string, string>();\n  const outputTextByPart = new Map<string, string>();\n  const pendingOutputTextByPart = new Map<\n    string,\n    { itemId: string; contentIndex: number; text: string }\n  >();\n  let inputTokens = 0;\n  let outputTokens = 0;\n  let cacheRead = 0;\n  let cacheWrite = 0;\n\n  // ── Diagnostic: log the first occurrence of each raw SSE event type with\n  // timing, so we can see what Codex sends during the pre-reasoning window\n  // and decide whether earlier signals are available to drive the UI.\n  const diagStart = Date.now();\n  const diagSeen = new Set<string>();\n\n  for await (const event of parseSSE(response.body)) {\n    const type = event.type as string | undefined;\n    if (!type) continue;\n\n    if (!diagSeen.has(type)) {\n      diagSeen.add(type);\n      providerDiag(\"codex_event_first\", { type, sinceStartMs: Date.now() - diagStart });\n    }\n\n    if (type === \"error\") {\n      // Codex Responses streams two error shapes:\n      //   { type:\"error\", error:{ type, code, message, param }, sequence_number }\n      //   { type:\"error\", code, message, param, sequence_number }\n      // Pick the first message field we find; fall back to the chunk code/type\n      // rather than dumping the raw JSON at the user.\n      const nested = (event.error as Record<string, unknown> | undefined) ?? undefined;\n      const message =\n        (nested?.message as string | undefined) ??\n        (event.message as string | undefined) ??\n        \"Codex stream emitted an error chunk without a message.\";\n      const code =\n        (nested?.code as string | undefined) ??\n        (nested?.type as string | undefined) ??\n        (event.code as string | undefined) ??\n        \"server_error\";\n      // OpenAI sometimes embeds the request ID inside the human-readable\n      // message (\"…request ID abc123 in your message\"); fish it out so the\n      // FormattedError can surface it on its own line.\n      const requestId =\n        extractRequestIdFromMessage(message) ?? (event.request_id as string | undefined);\n      // ChatGPT-subscription usage-window exhaustion can arrive mid-stream as an\n      // error chunk. Surface it as a hard usage-limit stop, not a retriable error.\n      const usageLimit = codexUsageLimitError(\n        nested ?? (event as Record<string, unknown>),\n        undefined,\n        requestId,\n      );\n      if (usageLimit) throw usageLimit;\n      throw new ProviderError(\"openai\", message, {\n        ...(requestId != null ? { requestId } : {}),\n        ...(code === \"server_error\" ? { statusCode: 500 } : {}),\n      });\n    }\n\n    if (type === \"response.failed\") {\n      const nested = event.error as Record<string, unknown> | undefined;\n      const message = (nested?.message as string | undefined) ?? \"Codex response failed.\";\n      const requestId =\n        extractRequestIdFromMessage(message) ?? (event.request_id as string | undefined);\n      throw new ProviderError(\"openai\", message, {\n        ...(requestId != null ? { requestId } : {}),\n      });\n    }\n\n    // Text delta. OpenAI documents response.output_text.* as output content\n    // text, while reasoning has separate response.reasoning*_text.delta events.\n    // The ChatGPT Codex transport can occasionally attach output_text chunks to\n    // reasoning or send text before item metadata. Never expose output_text unless\n    // the item is positively identified as a visible assistant message.\n    if (type === \"response.output_text.delta\") {\n      const delta = event.delta as string;\n      const itemId = event.item_id as string | undefined;\n      const contentIndex = event.content_index as number | undefined;\n      const key = outputTextKey(itemId, contentIndex);\n      outputTextByPart.set(key, `${outputTextByPart.get(key) ?? \"\"}${delta}`);\n      const itemType = itemId ? outputItemTypes.get(itemId) : undefined;\n      if (itemId && isVisibleOutputItem(itemType)) {\n        textAccum += delta;\n        yield { type: \"text_delta\", text: delta };\n      } else if (itemId && itemType == null) {\n        const pending = pendingOutputTextByPart.get(key);\n        pendingOutputTextByPart.set(key, {\n          itemId,\n          contentIndex: contentIndex ?? 0,\n          text: `${pending?.text ?? \"\"}${delta}`,\n        });\n      }\n    }\n\n    // Text done. The final event can contain text not seen in deltas; emit only\n    // the missing suffix so consumers don't see duplicate visible output, and\n    // only after item metadata proves the part belongs to a message.\n    if (type === \"response.output_text.done\") {\n      const fullText = event.text as string | undefined;\n      if (fullText) {\n        const itemId = event.item_id as string | undefined;\n        const contentIndex = event.content_index as number | undefined;\n        const key = outputTextKey(itemId, contentIndex);\n        const streamedText = outputTextByPart.get(key) ?? \"\";\n        const missingText = streamedText ? fullText.slice(streamedText.length) : fullText;\n        outputTextByPart.set(key, fullText);\n        if (missingText && fullText.startsWith(streamedText)) {\n          const itemType = itemId ? outputItemTypes.get(itemId) : undefined;\n          if (itemId && isVisibleOutputItem(itemType)) {\n            textAccum += missingText;\n            yield { type: \"text_delta\", text: missingText };\n          } else if (itemId && itemType == null) {\n            const pending = pendingOutputTextByPart.get(key);\n            pendingOutputTextByPart.set(key, {\n              itemId,\n              contentIndex: contentIndex ?? 0,\n              text: `${pending?.text ?? \"\"}${missingText}`,\n            });\n          }\n        }\n      }\n    }\n\n    // Thinking delta\n    if (\n      type === \"response.reasoning_summary_text.delta\" ||\n      type === \"response.reasoning_summary.delta\" ||\n      type === \"response.reasoning_text.delta\" ||\n      type === \"response.reasoning.delta\"\n    ) {\n      const delta = event.delta as string;\n      if (options.thinking) yield { type: \"thinking_delta\", text: delta };\n    }\n\n    // Reasoning item started — the model has begun reasoning on the server.\n    // Surface this as an empty thinking_delta so the UI can flip to the\n    // \"thinking\" phase ~3s before the summary text actually starts streaming.\n    // (Codex emits this at ~1s vs reasoning_summary_text.delta at ~4–10s.)\n    if (type === \"response.output_item.added\") {\n      const item = event.item as Record<string, unknown>;\n      const itemId = item?.id as string | undefined;\n      const itemType = item?.type as string | undefined;\n      if (itemId && itemType) {\n        outputItemTypes.set(itemId, itemType);\n      }\n      if (itemType === \"reasoning\" && options.thinking) {\n        yield { type: \"thinking_delta\", text: \"\" };\n      }\n      if (itemId && itemType) {\n        const pending = [...pendingOutputTextByPart.entries()]\n          .filter(([, pendingPart]) => pendingPart.itemId === itemId)\n          .sort(([, a], [, b]) => a.contentIndex - b.contentIndex);\n        for (const [key, pendingPart] of pending) {\n          pendingOutputTextByPart.delete(key);\n          if (!pendingPart.text) continue;\n          if (isVisibleOutputItem(itemType)) {\n            textAccum += pendingPart.text;\n            yield { type: \"text_delta\", text: pendingPart.text };\n          }\n        }\n      }\n    }\n\n    // Tool call started\n    if (type === \"response.output_item.added\") {\n      const item = event.item as Record<string, unknown>;\n      if (item?.type === \"function_call\") {\n        const callId = item.call_id as string;\n        const itemId = item.id as string;\n        const id = `${callId}|${itemId}`;\n        const name = item.name as string;\n        toolCalls.set(id, { id, name, argsJson: (item.arguments as string) || \"\" });\n      }\n    }\n\n    // Tool call arguments delta\n    if (type === \"response.function_call_arguments.delta\") {\n      const delta = event.delta as string;\n      const itemId = event.item_id as string;\n      // Find the matching tool call\n      for (const [key, tc] of toolCalls) {\n        if (key.endsWith(`|${itemId}`)) {\n          tc.argsJson += delta;\n          yield {\n            type: \"toolcall_delta\",\n            id: tc.id,\n            name: tc.name,\n            argsJson: delta,\n          };\n          break;\n        }\n      }\n    }\n\n    // Tool call arguments done\n    if (type === \"response.function_call_arguments.done\") {\n      const itemId = event.item_id as string;\n      const argsStr = event.arguments as string;\n      for (const [key, tc] of toolCalls) {\n        if (key.endsWith(`|${itemId}`)) {\n          tc.argsJson = argsStr;\n          break;\n        }\n      }\n    }\n\n    // Item done — capture encrypted reasoning (round-trips next request) and\n    // finalize tool calls, recording both in stream arrival order.\n    if (type === \"response.output_item.done\") {\n      const item = event.item as Record<string, unknown>;\n      if (item?.type === \"reasoning\") {\n        const encrypted = item.encrypted_content as string | undefined;\n        const reasoningId = item.id as string | undefined;\n        if (encrypted && reasoningId) {\n          // Preserve the entire reasoning item verbatim so it round-trips\n          // byte-identical (summary defaulted to [] since the API requires an\n          // array). Re-emitting the exact item OpenAI returned is what keeps\n          // store:false replay valid — reconstructing a subset risks dropping\n          // fields the API echoes back.\n          orderedItems.push({\n            kind: \"reasoning\",\n            part: {\n              type: \"raw\",\n              data: { ...item, summary: Array.isArray(item.summary) ? item.summary : [] },\n            },\n          });\n        }\n      }\n      if (item?.type === \"function_call\") {\n        const callId = item.call_id as string;\n        const itemId = item.id as string;\n        const id = `${callId}|${itemId}`;\n        const tc = toolCalls.get(id);\n        if (tc) {\n          orderedItems.push({ kind: \"tool\", id });\n          const args = parseToolArguments(tc.argsJson);\n          yield {\n            type: \"toolcall_done\",\n            id: tc.id,\n            name: tc.name,\n            args,\n          };\n        }\n      }\n    }\n\n    // Response completed\n    if (type === \"response.completed\" || type === \"response.done\") {\n      const resp = event.response as Record<string, unknown> | undefined;\n      const usage = resp?.usage as\n        | (Record<string, number> & {\n            input_tokens_details?: { cached_tokens?: number; cache_write_tokens?: number };\n          })\n        | undefined;\n      if (usage) {\n        cacheRead = usage.input_tokens_details?.cached_tokens ?? 0;\n        cacheWrite = usage.input_tokens_details?.cache_write_tokens ?? 0;\n        inputTokens = (usage.input_tokens ?? 0) - cacheRead - cacheWrite;\n        outputTokens = usage.output_tokens ?? 0;\n      }\n    }\n  }\n\n  // Finalize content parts. Any encrypted reasoning that arrived before the\n  // first tool call leads the message so it precedes the function_call it\n  // reasoned about when round-tripped into input; visible answer text sits\n  // between leading reasoning and the tool calls.\n  const seenTool = new Set<string>();\n  let textInserted = false;\n  for (const entry of orderedItems) {\n    if (entry.kind === \"reasoning\") {\n      contentParts.push(entry.part);\n      continue;\n    }\n    if (textAccum && !textInserted) {\n      contentParts.push({ type: \"text\", text: textAccum });\n      textInserted = true;\n    }\n    const tc = toolCalls.get(entry.id);\n    if (!tc || seenTool.has(entry.id)) continue;\n    seenTool.add(entry.id);\n    const toolCall: ToolCall = {\n      type: \"tool_call\",\n      id: tc.id,\n      name: tc.name,\n      args: parseToolArguments(tc.argsJson),\n    };\n    contentParts.push(toolCall);\n  }\n  if (textAccum && !textInserted) {\n    contentParts.push({ type: \"text\", text: textAccum });\n  }\n\n  // Tool calls whose output_item.done never arrived (defensive — finalize from\n  // the toolCalls map in insertion order so none are dropped).\n  for (const [id, tc] of toolCalls) {\n    if (seenTool.has(id)) continue;\n    seenTool.add(id);\n    contentParts.push({\n      type: \"tool_call\",\n      id: tc.id,\n      name: tc.name,\n      args: parseToolArguments(tc.argsJson),\n    });\n  }\n\n  const hasToolCalls = contentParts.some((p) => p.type === \"tool_call\");\n  const stopReason = hasToolCalls ? \"tool_use\" : \"end_turn\";\n\n  const streamResponse: StreamResponse = {\n    message: {\n      role: \"assistant\",\n      content: contentParts.length > 0 ? contentParts : textAccum || \"\",\n    },\n    stopReason,\n    usage: {\n      inputTokens,\n      outputTokens,\n      ...(cacheRead > 0 && { cacheRead }),\n      ...(cacheWrite > 0 && { cacheWrite }),\n    },\n  };\n\n  yield { type: \"done\", stopReason };\n  return streamResponse;\n}\n\n// ── SSE Parser ─────────────────────────────────────────────\n\nasync function* parseSSE(\n  body: ReadableStream<Uint8Array>,\n): AsyncGenerator<Record<string, unknown>> {\n  for await (const event of readSseStream(body)) {\n    const data = event.data.trim();\n    if (!data || data === \"[DONE]\") continue;\n    try {\n      yield JSON.parse(data) as Record<string, unknown>;\n    } catch {\n      // skip malformed JSON\n    }\n  }\n}\n\n// ── Message Conversion ─────────────────────────────────────\n\n/**\n * Remap tool call IDs to Codex's stricter ID grammar.\n * Codex expects function-call IDs to start with `fc_`/`fc-` and contain only\n * letters, numbers, underscores, or dashes. Continued sessions can contain IDs\n * from other transports/tools such as `toolu_*` or `fc_tasks:153`.\n */\nfunction remapCodexId(id: string, idMap: Map<string, string>): string {\n  const existing = idMap.get(id);\n  if (existing) return existing;\n\n  const withPrefix =\n    id.startsWith(\"fc_\") || id.startsWith(\"fc-\") ? id : `fc_${id.replace(/^toolu_/, \"\")}`;\n  const sanitized = withPrefix.replace(/[^A-Za-z0-9_-]/g, \"_\");\n  let mapped = sanitized;\n  let suffix = 2;\n  const used = new Set(idMap.values());\n  while (used.has(mapped)) {\n    mapped = `${sanitized}_${suffix++}`;\n  }\n  idMap.set(id, mapped);\n  return mapped;\n}\n\n/** A raw content part that holds a Codex encrypted reasoning item for round-trip. */\nfunction isEncryptedReasoning(\n  data: Record<string, unknown>,\n): data is { type: \"reasoning\"; id: string; encrypted_content: string; summary?: unknown } {\n  return (\n    data.type === \"reasoning\" &&\n    typeof data.id === \"string\" &&\n    typeof data.encrypted_content === \"string\"\n  );\n}\n\nfunction toCodexInput(\n  messages: Message[],\n  options?: { supportsImages?: boolean },\n): { system: string | undefined; input: unknown[] } {\n  let system: string | undefined;\n  const input: unknown[] = [];\n  const idMap = new Map<string, string>();\n\n  for (const msg of messages) {\n    if (msg.role === \"system\") {\n      system = msg.content;\n      continue;\n    }\n\n    if (msg.role === \"user\") {\n      const content =\n        typeof msg.content === \"string\"\n          ? [{ type: \"input_text\", text: msg.content }]\n          : msg.content.map((part) => {\n              if (part.type === \"text\") return { type: \"input_text\", text: part.text };\n              return {\n                type: \"input_image\",\n                detail: \"auto\",\n                image_url: `data:${part.mediaType};base64,${part.data}`,\n              };\n            });\n      input.push({ role: \"user\", content });\n      continue;\n    }\n\n    if (msg.role === \"assistant\") {\n      if (typeof msg.content === \"string\") {\n        input.push({\n          type: \"message\",\n          role: \"assistant\",\n          content: [{ type: \"output_text\", text: msg.content, annotations: [] }],\n          status: \"completed\",\n        });\n        continue;\n      }\n\n      for (const part of msg.content) {\n        if (part.type === \"raw\" && isEncryptedReasoning(part.data)) {\n          // Re-emit the captured reasoning item verbatim in its original\n          // position so it precedes the following function_call (requires\n          // store:false + include reasoning.encrypted_content, both set on the\n          // request).\n          input.push(part.data);\n        } else if (part.type === \"text\") {\n          input.push({\n            type: \"message\",\n            role: \"assistant\",\n            content: [{ type: \"output_text\", text: part.text, annotations: [] }],\n            status: \"completed\",\n          });\n        } else if (part.type === \"tool_call\") {\n          const [callId, itemId] = part.id.includes(\"|\")\n            ? part.id.split(\"|\", 2)\n            : [part.id, part.id];\n          input.push({\n            type: \"function_call\",\n            id: remapCodexId(itemId, idMap),\n            call_id: remapCodexId(callId, idMap),\n            name: part.name,\n            arguments: JSON.stringify(part.args),\n          });\n        }\n        // thinking parts (and non-reasoning raw parts) are skipped for codex input\n      }\n      continue;\n    }\n\n    if (msg.role === \"tool\") {\n      const toolImages: ImageContent[] = [];\n      for (const result of msg.content) {\n        const [callId] = result.toolCallId.includes(\"|\")\n          ? result.toolCallId.split(\"|\", 2)\n          : [result.toolCallId];\n        const text = toolResultText(result.content);\n        input.push({\n          type: \"function_call_output\",\n          call_id: remapCodexId(callId, idMap),\n          output: text.length > 0 ? text : \"(see attached image)\",\n        });\n        if (options?.supportsImages !== false && Array.isArray(result.content)) {\n          for (const block of result.content) {\n            if (block.type === \"image\") toolImages.push(block);\n          }\n        }\n      }\n      if (toolImages.length > 0) {\n        input.push({\n          type: \"message\",\n          role: \"user\",\n          content: [\n            { type: \"input_text\", text: \"Attached image(s) from tool result:\" },\n            ...toolImages.map((img) => ({\n              type: \"input_image\",\n              detail: \"auto\",\n              image_url: `data:${img.mediaType};base64,${img.data}`,\n            })),\n          ],\n        });\n      }\n    }\n  }\n\n  return { system, input };\n}\n\n// ── Tool Conversion ────────────────────────────────────────\n\nfunction toCodexTools(tools: Tool[]): unknown[] {\n  return tools.map((tool) => ({\n    type: \"function\",\n    name: tool.name,\n    description: tool.description,\n    parameters: resolveToolSchema(tool),\n    strict: null,\n  }));\n}\n\n// HTTP error bodies may be JSON, useful plain text, or an HTML edge/proxy page.\n// Extract a bounded message plus request ID while keeping raw JSON and markup out\n// of every user-facing error path.\nfunction parseCodexErrorBody(\n  text: string,\n  statusCode: number,\n): {\n  message?: string;\n  requestId?: string;\n  errorObj?: Record<string, unknown>;\n} {\n  if (!text) return {};\n  try {\n    const parsed = JSON.parse(text) as Record<string, unknown>;\n    const error = parsed.error as Record<string, unknown> | undefined;\n    const detail = parsed.detail as unknown;\n    const rawMessage =\n      (error?.message as string | undefined) ??\n      (parsed.message as string | undefined) ??\n      (typeof detail === \"string\" ? detail : undefined);\n    const message =\n      rawMessage && isRawHtmlErrorEcho(rawMessage)\n        ? providerHtmlErrorMessage(statusCode)\n        : rawMessage;\n    const requestId =\n      (parsed.request_id as string | undefined) ??\n      (error?.request_id as string | undefined) ??\n      (message ? extractRequestIdFromMessage(message) : undefined);\n    // Some codex error payloads put the usage-limit fields at the top level\n    // rather than under `error` — prefer the nested object but fall back to the\n    // whole payload so resets_at / code are still visible.\n    const errorObj = error ?? parsed;\n    return {\n      ...(message ? { message } : {}),\n      ...(requestId ? { requestId } : {}),\n      ...(errorObj ? { errorObj } : {}),\n    };\n  } catch {\n    const trimmed = text.trim();\n    if (isRawHtmlErrorEcho(trimmed)) {\n      return { message: providerHtmlErrorMessage(statusCode) };\n    }\n    // Preserve useful plain-text errors, capped to keep accidental proxy output bounded.\n    const bounded = trimmed.slice(0, 240);\n    return bounded ? { message: bounded } : {};\n  }\n}\n\nconst CODEX_USAGE_LIMIT_CODE = /usage_limit_reached|usage_not_included/i;\nconst CODEX_RATE_LIMIT_CODE = /rate_limit_exceeded/i;\n\n/**\n * Detect a ChatGPT-subscription usage-window exhaustion from a Codex error\n * payload and build a canonical usage-limit ProviderError. The codex backend\n * returns HTTP 429 with an error `code`/`type` of usage_limit_reached /\n * usage_not_included (hard plan-window stop) or rate_limit_exceeded, plus a\n * `resets_at` (unix seconds) directly or nested under `rate_limits.primary` /\n * `.secondary` (or a `resets_in_seconds` countdown).\n *\n * Returns null for anything that isn't clearly a usage-window stop — a bare\n * transient 429 with no reset info still flows through the normal retry path.\n */\nfunction codexUsageLimitError(\n  errorObj: Record<string, unknown> | undefined,\n  statusCode: number | undefined,\n  requestId: string | undefined,\n): ProviderError | null {\n  const code = String(errorObj?.code ?? errorObj?.type ?? \"\");\n  const rateLimits = errorObj?.rate_limits as\n    | { primary?: { resets_at?: number }; secondary?: { resets_at?: number } }\n    | undefined;\n  const resetsAtRaw =\n    (typeof errorObj?.resets_at === \"number\" ? (errorObj.resets_at as number) : undefined) ??\n    rateLimits?.primary?.resets_at ??\n    rateLimits?.secondary?.resets_at;\n  const resetsInSeconds =\n    typeof errorObj?.resets_in_seconds === \"number\"\n      ? (errorObj.resets_in_seconds as number)\n      : undefined;\n  const resetsAt =\n    typeof resetsAtRaw === \"number\" && resetsAtRaw > 0\n      ? resetsAtRaw\n      : resetsInSeconds != null && resetsInSeconds > 0\n        ? Math.floor(Date.now() / 1000) + resetsInSeconds\n        : undefined;\n\n  const isHardUsage = CODEX_USAGE_LIMIT_CODE.test(code);\n  const isRateOr429 = CODEX_RATE_LIMIT_CODE.test(code) || statusCode === 429;\n  if (!isHardUsage && !(isRateOr429 && resetsAt != null)) return null;\n\n  return new ProviderError(\"openai\", \"ChatGPT usage limit reached\", {\n    statusCode: statusCode ?? 429,\n    ...(requestId ? { requestId } : {}),\n    ...(resetsAt ? { resetsAt } : {}),\n  });\n}\n","export interface SseEvent {\n  event?: string;\n  data: string;\n}\n\n/**\n * Pure incremental SSE parser. Splits a buffer on blank lines (`\\n\\n`),\n * extracting `event:` names and joined `data:` payloads. Returns the parsed\n * events plus any trailing partial event still buffered.\n *\n * Input is expected to already be CRLF-normalized (`\\r\\n` → `\\n`).\n */\nexport function parseSseBuffer(buffer: string): { events: SseEvent[]; remaining: string } {\n  const events: SseEvent[] = [];\n  let cursor = 0;\n\n  while (true) {\n    const next = buffer.indexOf(\"\\n\\n\", cursor);\n    if (next === -1) break;\n    const raw = buffer.slice(cursor, next);\n    cursor = next + 2;\n\n    let eventName: string | undefined;\n    const dataLines: string[] = [];\n    for (const line of raw.split(\"\\n\")) {\n      if (line.startsWith(\"event:\")) {\n        eventName = line.slice(\"event:\".length).trim();\n      } else if (line.startsWith(\"data:\")) {\n        dataLines.push(line.slice(\"data:\".length).trimStart());\n      }\n    }\n\n    if (dataLines.length > 0) {\n      events.push({ event: eventName, data: dataLines.join(\"\\n\") });\n    }\n  }\n\n  return { events, remaining: buffer.slice(cursor) };\n}\n\n/**\n * Stream wrapper over a web `ReadableStream`. Decodes bytes, normalizes CRLF,\n * yields each complete SSE event, and flushes the trailing buffer after the\n * stream ends (so a final event lacking a trailing blank line is not dropped).\n */\nexport async function* readSseStream(body: ReadableStream<Uint8Array>): AsyncGenerator<SseEvent> {\n  const reader = body.getReader();\n  const decoder = new TextDecoder();\n  let buffer = \"\";\n\n  try {\n    while (true) {\n      const { done, value } = await reader.read();\n      if (done) break;\n      buffer += decoder.decode(value, { stream: true }).replace(/\\r\\n/g, \"\\n\");\n      const parsed = parseSseBuffer(buffer);\n      buffer = parsed.remaining;\n      yield* parsed.events;\n    }\n    buffer += decoder.decode().replace(/\\r\\n/g, \"\\n\");\n    const parsed = parseSseBuffer(buffer + \"\\n\\n\");\n    yield* parsed.events;\n  } finally {\n    reader.releaseLock();\n  }\n}\n","// OpenAI's server_error messages embed the request ID inline (\"…request ID\n// abc123 in your message\"). Pull it out so we can surface it as a structured\n// field rather than leaving it buried in the message.\nexport function extractRequestIdFromMessage(message: string): string | undefined {\n  const match = message.match(/request ID ([a-z0-9-]{8,})/i);\n  return match?.[1];\n}\n","import type {\n  ContentPart,\n  Message,\n  StreamEvent,\n  StreamOptions,\n  StreamResponse,\n  Tool,\n  ToolCall,\n  ToolChoice,\n  ToolResultContent,\n} from \"../types.js\";\nimport { ProviderError } from \"../errors.js\";\nimport { StreamResult } from \"../utils/event-stream.js\";\nimport { downgradeUnsupportedImages, downgradeUnsupportedVideos } from \"./transform.js\";\nimport { resolveToolSchema } from \"../utils/zod-to-json-schema.js\";\nimport { isJsonObject } from \"../utils/json.js\";\nimport { readSseStream } from \"../utils/sse.js\";\nimport { getEnvironment } from \"../utils/env.js\";\n\nconst DEFAULT_CODE_ASSIST_BASE_URL = \"https://cloudcode-pa.googleapis.com\";\nconst CODE_ASSIST_API_VERSION = \"v1internal\";\nconst GEMINI_CLI_USER_AGENT = \"google-gemini-cli\";\nconst GEMINI_CLI_API_CLIENT = \"gemini-cli/0.0.0\";\nconst CODE_ASSIST_NON_STREAMING_RETRIES = 3;\nconst CODE_ASSIST_NON_STREAMING_RETRY_DELAY_MS = 1_000;\nconst SYNTHETIC_THOUGHT_SIGNATURE = \"skip_thought_signature_validator\";\n// Mirrors VALID_GEMINI_MODELS in the official gemini-cli\n// (packages/core/src/config/models.ts). Preview flash-lite went GA and was\n// renamed to `gemini-3.1-flash-lite`; `gemini-3.5-flash` (and its backend alias\n// `gemini-3-flash`) are now served over Code Assist. `gemini-3.7-flash` is\n// AHEAD of upstream: gemini-cli hasn't listed it yet (issue #28802), but the\n// model is GA on the Gemini API and entitled Code Assist accounts serve it.\nconst CODE_ASSIST_SUPPORTED_MODELS = new Set([\n  \"gemini-3-pro-preview\",\n  \"gemini-3.1-pro-preview\",\n  \"gemini-3.1-pro-preview-customtools\",\n  \"gemini-3-flash-preview\",\n  \"gemini-3.5-flash\",\n  \"gemini-3-flash\",\n  \"gemini-3.1-flash-lite\",\n  \"gemini-3.7-flash\",\n  \"gemini-2.5-pro\",\n  \"gemini-2.5-flash\",\n  \"gemma-4-31b-it\",\n  \"gemma-4-26b-a4b-it\",\n]);\n\ninterface GeminiTextPart {\n  text: string;\n  thought?: boolean;\n  thoughtSignature?: string;\n}\n\ninterface GeminiInlineDataPart {\n  inlineData: {\n    mimeType: string;\n    data: string;\n  };\n}\n\ninterface GeminiFunctionCallPart {\n  functionCall: {\n    id?: string;\n    name: string;\n    args?: Record<string, unknown>;\n  };\n  thoughtSignature?: string;\n}\n\ninterface GeminiFunctionResponsePart {\n  functionResponse: {\n    id?: string;\n    name: string;\n    response: Record<string, unknown>;\n  };\n}\n\ntype GeminiPart =\n  | GeminiTextPart\n  | GeminiInlineDataPart\n  | GeminiFunctionCallPart\n  | GeminiFunctionResponsePart;\n\ninterface GeminiContent {\n  role?: \"user\" | \"model\";\n  parts: GeminiPart[];\n}\n\ninterface GeminiTool {\n  functionDeclarations: Array<{\n    name: string;\n    description?: string;\n    parameters?: Record<string, unknown>;\n  }>;\n}\n\ninterface GeminiGenerationConfig {\n  maxOutputTokens?: number;\n  temperature?: number;\n  topP?: number;\n  stopSequences?: string[];\n  thinkingConfig?: {\n    includeThoughts?: boolean;\n    thinkingBudget?: number;\n    thinkingLevel?: \"LOW\" | \"MEDIUM\" | \"HIGH\";\n  };\n}\n\ninterface GeminiGenerateContentRequest {\n  contents: GeminiContent[];\n  systemInstruction?: GeminiContent;\n  tools?: GeminiTool[];\n  toolConfig?: {\n    functionCallingConfig: {\n      mode: \"AUTO\" | \"NONE\" | \"ANY\";\n      allowedFunctionNames?: string[];\n    };\n  };\n  generationConfig?: GeminiGenerationConfig;\n  session_id?: string;\n}\n\ninterface GeminiCodeAssistRequest {\n  model: string;\n  project?: string;\n  user_prompt_id: string;\n  request: GeminiGenerateContentRequest;\n}\n\ninterface GeminiRequestPlan {\n  url: URL;\n  headers: Record<string, string>;\n  body: GeminiCodeAssistRequest;\n}\n\ninterface GeminiCandidate {\n  content?: GeminiContent;\n  finishReason?: string;\n}\n\ninterface GeminiUsageMetadata {\n  promptTokenCount?: number;\n  candidatesTokenCount?: number;\n  totalTokenCount?: number;\n  cachedContentTokenCount?: number;\n  thoughtsTokenCount?: number;\n}\n\ninterface GeminiGenerateResponse {\n  traceId?: string;\n  response?: {\n    candidates?: GeminiCandidate[];\n    usageMetadata?: GeminiUsageMetadata;\n  };\n  candidates?: GeminiCandidate[];\n  usageMetadata?: GeminiUsageMetadata;\n}\n\nfunction getGoogleProject(options: StreamOptions): string | undefined {\n  const env = getEnvironment();\n  return options.projectId ?? env?.GOOGLE_CLOUD_PROJECT ?? env?.GOOGLE_CLOUD_PROJECT_ID;\n}\n\nfunction getCodeAssistEndpoint(method: string): URL {\n  const env = getEnvironment();\n  const endpoint = env?.CODE_ASSIST_ENDPOINT ?? DEFAULT_CODE_ASSIST_BASE_URL;\n  const version = env?.CODE_ASSIST_API_VERSION || CODE_ASSIST_API_VERSION;\n  return new URL(`${endpoint}/${version}:${method}`);\n}\n\nfunction formatUnsupportedModelMessage(model: string): string {\n  return `Gemini OAuth is configured to use the Gemini Code Assist subscription endpoint only. That endpoint does not currently expose model \"${model}\".`;\n}\n\n// Models that exist in the Code Assist catalog but are gated per-account by\n// Google (Code Assist Standard/Enterprise + admin/preview enablement). A 404 on\n// these is an entitlement problem, not a wrong model string — free/personal\n// OAuth accounts routinely can't call them. Explain that instead of echoing the\n// bare \"Requested entity was not found\" body, which reads like an app bug.\nconst ACCOUNT_GATED_MODELS = new Set([\n  \"gemini-3-flash\",\n  \"gemini-3.5-flash\",\n  \"gemini-3.1-pro-preview\",\n  \"gemini-3.1-pro-preview-customtools\",\n  \"gemini-3.7-flash\",\n]);\n\n// The user-facing account-gated message is split so the error UI (gg-app + TUI)\n// can render it as `message` (what happened — an entitlement gap, not a bug)\n// plus `hint` (the actionable next step, shown on the dedicated guidance line).\nfunction accountGatedMessage(model: string): string {\n  return (\n    `Your Google account isn't entitled to \"${model}\" over Gemini Code Assist OAuth, ` +\n    `so the API reports it as not found. This is an account-access limit, not a ggcoder bug.`\n  );\n}\n\nfunction accountGatedHint(): string {\n  return (\n    `Newer Gemini models (3.7 Flash, 3.5 Flash, 3.1 Pro Preview) are available only to Code Assist ` +\n    `Standard/Enterprise accounts with preview/GA access enabled by a cloud admin — ` +\n    `free/personal accounts usually can't call them. Switch to Gemini 3.1 Flash Lite ` +\n    `(it works on this account) with /model, or sign in with a Code Assist ` +\n    `Standard/Enterprise account that has preview access.`\n  );\n}\n\nfunction formatErrorMessage(status: number, body: string, model: string): string {\n  if (status === 404 && !CODE_ASSIST_SUPPORTED_MODELS.has(model)) {\n    return `Gemini API error (404): ${body}\\n\\n${formatUnsupportedModelMessage(model)}`;\n  }\n  return `Gemini API error (${status}): ${body}`;\n}\n\n/**\n * Gemini answers HTTP 429 with status `RESOURCE_EXHAUSTED` for two distinct\n * conditions that must be handled differently:\n *\n *  - **Transient per-minute throttle** — the body carries a `RetryInfo` detail\n *    with a short `retryDelay` (e.g. \"18s\"). Retrying after that delay clears it.\n *  - **Hard quota exhaustion** — daily cap, disabled billing, or an\n *    unprovisioned preview model. No `retryDelay`, and the message says the\n *    capacity/quota is exhausted. Retrying just burns the backoff budget and\n *    misleads the user with \"Rate limited — retrying\", so the agent loop must\n *    surface it immediately.\n *\n * This returns the parsed signal so the caller can stamp `resetsAt` (transient)\n * onto the ProviderError, or mark it a hard quota error (non-retriable).\n */\ninterface GeminiQuotaSignal {\n  /** Hard exhaustion — the loop should surface immediately, not retry. */\n  exhausted: boolean;\n  /** Seconds until the throttle clears, parsed from RetryInfo.retryDelay. */\n  retryDelaySeconds?: number;\n}\n\nfunction parseRetryDelaySeconds(body: string): number | undefined {\n  // RetryInfo.retryDelay is a protobuf Duration string like \"18s\" or \"1.5s\".\n  const match = body.match(/\"retryDelay\"\\s*:\\s*\"(\\d+(?:\\.\\d+)?)s\"/);\n  if (!match) return undefined;\n  const seconds = Number(match[1]);\n  return Number.isFinite(seconds) ? seconds : undefined;\n}\n\nfunction parseGeminiQuota(status: number, body: string): GeminiQuotaSignal | null {\n  if (status !== 429) return null;\n  const lower = body.toLowerCase();\n  if (!lower.includes(\"resource_exhausted\") && !lower.includes(\"quota\")) return null;\n  // The presence of a `RetryInfo.retryDelay` is Gemini's authoritative signal\n  // that the 429 is a recoverable throttle: it tells us exactly how long to\n  // wait. Its absence means a hard stop (daily cap, disabled billing, or an\n  // unprovisioned preview model) that won't clear with a quick retry. We rely\n  // on this delay rather than sniffing message wording, since per-minute and\n  // per-day quota IDs both appear in the body regardless of which limit fired.\n  const retryDelaySeconds = parseRetryDelaySeconds(body);\n  const exhausted = retryDelaySeconds === undefined;\n  return { exhausted, retryDelaySeconds };\n}\n\nfunction toSystemAndContents(messages: Message[]): {\n  systemInstruction?: GeminiContent;\n  contents: GeminiContent[];\n} {\n  let systemText = \"\";\n  const contents: GeminiContent[] = [];\n  const toolNamesById = new Map<string, string>();\n\n  for (const msg of messages) {\n    if (msg.role === \"system\") {\n      systemText = systemText ? `${systemText}\\n\\n${msg.content}` : msg.content;\n      continue;\n    }\n\n    if (msg.role === \"user\") {\n      contents.push({\n        role: \"user\",\n        parts:\n          typeof msg.content === \"string\"\n            ? [{ text: msg.content }]\n            : msg.content.map((part): GeminiPart => {\n                if (part.type === \"text\") return { text: part.text };\n                // Both image and video ride Gemini's inlineData part shape.\n                return { inlineData: { mimeType: part.mediaType, data: part.data } };\n              }),\n      });\n      continue;\n    }\n\n    if (msg.role === \"assistant\") {\n      const parts: GeminiPart[] = [];\n      const source = msg.content;\n      if (typeof source === \"string\") {\n        if (source) parts.push({ text: source });\n      } else {\n        for (const part of source) {\n          if (part.type === \"text\" && part.text) {\n            parts.push({ text: part.text });\n          } else if (part.type === \"thinking\" && part.text) {\n            parts.push({ text: part.text });\n          } else if (part.type === \"tool_call\") {\n            toolNamesById.set(part.id, part.name);\n            parts.push({\n              functionCall: { id: part.id, name: part.name, args: part.args },\n              thoughtSignature: SYNTHETIC_THOUGHT_SIGNATURE,\n            });\n          }\n        }\n      }\n      if (parts.length > 0) contents.push({ role: \"model\", parts });\n      continue;\n    }\n\n    if (msg.role === \"tool\") {\n      const parts: GeminiPart[] = [];\n      for (const result of msg.content) {\n        const name = toolNamesById.get(result.toolCallId) ?? result.toolCallId;\n        const content =\n          typeof result.content === \"string\"\n            ? result.content\n            : stringifyToolContent(result.content);\n        parts.push({\n          functionResponse: {\n            id: result.toolCallId,\n            name,\n            response: {\n              content,\n              ...(result.isError ? { isError: true } : {}),\n            },\n          },\n        });\n        // functionResponse can't carry media, so a tool that returned video\n        // (e.g. read on a .mp4) gets its clips appended as inlineData parts the\n        // model actually watches. stringifyToolContent left a text marker above.\n        if (typeof result.content !== \"string\") {\n          for (const block of result.content) {\n            if (block.type === \"video\") {\n              parts.push({ inlineData: { mimeType: block.mediaType, data: block.data } });\n            }\n          }\n        }\n      }\n      if (parts.length > 0) contents.push({ role: \"user\", parts });\n    }\n  }\n\n  return {\n    ...(systemText ? { systemInstruction: { parts: [{ text: systemText }] } } : {}),\n    contents,\n  };\n}\n\nfunction stringifyToolContent(content: Exclude<ToolResultContent, string>): string {\n  return content\n    .map((part) => (part.type === \"text\" ? part.text : `[image ${part.mediaType}]`))\n    .join(\"\\n\");\n}\n\nfunction toGeminiTools(tools: Tool[] | undefined): GeminiTool[] | undefined {\n  if (!tools?.length) return undefined;\n  return [\n    {\n      functionDeclarations: tools.map((tool) => ({\n        name: tool.name,\n        description: tool.description,\n        parameters: sanitizeSchema(resolveToolSchema(tool)),\n      })),\n    },\n  ];\n}\n\nfunction sanitizeSchema(schema: Record<string, unknown>): Record<string, unknown> {\n  const clone = JSON.parse(JSON.stringify(schema)) as Record<string, unknown>;\n  stripUnsupportedSchemaFields(clone);\n  return clone;\n}\n\nfunction stripUnsupportedSchemaFields(value: unknown): void {\n  if (!isJsonObject(value)) {\n    if (Array.isArray(value)) {\n      for (const item of value) stripUnsupportedSchemaFields(item);\n    }\n    return;\n  }\n\n  delete value.$schema;\n  delete value.additionalProperties;\n\n  for (const item of Object.values(value)) {\n    if (isJsonObject(item) || Array.isArray(item)) {\n      stripUnsupportedSchemaFields(item);\n    }\n  }\n}\n\nfunction toGeminiToolConfig(\n  choice: ToolChoice | undefined,\n  tools: Tool[] | undefined,\n): GeminiGenerateContentRequest[\"toolConfig\"] | undefined {\n  if (!choice || !tools?.length) return undefined;\n  if (choice === \"auto\") return { functionCallingConfig: { mode: \"AUTO\" } };\n  if (choice === \"none\") return { functionCallingConfig: { mode: \"NONE\" } };\n  if (choice === \"required\") return { functionCallingConfig: { mode: \"ANY\" } };\n  return { functionCallingConfig: { mode: \"ANY\", allowedFunctionNames: [choice.name] } };\n}\n\nfunction isGemini3Model(model: string): boolean {\n  return /^gemini-3(?:\\.|-|$)/.test(model);\n}\n\nfunction toGemini3ThinkingLevel(\n  level: NonNullable<StreamOptions[\"thinking\"]>,\n): \"LOW\" | \"MEDIUM\" | \"HIGH\" {\n  switch (level) {\n    case \"low\":\n      return \"LOW\";\n    case \"medium\":\n      return \"MEDIUM\";\n    case \"high\":\n    case \"xhigh\":\n    case \"max\":\n    case \"ultra\":\n      return \"HIGH\";\n  }\n}\n\nfunction toThinkingBudget(level: NonNullable<StreamOptions[\"thinking\"]>): number {\n  switch (level) {\n    case \"low\":\n      return 1_024;\n    case \"medium\":\n      return 8_192;\n    case \"high\":\n    case \"xhigh\":\n    case \"max\":\n    case \"ultra\":\n      return 8_192;\n  }\n}\n\nfunction toThinkingConfig(\n  model: string,\n  level: StreamOptions[\"thinking\"],\n): GeminiGenerationConfig[\"thinkingConfig\"] | undefined {\n  if (!level) return undefined;\n  if (isGemini3Model(model)) {\n    return {\n      includeThoughts: true,\n      thinkingLevel: toGemini3ThinkingLevel(level),\n    };\n  }\n  return {\n    includeThoughts: true,\n    thinkingBudget: toThinkingBudget(level),\n  };\n}\n\nfunction buildGenerateRequest(options: StreamOptions): GeminiGenerateContentRequest {\n  const downgradedImages = downgradeUnsupportedImages(options.messages, options.supportsImages);\n  const downgradedMessages = downgradeUnsupportedVideos(downgradedImages, options.supportsVideo);\n  const { systemInstruction, contents } = toSystemAndContents(downgradedMessages);\n  const tools = toGeminiTools(options.tools);\n  const toolConfig = toGeminiToolConfig(options.toolChoice, options.tools);\n  const thinkingConfig = toThinkingConfig(options.model, options.thinking);\n  const generationConfig: GeminiGenerationConfig = {\n    ...(options.maxTokens ? { maxOutputTokens: options.maxTokens } : {}),\n    ...(options.temperature != null && !options.thinking\n      ? { temperature: options.temperature }\n      : {}),\n    ...(options.topP != null ? { topP: options.topP } : {}),\n    ...(options.stop ? { stopSequences: options.stop } : {}),\n    ...(thinkingConfig ? { thinkingConfig } : {}),\n  };\n\n  return {\n    contents,\n    ...(systemInstruction ? { systemInstruction } : {}),\n    ...(tools ? { tools } : {}),\n    ...(toolConfig ? { toolConfig } : {}),\n    ...(Object.keys(generationConfig).length > 0 ? { generationConfig } : {}),\n    ...(options.promptCacheKey ? { session_id: options.promptCacheKey } : {}),\n  };\n}\n\nfunction buildCodeAssistRequest(\n  options: StreamOptions,\n  request: GeminiGenerateContentRequest,\n  projectId?: string,\n): GeminiCodeAssistRequest {\n  return {\n    model: options.model,\n    ...(projectId ? { project: projectId } : {}),\n    user_prompt_id: crypto.randomUUID(),\n    request,\n  };\n}\n\nfunction buildRequestPlan(options: StreamOptions, method: string): GeminiRequestPlan {\n  if (!CODE_ASSIST_SUPPORTED_MODELS.has(options.model)) {\n    throw new ProviderError(\"gemini\", formatUnsupportedModelMessage(options.model));\n  }\n\n  const projectId = getGoogleProject(options);\n  const request = buildGenerateRequest(options);\n\n  return {\n    url: getCodeAssistEndpoint(method),\n    headers: {\n      Authorization: `Bearer ${options.apiKey}`,\n      \"Content-Type\": \"application/json\",\n      \"User-Agent\": GEMINI_CLI_USER_AGENT,\n      \"X-Goog-Api-Client\": GEMINI_CLI_API_CLIENT,\n    },\n    body: buildCodeAssistRequest(options, request, projectId),\n  };\n}\n\nfunction normalizeGeminiStopReason(reason: string | undefined): StreamResponse[\"stopReason\"] {\n  switch (reason) {\n    case \"MAX_TOKENS\":\n      return \"max_tokens\";\n    case \"STOP\":\n      return \"stop_sequence\";\n    case \"SAFETY\":\n    case \"RECITATION\":\n    case \"BLOCKLIST\":\n    case \"PROHIBITED_CONTENT\":\n    case \"SPII\":\n      return \"refusal\";\n    default:\n      return \"end_turn\";\n  }\n}\n\nasync function* streamSse(response: Response): AsyncGenerator<GeminiGenerateResponse> {\n  if (!response.body) return;\n  for await (const event of readSseStream(response.body)) {\n    if (event.data === \"[DONE]\") continue;\n    yield JSON.parse(event.data) as GeminiGenerateResponse;\n  }\n}\n\nfunction candidatesFromResponse(response: GeminiGenerateResponse): GeminiCandidate[] | undefined {\n  return response.response?.candidates ?? response.candidates;\n}\n\nfunction usageFromResponse(response: GeminiGenerateResponse): GeminiUsageMetadata | undefined {\n  return response.response?.usageMetadata ?? response.usageMetadata;\n}\n\nfunction partsFromResponse(response: GeminiGenerateResponse): GeminiPart[] {\n  return candidatesFromResponse(response)?.[0]?.content?.parts ?? [];\n}\n\nfunction finishReasonFromResponse(response: GeminiGenerateResponse): string | undefined {\n  return candidatesFromResponse(response)?.[0]?.finishReason;\n}\n\nfunction readTextPart(part: GeminiPart): { text: string; thought: boolean } | undefined {\n  return \"text\" in part ? { text: part.text, thought: part.thought === true } : undefined;\n}\n\nfunction readFunctionCallPart(\n  part: GeminiPart,\n): { id?: string; name: string; args: Record<string, unknown> } | undefined {\n  if (!(\"functionCall\" in part)) return undefined;\n  return {\n    ...(part.functionCall.id ? { id: part.functionCall.id } : {}),\n    name: part.functionCall.name,\n    args: isJsonObject(part.functionCall.args) ? part.functionCall.args : {},\n  };\n}\n\nfunction makeToolCallId(index: number, providerId?: string): string {\n  return providerId ?? `gemini_call_${index}_${crypto.randomUUID().replace(/-/g, \"\")}`;\n}\n\nfunction shouldRetryCodeAssistStatus(status: number): boolean {\n  return status === 429 || status === 499 || (status >= 500 && status <= 599);\n}\n\nfunction isAbortError(err: unknown): boolean {\n  return err instanceof Error && err.name === \"AbortError\";\n}\n\nasync function sleep(ms: number, signal?: AbortSignal): Promise<void> {\n  if (ms <= 0) return;\n  await new Promise<void>((resolve, reject) => {\n    const cleanup = (): void => signal?.removeEventListener(\"abort\", onAbort);\n    const timer = setTimeout(() => {\n      cleanup();\n      resolve();\n    }, ms);\n    const onAbort = (): void => {\n      clearTimeout(timer);\n      cleanup();\n      reject(new DOMException(\"The operation was aborted.\", \"AbortError\"));\n    };\n    signal?.addEventListener(\"abort\", onAbort, { once: true });\n    if (signal?.aborted) onAbort();\n  });\n}\n\nasync function fetchCodeAssist(plan: GeminiRequestPlan, options: StreamOptions): Promise<Response> {\n  try {\n    const response = await fetch(plan.url, {\n      method: \"POST\",\n      headers: plan.headers,\n      body: JSON.stringify(plan.body),\n      signal: options.signal,\n    });\n\n    if (!response.ok) {\n      const text = await response.text().catch(() => \"\");\n      const quota = parseGeminiQuota(response.status, text);\n      const accountGated = response.status === 404 && ACCOUNT_GATED_MODELS.has(options.model);\n      let message = accountGated\n        ? accountGatedMessage(options.model)\n        : formatErrorMessage(response.status, text, options.model);\n      let resetsAt: number | undefined;\n      if (quota?.exhausted) {\n        // Stamp the canonical phrase the agent loop matches on so this hard\n        // 429 is surfaced immediately instead of retried for minutes.\n        message = `Gemini quota exhausted — usage limit reached. ${message}`;\n      } else if (quota?.retryDelaySeconds !== undefined) {\n        resetsAt = Math.floor(Date.now() / 1000) + Math.ceil(quota.retryDelaySeconds);\n      }\n      throw new ProviderError(\"gemini\", message, {\n        statusCode: response.status,\n        ...(resetsAt !== undefined ? { resetsAt } : {}),\n        ...(accountGated ? { hint: accountGatedHint() } : {}),\n      });\n    }\n\n    return response;\n  } catch (err) {\n    throw toError(err);\n  }\n}\n\nasync function fetchCodeAssistWithRetry(\n  plan: GeminiRequestPlan,\n  options: StreamOptions,\n): Promise<Response> {\n  let lastError: Error | undefined;\n\n  for (let attempt = 0; attempt <= CODE_ASSIST_NON_STREAMING_RETRIES; attempt++) {\n    try {\n      return await fetchCodeAssist(plan, options);\n    } catch (err) {\n      const error = toError(err);\n      const statusCode = error instanceof ProviderError ? error.statusCode : undefined;\n      if (\n        options.signal?.aborted ||\n        isAbortError(error) ||\n        attempt === CODE_ASSIST_NON_STREAMING_RETRIES ||\n        (statusCode != null && !shouldRetryCodeAssistStatus(statusCode))\n      ) {\n        throw error;\n      }\n      lastError = error;\n    }\n\n    try {\n      await sleep(CODE_ASSIST_NON_STREAMING_RETRY_DELAY_MS, options.signal);\n    } catch (err) {\n      throw toError(err);\n    }\n  }\n\n  throw lastError ?? new ProviderError(\"gemini\", \"Gemini Code Assist request failed.\");\n}\n\nexport function streamGemini(options: StreamOptions): StreamResult {\n  return new StreamResult(runStream(options), options.signal);\n}\n\nasync function* runStream(options: StreamOptions): AsyncGenerator<StreamEvent, StreamResponse> {\n  const useStreaming = options.streaming !== false;\n  const method = useStreaming ? \"streamGenerateContent\" : \"generateContent\";\n  const plan = buildRequestPlan(options, method);\n  if (useStreaming) plan.url.searchParams.set(\"alt\", \"sse\");\n\n  const response = useStreaming\n    ? await fetchCodeAssist(plan, options)\n    : await fetchCodeAssistWithRetry(plan, options);\n\n  const contentParts: ContentPart[] = [];\n  const pendingToolCalls: ToolCall[] = [];\n  let textAccum = \"\";\n  let thinkingAccum = \"\";\n  let stopReason: StreamResponse[\"stopReason\"] = \"end_turn\";\n  let inputTokens = 0;\n  let candidateTokens = 0;\n  let reasoningTokens = 0;\n  let cacheRead = 0;\n  let toolIndex = 0;\n\n  const handleResponse = function* (chunk: GeminiGenerateResponse): Generator<StreamEvent> {\n    const usage = usageFromResponse(chunk);\n    if (usage) {\n      inputTokens = usage.promptTokenCount ?? inputTokens;\n      candidateTokens = usage.candidatesTokenCount ?? candidateTokens;\n      reasoningTokens = usage.thoughtsTokenCount ?? reasoningTokens;\n      cacheRead = usage.cachedContentTokenCount ?? cacheRead;\n    }\n\n    const reason = finishReasonFromResponse(chunk);\n    if (reason) stopReason = normalizeGeminiStopReason(reason);\n\n    for (const part of partsFromResponse(chunk)) {\n      const textPart = readTextPart(part);\n      if (textPart) {\n        if (textPart.thought) {\n          thinkingAccum += textPart.text;\n          yield { type: \"thinking_delta\", text: textPart.text };\n        } else {\n          textAccum += textPart.text;\n          yield { type: \"text_delta\", text: textPart.text };\n        }\n        continue;\n      }\n\n      const functionCall = readFunctionCallPart(part);\n      if (functionCall) {\n        const id = makeToolCallId(toolIndex++, functionCall.id);\n        const argsJson = JSON.stringify(functionCall.args);\n        pendingToolCalls.push({\n          type: \"tool_call\",\n          id,\n          name: functionCall.name,\n          args: functionCall.args,\n        });\n        yield { type: \"toolcall_delta\", id, name: functionCall.name, argsJson };\n      }\n    }\n  };\n\n  try {\n    if (useStreaming) {\n      for await (const chunk of streamSse(response)) {\n        yield* handleResponse(chunk);\n      }\n    } else {\n      const chunk = (await response.json()) as GeminiGenerateResponse;\n      yield* handleResponse(chunk);\n    }\n  } catch (err) {\n    throw toError(err);\n  }\n\n  if (thinkingAccum) contentParts.push({ type: \"thinking\", text: thinkingAccum });\n  if (textAccum) contentParts.push({ type: \"text\", text: textAccum });\n\n  for (const toolCall of pendingToolCalls) {\n    contentParts.push(toolCall);\n    yield {\n      type: \"toolcall_done\",\n      id: toolCall.id,\n      name: toolCall.name,\n      args: toolCall.args,\n    };\n  }\n\n  if (pendingToolCalls.length > 0) stopReason = \"tool_use\";\n\n  const adjustedInputTokens = Math.max(0, inputTokens - cacheRead);\n  // Gemini reports thoughts separately from candidate output, but both are billed\n  // output. Keep the subset for diagnostics while making outputTokens the cost-safe total.\n  const outputTokens = candidateTokens + reasoningTokens;\n  const streamResponse: StreamResponse = {\n    message: {\n      role: \"assistant\",\n      content: contentParts.length > 0 ? contentParts : textAccum,\n    },\n    stopReason,\n    usage: {\n      inputTokens: adjustedInputTokens,\n      outputTokens,\n      ...(reasoningTokens > 0 ? { reasoningTokens } : {}),\n      ...(cacheRead > 0 ? { cacheRead } : {}),\n    },\n  };\n\n  yield { type: \"done\", stopReason };\n  return streamResponse;\n}\n\nfunction toError(err: unknown): Error {\n  if (err instanceof ProviderError) return err;\n  if (err instanceof Error) return new ProviderError(\"gemini\", err.message, { cause: err });\n  return new ProviderError(\"gemini\", String(err));\n}\n","import type { StreamOptions } from \"./types.js\";\nimport type { StreamResult } from \"./utils/event-stream.js\";\n\n/**\n * A provider stream function. Takes StreamOptions and returns a StreamResult.\n * Each provider implements this to handle its specific API format.\n */\nexport type ProviderStreamFn = (options: StreamOptions) => StreamResult;\n\n/**\n * Registry entry for a provider. A provider can have a simple stream function\n * or a more complex setup with custom routing logic.\n */\nexport interface ProviderEntry {\n  /** Main stream function for this provider */\n  stream: ProviderStreamFn;\n}\n\n/**\n * Map-based provider registry. Built-in providers are registered at module load,\n * and extensions can register custom providers at runtime.\n */\nclass ProviderRegistryImpl {\n  private providers = new Map<string, ProviderEntry>();\n\n  /**\n   * Register a provider. Overwrites any existing provider with the same name.\n   *\n   * ```ts\n   * import { providerRegistry } from \"@kenkaiiii/gg-ai\";\n   *\n   * providerRegistry.register(\"deepseek\", {\n   *   stream: (options) => streamOpenAI({ ...options, baseUrl: \"https://api.deepseek.com/v1\" }),\n   * });\n   * ```\n   */\n  register(name: string, entry: ProviderEntry): void {\n    this.providers.set(name, entry);\n  }\n\n  /** Remove a registered provider. */\n  unregister(name: string): boolean {\n    return this.providers.delete(name);\n  }\n\n  /** Get a provider entry by name. */\n  get(name: string): ProviderEntry | undefined {\n    return this.providers.get(name);\n  }\n\n  /** Check if a provider is registered. */\n  has(name: string): boolean {\n    return this.providers.has(name);\n  }\n\n  /** List all registered provider names. */\n  list(): string[] {\n    return [...this.providers.keys()];\n  }\n}\n\n/** Global provider registry. Import this to register custom providers. */\nexport const providerRegistry = new ProviderRegistryImpl();\n","import type { ContentPart, Message, ToolResult, ToolResultContent } from \"../types.js\";\n\n/**\n * Lone (unpaired) UTF-16 surrogate. A string holding one cannot be encoded as\n * valid UTF-8, so `JSON.stringify` emits a `\\uD83D`-style escape that every\n * provider's JSON parser rejects:\n *\n *   \"The request body is not valid JSON: no low surrogate in string\"  (Anthropic)\n *   \"Bad Request\"                                                     (OpenAI)\n *\n * They enter the conversation from outside our control — a model streaming a\n * split emoji escape inside tool-call arguments, a character-indexed truncation\n * that cut an astral character in half, or file/shell bytes that decoded to a\n * half pair — and then persist in history, so every later turn fails too,\n * including after a retry or a model switch.\n */\nconst LONE_SURROGATE = /[\\uD800-\\uDBFF](?![\\uDC00-\\uDFFF])|(?<![\\uD800-\\uDBFF])[\\uDC00-\\uDFFF]/;\nconst LONE_SURROGATE_GLOBAL = new RegExp(LONE_SURROGATE, \"g\");\nconst REPLACEMENT = \"\\uFFFD\";\n\n/** True when the string contains at least one unpaired surrogate. */\nexport function hasLoneSurrogate(text: string): boolean {\n  // `isWellFormed` (Node 20+) is a native linear scan — far cheaper than regex\n  // over megabyte-sized transcripts. Fall back for older runtimes.\n  const isWellFormed = (text as { isWellFormed?: () => boolean }).isWellFormed;\n  if (typeof isWellFormed === \"function\") return !isWellFormed.call(text);\n  return LONE_SURROGATE.test(text);\n}\n\n/** Replace unpaired surrogates with U+FFFD; returns the input when already valid. */\nexport function toWellFormedText(text: string): string {\n  if (!hasLoneSurrogate(text)) return text;\n  const toWellFormed = (text as { toWellFormed?: () => string }).toWellFormed;\n  if (typeof toWellFormed === \"function\") return toWellFormed.call(text);\n  return text.replace(LONE_SURROGATE_GLOBAL, REPLACEMENT);\n}\n\n/** True when `code` is a high surrogate — the first half of an astral pair. */\nfunction isHighSurrogate(code: number | undefined): boolean {\n  return code !== undefined && code >= 0xd800 && code <= 0xdbff;\n}\n\n/** True when `code` is a low surrogate — the second half of an astral pair. */\nfunction isLowSurrogate(code: number | undefined): boolean {\n  return code !== undefined && code >= 0xdc00 && code <= 0xdfff;\n}\n\n/** `text.slice(0, chars)` that never cuts an astral character in half. */\nexport function sliceHead(text: string, chars: number): string {\n  if (chars <= 0) return \"\";\n  if (chars >= text.length) return text;\n  const end = isHighSurrogate(text.charCodeAt(chars - 1)) ? chars - 1 : chars;\n  return text.slice(0, end);\n}\n\n/** `text.slice(-chars)` that never cuts an astral character in half. */\nexport function sliceTail(text: string, chars: number): string {\n  if (chars <= 0) return \"\";\n  if (chars >= text.length) return text;\n  const start = text.length - chars;\n  return text.slice(isLowSurrogate(text.charCodeAt(start)) ? start + 1 : start);\n}\n\n/** Sanitize arbitrary JSON-ish data (tool args, server tool payloads), cloning only when needed. */\nfunction sanitizeJsonValue(value: unknown): unknown {\n  if (typeof value === \"string\") return toWellFormedText(value);\n  if (Array.isArray(value)) {\n    let changed = false;\n    const next = value.map((item) => {\n      const sanitized = sanitizeJsonValue(item);\n      if (sanitized !== item) changed = true;\n      return sanitized;\n    });\n    return changed ? next : value;\n  }\n  if (value !== null && typeof value === \"object\") {\n    let changed = false;\n    const next: Record<string, unknown> = {};\n    for (const [key, item] of Object.entries(value as Record<string, unknown>)) {\n      const sanitizedKey = toWellFormedText(key);\n      const sanitized = sanitizeJsonValue(item);\n      if (sanitizedKey !== key || sanitized !== item) changed = true;\n      next[sanitizedKey] = sanitized;\n    }\n    return changed ? next : value;\n  }\n  return value;\n}\n\nfunction sanitizeRecord(value: Record<string, unknown>): Record<string, unknown> {\n  return sanitizeJsonValue(value) as Record<string, unknown>;\n}\n\n/** Sanitize one content block. Base64 media payloads are skipped — they are\n *  ASCII by construction and can be megabytes, so scanning them is pure cost. */\nfunction sanitizePart<T extends ContentPart>(part: T): T {\n  switch (part.type) {\n    case \"text\":\n    case \"thinking\": {\n      // `signature` is provider-issued and must round-trip byte-for-byte.\n      const text = toWellFormedText(part.text);\n      return text === part.text ? part : { ...part, text };\n    }\n    case \"tool_call\": {\n      const args = sanitizeRecord(part.args);\n      return args === part.args ? part : { ...part, args };\n    }\n    case \"server_tool_call\": {\n      const input = sanitizeJsonValue(part.input);\n      return input === part.input ? part : { ...part, input };\n    }\n    case \"server_tool_result\": {\n      const data = sanitizeJsonValue(part.data);\n      return data === part.data ? part : { ...part, data };\n    }\n    case \"raw\": {\n      const data = sanitizeRecord(part.data);\n      return data === part.data ? part : { ...part, data };\n    }\n    default:\n      return part;\n  }\n}\n\nfunction sanitizeParts<T extends ContentPart>(parts: T[]): T[] {\n  let changed = false;\n  const next = parts.map((part) => {\n    const sanitized = sanitizePart(part);\n    if (sanitized !== part) changed = true;\n    return sanitized as T;\n  });\n  return changed ? next : parts;\n}\n\nfunction sanitizeToolResultContent(content: ToolResultContent): ToolResultContent {\n  if (typeof content === \"string\") return toWellFormedText(content);\n  return sanitizeParts(content);\n}\n\nfunction sanitizeToolResults(results: ToolResult[]): ToolResult[] {\n  let changed = false;\n  const next = results.map((result) => {\n    const content = sanitizeToolResultContent(result.content);\n    if (content === result.content) return result;\n    changed = true;\n    return { ...result, content };\n  });\n  return changed ? next : results;\n}\n\nfunction sanitizeMessage(message: Message): Message {\n  if (message.role === \"tool\") {\n    const content = sanitizeToolResults(message.content);\n    return content === message.content ? message : { ...message, content };\n  }\n  if (typeof message.content === \"string\") {\n    const content = toWellFormedText(message.content);\n    return content === message.content ? message : { ...message, content };\n  }\n  const content = sanitizeParts(message.content);\n  return content === message.content ? message : ({ ...message, content } as Message);\n}\n\n/**\n * Strip unpaired surrogates from everything headed for the wire. Returns the\n * same array (and same message objects) when the history is already valid, so\n * the clean path stays allocation-free.\n */\nexport function sanitizeMessagesForWire(messages: Message[]): Message[] {\n  let sanitized: Message[] | undefined;\n  for (let index = 0; index < messages.length; index++) {\n    const message = messages[index]!;\n    const next = sanitizeMessage(message);\n    if (next === message) continue;\n    sanitized ??= messages.slice();\n    sanitized[index] = next;\n  }\n  return sanitized ?? messages;\n}\n","import type { Message, StreamOptions } from \"./types.js\";\nimport { GGAIError, VideoUnsupportedError } from \"./errors.js\";\nimport type { StreamResult } from \"./utils/event-stream.js\";\nimport { streamAnthropic } from \"./providers/anthropic.js\";\nimport { streamOpenAI } from \"./providers/openai.js\";\nimport { streamOpenAICodex } from \"./providers/openai-codex.js\";\nimport { streamGemini } from \"./providers/gemini.js\";\nimport { providerRegistry } from \"./provider-registry.js\";\nimport { clampProviderContextImages } from \"./providers/transform.js\";\nimport { sanitizeMessagesForWire } from \"./utils/well-formed.js\";\n\n/** Z.AI coding API endpoint — the primary endpoint for all GLM models. */\nconst GLM_CODING_BASE_URL = \"https://api.z.ai/api/coding/paas/v4\";\n\n/**\n * User-Agent the Kimi For Coding endpoint requires to recognize ggcoder as a\n * coding agent. The endpoint gates solely on this header; the version is\n * overridable via KIMI_CODE_VERSION for forward compatibility.\n */\nconst KIMI_CODE_USER_AGENT = `kimi-code-cli/${process.env.KIMI_CODE_VERSION ?? \"1.0.11\"}`;\n\n/**\n * Grok CLI chat proxy — the endpoint a Grok subscription OAuth token is valid\n * against (gg-core's `grokCliBaseUrl()` persists it on the credential). Matched\n * by host so an env override of that base URL still gets the identity headers.\n */\nconst GROK_CLI_PROXY_HOST = \"cli-chat-proxy.grok.com\";\n\n/**\n * Client identity the Grok CLI chat proxy requires. It hard-gates on this: with\n * no version it answers \"Your Grok CLI version (none) is outdated. Please update\n * to version 0.1.202 or later\", so the value must look like a real Grok CLI build\n * (they ship 0.1.x/0.2.x) rather than a placeholder. Overridable via\n * GROK_CLI_VERSION. Keep in sync with gg-core's `grokCliHeaders()`, the\n * login-side source of truth.\n */\nconst GROK_CLI_VERSION = process.env.GROK_CLI_VERSION ?? \"0.2.101\";\n\n// ── Register built-in providers ────────────────────────────\n\nproviderRegistry.register(\"anthropic\", {\n  stream: (options) => streamAnthropic(options),\n});\n\nproviderRegistry.register(\"xiaomi\", {\n  stream: (options) =>\n    streamOpenAI({\n      ...options,\n      baseUrl: options.baseUrl ?? \"https://token-plan-sgp.xiaomimimo.com/v1\",\n      webSearch: false,\n    }),\n});\n\nproviderRegistry.register(\"openai\", {\n  stream: (options) => {\n    // Use codex endpoint for OAuth tokens (have accountId)\n    if (options.accountId) {\n      return streamOpenAICodex(options);\n    }\n    return streamOpenAI(options);\n  },\n});\n\nproviderRegistry.register(\"gemini\", {\n  stream: (options) => streamGemini(options),\n});\n\nproviderRegistry.register(\"glm\", {\n  stream: (options) =>\n    streamOpenAI({\n      ...options,\n      baseUrl: options.baseUrl ?? GLM_CODING_BASE_URL,\n    }),\n});\n\nproviderRegistry.register(\"moonshot\", {\n  stream: (options) => {\n    const baseUrl = options.baseUrl ?? \"https://api.moonshot.ai/v1\";\n    // The Kimi For Coding (OAuth) endpoint at api.kimi.com gates access to\n    // recognized coding agents and 403s any request whose `User-Agent` isn't a\n    // known client (verified empirically: User-Agent alone is the gate). Inject\n    // it centrally here so EVERY stream — agent loop, compaction, title-gen,\n    // sub-agents — passes, instead of relying on each call site to thread\n    // headers. Caller-provided headers still win on collision.\n    const defaultHeaders = baseUrl.includes(\"api.kimi.com\")\n      ? { \"User-Agent\": KIMI_CODE_USER_AGENT, ...options.defaultHeaders }\n      : options.defaultHeaders;\n    return streamOpenAI({ ...options, baseUrl, defaultHeaders });\n  },\n});\n\nproviderRegistry.register(\"deepseek\", {\n  stream: (options) =>\n    streamOpenAI({\n      ...options,\n      baseUrl: options.baseUrl ?? \"https://api.deepseek.com/v1\",\n    }),\n});\n\nproviderRegistry.register(\"openrouter\", {\n  stream: (options) =>\n    streamOpenAI({\n      ...options,\n      baseUrl: options.baseUrl ?? \"https://openrouter.ai/api/v1\",\n    }),\n});\n\nproviderRegistry.register(\"huggingface\", {\n  // Hugging Face Inference Providers router — one HF token (hf.co/settings/tokens,\n  // \"Make calls to Inference Providers\" permission) routes to whichever hosted\n  // backend serves each open model. Chat Completions-compatible; model ids are\n  // Hub repo paths (\"Qwen/Qwen3-Coder-480B-A35B-Instruct\"), optionally with an\n  // \":auto\"/\":fastest\"/\":cheapest\" provider-selection suffix. Billing follows\n  // each backend's per-token rates on the HF account (small free tier).\n  stream: (options) =>\n    streamOpenAI({\n      ...options,\n      baseUrl: options.baseUrl ?? \"https://router.huggingface.co/v1\",\n    }),\n});\n\nproviderRegistry.register(\"sakana\", {\n  // Sakana Fugu is a multi-agent system exposed as a standard LLM through the\n  // OpenAI-compatible Sakana API. We ride the Chat Completions transport (the\n  // Responses API is also offered). Fugu models only accept \"high\"/\"xhigh\"\n  // reasoning effort — clamped centrally in toOpenAIReasoningEffort.\n  stream: (options) =>\n    streamOpenAI({\n      ...options,\n      baseUrl: options.baseUrl ?? \"https://api.sakana.ai/v1\",\n    }),\n});\n\nproviderRegistry.register(\"xai\", {\n  // xAI's public API (console.x.ai key) is OpenAI-compatible — ride the Chat\n  // Completions transport like Moonshot/DeepSeek. Grok reasoning models take\n  // top-level `reasoning_effort` (low/medium/high), which the shared thinking\n  // path already sends.\n  //\n  // Subscription OAuth (SuperGrok / X Premium) routes to the Grok CLI chat proxy\n  // instead, which speaks the same Chat Completions wire but gates on Grok-CLI\n  // client identity. Inject those headers centrally here — exactly as the Kimi\n  // endpoint above — so EVERY stream (agent loop, compaction, title-gen,\n  // sub-agents) is accepted rather than depending on each call site to thread\n  // headers. Caller-provided headers still win on collision.\n  stream: (options) => {\n    const baseUrl = options.baseUrl ?? \"https://api.x.ai/v1\";\n    const defaultHeaders = baseUrl.includes(GROK_CLI_PROXY_HOST)\n      ? {\n          \"X-XAI-Token-Auth\": \"xai-grok-cli\",\n          \"x-grok-client-version\": GROK_CLI_VERSION,\n          \"x-grok-client-identifier\": \"ggcoder\",\n          \"x-grok-model-override\": options.model,\n          ...options.defaultHeaders,\n        }\n      : options.defaultHeaders;\n    return streamOpenAI({ ...options, baseUrl, defaultHeaders });\n  },\n});\n\nproviderRegistry.register(\"minimax\", {\n  stream: (options) =>\n    streamAnthropic({\n      ...options,\n      baseUrl: options.baseUrl ?? \"https://api.minimax.io/anthropic\",\n      // MiniMax's Anthropic-compatible API does not support Anthropic-specific\n      // server tools (web_search), context_management, or server-side tools.\n      webSearch: false,\n      compaction: false,\n      clearToolUses: false,\n      serverTools: undefined,\n    }),\n});\n\n/**\n * Local model ids are namespaced by endpoint (`local/<endpointId>/<rawId>`) so\n * the same model name served by two machines stays distinct in the registry.\n * The server only knows the raw id, so strip the routing prefix here — at the\n * one place that talks to the wire. Counterpart to gg-core's\n * `formatLocalModelId`/`parseLocalModelId`.\n */\nexport function localWireModelId(id: string): string {\n  const match = /^local\\/[^/]+\\/(.+)$/.exec(id);\n  return match?.[1] ?? id;\n}\n\nproviderRegistry.register(\"local\", {\n  // Locally hosted OpenAI-compatible servers (Ollama, LM Studio, llama.cpp,\n  // vLLM). There is no default endpoint: the baseUrl comes from the endpoint\n  // credential the discovery layer wrote, so a missing one is a wiring bug, not\n  // something to paper over with a guess at someone else's port.\n  stream: (options) => {\n    if (!options.baseUrl) {\n      throw new GGAIError(\n        \"Local provider requires a baseUrl (e.g. http://127.0.0.1:11434/v1). \" +\n          \"No local endpoint was resolved for this model — re-scan for local models.\",\n      );\n    }\n    return streamOpenAI({\n      ...options,\n      model: localWireModelId(options.model),\n      webSearch: false,\n    });\n  },\n});\n\n// ── Public API ─────────────────────────────────────────────\n\n/**\n * Unified streaming entry point. Returns a StreamResult that is both\n * an async iterable (for streaming events) and thenable (await for\n * the final response).\n *\n * Providers are resolved via the provider registry. Built-in providers\n * (anthropic, openai, glm, moonshot) are registered at module load.\n * Extensions can register custom providers via `providerRegistry.register()`.\n *\n * ```ts\n * // Stream events\n * for await (const event of stream({ provider: \"anthropic\", model: \"claude-sonnet-5\", messages })) {\n *   if (event.type === \"text_delta\") process.stdout.write(event.text);\n * }\n *\n * // Or just await the final message\n * const response = await stream({ provider: \"openai\", model: \"gpt-4.1\", messages });\n * ```\n */\nexport function stream(options: StreamOptions): StreamResult {\n  const entry = providerRegistry.get(options.provider);\n  if (!entry) {\n    throw new GGAIError(\n      `Unknown provider: \"${options.provider}\". Registered: ${providerRegistry.list().join(\", \")}`,\n    );\n  }\n  // Fail fast with a clean capability error when video is in the request but the\n  // model can't watch it (e.g. a video read under Kimi/Gemini left in history,\n  // then the user switched to a text-only model). Without this, the provider\n  // rejects the video block with an opaque \"invalid tag 'video'\" API error.\n  if (options.supportsVideo !== true && messagesContainVideo(options.messages)) {\n    throw new VideoUnsupportedError();\n  }\n  const wireMessages = stripMessageProvenance(options.messages);\n  // Unpaired surrogates (split emoji in tool args, char-indexed truncation, odd\n  // shell bytes) make the JSON body unparseable for every provider — and stay in\n  // history, so retries and model switches fail identically. Scrub them here,\n  // the one place all providers pass through.\n  const messages = clampProviderContextImages(\n    sanitizeMessagesForWire(wireMessages),\n    options.provider,\n    options.supportsImages,\n  );\n  return entry.stream(messages === options.messages ? options : { ...options, messages });\n}\n\n/** Clone provenance-bearing messages and remove internal metadata at the provider boundary. */\nfunction stripMessageProvenance(messages: Message[]): Message[] {\n  let stripped: Message[] | undefined;\n  for (let index = 0; index < messages.length; index++) {\n    const message = messages[index]!;\n    if (!message.provenance) continue;\n    stripped ??= messages.slice();\n    const { provenance: _provenance, ...wireMessage } = message;\n    stripped[index] = wireMessage as Message;\n  }\n  return stripped ?? messages;\n}\n\n/** True if any message carries a video block, in user content or a tool result. */\nfunction messagesContainVideo(messages: Message[]): boolean {\n  for (const msg of messages) {\n    if (typeof msg.content === \"string\" || !Array.isArray(msg.content)) continue;\n    for (const part of msg.content) {\n      if (part.type === \"video\") return true;\n      if (part.type === \"tool_result\" && Array.isArray(part.content)) {\n        if (part.content.some((block) => block.type === \"video\")) return true;\n      }\n    }\n  }\n  return false;\n}\n","import { isHardBillingMessage } from \"./errors.js\";\n\n/**\n * Provider-error classification — tags a raw provider error message with a\n * machine-routable prefix so callers route on intent instead of regexing JSON.\n *\n * This lives in gg-ai (next to `formatError` / `isHardBillingMessage`) so every\n * provider-wording change is a one-file edit. The billing check reuses\n * `isHardBillingMessage` so billing substrings have exactly one home.\n *\n * Each provider phrases the same condition differently — a single substring\n * check would miss most real cases.\n *\n * Provider attribution (with example messages):\n *  - OpenAI Chat Completions: \"This model's maximum context length is 128000 tokens…\"\n *  - OpenAI Responses / Codex: \"Your input exceeds the context window of this model\"\n *  - OpenAI structured code:    error.code = \"context_length_exceeded\"\n *  - Anthropic (token overflow): \"prompt is too long: 213462 tokens > 200000 maximum\"\n *  - Anthropic (HTTP 413 byte):  error.type = \"request_too_large\"\n *  - Google / Gemini:            \"The input token count (1196265) exceeds the maximum number of tokens allowed\"\n *  - xAI / Grok:                 \"This model's maximum prompt length is 131072 but the request contains 537812 tokens\"\n *  - Mistral:                    \"Prompt contains X tokens … too large for model with Y maximum context length\"\n *  - Amazon Bedrock:             \"input is too long for requested model\"\n *  - OpenRouter:                 \"This endpoint's maximum context length is X tokens. However, you requested Y\"\n *  - Groq:                       \"Please reduce the length of the messages or completion\"\n *  - DeepSeek / GLM / MiniMax / Moonshot / Xiaomi: OpenAI-compatible — reuse `context_length_exceeded` and the maximum-context-length wording.\n */\nconst CONTEXT_OVERFLOW_PATTERNS: RegExp[] = [\n  /context_length_exceeded/i,\n  /context length exceeded/i,\n  /context window/i, // OpenAI Codex / Responses\n  /maximum context length/i, // OpenAI / OpenRouter / Mistral\n  /prompt is too long/i, // Anthropic\n  /request_too_large/i, // Anthropic HTTP 413\n  /input is too long/i, // Bedrock\n  /input token count.*exceeds the maximum/i, // Gemini\n  /maximum prompt length/i, // xAI / Grok\n  /reduce the length of the messages/i, // Groq\n  /too large for model/i, // Mistral\n  /token limit/i, // generic\n];\n\nconst RATE_LIMIT_PATTERNS: RegExp[] = [\n  /rate[ _-]?limit/i,\n  /\\b429\\b/,\n  /too many requests/i,\n  /tokens per minute/i,\n  /requests per minute/i,\n];\n\nconst PROVIDER_TRANSIENT_PATTERNS: RegExp[] = [\n  /\\b5\\d\\d\\b/,\n  /api_error/i,\n  /server_error/i,\n  /internal server error/i,\n  /bad gateway/i,\n  /service unavailable/i,\n  /gateway timeout/i,\n  /overloaded/i,\n  /\\b529\\b/,\n];\n\n/**\n * Billing/quota substrings that `isHardBillingMessage` does not already cover.\n * Kept minimal: shared billing wording lives in `isHardBillingMessage`; these\n * are transport-level signals (HTTP 402, \"payment required\") specific to the\n * classifier's routing needs.\n */\nconst BILLING_PATTERNS: RegExp[] = [\n  /payment required/i,\n  /\\b402\\b/,\n  /quota_exceeded/i, // underscore variant not in isHardBillingMessage\n  /credit balance/i,\n];\n\nconst AUTH_PATTERNS: RegExp[] = [\n  /invalid[ _]api[ _]key/i,\n  /unauthorized/i,\n  /\\b401\\b/,\n  /authentication[ _]failed/i,\n  /please run \\/login/i, // Anthropic Claude Code-style hint\n];\n\nfunction matchesAny(message: string, patterns: RegExp[]): boolean {\n  return patterns.some((p) => p.test(message));\n}\n\n/**\n * Inspect a raw provider error message and tag it with a clearer, actionable\n * prefix so a worker orchestrator can route on intent instead of regexing JSON.\n * Preserves the original message verbatim after the prefix — helpful for\n * debugging.\n *\n * Order matters: context-overflow is checked first because some providers wrap\n * overflow errors in HTTP 429 envelopes; we want the structural meaning, not\n * the transport status. Billing comes before auth/rate-limit because \"402\n * Payment Required\" must not be mis-routed as a rate-limit retry.\n */\nexport function classifyProviderError(message: string): string {\n  if (matchesAny(message, CONTEXT_OVERFLOW_PATTERNS)) {\n    return `[context_overflow] Worker context window exceeded — the conversation is too large to continue. Recovery: call reset_worker(project) to wipe history, then re-prompt with the task. Re-prompting WITHOUT reset will fail the same way.\\n\\nOriginal: ${message}`;\n  }\n  if (isHardBillingMessage(message) || matchesAny(message, BILLING_PATTERNS)) {\n    return `[billing] Provider billing/quota issue. Recovery: surface to the user — they need to top up or switch providers. Do NOT retry.\\n\\nOriginal: ${message}`;\n  }\n  if (matchesAny(message, AUTH_PATTERNS)) {\n    return `[auth] Provider authentication failed. Recovery: surface to the user — they need to re-login. Do NOT retry.\\n\\nOriginal: ${message}`;\n  }\n  if (matchesAny(message, RATE_LIMIT_PATTERNS)) {\n    return `[rate_limited] Provider rate limit hit. Recovery: wait ~30s, then re-prompt the same worker (no reset needed).\\n\\nOriginal: ${message}`;\n  }\n  if (matchesAny(message, PROVIDER_TRANSIENT_PATTERNS)) {\n    return `[provider_transient] Provider server-side/transient error. Recovery: wait briefly, then re-prompt the same worker (no reset needed). If it keeps happening, switch models/providers or check provider status.\\n\\nOriginal: ${message}`;\n  }\n  return message;\n}\n","const REDACTED = \"[REDACTED]\";\nconst TRUNCATED = \"[TRUNCATED]\";\nconst CIRCULAR = \"[CIRCULAR]\";\n\nconst SENSITIVE_NAME =\n  /(?:^|[_-])(?:api[_-]?key|access[_-]?token|refresh[_-]?token|token|key|auth(?:orization)?|bearer|cookie|credential|private[_-]?key|password|passwd|secret)(?:$|[_-])/i;\nconst SENSITIVE_ASSIGNMENT =\n  /\\b((?:api[_-]?key|access[_-]?token|refresh[_-]?token|token|key|auth(?:orization)?|bearer|cookie|credential|private[_-]?key|password|passwd|secret))\\b(\\s*[=:]\\s*)([\"']?)([^\\s,\"';}]+)\\3/gi;\n\nexport interface RedactionOptions {\n  /** Exact secret values to remove in addition to high-confidence formats. */\n  secrets?: Iterable<string>;\n  /** Maximum recursive object depth before a stable truncation marker is emitted. */\n  maxDepth?: number;\n  /** Maximum total array/object entries cloned before truncation markers are emitted. */\n  maxEntries?: number;\n  /** Maximum retained string length after sanitization. */\n  maxStringLength?: number;\n}\n\nfunction escaped(value: string): string {\n  return value.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n}\n\nfunction normalizedSecrets(secrets: Iterable<string> | undefined): string[] {\n  if (!secrets) return [];\n  return [...new Set([...secrets].filter((value) => value.length >= 8 && value !== REDACTED))].sort(\n    (a, b) => b.length - a.length,\n  );\n}\n\n/** Collect sufficiently distinctive secrets from security-sensitive environment variables. */\nexport function environmentSecrets(env: Record<string, string | undefined>): string[] {\n  const values = new Set<string>();\n  for (const [name, value] of Object.entries(env)) {\n    if (!value || value.length < 8 || value === REDACTED || !SENSITIVE_NAME.test(name)) continue;\n    values.add(value);\n  }\n  return [...values].sort((a, b) => b.length - a.length);\n}\n\n/** Redact credentials from arbitrary text without mutating its source. */\nexport function redactText(text: string, options: RedactionOptions = {}): string {\n  let result = text;\n\n  // PEM private keys, including multiline payloads.\n  result = result.replace(\n    /-----BEGIN (?:[A-Z0-9 ]+ )?PRIVATE KEY-----[\\s\\S]*?-----END (?:[A-Z0-9 ]+ )?PRIVATE KEY-----/g,\n    REDACTED,\n  );\n  // Credentials embedded in URLs.\n  result = result.replace(/\\b([a-z][a-z0-9+.-]*:\\/\\/)[^\\s/@:]+:[^\\s/@]+@/gi, `$1${REDACTED}@`);\n  // Authorization headers and inline auth values.\n  result = result.replace(\n    /\\b(authorization\\s*[:=]\\s*)(?:bearer|basic)\\s+[^\\s,;]+/gi,\n    `$1${REDACTED}`,\n  );\n  result = result.replace(/\\b(bearer|basic)\\s+[A-Za-z0-9+/_.=-]{8,}/gi, `$1 ${REDACTED}`);\n  // Cookie headers are security-sensitive as a whole; avoid trying to infer safe cookie names.\n  result = result.replace(/\\b(cookie|set-cookie)(\\s*[:=]\\s*)[^\\r\\n]+/gi, `$1$2${REDACTED}`);\n  // JWTs and well-known provider/repository token prefixes.\n  result = result.replace(\n    /\\beyJ[A-Za-z0-9_-]{6,}\\.[A-Za-z0-9_-]{6,}\\.[A-Za-z0-9_-]{6,}\\b/g,\n    REDACTED,\n  );\n  result = result.replace(\n    /\\b(?:sk-(?:ant-|proj-)?|xox[baprs]-|gh[pousr]_|github_pat_|AIza)[A-Za-z0-9_-]{12,}\\b/g,\n    REDACTED,\n  );\n  result = result.replace(\n    SENSITIVE_ASSIGNMENT,\n    (_match, name: string, separator: string) => `${name}${separator}${REDACTED}`,\n  );\n\n  for (const secret of normalizedSecrets(options.secrets)) {\n    result = result.replace(new RegExp(escaped(secret), \"g\"), REDACTED);\n  }\n\n  const maxStringLength = options.maxStringLength ?? 1_000_000;\n  if (result.length > maxStringLength) {\n    result = `${result.slice(0, maxStringLength)}${TRUNCATED}`;\n  }\n  return result;\n}\n\nfunction isBinary(value: object): boolean {\n  return (\n    value instanceof ArrayBuffer ||\n    ArrayBuffer.isView(value) ||\n    (typeof Blob !== \"undefined\" && value instanceof Blob)\n  );\n}\n\nfunction isMediaObject(value: Record<string, unknown>): boolean {\n  return (\n    (value.type === \"image\" || value.type === \"video\") &&\n    (typeof value.data === \"string\" || typeof value.url === \"string\")\n  );\n}\n\n/**\n * Recursively clone and sanitize transport/persistence payloads.\n * Cycles, excessive depth, and excessive collection sizes become stable markers.\n */\nexport function redactValue<T>(value: T, options: RedactionOptions = {}): T {\n  const maxDepth = options.maxDepth ?? 20;\n  const maxEntries = options.maxEntries ?? 10_000;\n  const seen = new WeakSet<object>();\n  let entries = 0;\n\n  const visit = (current: unknown, depth: number, sensitive = false): unknown => {\n    if (typeof current === \"string\") {\n      if (sensitive && current.length > 0 && current !== REDACTED) return REDACTED;\n      return redactText(current, options);\n    }\n    if (\n      current === null ||\n      current === undefined ||\n      typeof current === \"number\" ||\n      typeof current === \"boolean\" ||\n      typeof current === \"bigint\"\n    ) {\n      return current;\n    }\n    if (typeof current !== \"object\") return current;\n    if (isBinary(current)) return current;\n    if (current instanceof Date) return new Date(current.getTime());\n    if (depth >= maxDepth) return TRUNCATED;\n    if (seen.has(current)) return CIRCULAR;\n    seen.add(current);\n\n    if (current instanceof Error) {\n      const error: Record<string, unknown> = {\n        name: current.name,\n        message: visit(current.message, depth + 1),\n        stack: visit(current.stack, depth + 1),\n      };\n      for (const [key, child] of Object.entries(current)) {\n        error[key] = visit(child, depth + 1, SENSITIVE_NAME.test(key));\n      }\n      return error;\n    }\n\n    if (Array.isArray(current)) {\n      const clone: unknown[] = [];\n      for (const child of current) {\n        if (++entries > maxEntries) {\n          clone.push(TRUNCATED);\n          break;\n        }\n        clone.push(visit(child, depth + 1));\n      }\n      return clone;\n    }\n\n    const record = current as Record<string, unknown>;\n    if (isMediaObject(record)) return { ...record };\n    const clone: Record<string, unknown> = {};\n    for (const [key, child] of Object.entries(record)) {\n      if (++entries > maxEntries) {\n        clone[TRUNCATED] = true;\n        break;\n      }\n      clone[key] = visit(child, depth + 1, SENSITIVE_NAME.test(key));\n    }\n    return clone;\n  };\n\n  return visit(value, 0) as T;\n}\n\nexport { REDACTED as REDACTION_MARKER };\n","import type {\n  AssistantMessage,\n  ContentPart,\n  Message,\n  StopReason,\n  StreamEvent,\n  StreamOptions,\n  StreamResponse,\n  Usage,\n} from \"../types.js\";\nimport { StreamResult } from \"../utils/event-stream.js\";\nimport { providerRegistry } from \"../provider-registry.js\";\n\n// ── Response Types ────────────────────────────────────────\n\nexport interface PalsuProviderState {\n  callCount: number;\n}\n\nexport type PalsuResponseFactory = (\n  messages: Message[],\n  options: StreamOptions,\n  state: PalsuProviderState,\n) => AssistantMessage | Promise<AssistantMessage>;\n\nexport type PalsuResponse = AssistantMessage | PalsuResponseFactory;\n\n// ── Helper Constructors ──────────────��────────────────────\n\n/** Create an assistant message with a single text block. */\nexport function palsuText(text: string): AssistantMessage {\n  return { role: \"assistant\", content: text ? [{ type: \"text\", text }] : [] };\n}\n\n/** Create an assistant message with a thinking block and optional text reply. */\nexport function palsuThinking(thinking: string, text?: string): AssistantMessage {\n  const content: ContentPart[] = [{ type: \"thinking\", text: thinking }];\n  if (text) content.push({ type: \"text\", text });\n  return { role: \"assistant\", content };\n}\n\n/** Create an assistant message with a single tool call. */\nexport function palsuToolCall(\n  name: string,\n  args: Record<string, unknown>,\n  id?: string,\n): AssistantMessage {\n  return {\n    role: \"assistant\",\n    content: [{ type: \"tool_call\", id: id ?? `palsu_${name}_${Date.now()}`, name, args }],\n  };\n}\n\n/** Create an assistant message from content parts with optional stop reason. */\nexport function palsuAssistantMessage(\n  content: ContentPart[],\n  options?: { stopReason?: StopReason },\n): AssistantMessage & { _stopReason?: StopReason } {\n  return { role: \"assistant\", content, _stopReason: options?.stopReason };\n}\n\n// ── Streaming Simulation ────────────���─────────────────────\n\nconst DEFAULT_CHUNK_SIZE = 20;\n\nfunction chunkText(text: string, size: number): string[] {\n  const chunks: string[] = [];\n  for (let i = 0; i < text.length; i += size) {\n    chunks.push(text.slice(i, i + size));\n  }\n  return chunks.length > 0 ? chunks : [\"\"];\n}\n\ninterface CacheUsage {\n  cacheRead: number;\n  cacheWrite: number;\n}\n\nasync function* simulateStream(\n  message: AssistantMessage,\n  stopReason: StopReason,\n  signal?: AbortSignal,\n  cacheUsage?: CacheUsage,\n): AsyncGenerator<StreamEvent, StreamResponse> {\n  if (signal?.aborted) {\n    throw new Error(\"aborted\");\n  }\n\n  const content =\n    typeof message.content === \"string\"\n      ? message.content\n        ? [{ type: \"text\" as const, text: message.content }]\n        : []\n      : message.content;\n\n  let outputChars = 0;\n\n  for (const part of content) {\n    if (signal?.aborted) {\n      throw new Error(\"aborted\");\n    }\n\n    if (part.type === \"text\") {\n      const chunks = chunkText(part.text, DEFAULT_CHUNK_SIZE);\n      for (const chunk of chunks) {\n        yield { type: \"text_delta\", text: chunk };\n        outputChars += chunk.length;\n      }\n    } else if (part.type === \"thinking\") {\n      yield { type: \"thinking_delta\", text: part.text };\n      outputChars += part.text.length;\n    } else if (part.type === \"tool_call\") {\n      const argsJson = JSON.stringify(part.args);\n      yield { type: \"toolcall_delta\", id: part.id, name: part.name, argsJson };\n      yield { type: \"toolcall_done\", id: part.id, name: part.name, args: part.args };\n      outputChars += argsJson.length;\n    }\n  }\n\n  // Rough token estimate: ~4 chars per token\n  const outputTokens = Math.max(1, Math.ceil(outputChars / 4));\n  const usage: Usage = {\n    inputTokens: 100,\n    outputTokens,\n    ...(cacheUsage?.cacheRead ? { cacheRead: cacheUsage.cacheRead } : {}),\n    ...(cacheUsage?.cacheWrite ? { cacheWrite: cacheUsage.cacheWrite } : {}),\n  };\n\n  yield { type: \"done\", stopReason };\n  return { message, stopReason, usage };\n}\n\n// ── Prompt Cache Simulation ���─────────────────────────────\n\nfunction computeCacheUsage(current: string, previous: string | null): CacheUsage {\n  if (!previous) {\n    // First call — everything is a cache write\n    return { cacheRead: 0, cacheWrite: Math.ceil(current.length / 4) };\n  }\n  // Find common prefix length\n  const maxLen = Math.min(current.length, previous.length);\n  let commonLen = 0;\n  for (let i = 0; i < maxLen; i++) {\n    if (current[i] !== previous[i]) break;\n    commonLen++;\n  }\n  return {\n    cacheRead: Math.ceil(commonLen / 4),\n    cacheWrite: Math.ceil((current.length - commonLen) / 4),\n  };\n}\n\n// ── Model Config ─────────────────────────────────────────\n\nexport interface PalsuModelConfig {\n  /** Default response for this model when its queue is empty. */\n  defaultResponse?: PalsuResponse;\n}\n\ninterface ModelState {\n  responses: PalsuResponse[];\n  defaultResponse?: PalsuResponse;\n}\n\n// ── Registration Handle ───────────────────────────────────\n\nexport interface PalsuModelHandle {\n  /** Replace this model's response queue. */\n  setResponses(responses: PalsuResponse[]): void;\n  /** Append responses to this model's queue. */\n  appendResponses(...responses: PalsuResponse[]): void;\n  /** Number of unconsumed responses in this model's queue. */\n  getPendingResponseCount(): number;\n}\n\nexport interface PalsuProviderHandle {\n  /** Replace the shared response queue entirely. */\n  setResponses(responses: PalsuResponse[]): void;\n  /** Append responses to the shared queue. */\n  appendResponses(...responses: PalsuResponse[]): void;\n  /** Number of unconsumed responses in the shared queue. */\n  getPendingResponseCount(): number;\n  /** Mutable state — tracks call count. */\n  state: PalsuProviderState;\n  /** Get a handle for a model-specific response queue. */\n  getModel(name: string): PalsuModelHandle;\n  /** Remove this provider from the registry. */\n  unregister(): void;\n}\n\nexport interface PalsuProviderConfig {\n  /** Provider name to register under. Default: \"palsu\". */\n  name?: string;\n  /** Response returned when all queues are empty. Default: empty text message. */\n  defaultResponse?: PalsuResponse;\n  /** Enable prompt cache simulation. Tracks common message prefixes across calls. */\n  promptCache?: boolean;\n  /** Model-specific configurations with per-model response queues. */\n  models?: Record<string, PalsuModelConfig>;\n}\n\n// ── Main Registration Function ────────────────────────────\n\n/**\n * Register a palsu (mock) LLM provider for testing.\n * Returns a handle to control responses and inspect state.\n *\n * ```ts\n * const palsu = registerPalsuProvider();\n * palsu.appendResponses(palsuText(\"Hello!\"));\n *\n * const result = await stream({ provider: \"palsu\", model: \"test\", messages });\n * console.log(result.message); // { role: \"assistant\", content: [{ type: \"text\", text: \"Hello!\" }] }\n *\n * palsu.unregister(); // cleanup\n * ```\n */\nexport function registerPalsuProvider(config?: PalsuProviderConfig): PalsuProviderHandle {\n  const name = config?.name ?? \"palsu\";\n  const responses: PalsuResponse[] = [];\n  const state: PalsuProviderState = { callCount: 0 };\n  const defaultResponse = config?.defaultResponse ?? palsuText(\"\");\n  const enableCache = config?.promptCache ?? false;\n  let lastMessagesSerialized: string | null = null;\n\n  // Initialize model-specific state\n  const modelStates = new Map<string, ModelState>();\n  if (config?.models) {\n    for (const [modelName, modelConfig] of Object.entries(config.models)) {\n      modelStates.set(modelName, {\n        responses: [],\n        defaultResponse: modelConfig.defaultResponse,\n      });\n    }\n  }\n\n  const handle: PalsuProviderHandle = {\n    setResponses(r) {\n      responses.length = 0;\n      responses.push(...r);\n    },\n    appendResponses(...r) {\n      responses.push(...r);\n    },\n    getPendingResponseCount() {\n      return responses.length;\n    },\n    state,\n    getModel(modelName: string): PalsuModelHandle {\n      if (!modelStates.has(modelName)) {\n        modelStates.set(modelName, { responses: [] });\n      }\n      const ms = modelStates.get(modelName)!;\n      return {\n        setResponses(r) {\n          ms.responses.length = 0;\n          ms.responses.push(...r);\n        },\n        appendResponses(...r) {\n          ms.responses.push(...r);\n        },\n        getPendingResponseCount() {\n          return ms.responses.length;\n        },\n      };\n    },\n    unregister() {\n      providerRegistry.unregister(name);\n    },\n  };\n\n  providerRegistry.register(name, {\n    stream(options: StreamOptions): StreamResult {\n      state.callCount++;\n\n      // Resolve response: model-specific queue → shared queue → model default → shared default\n      const ms = modelStates.get(options.model);\n      const responseDef =\n        (ms && ms.responses.length > 0 ? ms.responses.shift() : undefined) ??\n        (responses.length > 0 ? responses.shift() : undefined) ??\n        ms?.defaultResponse ??\n        defaultResponse;\n\n      // Compute cache usage before streaming (needs messages serialized)\n      let cacheUsage: CacheUsage | undefined;\n      if (enableCache) {\n        const serialized = JSON.stringify(options.messages);\n        cacheUsage = computeCacheUsage(serialized, lastMessagesSerialized);\n        lastMessagesSerialized = serialized;\n      }\n\n      const gen = (async function* (): AsyncGenerator<StreamEvent, StreamResponse> {\n        // Resolve factory (sync or async) then stream\n        const rawMessage =\n          typeof responseDef === \"function\"\n            ? responseDef(options.messages, options, state)\n            : responseDef;\n        const message = await Promise.resolve(rawMessage);\n\n        const hasToolCalls =\n          Array.isArray(message.content) && message.content.some((p) => p.type === \"tool_call\");\n        const explicitStop = (message as { _stopReason?: StopReason })._stopReason;\n        const stopReason = explicitStop ?? (hasToolCalls ? \"tool_use\" : \"end_turn\");\n\n        return yield* simulateStream(message, stopReason, options.signal, cacheUsage);\n      })();\n\n      return new StreamResult(gen, options.signal);\n    },\n  });\n\n  return handle;\n}\n"],"mappings":"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","names":["required","Anthropic","stream","createClient","OpenAI","runStream","toError","stream","parsed","runStream","os","toError","runStream","content","clone"]}