@broberg/ai-sdk 0.7.0 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/routing/tier-map.ts","../src/transport/http.ts","../src/transport/subprocess.ts","../src/transport/stream.ts","../src/providers/tools.ts","../src/cost/pricing.ts","../src/cost/usage.ts","../src/providers/anthropic.ts","../src/providers/openai-compatible.ts","../src/providers/openai.ts","../src/providers/gemini.ts","../src/providers/deepinfra.ts","../src/providers/openrouter.ts","../src/providers/mistral.ts","../src/providers/fal.ts","../src/providers/registry.ts","../src/cost/budget.ts","../src/capabilities/vision.ts","../src/capabilities/video.ts","../src/capabilities/translate.ts","../src/capabilities/embedding.ts","../src/capabilities/transcribe.ts","../src/capabilities/contracts/index.ts","../src/schema/inputs.ts","../src/client.ts","../src/providers/stub.ts","../src/version.ts","../src/cost/budget-store.ts","../src/cost/sinks/noop.ts","../src/cost/sinks/multi.ts","../src/cost/sinks/upmetrics.ts","../src/cost/sinks/discord.ts","../src/cost/sinks/sqlite.ts"],"sourcesContent":["// Tier routing: a named Tier resolves to a concrete (provider, model, transport).\n// Precedence is per-call override > client config map > built-in defaults.\nimport type { Tier, TierSpec } from \"../types.js\";\n\n/** Built-in defaults. Every entry is overridable via AiConfig.defaults or a\n * per-call override. Model IDs are current at scaffold time; callers pin their\n * own via config. `cheap` routes through the local `claude -p` subprocess\n * (Max plan → costUsd 0); everything else is HTTP. */\nexport const DEFAULT_TIER_MAP: Record<Tier, TierSpec> = {\n fast: { provider: \"anthropic\", model: \"claude-haiku-4-5\", transport: \"http\" },\n smart: { provider: \"anthropic\", model: \"claude-sonnet-4-6\", transport: \"http\" },\n powerful: { provider: \"anthropic\", model: \"claude-opus-4-8\", transport: \"http\" },\n cheap: { provider: \"anthropic\", model: \"claude-haiku-4-5\", transport: \"subprocess\" },\n vision: { provider: \"anthropic\", model: \"claude-sonnet-4-6\", transport: \"http\" },\n // Native video understanding — Gemini leads; flash-lite is the cheap default (F019).\n video: { provider: \"gemini\", model: \"gemini-2.5-flash-lite\", transport: \"http\" },\n embedding: { provider: \"openai\", model: \"text-embedding-3-small\", transport: \"http\" },\n};\n\n/**\n * Resolve a Tier to a concrete TierSpec.\n *\n * Merge order (later wins): DEFAULT_TIER_MAP < configMap < override.\n * - `configMap` is the client-level AiConfig.defaults (per-tier full specs).\n * - `override` is a per-call Partial<TierSpec> — only the fields it sets win.\n */\nexport function resolveTier(\n tier: Tier,\n override?: Partial<TierSpec>,\n configMap?: Partial<Record<Tier, TierSpec>>,\n): TierSpec {\n const base = configMap?.[tier] ?? DEFAULT_TIER_MAP[tier];\n return { ...base, ...override };\n}\n","// HTTP transport: a thin fetch wrapper. Provider-agnostic — the adapter supplies\n// the fully-built url/headers/body and parses the returned json itself.\nimport type { TransportRequest, HttpResponse } from \"./types.js\";\n\nexport async function httpTransport(req: TransportRequest): Promise<HttpResponse> {\n if (!req.http) {\n throw new Error(\"httpTransport: req.http is required for http transport\");\n }\n const { url, method = \"POST\", headers, body } = req.http;\n const res = await fetch(url, {\n method,\n headers,\n body:\n body === undefined\n ? undefined\n : typeof body === \"string\"\n ? body\n : JSON.stringify(body),\n });\n const json: unknown = await res.json().catch(() => undefined);\n return { ok: res.ok, status: res.status, json };\n}\n","// Subprocess transport: runs the local `claude -p` CLI (Anthropic Max plan).\n// No API key, no metered charge — costUsd is always 0, flagged subprocess:true so\n// dashboards can split free (Max) from paid (API). Token counts still come back\n// from the CLI's JSON so usage is tracked even when cost is zero.\nimport type { TransportRequest, SubprocessResponse } from \"./types.js\";\n\n/** The subset of `claude -p --output-format json` output we read. The CLI emits\n * more fields; we only need the result text + token usage. */\ninterface ClaudeCliJson {\n result?: string;\n usage?: {\n input_tokens?: number;\n output_tokens?: number;\n cache_creation_input_tokens?: number;\n cache_read_input_tokens?: number;\n };\n}\n\n/** Pure parser for the `claude -p --output-format json` stdout. Exported so it\n * can be unit-tested without spawning the binary. costUsd is pinned to 0. */\nexport function parseClaudeCliJson(raw: string): SubprocessResponse {\n let parsed: ClaudeCliJson;\n try {\n parsed = JSON.parse(raw) as ClaudeCliJson;\n } catch {\n throw new Error(\n `subprocessTransport: could not parse claude -p JSON output: ${raw.slice(0, 200)}`,\n );\n }\n const u = parsed.usage ?? {};\n return {\n text: parsed.result ?? \"\",\n inputTokens: u.input_tokens ?? 0,\n outputTokens: u.output_tokens ?? 0,\n cacheReadTokens: u.cache_read_input_tokens ?? 0,\n cacheCreationTokens: u.cache_creation_input_tokens ?? 0,\n costUsd: 0,\n subprocess: true,\n };\n}\n\nexport async function subprocessTransport(\n req: TransportRequest,\n): Promise<SubprocessResponse> {\n if (!req.subprocess) {\n throw new Error(\"subprocessTransport: req.subprocess is required for subprocess transport\");\n }\n const { prompt, systemPrompt } = req.subprocess;\n\n const cmd = [\"claude\", \"-p\", \"--output-format\", \"json\", \"--model\", req.spec.model];\n if (systemPrompt) cmd.push(\"--system-prompt\", systemPrompt);\n\n // Prompt goes in on stdin as a Blob (no argv length limit, no manual FileSink).\n const proc = (() => {\n try {\n return Bun.spawn(cmd, {\n stdin: new Blob([prompt]),\n stdout: \"pipe\",\n stderr: \"pipe\",\n });\n } catch (err) {\n throw new Error(\n `subprocessTransport: failed to spawn 'claude' — is the CLI installed and on PATH? (${String(err)})`,\n );\n }\n })();\n\n const [stdout, stderr, exitCode] = await Promise.all([\n new Response(proc.stdout).text(),\n new Response(proc.stderr).text(),\n proc.exited,\n ]);\n\n if (exitCode !== 0) {\n throw new Error(\n `subprocessTransport: claude -p exited ${exitCode}: ${stderr.slice(0, 300) || stdout.slice(0, 300)}`,\n );\n }\n\n return parseClaudeCliJson(stdout);\n}\n","// SSE streaming transport (F8.1). Like httpTransport but yields the parsed\n// `data:` payloads from the response body instead of awaiting .json() — pure\n// fetch + a ReadableStream reader, so it is Node 18+ and Bun safe. The adapter\n// supplies the `stream:true` body and parses each yielded JSON string itself.\nimport type { TransportRequest } from \"./types.js\";\n\n/** HTTP error from a streaming connect — carries `status` so the client's\n * pre-stream fallback can tell an eligible 429/5xx from a hard 4xx. */\nexport class StreamHttpError extends Error {\n readonly status: number;\n constructor(message: string, status: number) {\n super(message);\n this.name = \"StreamHttpError\";\n this.status = status;\n }\n}\n\nexport interface StreamTransportRequest extends TransportRequest {\n /** Injectable fetch for tests. */\n fetch?: typeof fetch;\n}\n\n/**\n * Open an SSE stream and yield each event's `data:` payload as a raw string\n * (the JSON after `data: `), skipping the `[DONE]` terminator and non-data\n * lines. Throws StreamHttpError before the first yield on a non-2xx connect.\n */\nexport async function* streamTransport(req: StreamTransportRequest): AsyncIterable<string> {\n if (!req.http) throw new Error(\"streamTransport: req.http is required for http transport\");\n const { url, method = \"POST\", headers, body } = req.http;\n const fetchImpl = req.fetch ?? fetch;\n const res = await fetchImpl(url, {\n method,\n headers,\n body:\n body === undefined\n ? undefined\n : typeof body === \"string\"\n ? body\n : JSON.stringify(body),\n });\n if (!res.ok || !res.body) {\n const text = await res.text().catch(() => \"\");\n throw new StreamHttpError(`stream ${res.status}: ${text.slice(0, 300)}`, res.status);\n }\n const reader = res.body.getReader();\n const decoder = new TextDecoder();\n let buffer = \"\";\n try {\n for (;;) {\n const { done, value } = await reader.read();\n if (done) break;\n buffer += decoder.decode(value, { stream: true });\n // OpenAI/Anthropic emit one `data: {json}\\n\\n` per event — parse per line.\n let nl: number;\n while ((nl = buffer.indexOf(\"\\n\")) >= 0) {\n const line = buffer.slice(0, nl).replace(/\\r$/, \"\");\n buffer = buffer.slice(nl + 1);\n if (!line.startsWith(\"data:\")) continue; // skip comments / event: / id:\n const data = line.slice(5).trim();\n if (data === \"[DONE]\") return;\n if (data) yield data;\n }\n }\n } finally {\n reader.releaseLock();\n }\n}\n","// Cross-provider tool/function-calling normalization. The SDK speaks one Tool /\n// ToolCall shape; each provider has its own. toProviderTools builds the request\n// tools array; fromProviderToolCall parses one tool-call out of a response.\n// OpenAI, DeepInfra and OpenRouter share the OpenAI-compatible format.\nimport type { Tool, ToolCall } from \"../types.js\";\n\ntype ToolProvider = \"openai\" | \"deepinfra\" | \"openrouter\" | \"gemini\" | \"anthropic\";\n\nfunction family(provider: string): ToolProvider {\n if (provider === \"gemini\" || provider === \"google\") return \"gemini\";\n if (provider === \"anthropic\") return \"anthropic\";\n // openai, deepinfra, openrouter — all OpenAI-compatible\n return \"openai\";\n}\n\n/** Convert SDK tools to a provider's request format. */\nexport function toProviderTools(tools: Tool[], provider: string): unknown {\n switch (family(provider)) {\n case \"openai\":\n return tools.map((t) => ({\n type: \"function\",\n function: { name: t.name, description: t.description, parameters: t.parameters },\n }));\n case \"gemini\":\n return [\n {\n functionDeclarations: tools.map((t) => ({\n name: t.name,\n description: t.description,\n parameters: t.parameters,\n })),\n },\n ];\n case \"anthropic\":\n return tools.map((t) => ({\n name: t.name,\n description: t.description,\n input_schema: t.parameters,\n }));\n default:\n throw new Error(`toProviderTools: unsupported provider family for \"${provider}\"`);\n }\n}\n\n/** Parse a single provider-shaped tool call back into the SDK ToolCall shape. */\nexport function fromProviderToolCall(raw: unknown, provider: string): ToolCall {\n const r = raw as Record<string, unknown>;\n switch (family(provider)) {\n case \"openai\": {\n // { id, type:\"function\", function:{ name, arguments:\"<json>\" } }\n const fn = (r.function ?? {}) as { name?: string; arguments?: string };\n return {\n id: typeof r.id === \"string\" ? r.id : \"\",\n name: fn.name ?? \"\",\n arguments: parseArgs(fn.arguments),\n };\n }\n case \"gemini\": {\n // { functionCall:{ name, args } } or { name, args }\n const fc = (r.functionCall ?? r) as { name?: string; args?: unknown };\n return {\n id: \"\", // Gemini function calls have no id\n name: fc.name ?? \"\",\n arguments: (fc.args as Record<string, unknown>) ?? {},\n };\n }\n case \"anthropic\": {\n // { type:\"tool_use\", id, name, input }\n return {\n id: typeof r.id === \"string\" ? r.id : \"\",\n name: typeof r.name === \"string\" ? r.name : \"\",\n arguments: (r.input as Record<string, unknown>) ?? {},\n };\n }\n default:\n throw new Error(`fromProviderToolCall: unsupported provider family for \"${provider}\"`);\n }\n}\n\nfunction parseArgs(raw: unknown): Record<string, unknown> {\n if (raw === undefined || raw === null) return {};\n if (typeof raw === \"object\") return raw as Record<string, unknown>;\n if (typeof raw === \"string\") {\n try {\n return JSON.parse(raw) as Record<string, unknown>;\n } catch {\n return {};\n }\n }\n return {};\n}\n","// Versioned per-(provider, model) pricing. F3.6 populates the table + adds tests\n// + MiniMax coverage. F3.1 ships the type + lookup with an empty table, so\n// computeCost returns 0 for every model until F3.6 lands (calls still complete).\nexport interface PricingEntry {\n /** USD per 1M input tokens. */\n inputPer1M: number;\n /** USD per 1M output tokens. */\n outputPer1M: number;\n /** USD per 1M cache-read tokens (falls back to input rate if unset). */\n cacheReadPer1M?: number;\n /** USD per 1M cache-write/creation tokens (falls back to input rate if unset). */\n cacheWritePer1M?: number;\n /** Pricing snapshot version (date or tag) so stale entries are detectable. */\n version: string;\n}\n\n// USD per 1M tokens. Anthropic cache multipliers follow the standard model:\n// cache-read ≈ 0.1× input, cache-write ≈ 1.25× input. Verified against the\n// pricing tables in cms (packages/cms-ai/src/providers) + trail (model-lab).\n// MiniMax M2.7 is an estimate pending confirmation against OpenRouter's live\n// price page — flagged in its version string.\nconst V = \"2026-06-02\";\n// Mistral prices come straight from mistral.ai/pricing (per Christian's CD report).\nconst MS = \"2026-06-04-mistral.ai\";\n\n/** Keyed `${provider}:${model}`. Exported so the catalogue-research job (F014)\n * can enumerate every priced entry and diff it against the live provider lists. */\nexport const PRICING: Record<string, PricingEntry> = {\n // Anthropic (direct API). DEFAULT_TIER_MAP: fast/cheap=haiku, smart/vision=sonnet, powerful=opus.\n \"anthropic:claude-haiku-4-5\": {\n inputPer1M: 0.8,\n outputPer1M: 4.0,\n cacheReadPer1M: 0.08,\n cacheWritePer1M: 1.0,\n version: V,\n },\n \"anthropic:claude-sonnet-4-6\": {\n inputPer1M: 3.0,\n outputPer1M: 15.0,\n cacheReadPer1M: 0.3,\n cacheWritePer1M: 3.75,\n version: V,\n },\n \"anthropic:claude-opus-4-8\": {\n inputPer1M: 15.0,\n outputPer1M: 75.0,\n cacheReadPer1M: 1.5,\n cacheWritePer1M: 18.75,\n version: V,\n },\n\n // OpenAI. embedding default tier = text-embedding-3-small (no output tokens).\n \"openai:text-embedding-3-small\": { inputPer1M: 0.02, outputPer1M: 0, version: V },\n \"openai:text-embedding-3-large\": { inputPer1M: 0.13, outputPer1M: 0, version: V },\n \"openai:gpt-4o\": { inputPer1M: 2.5, outputPer1M: 10.0, version: V },\n \"openai:gpt-4o-mini\": { inputPer1M: 0.15, outputPer1M: 0.6, version: V },\n // Whisper is priced per minute, not per token — not representable here; transcribe\n // (F5.6) computes its own cost. Listed as 0 so token-based compute never charges it.\n \"openai:whisper-1\": { inputPer1M: 0, outputPer1M: 0, version: V },\n\n // OpenRouter (meta-router — model slugs include the upstream vendor). Slugs use\n // dots (claude-sonnet-4.6) to match OpenRouter's live ids; the dashed forms\n // never matched a real call. Caught by the F014 catalogue research.\n \"openrouter:anthropic/claude-sonnet-4.6\": { inputPer1M: 3.0, outputPer1M: 15.0, version: V },\n // OpenRouter ground-truth $1/$5 — a markup over Anthropic-direct's $0.8/$4\n // (the `anthropic:` entry above). Was masked while the slug used dashes.\n \"openrouter:anthropic/claude-haiku-4.5\": { inputPer1M: 1.0, outputPer1M: 5.0, version: \"2026-06-04\" },\n \"openrouter:google/gemini-2.5-flash\": { inputPer1M: 0.3, outputPer1M: 2.5, version: V },\n // Ground-truth from OpenRouter /api/v1/models (was a 0.3 estimate; now 0.279).\n \"openrouter:minimax/minimax-m2.7\": {\n inputPer1M: 0.279,\n outputPer1M: 1.2,\n version: \"2026-06-04\",\n },\n\n // Google Gemini (direct). Provider key is \"gemini\" — matches the adapter's\n // usage.provider + the override.provider callers pass. (Image-gen models are\n // priced per-image in the adapter, not here.)\n \"gemini:gemini-2.5-flash\": { inputPer1M: 0.3, outputPer1M: 2.5, version: V },\n // flash-lite is the default `video` tier (F019) — cheap native video understanding.\n \"gemini:gemini-2.5-flash-lite\": { inputPer1M: 0.1, outputPer1M: 0.4, version: \"2026-06-04-or-xref\" },\n\n // Mistral (direct, La Plateforme). Official prices from mistral.ai/pricing\n // (2026-06-04, per Christian's CD report). EU/Paris-hosted — the designated\n // GDPR-safe provider for client/personal-data workloads (see F015). NB:\n // medium-3.5 is the premium \"Vibe\" coding tier ($1.5/$7.5); Large 3 ($0.5/$1.5)\n // is the cheaper frontier general-purpose model despite the higher number.\n \"mistral:mistral-large-latest\": { inputPer1M: 0.5, outputPer1M: 1.5, version: MS },\n \"mistral:mistral-large-2512\": { inputPer1M: 0.5, outputPer1M: 1.5, version: MS },\n \"mistral:mistral-medium-latest\": { inputPer1M: 1.5, outputPer1M: 7.5, version: MS },\n \"mistral:mistral-medium-3.5\": { inputPer1M: 1.5, outputPer1M: 7.5, version: MS },\n \"mistral:mistral-medium-3\": { inputPer1M: 0.4, outputPer1M: 2.0, version: \"2026-06-04-or-xref\" },\n \"mistral:mistral-small-latest\": { inputPer1M: 0.1, outputPer1M: 0.3, version: MS },\n \"mistral:mistral-small-2603\": { inputPer1M: 0.1, outputPer1M: 0.3, version: MS },\n \"mistral:ministral-3b-latest\": { inputPer1M: 0.1, outputPer1M: 0.1, version: MS },\n \"mistral:ministral-8b-latest\": { inputPer1M: 0.15, outputPer1M: 0.15, version: MS },\n \"mistral:ministral-14b-latest\": { inputPer1M: 0.2, outputPer1M: 0.2, version: MS },\n \"mistral:magistral-medium-latest\": { inputPer1M: 2.0, outputPer1M: 5.0, version: MS },\n \"mistral:magistral-small-latest\": { inputPer1M: 0.5, outputPer1M: 1.5, version: MS },\n \"mistral:devstral-latest\": { inputPer1M: 0.4, outputPer1M: 2.0, version: MS },\n \"mistral:codestral-latest\": { inputPer1M: 0.3, outputPer1M: 0.9, version: MS },\n \"mistral:open-mistral-nemo\": { inputPer1M: 0.15, outputPer1M: 0.15, version: MS },\n // Moderation (F016.4) — per input token; output 0. (OCR is per-page in the adapter.)\n \"mistral:mistral-moderation-latest\": { inputPer1M: 0.1, outputPer1M: 0, version: MS },\n};\n\nexport function getPrice(provider: string, model: string): PricingEntry | undefined {\n const exact = PRICING[`${provider}:${model}`];\n if (exact) return exact;\n // Providers ship dated model snapshots, e.g. \"claude-haiku-4-5-20251001\".\n // Strip a trailing -YYYYMMDD and retry the base lookup so a dated variant\n // prices the same as its base model instead of falling through to 0 — a real\n // paid call must never be logged as $0 (F012). Covers openrouter slugs too.\n const base = model.replace(/-\\d{8}$/, \"\");\n if (base !== model) return PRICING[`${provider}:${base}`];\n return undefined;\n}\n","// Usage construction + cost computation. Real adapters (F4) build their Usage via\n// freshUsage() and fill costUsd from computeCost(). The pricing table lives in\n// ./pricing.ts (F3.6); until a model is priced, computeCost returns 0 so calls\n// still complete (cost just shows $0 rather than throwing).\nimport { getPrice } from \"./pricing.js\";\nimport type { Usage, Transport, Capability } from \"../types.js\";\n\n/**\n * Cost in USD for a call. cache-read/creation tokens are priced separately when\n * the pricing entry defines rates for them; otherwise they fall back to the\n * input rate (read) / are ignored (creation). Unknown model → 0.\n */\nexport function computeCost(\n provider: string,\n model: string,\n inputTokens: number,\n outputTokens: number,\n cacheReadTokens = 0,\n cacheCreationTokens = 0,\n): number {\n const price = getPrice(provider, model);\n if (!price) return 0;\n const perToken = (per1M: number) => per1M / 1_000_000;\n const inRate = perToken(price.inputPer1M);\n const outRate = perToken(price.outputPer1M);\n const cacheReadRate =\n price.cacheReadPer1M !== undefined ? perToken(price.cacheReadPer1M) : inRate;\n const cacheWriteRate =\n price.cacheWritePer1M !== undefined ? perToken(price.cacheWritePer1M) : inRate;\n return (\n inputTokens * inRate +\n outputTokens * outRate +\n cacheReadTokens * cacheReadRate +\n cacheCreationTokens * cacheWriteRate\n );\n}\n\n/** Build a Usage with cost computed from the pricing table. Adapters call this\n * after a successful provider call; latencyMs/ts/capability are stamped by the\n * client (call-context owner), so they default to 0/\"\"/the passed capability. */\nexport function freshUsage(args: {\n provider: string;\n model: string;\n transport: Transport;\n capability: Capability;\n inputTokens: number;\n outputTokens: number;\n cacheReadTokens?: number;\n cacheCreationTokens?: number;\n subprocess?: boolean;\n}): Usage {\n const cacheReadTokens = args.cacheReadTokens ?? 0;\n const cacheCreationTokens = args.cacheCreationTokens ?? 0;\n // Subprocess (Max plan) is never a metered charge to us — cost is always 0.\n const costUsd = args.subprocess\n ? 0\n : computeCost(\n args.provider,\n args.model,\n args.inputTokens,\n args.outputTokens,\n cacheReadTokens,\n cacheCreationTokens,\n );\n const usage: Usage = {\n provider: args.provider,\n model: args.model,\n transport: args.transport,\n inputTokens: args.inputTokens,\n outputTokens: args.outputTokens,\n cacheReadTokens,\n cacheCreationTokens,\n costUsd,\n latencyMs: 0,\n capability: args.capability,\n ts: \"\",\n };\n if (args.subprocess) usage.subprocess = true;\n return usage;\n}\n","// Anthropic adapter (F4.6) — the real one (F2.5 shipped only a stub). Two\n// transports: http (api.anthropic.com/v1/messages) and subprocess (claude -p,\n// Max plan, costUsd 0). Critical for the xrt81 vision pilot. Tools normalized\n// via F4.5. No @anthropic-ai/sdk package — plain fetch through httpTransport.\nimport { httpTransport } from \"../transport/http.js\";\nimport { subprocessTransport } from \"../transport/subprocess.js\";\nimport { streamTransport } from \"../transport/stream.js\";\nimport { toProviderTools, fromProviderToolCall } from \"./tools.js\";\nimport { freshUsage } from \"../cost/usage.js\";\nimport type {\n ProviderAdapter,\n ChatRequest,\n ChatResult,\n ChatStreamEvent,\n Message,\n ContentPart,\n ToolCall,\n} from \"../types.js\";\n\ninterface AnthropicBlock {\n type: string;\n text?: string;\n id?: string;\n name?: string;\n input?: Record<string, unknown>;\n}\ninterface AnthropicResponse {\n content?: AnthropicBlock[];\n usage?: {\n input_tokens?: number;\n output_tokens?: number;\n cache_read_input_tokens?: number;\n cache_creation_input_tokens?: number;\n };\n error?: unknown;\n}\n\nfunction contentBlocks(content: string | ContentPart[]): unknown {\n if (typeof content === \"string\") return content;\n return content.map((p) => {\n if (p.type === \"text\") return { type: \"text\", text: p.text };\n // Anthropic has no native video input — route video via a video-capable\n // provider (Gemini, F019) instead.\n if (p.type === \"video\") {\n throw new Error(\"anthropic adapter: video input is not supported — use a video provider (e.g. gemini)\");\n }\n if (typeof p.image === \"string\" && /^https?:\\/\\//.test(p.image)) {\n return { type: \"image\", source: { type: \"url\", url: p.image } };\n }\n const data =\n typeof p.image === \"string\"\n ? p.image.replace(/^data:[^;]+;base64,/, \"\")\n : Buffer.from(p.image).toString(\"base64\");\n return {\n type: \"image\",\n source: { type: \"base64\", media_type: p.mimeType ?? \"image/png\", data },\n };\n });\n}\n\n/** Flatten messages to a single prompt for the subprocess (claude -p) path. */\nfunction flattenForSubprocess(messages: Message[]): { prompt: string; system?: string } {\n const sys: string[] = [];\n const turns: string[] = [];\n for (const m of messages) {\n const text =\n typeof m.content === \"string\"\n ? m.content\n : m.content.map((p) => (p.type === \"text\" ? p.text : \"[image]\")).join(\" \");\n if (m.role === \"system\") sys.push(text);\n else turns.push(`${m.role}: ${text}`);\n }\n return { prompt: turns.join(\"\\n\\n\"), system: sys.length ? sys.join(\"\\n\") : undefined };\n}\n\nexport function anthropicAdapter(\n config: { apiKey?: string; baseUrl?: string; anthropicVersion?: string; fetch?: typeof fetch } = {},\n): ProviderAdapter {\n const baseUrl = config.baseUrl ?? \"https://api.anthropic.com\";\n const version = config.anthropicVersion ?? \"2023-06-01\";\n\n /** Build the /v1/messages body (shared by the http + stream paths). */\n function buildBody(req: ChatRequest): Record<string, unknown> {\n const system: string[] = [];\n const messages: { role: string; content: unknown }[] = [];\n for (const m of req.messages as Message[]) {\n if (m.role === \"system\") {\n system.push(typeof m.content === \"string\" ? m.content : \"\");\n continue;\n }\n // tool-result turn → a user message carrying a tool_result block (F8.7).\n if (m.role === \"tool\") {\n messages.push({\n role: \"user\",\n content: [\n {\n type: \"tool_result\",\n tool_use_id: m.toolCallId ?? \"\",\n content: typeof m.content === \"string\" ? m.content : \"\",\n },\n ],\n });\n continue;\n }\n // assistant turn that called tools → text blocks + tool_use blocks (F8.7).\n if (m.role === \"assistant\" && m.toolCalls && m.toolCalls.length > 0) {\n const blocks: unknown[] = [];\n if (typeof m.content === \"string\") {\n if (m.content.length > 0) blocks.push({ type: \"text\", text: m.content });\n } else {\n blocks.push(...(contentBlocks(m.content) as unknown[]));\n }\n for (const tc of m.toolCalls) {\n blocks.push({ type: \"tool_use\", id: tc.id, name: tc.name, input: tc.arguments });\n }\n messages.push({ role: \"assistant\", content: blocks });\n continue;\n }\n messages.push({ role: m.role === \"assistant\" ? \"assistant\" : \"user\", content: contentBlocks(m.content) });\n }\n const body: Record<string, unknown> = {\n model: req.spec.model,\n max_tokens: req.maxTokens ?? 1024, // Anthropic requires max_tokens\n messages,\n };\n if (system.length > 0) body.system = system.join(\"\\n\");\n if (req.tools) body.tools = toProviderTools(req.tools, \"anthropic\");\n if (req.temperature !== undefined) body.temperature = req.temperature;\n return body;\n }\n\n function apiKeyOrThrow(): string {\n const apiKey = config.apiKey ?? process.env.ANTHROPIC_API_KEY;\n if (!apiKey) throw new Error(\"anthropic adapter: API key not set (env ANTHROPIC_API_KEY)\");\n return apiKey;\n }\n\n async function chatHttp(req: ChatRequest): Promise<ChatResult> {\n const apiKey = apiKeyOrThrow();\n const body = buildBody(req);\n\n const res = await httpTransport({\n spec: req.spec,\n http: {\n url: `${baseUrl}/v1/messages`,\n headers: {\n \"content-type\": \"application/json\",\n \"x-api-key\": apiKey,\n \"anthropic-version\": version,\n },\n body,\n },\n });\n if (!res.ok) throw new Error(`anthropic ${res.status}: ${JSON.stringify(res.json).slice(0, 300)}`);\n\n const data = res.json as AnthropicResponse;\n const blocks = data.content ?? [];\n const text = blocks\n .filter((b) => b.type === \"text\" && typeof b.text === \"string\")\n .map((b) => b.text)\n .join(\"\");\n const toolCalls: ToolCall[] = blocks\n .filter((b) => b.type === \"tool_use\")\n .map((b) => fromProviderToolCall(b, \"anthropic\"));\n\n const usage = freshUsage({\n provider: \"anthropic\",\n model: req.spec.model,\n transport: \"http\",\n capability: \"chat\",\n inputTokens: data.usage?.input_tokens ?? 0,\n outputTokens: data.usage?.output_tokens ?? 0,\n cacheReadTokens: data.usage?.cache_read_input_tokens ?? 0,\n cacheCreationTokens: data.usage?.cache_creation_input_tokens ?? 0,\n });\n const result: ChatResult = { text, usage };\n if (toolCalls.length > 0) result.toolCalls = toolCalls;\n return result;\n }\n\n async function chatSubprocess(req: ChatRequest): Promise<ChatResult> {\n const { prompt, system } = flattenForSubprocess(req.messages as Message[]);\n const r = await subprocessTransport({ spec: req.spec, subprocess: { prompt, systemPrompt: system } });\n const usage = freshUsage({\n provider: \"anthropic\",\n model: req.spec.model,\n transport: \"subprocess\",\n capability: \"chat\",\n inputTokens: r.inputTokens,\n outputTokens: r.outputTokens,\n cacheReadTokens: r.cacheReadTokens,\n cacheCreationTokens: r.cacheCreationTokens,\n subprocess: true,\n });\n return { text: r.text, usage };\n }\n\n async function chat(req: ChatRequest): Promise<ChatResult> {\n return req.spec.transport === \"subprocess\" ? chatSubprocess(req) : chatHttp(req);\n }\n\n // Streaming chat (F8.4) over the native /v1/messages SSE. Maps\n // content_block_delta(text_delta) → text events, accumulates tool_use blocks\n // (id/name from content_block_start, input from input_json_delta) → complete\n // tool_call events, and reads usage from message_start + message_delta. Only\n // the http transport streams — `claude -p` subprocess is one-shot.\n async function* chatStream(req: ChatRequest): AsyncIterable<ChatStreamEvent> {\n if (req.spec.transport === \"subprocess\") {\n throw new Error(\"anthropic adapter: streaming is not supported over the subprocess transport\");\n }\n const apiKey = apiKeyOrThrow();\n const body = { ...buildBody(req), stream: true };\n const stream = streamTransport({\n spec: req.spec,\n fetch: config.fetch,\n http: {\n url: `${baseUrl}/v1/messages`,\n headers: {\n \"content-type\": \"application/json\",\n \"x-api-key\": apiKey,\n \"anthropic-version\": version,\n },\n body,\n },\n });\n\n let inputTokens = 0;\n let outputTokens = 0;\n let cacheReadTokens = 0;\n let cacheCreationTokens = 0;\n let stopReason: string | null = null;\n // index → accumulated tool_use block (input_json_delta fragments concatenated).\n const toolBlocks = new Map<number, { id: string; name: string; json: string }>();\n\n for await (const data of stream) {\n let ev: AnthropicStreamEvent;\n try {\n ev = JSON.parse(data) as AnthropicStreamEvent;\n } catch {\n continue;\n }\n switch (ev.type) {\n case \"message_start\": {\n const u = ev.message?.usage;\n inputTokens = u?.input_tokens ?? 0;\n cacheReadTokens = u?.cache_read_input_tokens ?? 0;\n cacheCreationTokens = u?.cache_creation_input_tokens ?? 0;\n break;\n }\n case \"content_block_start\": {\n if (ev.content_block?.type === \"tool_use\" && ev.index !== undefined) {\n toolBlocks.set(ev.index, {\n id: ev.content_block.id ?? \"\",\n name: ev.content_block.name ?? \"\",\n json: \"\",\n });\n }\n break;\n }\n case \"content_block_delta\": {\n const d = ev.delta;\n if (d?.type === \"text_delta\" && d.text) {\n yield { type: \"text\", delta: d.text };\n } else if (d?.type === \"input_json_delta\" && d.partial_json && ev.index !== undefined) {\n const b = toolBlocks.get(ev.index);\n if (b) b.json += d.partial_json;\n }\n break;\n }\n case \"message_delta\": {\n if (ev.delta?.stop_reason) stopReason = ev.delta.stop_reason;\n if (ev.usage?.output_tokens !== undefined) outputTokens = ev.usage.output_tokens;\n break;\n }\n default:\n break; // content_block_stop / message_stop / ping\n }\n }\n\n for (const [, b] of [...toolBlocks.entries()].sort((a, c) => a[0] - c[0])) {\n let args: Record<string, unknown> = {};\n try {\n args = b.json ? (JSON.parse(b.json) as Record<string, unknown>) : {};\n } catch {\n args = {};\n }\n yield { type: \"tool_call\", id: b.id, name: b.name, args };\n }\n const usage = freshUsage({\n provider: \"anthropic\",\n model: req.spec.model,\n transport: \"http\",\n capability: \"chat\",\n inputTokens,\n outputTokens,\n cacheReadTokens,\n cacheCreationTokens,\n });\n yield { type: \"usage\", costUsd: usage.costUsd, model: usage.model, usage };\n yield { type: \"finish\", reason: mapAnthropicStop(stopReason) };\n }\n\n return { name: \"anthropic\", chat, chatStream, vision: chat };\n}\n\n/** Anthropic Messages SSE event (only the fields we read). */\ninterface AnthropicStreamEvent {\n type: string;\n index?: number;\n message?: {\n usage?: {\n input_tokens?: number;\n cache_read_input_tokens?: number;\n cache_creation_input_tokens?: number;\n };\n };\n content_block?: { type?: string; id?: string; name?: string };\n delta?: { type?: string; text?: string; partial_json?: string; stop_reason?: string };\n usage?: { output_tokens?: number };\n}\n\n/** Map Anthropic stop_reason → the SDK's ChatStreamEvent finish reason. */\nfunction mapAnthropicStop(reason: string | null): \"end_turn\" | \"tool_calls\" | \"length\" | \"stop\" {\n switch (reason) {\n case \"tool_use\":\n return \"tool_calls\";\n case \"max_tokens\":\n return \"length\";\n case \"stop_sequence\":\n return \"stop\";\n default:\n return \"end_turn\";\n }\n}\n","// Shared core for OpenAI-compatible chat APIs. OpenAI (F4.1), DeepInfra (F4.3)\n// and OpenRouter (F4.4) all speak this wire format — only base URL, key and a\n// couple of headers differ. The adapter uses httpTransport (F2.4) for the wire\n// I/O and the F4.5 tool contract for tool round-tripping.\nimport { httpTransport } from \"../transport/http.js\";\nimport { streamTransport } from \"../transport/stream.js\";\nimport { toProviderTools, fromProviderToolCall } from \"./tools.js\";\nimport { freshUsage } from \"../cost/usage.js\";\nimport type {\n ProviderAdapter,\n ChatRequest,\n ChatResult,\n ChatStreamEvent,\n Message,\n ToolCall,\n} from \"../types.js\";\n\nexport interface OpenAICompatibleConfig {\n /** Provider name recorded on Usage (e.g. \"openai\", \"deepinfra\", \"openrouter\"). */\n name: string;\n /** Chat completions base, e.g. \"https://api.openai.com/v1\". */\n baseUrl: string;\n /** Resolved at call time if omitted (env var per provider). */\n apiKey?: string;\n /** Extra headers (e.g. OpenRouter's HTTP-Referer / X-Title). */\n extraHeaders?: Record<string, string>;\n /** Injectable fetch for the streaming path (tests). */\n fetch?: typeof fetch;\n /** OpenRouter ground-truth cost (F010): send `usage:{include:true}` and use the\n * response's `usage.cost` (USD) as costUsd, falling back to the pricing table.\n * Only OpenRouter returns this field — openai/deepinfra leave it false. */\n costFromResponseField?: boolean;\n}\n\ninterface OAToolCall {\n id?: string;\n function?: { name?: string; arguments?: string };\n}\ninterface OAResponse {\n choices?: { message?: { content?: string | null; tool_calls?: OAToolCall[] } }[];\n usage?: { prompt_tokens?: number; completion_tokens?: number; cost?: number };\n error?: unknown;\n}\n\n/** SDK message → OpenAI message (string content, or multimodal parts for vision).\n * Threads the normalized tool form to the wire: a `tool`-role message's\n * `toolCallId` → `tool_call_id`, and an assistant message's `toolCalls` →\n * `tool_calls:[{id,type:'function',function:{name,arguments}}]` (F8.3) so a\n * multi-turn tool conversation round-trips. Exported for serialization tests. */\nexport function toOpenAIMessage(m: Message): Record<string, unknown> {\n if (typeof m.content === \"string\") {\n const base: Record<string, unknown> = { role: m.role, content: m.content };\n if (m.toolCallId) base.tool_call_id = m.toolCallId;\n if (m.toolCalls && m.toolCalls.length > 0) {\n base.tool_calls = m.toolCalls.map((tc) => ({\n id: tc.id,\n type: \"function\",\n function: { name: tc.name, arguments: JSON.stringify(tc.arguments) },\n }));\n }\n return base;\n }\n const content = m.content.map((p) => {\n if (p.type === \"text\") return { type: \"text\", text: p.text };\n if (p.type === \"video\") {\n // F019.3 — OpenRouter video models. `video_url` mirrors `image_url`;\n // VERIFIED live 2026-06-04 against gemma-4 + nvidia-nemotron (both described\n // a real 2MB clip sent inline as a base64 data-URL).\n const url =\n typeof p.video === \"string\"\n ? p.video\n : `data:${p.mimeType ?? \"video/mp4\"};base64,${Buffer.from(p.video).toString(\"base64\")}`;\n return { type: \"video_url\", video_url: { url } };\n }\n const url =\n typeof p.image === \"string\"\n ? p.image\n : `data:${p.mimeType ?? \"image/png\"};base64,${Buffer.from(p.image).toString(\"base64\")}`;\n return { type: \"image_url\", image_url: { url } };\n });\n return { role: m.role, content };\n}\n\nexport function makeOpenAICompatibleAdapter(config: OpenAICompatibleConfig): ProviderAdapter {\n async function chat(req: ChatRequest): Promise<ChatResult> {\n const apiKey = config.apiKey ?? process.env[`${config.name.toUpperCase()}_API_KEY`];\n if (!apiKey) {\n throw new Error(`${config.name} adapter: API key not set (env ${config.name.toUpperCase()}_API_KEY)`);\n }\n const body: Record<string, unknown> = {\n model: req.spec.model,\n messages: req.messages.map(toOpenAIMessage),\n };\n if (req.tools) body.tools = toProviderTools(req.tools, \"openai\");\n if (req.maxTokens !== undefined) body.max_tokens = req.maxTokens;\n if (req.temperature !== undefined) body.temperature = req.temperature;\n if (req.responseFormat === \"json\") body.response_format = { type: \"json_object\" };\n if (config.costFromResponseField) body.usage = { include: true };\n\n const res = await httpTransport({\n spec: req.spec,\n http: {\n url: `${config.baseUrl}/chat/completions`,\n headers: {\n \"content-type\": \"application/json\",\n Authorization: `Bearer ${apiKey}`,\n ...config.extraHeaders,\n },\n body,\n },\n });\n if (!res.ok) {\n throw new Error(`${config.name} ${res.status}: ${JSON.stringify(res.json).slice(0, 300)}`);\n }\n const data = res.json as OAResponse;\n const msg = data.choices?.[0]?.message;\n const text = msg?.content ?? \"\";\n const toolCalls: ToolCall[] | undefined = msg?.tool_calls?.map((tc) =>\n fromProviderToolCall(tc, \"openai\"),\n );\n const usage = freshUsage({\n provider: config.name,\n model: req.spec.model,\n transport: \"http\",\n capability: \"chat\",\n inputTokens: data.usage?.prompt_tokens ?? 0,\n outputTokens: data.usage?.completion_tokens ?? 0,\n });\n if (config.costFromResponseField && typeof data.usage?.cost === \"number\") {\n usage.costUsd = data.usage.cost; // OpenRouter ground-truth beats the estimate\n }\n const result: ChatResult = { text, usage };\n if (toolCalls && toolCalls.length > 0) result.toolCalls = toolCalls;\n return result;\n }\n\n // Streaming chat (F8.2). Parses the OpenAI chat.completions SSE: content\n // deltas → text events, tool_calls deltas accumulated (index-keyed, arguments\n // string concatenated) → complete tool_call events at end, the include_usage\n // chunk → a usage event, finish_reason → the terminal finish (emitted last so\n // tool_calls + usage precede it).\n async function* chatStream(req: ChatRequest): AsyncIterable<ChatStreamEvent> {\n const apiKey = config.apiKey ?? process.env[`${config.name.toUpperCase()}_API_KEY`];\n if (!apiKey) {\n throw new Error(`${config.name} adapter: API key not set (env ${config.name.toUpperCase()}_API_KEY)`);\n }\n const body: Record<string, unknown> = {\n model: req.spec.model,\n messages: req.messages.map(toOpenAIMessage),\n stream: true,\n stream_options: { include_usage: true },\n };\n if (req.tools) body.tools = toProviderTools(req.tools, \"openai\");\n if (req.maxTokens !== undefined) body.max_tokens = req.maxTokens;\n if (req.temperature !== undefined) body.temperature = req.temperature;\n if (req.responseFormat === \"json\") body.response_format = { type: \"json_object\" };\n if (config.costFromResponseField) body.usage = { include: true };\n\n const stream = streamTransport({\n spec: req.spec,\n fetch: config.fetch,\n http: {\n url: `${config.baseUrl}/chat/completions`,\n headers: {\n \"content-type\": \"application/json\",\n Authorization: `Bearer ${apiKey}`,\n ...config.extraHeaders,\n },\n body,\n },\n });\n\n // index → accumulated tool call (id/name set once, arguments concatenated).\n const toolAcc = new Map<number, { id: string; name: string; args: string }>();\n let finishReason: string | null = null;\n\n for await (const data of stream) {\n let chunk: OAStreamChunk;\n try {\n chunk = JSON.parse(data) as OAStreamChunk;\n } catch {\n continue; // ignore unparseable keep-alive noise\n }\n const choice = chunk.choices?.[0];\n if (choice) {\n const delta = choice.delta ?? {};\n if (typeof delta.content === \"string\" && delta.content.length > 0) {\n yield { type: \"text\", delta: delta.content };\n }\n for (const tc of delta.tool_calls ?? []) {\n const idx = tc.index ?? 0;\n const cur = toolAcc.get(idx) ?? { id: \"\", name: \"\", args: \"\" };\n if (tc.id) cur.id = tc.id;\n if (tc.function?.name) cur.name = tc.function.name;\n if (tc.function?.arguments) cur.args += tc.function.arguments;\n toolAcc.set(idx, cur);\n }\n if (choice.finish_reason) finishReason = choice.finish_reason;\n }\n if (chunk.usage) {\n const usage = freshUsage({\n provider: config.name,\n model: req.spec.model,\n transport: \"http\",\n capability: \"chat\",\n inputTokens: chunk.usage.prompt_tokens ?? 0,\n outputTokens: chunk.usage.completion_tokens ?? 0,\n });\n if (config.costFromResponseField && typeof chunk.usage.cost === \"number\") {\n usage.costUsd = chunk.usage.cost; // OpenRouter ground-truth\n }\n yield { type: \"usage\", costUsd: usage.costUsd, model: usage.model, usage };\n }\n }\n\n // Flush accumulated tool calls (complete), then the terminal finish.\n for (const [, t] of [...toolAcc.entries()].sort((a, b) => a[0] - b[0])) {\n let args: Record<string, unknown> = {};\n try {\n args = t.args ? (JSON.parse(t.args) as Record<string, unknown>) : {};\n } catch {\n args = {};\n }\n yield { type: \"tool_call\", id: t.id, name: t.name, args };\n }\n yield { type: \"finish\", reason: mapFinishReason(finishReason) };\n }\n\n return {\n name: config.name,\n chat,\n chatStream,\n // gpt-4o-class models are multimodal — vision shares the chat path.\n vision: chat,\n };\n}\n\n/** OpenAI streaming chunk shape (only the fields we read). */\ninterface OAStreamChunk {\n choices?: {\n delta?: {\n content?: string | null;\n tool_calls?: { index?: number; id?: string; function?: { name?: string; arguments?: string } }[];\n };\n finish_reason?: string | null;\n }[];\n usage?: { prompt_tokens?: number; completion_tokens?: number; cost?: number };\n}\n\n/** Map OpenAI finish_reason → the SDK's ChatStreamEvent finish reason. */\nfunction mapFinishReason(reason: string | null): \"end_turn\" | \"tool_calls\" | \"length\" | \"stop\" {\n switch (reason) {\n case \"tool_calls\":\n return \"tool_calls\";\n case \"length\":\n return \"length\";\n case \"stop\":\n return \"stop\";\n default:\n return \"end_turn\";\n }\n}\n","// OpenAI adapter (F4.1 chat/vision + F5.4 embedding). Chat/vision come from the\n// shared OpenAI-compatible core; embedding uses the /embeddings endpoint. No\n// openai npm package — plain fetch through httpTransport.\nimport { makeOpenAICompatibleAdapter } from \"./openai-compatible.js\";\nimport { httpTransport } from \"../transport/http.js\";\nimport { freshUsage } from \"../cost/usage.js\";\nimport type {\n ProviderAdapter,\n EmbeddingRequest,\n EmbeddingResult,\n TranscribeRequest,\n TranscribeResult,\n} from \"../types.js\";\n\n/** Whisper-family per-minute USD prices (audio is not token-priced). */\nconst WHISPER_PRICE_PER_MIN: Record<string, number> = {\n \"whisper-1\": 0.006,\n};\n\nexport function openaiAdapter(\n config: { apiKey?: string; baseUrl?: string; fetch?: typeof fetch } = {},\n): ProviderAdapter {\n const baseUrl = config.baseUrl ?? \"https://api.openai.com/v1\";\n const base = makeOpenAICompatibleAdapter({ name: \"openai\", baseUrl, apiKey: config.apiKey });\n\n async function embedding(req: EmbeddingRequest): Promise<EmbeddingResult> {\n const apiKey = config.apiKey ?? process.env.OPENAI_API_KEY;\n if (!apiKey) throw new Error(\"openai adapter: API key not set (env OPENAI_API_KEY)\");\n const res = await httpTransport({\n spec: req.spec,\n http: {\n url: `${baseUrl}/embeddings`,\n headers: { \"content-type\": \"application/json\", Authorization: `Bearer ${apiKey}` },\n body: { model: req.spec.model, input: req.input },\n },\n });\n if (!res.ok) {\n throw new Error(`openai ${res.status}: ${JSON.stringify(res.json).slice(0, 300)}`);\n }\n const data = res.json as {\n data?: { embedding: number[] }[];\n usage?: { prompt_tokens?: number };\n };\n const vectors = (data.data ?? []).map((d) => d.embedding);\n const usage = freshUsage({\n provider: \"openai\",\n model: req.spec.model,\n transport: \"http\",\n capability: \"embedding\",\n inputTokens: data.usage?.prompt_tokens ?? 0,\n outputTokens: 0,\n });\n return { vectors, usage };\n }\n\n async function transcribe(req: TranscribeRequest): Promise<TranscribeResult> {\n const apiKey = config.apiKey ?? process.env.OPENAI_API_KEY;\n if (!apiKey) throw new Error(\"openai adapter: API key not set (env OPENAI_API_KEY)\");\n // Whisper is multipart/form-data — bypass httpTransport (JSON-only). Don't set\n // content-type; fetch adds the multipart boundary.\n const form = new FormData();\n form.append(\"file\", new Blob([req.audio]), \"audio\");\n form.append(\"model\", req.spec.model);\n if (req.language) form.append(\"language\", req.language);\n const fetchImpl = config.fetch ?? fetch;\n const res = await fetchImpl(`${baseUrl}/audio/transcriptions`, {\n method: \"POST\",\n headers: { Authorization: `Bearer ${apiKey}` },\n body: form,\n });\n if (!res.ok) {\n throw new Error(`openai ${res.status}: ${(await res.text().catch(() => \"\")).slice(0, 200)}`);\n }\n const data = (await res.json()) as { text?: string };\n const usage = freshUsage({\n provider: \"openai\",\n model: req.spec.model,\n transport: \"http\",\n capability: \"transcribe\",\n inputTokens: 0,\n outputTokens: 0, // Whisper is per-minute, not token-priced.\n });\n // Per-minute cost when the caller supplies the audio duration (API returns none).\n if (req.durationSec !== undefined) {\n const perMinute = WHISPER_PRICE_PER_MIN[req.spec.model] ?? 0;\n usage.costUsd = (req.durationSec / 60) * perMinute;\n }\n return { text: data.text ?? \"\", usage };\n }\n\n return { ...base, embedding, transcribe };\n}\n","// Google Gemini adapter (F4.2). generateContent REST API; API key in the query\n// param (?key=), not a header. System turns map to systemInstruction; assistant\n// maps to role \"model\". Token counts come from usageMetadata. Tools normalized\n// via F4.5. No @google/generative-ai package — plain fetch through httpTransport.\nimport { httpTransport } from \"../transport/http.js\";\nimport { streamTransport } from \"../transport/stream.js\";\nimport { toProviderTools, fromProviderToolCall } from \"./tools.js\";\nimport { freshUsage } from \"../cost/usage.js\";\nimport type {\n ProviderAdapter,\n ChatRequest,\n ChatResult,\n ChatStreamEvent,\n ImageRequest,\n ImageResult,\n Message,\n ContentPart,\n ToolCall,\n} from \"../types.js\";\n\n/** Per-image USD price for Gemini image-gen models (generateContent image output\n * is billed per image, not per token). nano-banana = $0.039. Overridable via\n * geminiAdapter config.pricePerImage. */\nconst GEMINI_IMAGE_PRICE_PER_IMAGE: Record<string, number> = {\n \"gemini-3-pro-image-preview\": 0.039,\n \"gemini-2.5-flash-image\": 0.039,\n};\n\ninterface GeminiPart {\n text?: string;\n functionCall?: { name: string; args: Record<string, unknown> };\n inlineData?: { mimeType: string; data: string };\n}\ninterface GeminiResponse {\n candidates?: { content?: { parts?: GeminiPart[] } }[];\n usageMetadata?: { promptTokenCount?: number; candidatesTokenCount?: number };\n error?: unknown;\n}\n\nfunction partsFrom(content: string | ContentPart[]): GeminiPart[] {\n if (typeof content === \"string\") return [{ text: content }];\n return content.map((p): GeminiPart => {\n if (p.type === \"text\") return { text: p.text };\n // Video (F019) and image both go inline as base64 — Gemini accepts video mime\n // types natively. (Clips over ~20MB need the Files API — not handled here.)\n if (p.type === \"video\") {\n const data =\n typeof p.video === \"string\"\n ? p.video.replace(/^data:[^;]+;base64,/, \"\")\n : Buffer.from(p.video).toString(\"base64\");\n return { inlineData: { mimeType: p.mimeType ?? \"video/mp4\", data } };\n }\n const data =\n typeof p.image === \"string\"\n ? p.image.replace(/^data:[^;]+;base64,/, \"\")\n : Buffer.from(p.image).toString(\"base64\");\n return { inlineData: { mimeType: p.mimeType ?? \"image/png\", data } };\n });\n}\n\nexport function geminiAdapter(\n config: { apiKey?: string; baseUrl?: string; fetch?: typeof fetch; pricePerImage?: number } = {},\n): ProviderAdapter {\n const baseUrl = config.baseUrl ?? \"https://generativelanguage.googleapis.com/v1beta\";\n\n function resolveKey(): string {\n const apiKey = config.apiKey ?? process.env.GOOGLE_API_KEY ?? process.env.GEMINI_API_KEY;\n if (!apiKey) throw new Error(\"gemini adapter: API key not set (env GOOGLE_API_KEY)\");\n return apiKey;\n }\n\n /** Build the generateContent body (shared by the http + stream paths). */\n function buildBody(req: ChatRequest): Record<string, unknown> {\n const systemParts: GeminiPart[] = [];\n const contents: { role: string; parts: GeminiPart[] }[] = [];\n for (const m of req.messages as Message[]) {\n if (m.role === \"system\") {\n systemParts.push(...partsFrom(m.content));\n } else {\n contents.push({\n role: m.role === \"assistant\" ? \"model\" : \"user\",\n parts: partsFrom(m.content),\n });\n }\n }\n const body: Record<string, unknown> = { contents };\n if (systemParts.length > 0) body.systemInstruction = { parts: systemParts };\n if (req.tools) body.tools = toProviderTools(req.tools, \"gemini\");\n const genConfig: Record<string, unknown> = {};\n if (req.maxTokens !== undefined) genConfig.maxOutputTokens = req.maxTokens;\n if (req.temperature !== undefined) genConfig.temperature = req.temperature;\n if (Object.keys(genConfig).length > 0) body.generationConfig = genConfig;\n return body;\n }\n\n async function chat(req: ChatRequest): Promise<ChatResult> {\n const apiKey = resolveKey();\n const body = buildBody(req);\n\n const res = await httpTransport({\n spec: req.spec,\n http: {\n url: `${baseUrl}/models/${req.spec.model}:generateContent?key=${encodeURIComponent(apiKey)}`,\n headers: { \"content-type\": \"application/json\" },\n body,\n },\n });\n if (!res.ok) {\n throw new Error(`gemini ${res.status}: ${JSON.stringify(res.json).slice(0, 300)}`);\n }\n const data = res.json as GeminiResponse;\n const parts = data.candidates?.[0]?.content?.parts ?? [];\n const text = parts\n .filter((p) => typeof p.text === \"string\")\n .map((p) => p.text)\n .join(\"\");\n const toolCalls: ToolCall[] = parts\n .filter((p) => p.functionCall)\n .map((p) => fromProviderToolCall({ functionCall: p.functionCall }, \"gemini\"));\n\n const usage = freshUsage({\n provider: \"gemini\",\n model: req.spec.model,\n transport: \"http\",\n capability: \"chat\",\n inputTokens: data.usageMetadata?.promptTokenCount ?? 0,\n outputTokens: data.usageMetadata?.candidatesTokenCount ?? 0,\n });\n const result: ChatResult = { text, usage };\n if (toolCalls.length > 0) result.toolCalls = toolCalls;\n return result;\n }\n\n // Streaming chat (F8.6) over streamGenerateContent?alt=sse. Each SSE chunk is\n // a partial GenerateContentResponse: parts[].text → text events, parts[].\n // functionCall → complete tool_call events (gemini sends each call whole), and\n // the final usageMetadata → a usage event. finishReason maps the terminal.\n async function* chatStream(req: ChatRequest): AsyncIterable<ChatStreamEvent> {\n const apiKey = resolveKey();\n const body = buildBody(req);\n const stream = streamTransport({\n spec: req.spec,\n fetch: config.fetch,\n http: {\n url: `${baseUrl}/models/${req.spec.model}:streamGenerateContent?alt=sse&key=${encodeURIComponent(apiKey)}`,\n headers: { \"content-type\": \"application/json\" },\n body,\n },\n });\n\n const toolCalls: ToolCall[] = [];\n let inputTokens = 0;\n let outputTokens = 0;\n let finishReason: string | null = null;\n\n for await (const data of stream) {\n let chunk: GeminiResponse & { candidates?: { finishReason?: string }[] };\n try {\n chunk = JSON.parse(data) as typeof chunk;\n } catch {\n continue;\n }\n const candidate = chunk.candidates?.[0];\n for (const p of candidate?.content?.parts ?? []) {\n if (typeof p.text === \"string\" && p.text.length > 0) {\n yield { type: \"text\", delta: p.text };\n } else if (p.functionCall) {\n toolCalls.push(fromProviderToolCall({ functionCall: p.functionCall }, \"gemini\"));\n }\n }\n if (candidate?.finishReason) finishReason = candidate.finishReason;\n if (chunk.usageMetadata) {\n inputTokens = chunk.usageMetadata.promptTokenCount ?? inputTokens;\n outputTokens = chunk.usageMetadata.candidatesTokenCount ?? outputTokens;\n }\n }\n\n for (const tc of toolCalls) {\n yield { type: \"tool_call\", id: tc.id, name: tc.name, args: tc.arguments };\n }\n const usage = freshUsage({\n provider: \"gemini\",\n model: req.spec.model,\n transport: \"http\",\n capability: \"chat\",\n inputTokens,\n outputTokens,\n });\n yield { type: \"usage\", costUsd: usage.costUsd, model: usage.model, usage };\n yield {\n type: \"finish\",\n reason: toolCalls.length > 0 ? \"tool_calls\" : mapGeminiFinish(finishReason),\n };\n }\n\n // Image generation (F013) via generateContent with IMAGE response modality.\n // Gemini returns the image inline as base64 (not a hosted URL like fal), so we\n // hand it back as a data: URL. Built to match cms's nano-banana request.\n async function image(req: ImageRequest): Promise<ImageResult> {\n const apiKey = resolveKey();\n // Direct fetch (injectable for tests) — generateContent is JSON in/out but\n // we read inline image bytes, so we don't route through httpTransport here.\n const fetchImpl = config.fetch ?? fetch;\n const res = await fetchImpl(`${baseUrl}/models/${req.spec.model}:generateContent?key=${encodeURIComponent(apiKey)}`, {\n method: \"POST\",\n headers: { \"content-type\": \"application/json\" },\n body: JSON.stringify({\n contents: [{ role: \"user\", parts: [{ text: req.prompt }] }],\n // The multimodal image model can return text + image; ask for both.\n generationConfig: { responseModalities: [\"TEXT\", \"IMAGE\"] },\n }),\n });\n if (!res.ok) {\n const body = await res.text().catch(() => \"\");\n throw new Error(`gemini image ${res.status}: ${body.slice(0, 300)}`);\n }\n const data = (await res.json()) as GeminiResponse & {\n candidates?: { content?: { parts?: GeminiImagePart[] } }[];\n promptFeedback?: { blockReason?: string };\n };\n if (data.promptFeedback?.blockReason) {\n throw new Error(`gemini image blocked: ${data.promptFeedback.blockReason}`);\n }\n let url: string | undefined;\n for (const p of data.candidates?.[0]?.content?.parts ?? []) {\n // Some responses use camelCase inlineData, others snake_case inline_data.\n const inline = p.inlineData ?? p.inline_data;\n const mime = inline?.mimeType ?? inline?.mime_type;\n const b64 = inline?.data;\n if (mime && b64) {\n url = `data:${mime};base64,${b64}`;\n break;\n }\n }\n if (!url) throw new Error(\"gemini image: response contained no inline image data\");\n const usage = freshUsage({\n provider: \"gemini\",\n model: req.spec.model,\n transport: \"http\",\n capability: \"image\",\n inputTokens: data.usageMetadata?.promptTokenCount ?? 0,\n outputTokens: data.usageMetadata?.candidatesTokenCount ?? 0,\n });\n usage.costUsd = config.pricePerImage ?? GEMINI_IMAGE_PRICE_PER_IMAGE[req.spec.model] ?? 0;\n return { url, usage };\n }\n\n return { name: \"gemini\", chat, chatStream, image, vision: chat };\n}\n\n/** Image part shape on a generateContent response (camel + snake aliases). */\ninterface GeminiInline {\n mimeType?: string;\n mime_type?: string;\n data?: string;\n}\ninterface GeminiImagePart {\n text?: string;\n inlineData?: GeminiInline;\n inline_data?: GeminiInline;\n}\n\n/** Map Gemini finishReason → the SDK's ChatStreamEvent finish reason. */\nfunction mapGeminiFinish(reason: string | null): \"end_turn\" | \"tool_calls\" | \"length\" | \"stop\" {\n switch (reason) {\n case \"MAX_TOKENS\":\n return \"length\";\n case \"STOP\":\n return \"end_turn\";\n default:\n return reason ? \"stop\" : \"end_turn\";\n }\n}\n","// DeepInfra adapter (F4.3). DeepInfra exposes an OpenAI-compatible endpoint, so\n// this is the shared core pointed at DeepInfra's base URL + key. No extra deps.\nimport { makeOpenAICompatibleAdapter } from \"./openai-compatible.js\";\nimport type { ProviderAdapter } from \"../types.js\";\n\nexport function deepinfraAdapter(\n config: { apiKey?: string; baseUrl?: string } = {},\n): ProviderAdapter {\n return makeOpenAICompatibleAdapter({\n name: \"deepinfra\",\n baseUrl: config.baseUrl ?? \"https://api.deepinfra.com/v1/openai\",\n apiKey: config.apiKey,\n });\n}\n","// OpenRouter adapter (F4.4). Meta-router with an OpenAI-compatible API — reuses\n// the shared core + OpenRouter's attribution headers. Any upstream model is\n// reachable by its slug, e.g. \"minimax/minimax-m2.7\", \"google/gemini-2.5-flash\".\nimport { makeOpenAICompatibleAdapter } from \"./openai-compatible.js\";\nimport type { ProviderAdapter } from \"../types.js\";\n\nexport function openrouterAdapter(\n config: { apiKey?: string; baseUrl?: string; referer?: string; title?: string } = {},\n): ProviderAdapter {\n return makeOpenAICompatibleAdapter({\n name: \"openrouter\",\n baseUrl: config.baseUrl ?? \"https://openrouter.ai/api/v1\",\n apiKey: config.apiKey,\n extraHeaders: {\n \"HTTP-Referer\": config.referer ?? \"https://broberg.ai\",\n \"X-Title\": config.title ?? \"@broberg/ai-sdk\",\n },\n // OpenRouter returns ground-truth usage.cost (USD) when usage:{include:true}\n // is set — use it over the local pricing-table estimate (F010).\n costFromResponseField: true,\n });\n}\n","// Mistral adapter. Mistral's La Plateforme exposes an OpenAI-compatible chat\n// endpoint (the shared core), plus two specialty endpoints we add here:\n// /ocr (F016.2, per-page) and /moderations (F016.4, per-token). Key resolved\n// from MISTRAL_API_KEY when not passed.\nimport { makeOpenAICompatibleAdapter } from \"./openai-compatible.js\";\nimport { freshUsage } from \"../cost/usage.js\";\nimport type {\n ProviderAdapter,\n OcrRequest,\n OcrResult,\n OcrPage,\n ModerationRequest,\n ModerationResult,\n ModerationItem,\n} from \"../types.js\";\n\n/** Per-page USD for Mistral OCR ($2 / 1000 pages). Overridable via config. */\nconst MISTRAL_OCR_PRICE_PER_PAGE = 0.002;\n\nexport function mistralAdapter(\n config: { apiKey?: string; baseUrl?: string; fetch?: typeof fetch; pricePerPage?: number } = {},\n): ProviderAdapter {\n const baseUrl = config.baseUrl ?? \"https://api.mistral.ai/v1\";\n const base = makeOpenAICompatibleAdapter({ name: \"mistral\", baseUrl, apiKey: config.apiKey });\n\n function key(): string {\n const k = config.apiKey ?? process.env.MISTRAL_API_KEY;\n if (!k) throw new Error(\"mistral adapter: API key not set (env MISTRAL_API_KEY)\");\n return k;\n }\n const fetchImpl = config.fetch ?? fetch;\n\n // OCR (F016.2) — POST /ocr. document is a URL/data-URL; image/* routes as an\n // image, anything else as a document (PDF etc.). Billed per page processed.\n async function ocr(req: OcrRequest): Promise<OcrResult> {\n const isImage = (req.mimeType ?? \"\").startsWith(\"image/\");\n const url =\n typeof req.document === \"string\"\n ? req.document\n : `data:${req.mimeType ?? \"application/pdf\"};base64,${Buffer.from(req.document).toString(\"base64\")}`;\n const document = isImage\n ? { type: \"image_url\", image_url: url }\n : { type: \"document_url\", document_url: url };\n\n const res = await fetchImpl(`${baseUrl}/ocr`, {\n method: \"POST\",\n headers: { \"content-type\": \"application/json\", authorization: `Bearer ${key()}` },\n body: JSON.stringify({ model: req.spec.model, document }),\n });\n if (!res.ok) {\n const body = await res.text().catch(() => \"\");\n throw new Error(`mistral ocr ${res.status}: ${body.slice(0, 300)}`);\n }\n const data = (await res.json()) as {\n pages?: { index?: number; markdown?: string }[];\n usage_info?: { pages_processed?: number };\n };\n const pages: OcrPage[] = (data.pages ?? []).map((p, i) => ({\n index: p.index ?? i,\n markdown: p.markdown ?? \"\",\n }));\n const pagesProcessed = data.usage_info?.pages_processed ?? pages.length;\n const usage = freshUsage({\n provider: \"mistral\",\n model: req.spec.model,\n transport: \"http\",\n capability: \"ocr\",\n inputTokens: 0,\n outputTokens: 0,\n });\n usage.costUsd = pagesProcessed * (config.pricePerPage ?? MISTRAL_OCR_PRICE_PER_PAGE);\n return { pages, usage };\n }\n\n // Moderation (F016.4) — POST /moderations. Returns per-input category booleans\n // + scores; `flagged` = any category true. Billed per input token (estimated\n // from input length when the API omits a usage count).\n async function moderate(req: ModerationRequest): Promise<ModerationResult> {\n const res = await fetchImpl(`${baseUrl}/moderations`, {\n method: \"POST\",\n headers: { \"content-type\": \"application/json\", authorization: `Bearer ${key()}` },\n body: JSON.stringify({ model: req.spec.model, input: req.input }),\n });\n if (!res.ok) {\n const body = await res.text().catch(() => \"\");\n throw new Error(`mistral moderation ${res.status}: ${body.slice(0, 300)}`);\n }\n const data = (await res.json()) as {\n results?: { categories?: Record<string, boolean>; category_scores?: Record<string, number> }[];\n usage?: { prompt_tokens?: number };\n };\n const results: ModerationItem[] = (data.results ?? []).map((r) => {\n const categories = r.categories ?? {};\n return {\n flagged: Object.values(categories).some(Boolean),\n categories,\n categoryScores: r.category_scores ?? {},\n };\n });\n // The moderation endpoint usually omits token counts → estimate from input.\n const estIn = req.input.reduce((n, s) => n + Math.ceil(s.length / 4), 0);\n const usage = freshUsage({\n provider: \"mistral\",\n model: req.spec.model,\n transport: \"http\",\n capability: \"moderation\",\n inputTokens: data.usage?.prompt_tokens ?? estIn,\n outputTokens: 0,\n });\n return { results, usage };\n }\n\n return { ...base, ocr, moderate };\n}\n","// fal.ai image adapter (F5.3). Two modes, both observed in the F1 inventory:\n// - sync : POST https://fal.run/{model}, image URL straight back (sanneandersen)\n// - queue : POST https://queue.fal.run/{model} → poll status → fetch result\n// Auth header `Authorization: Key <FAL_KEY>`. No @fal-ai/client — plain fetch.\nimport { freshUsage } from \"../cost/usage.js\";\nimport type { ProviderAdapter, ImageRequest, ImageResult } from \"../types.js\";\n\ninterface FalImagesResponse {\n images?: { url?: string }[];\n error?: unknown;\n}\ninterface FalQueueSubmit {\n request_id?: string;\n status_url?: string;\n response_url?: string;\n}\ninterface FalQueueStatus {\n status?: \"IN_QUEUE\" | \"IN_PROGRESS\" | \"COMPLETED\" | \"FAILED\";\n}\n\nexport interface FalAdapterConfig {\n apiKey?: string;\n /** \"sync\" (default — fal.run, fast models) or \"queue\" (queue.fal.run, polled). */\n mode?: \"sync\" | \"queue\";\n syncBaseUrl?: string;\n queueBaseUrl?: string;\n pollIntervalMs?: number;\n timeoutMs?: number;\n fetch?: typeof fetch;\n /** Override the per-image USD price (else a built-in estimate per model, 0 if unknown). */\n pricePerImage?: number;\n}\n\n// Per-image USD ESTIMATES (fal prices by megapixel/model and changes often —\n// verify before relying on these; override via config.pricePerImage). fal does\n// not return a price, so this is the SDK's best-effort cost for `usage.costUsd`.\nconst FAL_IMAGE_PRICE_ESTIMATE: Record<string, number> = {\n \"fal-ai/flux/schnell\": 0.003,\n \"fal-ai/flux/dev\": 0.025,\n \"fal-ai/flux-pro\": 0.05,\n \"fal-ai/flux-pro/v1.1\": 0.04,\n};\n\nconst sleep = (ms: number) => new Promise((r) => setTimeout(r, ms));\n\nexport function falAdapter(config: FalAdapterConfig = {}): ProviderAdapter {\n const doFetch = config.fetch ?? fetch;\n const syncBase = config.syncBaseUrl ?? \"https://fal.run\";\n const queueBase = config.queueBaseUrl ?? \"https://queue.fal.run\";\n const pollIntervalMs = config.pollIntervalMs ?? 2000;\n const timeoutMs = config.timeoutMs ?? 60000;\n\n async function image(req: ImageRequest): Promise<ImageResult> {\n const apiKey = config.apiKey ?? process.env.FAL_KEY;\n if (!apiKey) throw new Error(\"fal adapter: FAL_KEY not set\");\n const headers = { \"content-type\": \"application/json\", Authorization: `Key ${apiKey}` };\n\n const body: Record<string, unknown> = { prompt: req.prompt };\n if (req.width !== undefined && req.height !== undefined) {\n body.image_size = { width: req.width, height: req.height };\n }\n\n const mode = config.mode ?? \"sync\";\n const url = await (mode === \"sync\"\n ? runSync(req.spec.model, headers, body)\n : runQueue(req.spec.model, headers, body));\n\n // fal returns no price; estimate per-image (one image per call) so usage.costUsd\n // isn't silently 0. Override via config.pricePerImage.\n const usage = freshUsage({\n provider: \"fal\",\n model: req.spec.model,\n transport: \"http\",\n capability: \"image\",\n inputTokens: 0,\n outputTokens: 0,\n });\n usage.costUsd = config.pricePerImage ?? FAL_IMAGE_PRICE_ESTIMATE[req.spec.model] ?? 0;\n return { url, usage };\n }\n\n async function runSync(\n model: string,\n headers: Record<string, string>,\n body: unknown,\n ): Promise<string> {\n const res = await doFetch(`${syncBase}/${model}`, {\n method: \"POST\",\n headers,\n body: JSON.stringify(body),\n });\n if (!res.ok) {\n throw new Error(`fal ${res.status}: ${(await res.text().catch(() => \"\")).slice(0, 200)}`);\n }\n const data = (await res.json()) as FalImagesResponse;\n const out = data.images?.[0]?.url;\n if (!out) throw new Error(`fal: no image url in response`);\n return out;\n }\n\n async function runQueue(\n model: string,\n headers: Record<string, string>,\n body: unknown,\n ): Promise<string> {\n const submitRes = await doFetch(`${queueBase}/${model}`, {\n method: \"POST\",\n headers,\n body: JSON.stringify(body),\n });\n if (!submitRes.ok) {\n throw new Error(`fal queue submit ${submitRes.status}`);\n }\n const submit = (await submitRes.json()) as FalQueueSubmit;\n const statusUrl = submit.status_url;\n const responseUrl = submit.response_url;\n if (!statusUrl || !responseUrl) throw new Error(\"fal queue: missing status/response url\");\n\n const deadline = Date.now() + timeoutMs;\n for (;;) {\n const statusRes = await doFetch(statusUrl, { headers });\n const status = (await statusRes.json()) as FalQueueStatus;\n if (status.status === \"COMPLETED\") break;\n if (status.status === \"FAILED\") throw new Error(\"fal queue: generation FAILED\");\n if (Date.now() >= deadline) throw new Error(`fal queue: timed out after ${timeoutMs}ms`);\n await sleep(pollIntervalMs);\n }\n\n const resultRes = await doFetch(responseUrl, { headers });\n const result = (await resultRes.json()) as FalImagesResponse;\n const out = result.images?.[0]?.url;\n if (!out) throw new Error(\"fal queue: no image url in result\");\n return out;\n }\n\n return { name: \"fal\", image };\n}\n","// Default provider registry — the live adapters wired when AiConfig.providers is\n// absent. A bare createAI() makes real calls (keys from env). fal stays a stub\n// until F5.3 ships the real fal.ai image adapter.\nimport { anthropicAdapter } from \"./anthropic.js\";\nimport { openaiAdapter } from \"./openai.js\";\nimport { geminiAdapter } from \"./gemini.js\";\nimport { deepinfraAdapter } from \"./deepinfra.js\";\nimport { openrouterAdapter } from \"./openrouter.js\";\nimport { mistralAdapter } from \"./mistral.js\";\nimport { falAdapter } from \"./fal.js\";\nimport type { ProviderAdapter } from \"../types.js\";\n\nexport const defaultProviders: Record<string, ProviderAdapter> = {\n anthropic: anthropicAdapter(),\n openai: openaiAdapter(),\n gemini: geminiAdapter(),\n deepinfra: deepinfraAdapter(),\n openrouter: openrouterAdapter(),\n mistral: mistralAdapter(),\n fal: falAdapter(),\n};\n","// Pre-flight budget guard. check() runs BEFORE the transport fires, so a call\n// that would breach a ceiling never reaches the provider. record() folds the\n// actual cost into the running total after a successful call.\nimport type { BudgetConfig, BudgetStore } from \"../types.js\";\n\n/** Default rolling-total store: in-memory, per BudgetGuard instance. */\nclass InMemoryBudgetStore implements BudgetStore {\n private spentUsd = 0;\n getSpent(): number {\n return this.spentUsd;\n }\n addSpent(usd: number): void {\n this.spentUsd += usd;\n }\n}\n\nexport class BudgetExceededError extends Error {\n readonly kind: \"per-call\" | \"rolling\";\n readonly limit: number;\n readonly spent: number;\n readonly requested: number;\n\n constructor(\n kind: \"per-call\" | \"rolling\",\n limit: number,\n spent: number,\n requested: number,\n ) {\n super(\n `Budget exceeded (${kind}): this call's estimated $${requested.toFixed(6)} ` +\n (kind === \"rolling\"\n ? `+ $${spent.toFixed(6)} already spent exceeds the $${limit.toFixed(6)} rolling ceiling`\n : `exceeds the $${limit.toFixed(6)} per-call ceiling`),\n );\n this.name = \"BudgetExceededError\";\n this.kind = kind;\n this.limit = limit;\n this.spent = spent;\n this.requested = requested;\n }\n}\n\nexport class BudgetGuard {\n private readonly store: BudgetStore;\n\n constructor(private readonly config: BudgetConfig) {\n this.store = config.store ?? new InMemoryBudgetStore();\n }\n\n /** Throws BudgetExceededError if `requested` would breach the per-call ceiling\n * or push the rolling total past its ceiling. Call before firing the request.\n * Async because a persistent store may be I/O-backed. */\n async check(requested: number): Promise<void> {\n const { perCallUsd, rollingUsd } = this.config;\n if (perCallUsd !== undefined && requested > perCallUsd) {\n throw new BudgetExceededError(\"per-call\", perCallUsd, await this.store.getSpent(), requested);\n }\n if (rollingUsd !== undefined) {\n const spent = await this.store.getSpent();\n if (spent + requested > rollingUsd) {\n throw new BudgetExceededError(\"rolling\", rollingUsd, spent, requested);\n }\n }\n }\n\n /** Add an actual cost to the running total (after a successful call). */\n async record(actual: number): Promise<void> {\n await this.store.addSpent(actual);\n }\n\n async totalSpent(): Promise<number> {\n return this.store.getSpent();\n }\n}\n","// Vision capability helper. The client owns orchestration (tier/budget/sink);\n// this module owns the vision-specific message shaping so it's unit-testable and\n// the capabilities/ layout stays meaningful. Default tier: \"vision\".\nimport type { VisionInput } from \"../schema/inputs.js\";\nimport type { Message, Tier } from \"../types.js\";\n\nexport const VISION_DEFAULT_TIER: Tier = \"vision\";\n\n/** Build the single-user multimodal message (text + image) for a vision call. */\nexport function buildVisionMessages(input: VisionInput): Message[] {\n return [\n {\n role: \"user\",\n content: [\n { type: \"text\", text: input.prompt },\n { type: \"image\", image: input.image, mimeType: input.mimeType },\n ],\n },\n ];\n}\n","// Video Vision capability (F019). Like vision, but the multimodal part is a\n// video the model watches natively (Gemini, OpenRouter video models). The client\n// owns orchestration; this module owns the message shaping. Default tier: \"video\".\nimport type { VideoInput } from \"../schema/inputs.js\";\nimport type { Message, Tier } from \"../types.js\";\n\nexport const VIDEO_DEFAULT_TIER: Tier = \"video\";\n\n/** Build the single-user message (video + prompt) for a video-analysis call. */\nexport function buildVideoMessages(input: VideoInput): Message[] {\n return [\n {\n role: \"user\",\n content: [\n { type: \"video\", video: input.video, mimeType: input.mimeType },\n { type: \"text\", text: input.prompt },\n ],\n },\n ];\n}\n","// Translate capability helper. A thin prompt-contract on top of chat — the\n// client orchestrates (tier/budget/sink); this builds the messages. Default\n// tier: \"fast\". Returns the translation only, no preamble.\nimport type { TranslateInput } from \"../schema/inputs.js\";\nimport type { Message, Tier } from \"../types.js\";\n\nexport const TRANSLATE_DEFAULT_TIER: Tier = \"fast\";\n\nconst TRANSLATE_SYSTEM =\n \"You are a translation engine. Translate the user's text only. \" +\n \"Return the translation and nothing else — no preamble, no quotes.\";\n\nexport function buildTranslateMessages(input: TranslateInput): Message[] {\n const fromClause = input.from ? ` from ${input.from}` : \"\";\n return [\n { role: \"system\", content: TRANSLATE_SYSTEM },\n { role: \"user\", content: `Translate${fromClause} to ${input.to}:\\n\\n${input.text}` },\n ];\n}\n","// Embedding capability marker. The client orchestrates; this names the default\n// tier (OpenAI text-embedding-3-small via the embedding tier).\nimport type { Tier } from \"../types.js\";\n\nexport const EMBEDDING_DEFAULT_TIER: Tier = \"embedding\";\n","// Transcribe capability. No tier in the tier map (provider-specific, like image)\n// — defaults to OpenAI Whisper, overridable per call. Synergy: cctalk Danish\n// dictation. costUsd is 0 for v1 (Whisper is priced per minute, not per token).\nimport type { TierSpec } from \"../types.js\";\n\nexport const DEFAULT_TRANSCRIBE_SPEC: TierSpec = {\n provider: \"openai\",\n model: \"whisper-1\",\n transport: \"http\",\n};\n\n/** Fetch a URL to raw bytes; pass through bytes unchanged. */\nexport async function resolveAudio(\n audio: string | Uint8Array,\n fetchImpl: typeof fetch = fetch,\n): Promise<Uint8Array> {\n if (typeof audio !== \"string\") return audio;\n if (!/^https?:\\/\\//.test(audio)) {\n throw new Error(\"transcribe: string audio must be an http(s) URL (or pass raw bytes)\");\n }\n const res = await fetchImpl(audio);\n if (!res.ok) throw new Error(`transcribe: failed to fetch audio (${res.status})`);\n return new Uint8Array(await res.arrayBuffer());\n}\n","// Prompt-contract capabilities (F5.5). Each is a fixed system prompt over\n// chat/vision; extract adds Zod output validation with one retry. Exposed as\n// ai.contracts.* — built from the client so budget/cost tracking apply.\nimport type { AiClient, VisionInput } from \"../../schema/inputs.js\";\nimport type {\n Contracts,\n MockupInput,\n MockupResult,\n DesignInput,\n DesignResult,\n ExtractInput,\n ExtractResult,\n ClassifyInput,\n ClassifyResult,\n RerankInput,\n RerankResult,\n} from \"./types.js\";\n\n/** Pull the first JSON value out of a model reply (tolerates ```json fences + prose). */\nexport function parseJsonLoose(text: string): unknown {\n const fenced = text.replace(/```(?:json)?/gi, \"\").trim();\n const start = fenced.search(/[[{]/);\n if (start === -1) throw new Error(\"no JSON found in model output\");\n const slice = fenced.slice(start);\n // Walk back from the end to the matching closing bracket.\n const lastObj = slice.lastIndexOf(\"}\");\n const lastArr = slice.lastIndexOf(\"]\");\n const end = Math.max(lastObj, lastArr);\n return JSON.parse(slice.slice(0, end + 1));\n}\n\ntype ChatVision = Pick<AiClient, \"chat\" | \"vision\">;\n\nexport function makeContracts(client: ChatVision): Contracts {\n return {\n async mockup(input: MockupInput): Promise<MockupResult> {\n const constraints = input.constraints ? `\\n\\nConstraints:\\n${input.constraints}` : \"\";\n const res = await client.chat({\n system:\n \"You are a UI mockup generator. Output a single self-contained HTML document \" +\n \"using Tailwind CSS utility classes. Return ONLY the HTML — no markdown, no prose.\",\n prompt: `Build a UI mockup for:\\n${input.description}${constraints}`,\n tier: input.tier ?? \"smart\",\n purpose: input.purpose ?? \"contract:mockup\",\n });\n return { html: res.text, usage: res.usage };\n },\n\n async design(input: DesignInput): Promise<DesignResult> {\n const res = await client.vision({\n image: input.screenshot as VisionInput[\"image\"],\n prompt:\n \"You are a design-iteration engine. Given this screenshot, apply the instructions \" +\n `and return a single self-contained HTML document (Tailwind), ONLY the HTML.\\n\\n` +\n `Instructions:\\n${input.instructions}`,\n tier: input.tier ?? \"powerful\",\n purpose: input.purpose ?? \"contract:design\",\n });\n return { html: res.text, usage: res.usage };\n },\n\n async extract<T>(input: ExtractInput<T>): Promise<ExtractResult<T>> {\n const base =\n \"You are a structured-data extractor. Extract the requested data from the text and \" +\n \"return ONLY valid JSON — no markdown, no prose.\" +\n (input.instructions ? `\\n\\n${input.instructions}` : \"\");\n const run = async (reinforce: boolean) => {\n const res = await client.chat({\n system: reinforce ? `${base}\\n\\nYour previous output was not valid JSON. Return ONLY parseable JSON.` : base,\n prompt: input.text,\n tier: input.tier ?? \"smart\",\n purpose: input.purpose ?? \"contract:extract\",\n });\n return res;\n };\n let res = await run(false);\n try {\n return { data: input.schema.parse(parseJsonLoose(res.text)), usage: res.usage };\n } catch {\n // one retry with reinforcement\n res = await run(true);\n return { data: input.schema.parse(parseJsonLoose(res.text)), usage: res.usage };\n }\n },\n\n async classify(input: ClassifyInput): Promise<ClassifyResult> {\n const res = await client.chat({\n system:\n \"You are a zero-shot classifier. Choose exactly one label from the provided list. \" +\n 'Return ONLY JSON: {\"label\": \"<one of the labels>\", \"confidence\": <0..1>}.',\n prompt: `Labels: ${JSON.stringify(input.labels)}\\n\\nText:\\n${input.text}`,\n tier: input.tier ?? \"cheap\",\n purpose: input.purpose ?? \"contract:classify\",\n });\n const parsed = parseJsonLoose(res.text) as { label?: string; confidence?: number };\n const label = input.labels.includes(parsed.label ?? \"\") ? parsed.label! : (input.labels[0] ?? \"\");\n const confidence = typeof parsed.confidence === \"number\" ? parsed.confidence : 0;\n return { label, confidence, usage: res.usage };\n },\n\n async rerank(input: RerankInput): Promise<RerankResult> {\n const res = await client.chat({\n system:\n \"You are a relevance reranker. Score each item 0..1 for relevance to the query and \" +\n 'return ONLY JSON: [{\"item\": \"<verbatim item>\", \"score\": <0..1>}], ordered by score desc.',\n prompt: `Query: ${input.query}\\n\\nItems:\\n${JSON.stringify(input.items)}`,\n tier: input.tier ?? \"fast\",\n purpose: input.purpose ?? \"contract:rerank\",\n });\n const raw = parseJsonLoose(res.text) as { item?: string; score?: number }[];\n const ranked = (Array.isArray(raw) ? raw : [])\n .map((r) => ({ item: String(r.item ?? \"\"), score: typeof r.score === \"number\" ? r.score : 0 }))\n .sort((a, b) => b.score - a.score);\n return { ranked, usage: res.usage };\n },\n };\n}\n","// Zod is the single source of truth for the public input shapes. The TypeScript\n// types are derived via z.infer — no hand-written interface duplicates them.\n// The client .parse()s every input at the boundary, so invalid input throws a\n// ZodError before any provider work happens.\nimport { z } from \"zod\";\nimport type {\n ProviderAdapter,\n CostSink,\n TranslateResult,\n ChatResult,\n ChatStreamEvent,\n ImageResult,\n EmbeddingResult,\n TranscribeResult,\n OcrResult,\n ModerationResult,\n} from \"../types.js\";\nimport type { Contracts } from \"../capabilities/contracts/types.js\";\n\n// ── Reusable sub-schemas ───────────────────────────────────────────────────\n\nexport const transportSchema = z.enum([\"http\", \"subprocess\"]);\n\nexport const tierSchema = z.enum([\n \"fast\",\n \"smart\",\n \"powerful\",\n \"cheap\",\n \"vision\",\n \"video\",\n \"embedding\",\n]);\n\nexport const tierSpecSchema = z.object({\n provider: z.string(),\n model: z.string(),\n transport: transportSchema,\n});\n\nexport const toolSchema = z.object({\n name: z.string(),\n description: z.string(),\n parameters: z.record(z.unknown()),\n});\n\nexport const toolCallSchema = z.object({\n id: z.string(),\n name: z.string(),\n arguments: z.record(z.unknown()),\n});\n\nexport const contentPartSchema = z.union([\n z.object({ type: z.literal(\"text\"), text: z.string() }),\n z.object({\n type: z.literal(\"image\"),\n image: z.union([z.string(), z.instanceof(Uint8Array)]),\n mimeType: z.string().optional(),\n }),\n]);\n\nexport const messageSchema = z.object({\n role: z.enum([\"system\", \"user\", \"assistant\", \"tool\"]),\n content: z.union([z.string(), z.array(contentPartSchema)]),\n toolCalls: z.array(toolCallSchema).optional(),\n toolCallId: z.string().optional(),\n});\n\n/** Per-call options shared by every capability input. */\nconst callOptions = {\n tier: tierSchema.optional(),\n override: tierSpecSchema.partial().optional(),\n fallback: z.array(z.union([tierSchema, tierSpecSchema])).optional(),\n purpose: z.string().optional(),\n /** Consumer-defined attribution dimensions (e.g. {tenantId}) ridden into the\n * cost sink for per-tenant/per-customer cost breakdown (F011). */\n labels: z.record(z.string(), z.string()).optional(),\n} as const;\n\n// ── The 5 capability inputs ────────────────────────────────────────────────\n\nexport const chatInputSchema = z.object({\n prompt: z.string().optional(),\n messages: z.array(messageSchema).optional(),\n system: z.string().optional(),\n tools: z.array(toolSchema).optional(),\n maxTokens: z.number().int().positive().optional(),\n temperature: z.number().min(0).max(2).optional(),\n /** \"json\" requests JSON-object output (OpenAI-compatible response_format). */\n responseFormat: z.enum([\"json\", \"text\"]).optional(),\n ...callOptions,\n});\n\nexport const visionInputSchema = z.object({\n image: z.union([z.string(), z.instanceof(Uint8Array)]),\n prompt: z.string(),\n mimeType: z.string().optional(),\n ...callOptions,\n});\n\n// F019 — analyze a video natively (e.g. \"what's in the first 30s?\"). Same shape\n// as vision but with a video payload (URL, data-URL, or raw bytes).\nexport const videoInputSchema = z.object({\n video: z.union([z.string(), z.instanceof(Uint8Array)]),\n prompt: z.string(),\n mimeType: z.string().optional(),\n ...callOptions,\n});\n\nexport const translateInputSchema = z.object({\n text: z.string(),\n to: z.string(),\n from: z.string().optional(),\n ...callOptions,\n});\n\nexport const imageInputSchema = z.object({\n prompt: z.string(),\n width: z.number().int().positive().optional(),\n height: z.number().int().positive().optional(),\n ...callOptions,\n});\n\nexport const embeddingInputSchema = z.object({\n text: z.union([z.string(), z.array(z.string())]),\n ...callOptions,\n});\n\nexport const transcribeInputSchema = z.object({\n /** Audio URL or raw bytes. */\n audio: z.union([z.string(), z.instanceof(Uint8Array)]),\n language: z.string().optional(),\n /** Audio length in seconds — enables Whisper per-minute cost. */\n durationSec: z.number().positive().optional(),\n ...callOptions,\n});\n\n// OCR (F016.2) — document/image → structured markdown text, billed per page.\nexport const ocrInputSchema = z.object({\n /** A URL, data-URL, or raw bytes of the document/image. */\n document: z.union([z.string(), z.instanceof(Uint8Array)]),\n /** image/* → routed as an image; anything else → a document (PDF etc.). */\n mimeType: z.string().optional(),\n ...callOptions,\n});\n\n// Moderation (F016.4) — classify text against safety categories, billed per token.\nexport const moderationInputSchema = z.object({\n input: z.union([z.string(), z.array(z.string())]),\n ...callOptions,\n});\n\n// ── Client config ──────────────────────────────────────────────────────────\n\nexport const budgetSchema = z.object({\n perCallUsd: z.number().positive().optional(),\n rollingUsd: z.number().positive().optional(),\n});\n\nexport const aiConfigSchema = z.object({\n defaults: z.record(tierSchema, tierSpecSchema).optional(),\n // Functions can't be deeply validated — z.custom asserts the TS type and\n // passes the value through untouched.\n providers: z.record(z.string(), z.custom<ProviderAdapter>()).optional(),\n costSink: z.custom<CostSink>().optional(),\n budget: budgetSchema.optional(),\n});\n\n// ── Derived types (z.infer is the single source) ───────────────────────────\n\nexport type ChatInput = z.infer<typeof chatInputSchema>;\nexport type VisionInput = z.infer<typeof visionInputSchema>;\nexport type VideoInput = z.infer<typeof videoInputSchema>;\nexport type TranslateInput = z.infer<typeof translateInputSchema>;\nexport type ImageInput = z.infer<typeof imageInputSchema>;\nexport type EmbeddingInput = z.infer<typeof embeddingInputSchema>;\nexport type TranscribeInput = z.infer<typeof transcribeInputSchema>;\nexport type OcrInput = z.infer<typeof ocrInputSchema>;\nexport type ModerationInput = z.infer<typeof moderationInputSchema>;\nexport type AiConfig = z.infer<typeof aiConfigSchema>;\n\n/** The public facade. Defined here because it depends on the derived inputs. */\nexport interface AiClient {\n chat(input: ChatInput): Promise<ChatResult>;\n /** Streaming chat (F8) — same input as chat; yields ChatStreamEvents. The\n * caller owns the tool-loop (per-turn engine, not an agent runtime). */\n chatStream(input: ChatInput): AsyncIterable<ChatStreamEvent>;\n vision(input: VisionInput): Promise<ChatResult>;\n /** Video Vision (F019) — analyze a video natively. Default tier: \"video\". */\n video(input: VideoInput): Promise<ChatResult>;\n translate(input: TranslateInput): Promise<TranslateResult>;\n image(input: ImageInput): Promise<ImageResult>;\n embedding(input: EmbeddingInput): Promise<EmbeddingResult>;\n transcribe(input: TranscribeInput): Promise<TranscribeResult>;\n /** OCR (F016.2) — document/image → structured markdown, billed per page. Mistral. */\n ocr(input: OcrInput): Promise<OcrResult>;\n /** Moderation (F016.4) — classify text against safety categories. Mistral. */\n moderate(input: ModerationInput): Promise<ModerationResult>;\n /** Prompt-contract capabilities (F5.5) layered on chat/vision. */\n contracts: Contracts;\n}\n","// createAI() — the facade factory. Resolves routing, picks a provider adapter,\n// delegates the call, stamps call-context metadata onto Usage, and reports to the\n// cost sink. Provider specifics live in adapters; cost compute/budget land in F3.\nimport { resolveTier } from \"./routing/tier-map.js\";\nimport { defaultProviders } from \"./providers/registry.js\";\nimport { computeCost } from \"./cost/usage.js\";\nimport { BudgetGuard } from \"./cost/budget.js\";\nimport { buildVisionMessages, VISION_DEFAULT_TIER } from \"./capabilities/vision.js\";\nimport { buildVideoMessages, VIDEO_DEFAULT_TIER } from \"./capabilities/video.js\";\nimport { buildTranslateMessages, TRANSLATE_DEFAULT_TIER } from \"./capabilities/translate.js\";\nimport { EMBEDDING_DEFAULT_TIER } from \"./capabilities/embedding.js\";\nimport { DEFAULT_TRANSCRIBE_SPEC, resolveAudio } from \"./capabilities/transcribe.js\";\nimport { makeContracts } from \"./capabilities/contracts/index.js\";\nimport {\n aiConfigSchema,\n chatInputSchema,\n visionInputSchema,\n videoInputSchema,\n translateInputSchema,\n imageInputSchema,\n embeddingInputSchema,\n transcribeInputSchema,\n ocrInputSchema,\n moderationInputSchema,\n} from \"./schema/inputs.js\";\nimport type {\n AiConfig,\n AiClient,\n ChatInput,\n VisionInput,\n VideoInput,\n TranslateInput,\n ImageInput,\n EmbeddingInput,\n TranscribeInput,\n OcrInput,\n ModerationInput,\n} from \"./schema/inputs.js\";\nimport type {\n ChatResult,\n ChatStreamEvent,\n ImageResult,\n EmbeddingResult,\n TranscribeResult,\n OcrResult,\n ModerationResult,\n TranslateResult,\n ProviderAdapter,\n Message,\n Capability,\n Tier,\n TierSpec,\n Usage,\n} from \"./types.js\";\n\n/** Built-in image route (no image tier in the tier map — fal owns its routing). */\nconst DEFAULT_IMAGE_SPEC: TierSpec = {\n provider: \"fal\",\n model: \"fal-ai/flux/schnell\",\n transport: \"http\",\n};\n\n/** OCR + moderation are Mistral specialty endpoints (F016) — no tier, route by default. */\nconst DEFAULT_OCR_SPEC: TierSpec = { provider: \"mistral\", model: \"mistral-ocr-latest\", transport: \"http\" };\nconst DEFAULT_MODERATION_SPEC: TierSpec = { provider: \"mistral\", model: \"mistral-moderation-latest\", transport: \"http\" };\n\nexport function createAI(config: AiConfig = {}): AiClient {\n // Validate config at the boundary (throws ZodError on bad shape).\n const cfg = aiConfigSchema.parse(config);\n const providers = cfg.providers ?? defaultProviders;\n const budget = cfg.budget ? new BudgetGuard(cfg.budget) : undefined;\n\n const estTokens = (s: string): number => Math.ceil(s.length / 4);\n\n /** Pre-flight budget check. Estimates this call's cost and throws\n * BudgetExceededError before the transport fires. No-op without a budget. */\n async function preflight(spec: TierSpec, estInTokens: number, estOutTokens: number): Promise<void> {\n if (!budget) return;\n await budget.check(computeCost(spec.provider, spec.model, estInTokens, estOutTokens));\n }\n\n /** Fold the actual cost into the rolling total after a successful call. */\n async function settle(usage: Usage): Promise<void> {\n if (budget) await budget.record(usage.costUsd);\n }\n\n function pickProvider(name: string): ProviderAdapter {\n const adapter = providers[name];\n if (!adapter) {\n throw new Error(\n `createAI: no provider adapter registered for \"${name}\". Registered: ${Object.keys(providers).join(\", \") || \"(none)\"}`,\n );\n }\n return adapter;\n }\n\n /** Stamp call-context metadata the client owns onto the adapter's Usage:\n * capability, tier, purpose, the wall-clock latency, and the timestamp. */\n function enrich(\n usage: Usage,\n capability: Capability,\n tier: Tier | undefined,\n purpose: string | undefined,\n latencyMs: number,\n labels: Record<string, string> | undefined,\n ): Usage {\n usage.capability = capability;\n if (tier) usage.tier = tier;\n if (purpose) usage.purpose = purpose;\n if (labels && Object.keys(labels).length > 0) usage.labels = labels;\n usage.latencyMs = Math.round(latencyMs);\n if (!usage.ts) usage.ts = new Date().toISOString();\n return usage;\n }\n\n async function report(usage: Usage): Promise<void> {\n if (!cfg.costSink) return;\n try {\n await cfg.costSink.record(usage);\n } catch {\n // A broken sink must never crash a real AI call (F3.3 invariant).\n }\n }\n\n function toMessages(input: ChatInput): Message[] {\n if (input.messages && input.messages.length > 0) return input.messages;\n const msgs: Message[] = [];\n if (input.system) msgs.push({ role: \"system\", content: input.system });\n msgs.push({ role: \"user\", content: input.prompt ?? \"\" });\n return msgs;\n }\n\n /** Run a capability with an optional fallback chain. Tries the primary route,\n * then each fallback (Tier or TierSpec) in order if the call errors. A budget\n * breach propagates immediately (not a fallback trigger). On the first\n * success: stamp Usage, settle the budget, report to the sink, return. */\n async function runCapability<R extends { usage: Usage }>(opts: {\n primary: TierSpec;\n fallback?: (Tier | TierSpec)[];\n capability: Capability;\n tier?: Tier;\n purpose?: string;\n labels?: Record<string, string>;\n estIn: number;\n estOut: number;\n invoke: (spec: TierSpec) => Promise<R>;\n }): Promise<R> {\n const routes: TierSpec[] = [\n opts.primary,\n ...(opts.fallback ?? []).map((f) =>\n typeof f === \"string\" ? resolveTier(f, undefined, cfg.defaults) : f,\n ),\n ];\n let lastErr: unknown;\n for (let i = 0; i < routes.length; i++) {\n const spec = routes[i]!;\n await preflight(spec, opts.estIn, opts.estOut); // BudgetExceededError propagates\n try {\n const t0 = performance.now();\n const res = await opts.invoke(spec);\n enrich(res.usage, opts.capability, i === 0 ? opts.tier : undefined, opts.purpose, performance.now() - t0, opts.labels);\n await settle(res.usage);\n await report(res.usage);\n return res;\n } catch (e) {\n lastErr = e; // try the next fallback route\n }\n }\n throw lastErr;\n }\n\n /** Whether a pre-first-token streaming error should fall back to the next\n * route. Eligible: network/timeout/parse (no status) + 429 + 5xx. Hard 4xx\n * bubbles up (no silent re-route) — sa contract #2565. */\n function eligibleForFallback(e: unknown): boolean {\n const status = (e as { status?: number } | null)?.status;\n if (status === undefined) return true;\n return status === 429 || status >= 500;\n }\n\n function errorEvent(e: unknown): ChatStreamEvent {\n const ev: ChatStreamEvent = {\n type: \"error\",\n message: e instanceof Error ? e.message : String(e),\n };\n const status = (e as { status?: number } | null)?.status;\n if (status !== undefined) ev.status = status;\n return ev;\n }\n\n /** Streaming chat with pre-stream fallback (F8.1). Yields ChatStreamEvents as\n * the turn unfolds. Fallback re-routes only BEFORE the first text/tool_call\n * event (deltas can't be un-emitted); once streaming has begun, an error is\n * surfaced as an error event and the stream ends. Budget breaches propagate. */\n async function* chatStreamImpl(input: ChatInput): AsyncIterable<ChatStreamEvent> {\n input = chatInputSchema.parse(input);\n const tier = input.tier ?? \"smart\";\n const messages = toMessages(input);\n const estIn = messages.reduce(\n (n, m) => n + estTokens(typeof m.content === \"string\" ? m.content : JSON.stringify(m.content)),\n 0,\n );\n const estOut = input.maxTokens ?? 512;\n const routes: TierSpec[] = [\n resolveTier(tier, input.override, cfg.defaults),\n ...(input.fallback ?? []).map((f) =>\n typeof f === \"string\" ? resolveTier(f, undefined, cfg.defaults) : f,\n ),\n ];\n\n let lastErr: unknown;\n for (let i = 0; i < routes.length; i++) {\n const spec = routes[i]!;\n await preflight(spec, estIn, estOut); // BudgetExceededError propagates\n const adapter = pickProvider(spec.provider);\n if (!adapter.chatStream) {\n throw new Error(`createAI: provider \"${spec.provider}\" does not support streaming`);\n }\n const t0 = performance.now();\n let emitted = false;\n try {\n for await (const ev of adapter.chatStream({\n messages,\n spec,\n tools: input.tools,\n maxTokens: input.maxTokens,\n temperature: input.temperature,\n responseFormat: input.responseFormat,\n })) {\n if (ev.type === \"text\" || ev.type === \"tool_call\") emitted = true;\n if (ev.type === \"usage\") {\n enrich(ev.usage, \"chat\", i === 0 ? tier : undefined, input.purpose, performance.now() - t0, input.labels);\n await settle(ev.usage);\n await report(ev.usage);\n }\n yield ev;\n }\n return; // stream completed cleanly\n } catch (e) {\n lastErr = e;\n if (emitted || !eligibleForFallback(e)) {\n yield errorEvent(e); // mid-stream or hard error → surface + stop\n return;\n }\n // pre-first-token eligible error → try the next route\n }\n }\n yield errorEvent(lastErr);\n }\n\n const client: AiClient = {\n async chat(input: ChatInput): Promise<ChatResult> {\n input = chatInputSchema.parse(input);\n const tier = input.tier ?? \"smart\";\n const messages = toMessages(input);\n const estIn = messages.reduce(\n (n, m) => n + estTokens(typeof m.content === \"string\" ? m.content : JSON.stringify(m.content)),\n 0,\n );\n return runCapability({\n primary: resolveTier(tier, input.override, cfg.defaults),\n fallback: input.fallback,\n capability: \"chat\",\n tier,\n purpose: input.purpose,\n labels: input.labels,\n estIn,\n estOut: input.maxTokens ?? 512,\n invoke: async (spec) => {\n const adapter = pickProvider(spec.provider);\n if (!adapter.chat) throw new Error(`createAI: provider \"${spec.provider}\" does not support chat`);\n return adapter.chat({ messages, spec, tools: input.tools, maxTokens: input.maxTokens, temperature: input.temperature, responseFormat: input.responseFormat });\n },\n });\n },\n\n chatStream: chatStreamImpl,\n\n async vision(input: VisionInput): Promise<ChatResult> {\n input = visionInputSchema.parse(input);\n const tier = input.tier ?? VISION_DEFAULT_TIER;\n const messages: Message[] = buildVisionMessages(input);\n return runCapability({\n primary: resolveTier(tier, input.override, cfg.defaults),\n fallback: input.fallback,\n capability: \"vision\",\n tier,\n purpose: input.purpose,\n labels: input.labels,\n estIn: estTokens(input.prompt) + 1000, // prompt + ~1k image payload\n estOut: 512,\n invoke: async (spec) => {\n const adapter = pickProvider(spec.provider);\n if (!adapter.vision) throw new Error(`createAI: provider \"${spec.provider}\" does not support vision`);\n return adapter.vision({ messages, spec });\n },\n });\n },\n\n async video(input: VideoInput): Promise<ChatResult> {\n input = videoInputSchema.parse(input);\n const tier = input.tier ?? VIDEO_DEFAULT_TIER;\n const messages: Message[] = buildVideoMessages(input);\n return runCapability({\n primary: resolveTier(tier, input.override, cfg.defaults),\n fallback: input.fallback,\n capability: \"video\",\n tier,\n purpose: input.purpose,\n labels: input.labels,\n estIn: estTokens(input.prompt) + 4000, // prompt + video tokens (native video ≈ frames)\n estOut: 512,\n invoke: async (spec) => {\n const adapter = pickProvider(spec.provider);\n // Video routes through the vision method — same multimodal message path.\n if (!adapter.vision) throw new Error(`createAI: provider \"${spec.provider}\" does not support video`);\n return adapter.vision({ messages, spec });\n },\n });\n },\n\n async translate(input: TranslateInput): Promise<TranslateResult> {\n input = translateInputSchema.parse(input);\n const tier = input.tier ?? TRANSLATE_DEFAULT_TIER;\n const messages: Message[] = buildTranslateMessages(input);\n const estIn = estTokens(input.text) + 40;\n const res = await runCapability<ChatResult>({\n primary: resolveTier(tier, input.override, cfg.defaults),\n fallback: input.fallback,\n capability: \"translate\",\n tier,\n purpose: input.purpose,\n labels: input.labels,\n estIn,\n estOut: estIn,\n invoke: async (spec) => {\n const adapter = pickProvider(spec.provider);\n if (!adapter.chat) throw new Error(`createAI: provider \"${spec.provider}\" does not support chat (translate routes through chat)`);\n return adapter.chat({ messages, spec });\n },\n });\n return { text: res.text, usage: res.usage };\n },\n\n async image(input: ImageInput): Promise<ImageResult> {\n input = imageInputSchema.parse(input);\n return runCapability({\n primary: { ...DEFAULT_IMAGE_SPEC, ...input.override },\n fallback: input.fallback,\n capability: \"image\",\n purpose: input.purpose,\n labels: input.labels,\n estIn: 0, // image cost is not token-based\n estOut: 0,\n invoke: async (spec) => {\n const adapter = pickProvider(spec.provider);\n if (!adapter.image) throw new Error(`createAI: provider \"${spec.provider}\" does not support image`);\n return adapter.image({ prompt: input.prompt, spec, width: input.width, height: input.height });\n },\n });\n },\n\n async ocr(input: OcrInput): Promise<OcrResult> {\n input = ocrInputSchema.parse(input);\n return runCapability({\n primary: { ...DEFAULT_OCR_SPEC, ...input.override },\n fallback: input.fallback,\n capability: \"ocr\",\n purpose: input.purpose,\n labels: input.labels,\n estIn: 0, // OCR cost is per-page, not token-based\n estOut: 0,\n invoke: async (spec) => {\n const adapter = pickProvider(spec.provider);\n if (!adapter.ocr) throw new Error(`createAI: provider \"${spec.provider}\" does not support ocr`);\n return adapter.ocr({ document: input.document, mimeType: input.mimeType, spec });\n },\n });\n },\n\n async moderate(input: ModerationInput): Promise<ModerationResult> {\n input = moderationInputSchema.parse(input);\n const items = Array.isArray(input.input) ? input.input : [input.input];\n return runCapability({\n primary: { ...DEFAULT_MODERATION_SPEC, ...input.override },\n fallback: input.fallback,\n capability: \"moderation\",\n purpose: input.purpose,\n labels: input.labels,\n estIn: items.reduce((n, s) => n + estTokens(s), 0),\n estOut: 0,\n invoke: async (spec) => {\n const adapter = pickProvider(spec.provider);\n if (!adapter.moderate) throw new Error(`createAI: provider \"${spec.provider}\" does not support moderation`);\n return adapter.moderate({ input: items, spec });\n },\n });\n },\n\n async embedding(input: EmbeddingInput): Promise<EmbeddingResult> {\n input = embeddingInputSchema.parse(input);\n const tier = input.tier ?? EMBEDDING_DEFAULT_TIER;\n const text = Array.isArray(input.text) ? input.text : [input.text];\n return runCapability({\n primary: resolveTier(tier, input.override, cfg.defaults),\n fallback: input.fallback,\n capability: \"embedding\",\n tier,\n purpose: input.purpose,\n labels: input.labels,\n estIn: text.reduce((n, t) => n + estTokens(t), 0),\n estOut: 0,\n invoke: async (spec) => {\n const adapter = pickProvider(spec.provider);\n if (!adapter.embedding) throw new Error(`createAI: provider \"${spec.provider}\" does not support embedding`);\n return adapter.embedding({ input: text, spec });\n },\n });\n },\n\n async transcribe(input: TranscribeInput): Promise<TranscribeResult> {\n input = transcribeInputSchema.parse(input);\n const audio = await resolveAudio(input.audio);\n return runCapability({\n primary: { ...DEFAULT_TRANSCRIBE_SPEC, ...input.override },\n fallback: input.fallback,\n capability: \"transcribe\",\n purpose: input.purpose,\n labels: input.labels,\n estIn: 0,\n estOut: 0,\n invoke: async (spec) => {\n const adapter = pickProvider(spec.provider);\n if (!adapter.transcribe) throw new Error(`createAI: provider \"${spec.provider}\" does not support transcribe`);\n return adapter.transcribe({ audio, language: input.language, durationSec: input.durationSec, spec });\n },\n });\n },\n\n // Replaced below with the real prompt-contracts (needs the client itself).\n contracts: undefined as unknown as AiClient[\"contracts\"],\n };\n\n client.contracts = makeContracts(client);\n return client;\n}\n","// Stub provider adapters (F2.5). They satisfy ProviderAdapter so the client wires\n// up and resolves without real network calls. Real implementations land in F4\n// (anthropic/openai/gemini/openrouter/deepinfra) and F5.3 (fal image). The stub\n// usage carries zero tokens/cost — F3.1 fills real numbers in the live adapters.\nimport type {\n ProviderAdapter,\n ChatRequest,\n ChatResult,\n ImageRequest,\n ImageResult,\n EmbeddingRequest,\n EmbeddingResult,\n Usage,\n Capability,\n} from \"../types.js\";\n\nfunction stubUsage(\n provider: string,\n model: string,\n transport: \"http\" | \"subprocess\",\n capability: Capability,\n): Usage {\n return {\n provider,\n model,\n transport,\n inputTokens: 0,\n outputTokens: 0,\n cacheReadTokens: 0,\n cacheCreationTokens: 0,\n costUsd: 0,\n latencyMs: 0,\n capability,\n // ts is supplied by the caller-side at real call time; stub uses a fixed marker\n // ('' avoids Date.now() — keeps the stub pure/deterministic for tests).\n ts: \"\",\n };\n}\n\nfunction lastUserText(req: ChatRequest): string {\n for (let i = req.messages.length - 1; i >= 0; i--) {\n const m = req.messages[i];\n if (m && m.role === \"user\") {\n return typeof m.content === \"string\"\n ? m.content\n : m.content.map((p) => (p.type === \"text\" ? p.text : \"[image]\")).join(\" \");\n }\n }\n return \"\";\n}\n\n/** Anthropic adapter stub (HTTP path). */\nexport const anthropicApiAdapter: ProviderAdapter = {\n name: \"anthropic\",\n async chat(req: ChatRequest): Promise<ChatResult> {\n return {\n text: `[stub:anthropic-api] ${lastUserText(req)}`,\n usage: stubUsage(\"anthropic\", req.spec.model, \"http\", \"chat\"),\n };\n },\n async vision(req: ChatRequest): Promise<ChatResult> {\n return {\n text: `[stub:anthropic-api:vision] ${lastUserText(req)}`,\n usage: stubUsage(\"anthropic\", req.spec.model, \"http\", \"vision\"),\n };\n },\n};\n\n/** Anthropic adapter stub (subprocess / `claude -p` path). */\nexport const anthropicSubprocessAdapter: ProviderAdapter = {\n name: \"anthropic\",\n async chat(req: ChatRequest): Promise<ChatResult> {\n const usage = stubUsage(\"anthropic\", req.spec.model, \"subprocess\", \"chat\");\n usage.subprocess = true;\n return { text: `[stub:anthropic-subprocess] ${lastUserText(req)}`, usage };\n },\n};\n\n/** OpenAI adapter stub — covers the embedding default tier + a chat fallback. */\nexport const openaiStubAdapter: ProviderAdapter = {\n name: \"openai\",\n async chat(req: ChatRequest): Promise<ChatResult> {\n return {\n text: `[stub:openai] ${lastUserText(req)}`,\n usage: stubUsage(\"openai\", req.spec.model, \"http\", \"chat\"),\n };\n },\n async embedding(req: EmbeddingRequest): Promise<EmbeddingResult> {\n return {\n vectors: req.input.map(() => [0, 0, 0]),\n usage: stubUsage(\"openai\", req.spec.model, \"http\", \"embedding\"),\n };\n },\n};\n\n/** fal.ai adapter stub — image generation (real one in fal.ts, F5.3). */\nexport const falStubAdapter: ProviderAdapter = {\n name: \"fal\",\n async image(req: ImageRequest): Promise<ImageResult> {\n return {\n url: `https://stub.fal/${encodeURIComponent(req.prompt).slice(0, 32)}.png`,\n usage: stubUsage(\"fal\", req.spec.model, \"http\", \"image\"),\n };\n },\n};\n\n/** Stub provider registry — deterministic, no network. Used by tests via\n * createAI({ providers: stubProviders }). The real default registry (registry.ts)\n * wires the live adapters. */\nexport const stubProviders: Record<string, ProviderAdapter> = {\n anthropic: anthropicApiAdapter,\n openai: openaiStubAdapter,\n fal: falStubAdapter,\n};\n","// AUTO-GENERATED by scripts/gen-version.mjs — do not edit, do not commit.\nexport const VERSION = \"0.7.0\" as const;\nexport const SDK_TAG = \"@broberg/ai-sdk@0.7.0\" as const;\n","// Persistent BudgetStore backed by bun:sqlite (F7.1). The rolling total survives\n// process restarts and is shared by every process pointing at the same file, so\n// a budget ceiling is a real production guard — not a per-process counter that\n// resets on deploy. bun:sqlite is imported lazily (Node-safe import, like sqliteSink).\nimport type { BudgetStore } from \"../types.js\";\n\nexport interface SqliteBudgetStoreConfig {\n /** SQLite file path, e.g. \"./ai-budget.db\". */\n dbPath: string;\n /** Window/bucket key — use e.g. a day-stamp for a daily budget. Default \"default\". */\n key?: string;\n}\n\nexport function sqliteBudgetStore(config: SqliteBudgetStoreConfig): BudgetStore {\n const key = config.key ?? \"default\";\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n let ready: Promise<any> | null = null;\n const open = async () => {\n const { Database } = await import(\"bun:sqlite\");\n const db = new Database(config.dbPath);\n db.run(\n `CREATE TABLE IF NOT EXISTS budget_spend (key TEXT PRIMARY KEY, spent_usd REAL NOT NULL DEFAULT 0)`,\n );\n return db;\n };\n\n return {\n async getSpent(): Promise<number> {\n const db = await (ready ??= open());\n const row = db\n .query(`SELECT spent_usd FROM budget_spend WHERE key = $key`)\n .get({ $key: key }) as { spent_usd: number } | null;\n return row?.spent_usd ?? 0;\n },\n async addSpent(usd: number): Promise<void> {\n const db = await (ready ??= open());\n db.run(\n `INSERT INTO budget_spend (key, spent_usd) VALUES ($key, $usd)\n ON CONFLICT(key) DO UPDATE SET spent_usd = spent_usd + $usd`,\n { $key: key, $usd: usd },\n );\n },\n };\n}\n","import type { CostSink } from \"../../types.js\";\n\n/** A sink that does nothing. The default when no costSink is configured. */\nexport const noopSink: CostSink = {\n record() {\n // intentionally empty\n },\n};\n","import type { CostSink, Usage } from \"../../types.js\";\n\n/** Fan a Usage out to several sinks. Uses allSettled so one failing sink never\n * prevents the others from recording (and never propagates to the caller). */\nexport function multiSink(sinks: CostSink[]): CostSink {\n return {\n async record(usage: Usage): Promise<void> {\n // async wrapper turns a synchronous throw in s.record into a rejected\n // promise, so allSettled isolates it (a sync throw would otherwise escape\n // the .map before allSettled ran).\n await Promise.allSettled(sinks.map(async (s) => s.record(usage)));\n },\n };\n}\n","// upmetricsSink — the canonical cost sink. Forwards each Usage to the upmetrics\n// agent-run ingest (POST /api/agent, mode:\"record\"). Field mapping follows\n// upmetrics/docs/AGENT-SCHEMA.md \"For cost-sink authors\" exactly:\n// - agent_kind / agent_name are injected (not in Usage; required by ingest)\n// - camelCase Usage → snake_case wire fields\n// - capability + transport ride in tags (no top-level column)\n// - toolCalls[].errorCount → tool_calls[].error_count (deep rename)\n// - latencyMs → duration_ms; ts → started_at; ended_at = ts + latency\n// Errors never propagate (CostSink invariant). Do NOT use @upmetrics/agent\n// wrapAnthropic here — the SDK already owns the provider call.\nimport { SDK_TAG } from \"../../version.js\";\nimport type { CostSink, Usage } from \"../../types.js\";\n\nexport interface UpmetricsSinkConfig {\n /** Ingest base URL, e.g. https://upmetrics.org */\n baseUrl: string;\n /** Per-project api_key → sent as the X-Upmetrics-Key header. */\n apiKey: string;\n /** Consumer name dashboards group by (e.g. \"cms\", \"trail\", \"xrt81\") — NOT the\n * capability. */\n agentName: string;\n /** Defaults to \"chatbot\" (\"embedding\" auto-selected for embedding calls). */\n agentKind?: string;\n /** When true, guarantees no prompt/response content is ever sent (the sink\n * sends none regardless — Usage carries no excerpts — so this is belt-and-\n * suspenders for GDPR-health projects). */\n complianceMode?: boolean;\n /** Injectable fetch for testing; defaults to global fetch. */\n fetch?: typeof fetch;\n /** Optional error hook (errors are otherwise swallowed silently). */\n onError?: (err: unknown) => void;\n}\n\nexport function upmetricsSink(config: UpmetricsSinkConfig): CostSink {\n const doFetch = config.fetch ?? fetch;\n const url = `${config.baseUrl.replace(/\\/$/, \"\")}/api/agent`;\n\n return {\n async record(usage: Usage): Promise<void> {\n try {\n const startedAt = usage.ts || new Date().toISOString();\n const endedAt = new Date(\n new Date(startedAt).getTime() + (usage.latencyMs || 0),\n ).toISOString();\n\n const agentKind =\n config.agentKind ?? (usage.capability === \"embedding\" ? \"embedding\" : \"chatbot\");\n\n const body: Record<string, unknown> = {\n mode: \"record\",\n agent_kind: agentKind,\n agent_name: config.agentName,\n provider: usage.provider,\n model: usage.model,\n status: \"success\",\n input_tokens: usage.inputTokens,\n output_tokens: usage.outputTokens,\n cache_read_tokens: usage.cacheReadTokens,\n cache_creation_tokens: usage.cacheCreationTokens,\n cost_usd: usage.costUsd,\n duration_ms: usage.latencyMs,\n started_at: startedAt,\n ended_at: endedAt,\n tags: {\n // Consumer attribution labels (e.g. tenantId) ride in tags so no new\n // top-level field risks the strict-shape ingest schema (F011). The\n // SDK-owned keys win — a label can never clobber capability/transport/sdk.\n ...usage.labels,\n capability: usage.capability,\n transport: usage.transport,\n sdk: SDK_TAG,\n },\n };\n if (usage.tier !== undefined) body.tier = usage.tier;\n if (usage.purpose !== undefined) body.purpose = usage.purpose;\n if (usage.toolCalls) {\n body.tool_calls = usage.toolCalls.map((t) => ({\n name: t.name,\n count: t.count,\n error_count: t.errorCount ?? 0,\n }));\n }\n // complianceMode is a no-op today (we never send excerpts) but documents intent.\n void config.complianceMode;\n\n const res = await doFetch(url, {\n method: \"POST\",\n headers: {\n \"content-type\": \"application/json\",\n \"X-Upmetrics-Key\": config.apiKey,\n },\n body: JSON.stringify(body),\n });\n if (!res.ok) {\n const text = await res.text().catch(() => \"\");\n config.onError?.(\n new Error(`upmetricsSink: ingest returned ${res.status}: ${text.slice(0, 200)}`),\n );\n }\n } catch (err) {\n // Never let a sink failure crash a real AI call.\n config.onError?.(err);\n }\n },\n };\n}\n","// discordSink — posts a per-call cost embed to a Discord webhook. Secondary sink\n// (upmetricsSink is canonical); handy for repos not wired to Upmetrics or for an\n// at-a-glance spend feed. Plain fetch, no Discord SDK. Errors never propagate.\nimport type { CostSink, Usage } from \"../../types.js\";\n\nexport interface DiscordSinkConfig {\n webhookUrl: string;\n /** Skip posting paid calls below this USD threshold (anti-spam). Subprocess\n * (Max-plan free) calls always post so the \"free\" feed stays visible.\n * Default 0 → post everything. */\n minUsd?: number;\n fetch?: typeof fetch;\n onError?: (err: unknown) => void;\n}\n\nexport function discordSink(config: DiscordSinkConfig): CostSink {\n const doFetch = config.fetch ?? fetch;\n const minUsd = config.minUsd ?? 0;\n\n return {\n async record(usage: Usage): Promise<void> {\n try {\n // Skip cheap PAID calls; always show subprocess (free) calls.\n if (!usage.subprocess && usage.costUsd < minUsd) return;\n\n const costLabel = usage.subprocess\n ? \"Max plan (free)\"\n : `$${usage.costUsd.toFixed(6)}`;\n\n const embed = {\n title: `AI call — ${usage.capability}`,\n fields: [\n { name: \"Provider\", value: usage.provider, inline: true },\n { name: \"Model\", value: usage.model, inline: true },\n { name: \"Transport\", value: usage.transport, inline: true },\n { name: \"Cost\", value: costLabel, inline: true },\n {\n name: \"Tokens\",\n value: `${usage.inputTokens} in / ${usage.outputTokens} out`,\n inline: true,\n },\n { name: \"Latency\", value: `${usage.latencyMs} ms`, inline: true },\n ],\n timestamp: usage.ts || new Date().toISOString(),\n };\n\n const res = await doFetch(config.webhookUrl, {\n method: \"POST\",\n headers: { \"content-type\": \"application/json\" },\n body: JSON.stringify({ embeds: [embed] }),\n });\n if (!res.ok) {\n config.onError?.(new Error(`discordSink: webhook returned ${res.status}`));\n }\n } catch (err) {\n config.onError?.(err);\n }\n },\n };\n}\n","// sqliteSink — persists every Usage to a local bun:sqlite DB. Secondary/offline\n// sink (upmetricsSink is canonical). No npm dependency — bun:sqlite is built in.\n//\n// IMPORTANT: bun:sqlite is imported LAZILY (dynamic import on first use), not at\n// module top level. A static `import \"bun:sqlite\"` would leak into the package\n// entry and crash every Node consumer (`ERR_UNSUPPORTED_ESM_URL_SCHEME`). With\n// the lazy import, importing @broberg/ai-sdk works everywhere; bun:sqlite only\n// loads when sqliteSink/getCostSummary actually run (Bun only).\nimport type { CostSink, Usage } from \"../../types.js\";\n\nexport interface SqliteSinkConfig {\n /** Path to the SQLite file, e.g. \"./ai-cost.db\" (or \":memory:\"). */\n dbPath: string;\n}\n\nconst CREATE_TABLE = `\nCREATE TABLE IF NOT EXISTS ai_usage (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n ts TEXT NOT NULL,\n provider TEXT NOT NULL,\n model TEXT NOT NULL,\n tier TEXT,\n transport TEXT NOT NULL,\n capability TEXT NOT NULL,\n purpose TEXT,\n input_tokens INTEGER NOT NULL,\n output_tokens INTEGER NOT NULL,\n cache_read_tokens INTEGER NOT NULL,\n cache_creation_tokens INTEGER NOT NULL,\n cost_usd REAL NOT NULL,\n latency_ms INTEGER NOT NULL,\n subprocess INTEGER NOT NULL DEFAULT 0\n)`;\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nasync function openDb(dbPath: string, readonly = false): Promise<any> {\n const { Database } = await import(\"bun:sqlite\");\n return new Database(dbPath, readonly ? { readonly: true } : undefined);\n}\n\nexport function sqliteSink(config: SqliteSinkConfig): CostSink {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n let ready: Promise<any> | null = null;\n const init = async () => {\n const db = await openDb(config.dbPath);\n db.run(CREATE_TABLE);\n const insert = db.prepare(\n `INSERT INTO ai_usage\n (ts, provider, model, tier, transport, capability, purpose,\n input_tokens, output_tokens, cache_read_tokens, cache_creation_tokens,\n cost_usd, latency_ms, subprocess)\n VALUES ($ts, $provider, $model, $tier, $transport, $capability, $purpose,\n $input, $output, $cacheRead, $cacheCreation, $cost, $latency, $subprocess)`,\n );\n return insert;\n };\n\n return {\n async record(usage: Usage): Promise<void> {\n const insert = await (ready ??= init());\n insert.run({\n $ts: usage.ts || new Date().toISOString(),\n $provider: usage.provider,\n $model: usage.model,\n $tier: usage.tier ?? null,\n $transport: usage.transport,\n $capability: usage.capability,\n $purpose: usage.purpose ?? null,\n $input: usage.inputTokens,\n $output: usage.outputTokens,\n $cacheRead: usage.cacheReadTokens,\n $cacheCreation: usage.cacheCreationTokens,\n $cost: usage.costUsd,\n $latency: usage.latencyMs,\n $subprocess: usage.subprocess ? 1 : 0,\n });\n },\n };\n}\n\nexport interface CostSummary {\n totalUsd: number;\n byProvider: Record<string, number>;\n byCapability: Record<string, number>;\n}\n\n/** Aggregate the recorded spend from a sqliteSink DB. Creates the table if the\n * DB has never been written to, so an empty DB summarises cleanly to 0. */\nexport async function getCostSummary(dbPath: string): Promise<CostSummary> {\n const db = await openDb(dbPath);\n db.run(CREATE_TABLE);\n const total = db\n .query(`SELECT SUM(cost_usd) AS total FROM ai_usage`)\n .get() as { total: number | null };\n const byProvider: Record<string, number> = {};\n for (const row of db\n .query(`SELECT provider, SUM(cost_usd) AS sum FROM ai_usage GROUP BY provider`)\n .all() as { provider: string; sum: number }[]) {\n byProvider[row.provider] = row.sum;\n }\n const byCapability: Record<string, number> = {};\n for (const row of db\n .query(`SELECT capability, SUM(cost_usd) AS sum FROM ai_usage GROUP BY capability`)\n .all() as { capability: string; sum: number }[]) {\n byCapability[row.capability] = row.sum;\n }\n return { totalUsd: total?.total ?? 0, byProvider, byCapability };\n}\n"],"mappings":"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","names":["url","data","res"]}
1
+ {"version":3,"sources":["../src/routing/tier-map.ts","../src/transport/http.ts","../src/transport/subprocess.ts","../src/transport/stream.ts","../src/providers/tools.ts","../src/cost/pricing.ts","../src/cost/usage.ts","../src/providers/anthropic.ts","../src/providers/openai-compatible.ts","../src/providers/openai.ts","../src/providers/gemini.ts","../src/providers/deepinfra.ts","../src/providers/openrouter.ts","../src/providers/mistral.ts","../src/providers/elevenlabs.ts","../src/providers/fal.ts","../src/providers/registry.ts","../src/cost/budget.ts","../src/capabilities/vision.ts","../src/capabilities/video.ts","../src/capabilities/translate.ts","../src/capabilities/embedding.ts","../src/capabilities/transcribe.ts","../src/capabilities/contracts/index.ts","../src/schema/inputs.ts","../src/client.ts","../src/providers/stub.ts","../src/version.ts","../src/cost/budget-store.ts","../src/cost/sinks/noop.ts","../src/cost/sinks/multi.ts","../src/cost/sinks/upmetrics.ts","../src/cost/sinks/discord.ts","../src/cost/sinks/sqlite.ts"],"sourcesContent":["// Tier routing: a named Tier resolves to a concrete (provider, model, transport).\n// Precedence is per-call override > client config map > built-in defaults.\nimport type { Tier, TierSpec } from \"../types.js\";\n\n/** Built-in defaults. Every entry is overridable via AiConfig.defaults or a\n * per-call override. Model IDs are current at scaffold time; callers pin their\n * own via config. `cheap` routes through the local `claude -p` subprocess\n * (Max plan → costUsd 0); everything else is HTTP. */\nexport const DEFAULT_TIER_MAP: Record<Tier, TierSpec> = {\n fast: { provider: \"anthropic\", model: \"claude-haiku-4-5\", transport: \"http\" },\n smart: { provider: \"anthropic\", model: \"claude-sonnet-4-6\", transport: \"http\" },\n powerful: { provider: \"anthropic\", model: \"claude-opus-4-8\", transport: \"http\" },\n cheap: { provider: \"anthropic\", model: \"claude-haiku-4-5\", transport: \"subprocess\" },\n vision: { provider: \"anthropic\", model: \"claude-sonnet-4-6\", transport: \"http\" },\n // Native video understanding — Gemini leads; flash-lite is the cheap default (F019).\n video: { provider: \"gemini\", model: \"gemini-2.5-flash-lite\", transport: \"http\" },\n embedding: { provider: \"openai\", model: \"text-embedding-3-small\", transport: \"http\" },\n};\n\n/**\n * Resolve a Tier to a concrete TierSpec.\n *\n * Merge order (later wins): DEFAULT_TIER_MAP < configMap < override.\n * - `configMap` is the client-level AiConfig.defaults (per-tier full specs).\n * - `override` is a per-call Partial<TierSpec> — only the fields it sets win.\n */\nexport function resolveTier(\n tier: Tier,\n override?: Partial<TierSpec>,\n configMap?: Partial<Record<Tier, TierSpec>>,\n): TierSpec {\n const base = configMap?.[tier] ?? DEFAULT_TIER_MAP[tier];\n return { ...base, ...override };\n}\n","// HTTP transport: a thin fetch wrapper. Provider-agnostic — the adapter supplies\n// the fully-built url/headers/body and parses the returned json itself.\nimport type { TransportRequest, HttpResponse } from \"./types.js\";\n\nexport async function httpTransport(req: TransportRequest): Promise<HttpResponse> {\n if (!req.http) {\n throw new Error(\"httpTransport: req.http is required for http transport\");\n }\n const { url, method = \"POST\", headers, body } = req.http;\n const res = await fetch(url, {\n method,\n headers,\n body:\n body === undefined\n ? undefined\n : typeof body === \"string\"\n ? body\n : JSON.stringify(body),\n });\n const json: unknown = await res.json().catch(() => undefined);\n return { ok: res.ok, status: res.status, json };\n}\n","// Subprocess transport: runs the local `claude -p` CLI (Anthropic Max plan).\n// No API key, no metered charge — costUsd is always 0, flagged subprocess:true so\n// dashboards can split free (Max) from paid (API). Token counts still come back\n// from the CLI's JSON so usage is tracked even when cost is zero.\nimport type { TransportRequest, SubprocessResponse } from \"./types.js\";\n\n/** The subset of `claude -p --output-format json` output we read. The CLI emits\n * more fields; we only need the result text + token usage. */\ninterface ClaudeCliJson {\n result?: string;\n usage?: {\n input_tokens?: number;\n output_tokens?: number;\n cache_creation_input_tokens?: number;\n cache_read_input_tokens?: number;\n };\n}\n\n/** Pure parser for the `claude -p --output-format json` stdout. Exported so it\n * can be unit-tested without spawning the binary. costUsd is pinned to 0. */\nexport function parseClaudeCliJson(raw: string): SubprocessResponse {\n let parsed: ClaudeCliJson;\n try {\n parsed = JSON.parse(raw) as ClaudeCliJson;\n } catch {\n throw new Error(\n `subprocessTransport: could not parse claude -p JSON output: ${raw.slice(0, 200)}`,\n );\n }\n const u = parsed.usage ?? {};\n return {\n text: parsed.result ?? \"\",\n inputTokens: u.input_tokens ?? 0,\n outputTokens: u.output_tokens ?? 0,\n cacheReadTokens: u.cache_read_input_tokens ?? 0,\n cacheCreationTokens: u.cache_creation_input_tokens ?? 0,\n costUsd: 0,\n subprocess: true,\n };\n}\n\nexport async function subprocessTransport(\n req: TransportRequest,\n): Promise<SubprocessResponse> {\n if (!req.subprocess) {\n throw new Error(\"subprocessTransport: req.subprocess is required for subprocess transport\");\n }\n const { prompt, systemPrompt } = req.subprocess;\n\n const cmd = [\"claude\", \"-p\", \"--output-format\", \"json\", \"--model\", req.spec.model];\n if (systemPrompt) cmd.push(\"--system-prompt\", systemPrompt);\n\n // Prompt goes in on stdin as a Blob (no argv length limit, no manual FileSink).\n const proc = (() => {\n try {\n return Bun.spawn(cmd, {\n stdin: new Blob([prompt]),\n stdout: \"pipe\",\n stderr: \"pipe\",\n });\n } catch (err) {\n throw new Error(\n `subprocessTransport: failed to spawn 'claude' — is the CLI installed and on PATH? (${String(err)})`,\n );\n }\n })();\n\n const [stdout, stderr, exitCode] = await Promise.all([\n new Response(proc.stdout).text(),\n new Response(proc.stderr).text(),\n proc.exited,\n ]);\n\n if (exitCode !== 0) {\n throw new Error(\n `subprocessTransport: claude -p exited ${exitCode}: ${stderr.slice(0, 300) || stdout.slice(0, 300)}`,\n );\n }\n\n return parseClaudeCliJson(stdout);\n}\n","// SSE streaming transport (F8.1). Like httpTransport but yields the parsed\n// `data:` payloads from the response body instead of awaiting .json() — pure\n// fetch + a ReadableStream reader, so it is Node 18+ and Bun safe. The adapter\n// supplies the `stream:true` body and parses each yielded JSON string itself.\nimport type { TransportRequest } from \"./types.js\";\n\n/** HTTP error from a streaming connect — carries `status` so the client's\n * pre-stream fallback can tell an eligible 429/5xx from a hard 4xx. */\nexport class StreamHttpError extends Error {\n readonly status: number;\n constructor(message: string, status: number) {\n super(message);\n this.name = \"StreamHttpError\";\n this.status = status;\n }\n}\n\nexport interface StreamTransportRequest extends TransportRequest {\n /** Injectable fetch for tests. */\n fetch?: typeof fetch;\n}\n\n/**\n * Open an SSE stream and yield each event's `data:` payload as a raw string\n * (the JSON after `data: `), skipping the `[DONE]` terminator and non-data\n * lines. Throws StreamHttpError before the first yield on a non-2xx connect.\n */\nexport async function* streamTransport(req: StreamTransportRequest): AsyncIterable<string> {\n if (!req.http) throw new Error(\"streamTransport: req.http is required for http transport\");\n const { url, method = \"POST\", headers, body } = req.http;\n const fetchImpl = req.fetch ?? fetch;\n const res = await fetchImpl(url, {\n method,\n headers,\n body:\n body === undefined\n ? undefined\n : typeof body === \"string\"\n ? body\n : JSON.stringify(body),\n });\n if (!res.ok || !res.body) {\n const text = await res.text().catch(() => \"\");\n throw new StreamHttpError(`stream ${res.status}: ${text.slice(0, 300)}`, res.status);\n }\n const reader = res.body.getReader();\n const decoder = new TextDecoder();\n let buffer = \"\";\n try {\n for (;;) {\n const { done, value } = await reader.read();\n if (done) break;\n buffer += decoder.decode(value, { stream: true });\n // OpenAI/Anthropic emit one `data: {json}\\n\\n` per event — parse per line.\n let nl: number;\n while ((nl = buffer.indexOf(\"\\n\")) >= 0) {\n const line = buffer.slice(0, nl).replace(/\\r$/, \"\");\n buffer = buffer.slice(nl + 1);\n if (!line.startsWith(\"data:\")) continue; // skip comments / event: / id:\n const data = line.slice(5).trim();\n if (data === \"[DONE]\") return;\n if (data) yield data;\n }\n }\n } finally {\n reader.releaseLock();\n }\n}\n","// Cross-provider tool/function-calling normalization. The SDK speaks one Tool /\n// ToolCall shape; each provider has its own. toProviderTools builds the request\n// tools array; fromProviderToolCall parses one tool-call out of a response.\n// OpenAI, DeepInfra and OpenRouter share the OpenAI-compatible format.\nimport type { Tool, ToolCall } from \"../types.js\";\n\ntype ToolProvider = \"openai\" | \"deepinfra\" | \"openrouter\" | \"gemini\" | \"anthropic\";\n\nfunction family(provider: string): ToolProvider {\n if (provider === \"gemini\" || provider === \"google\") return \"gemini\";\n if (provider === \"anthropic\") return \"anthropic\";\n // openai, deepinfra, openrouter — all OpenAI-compatible\n return \"openai\";\n}\n\n/** Convert SDK tools to a provider's request format. */\nexport function toProviderTools(tools: Tool[], provider: string): unknown {\n switch (family(provider)) {\n case \"openai\":\n return tools.map((t) => ({\n type: \"function\",\n function: { name: t.name, description: t.description, parameters: t.parameters },\n }));\n case \"gemini\":\n return [\n {\n functionDeclarations: tools.map((t) => ({\n name: t.name,\n description: t.description,\n parameters: t.parameters,\n })),\n },\n ];\n case \"anthropic\":\n return tools.map((t) => ({\n name: t.name,\n description: t.description,\n input_schema: t.parameters,\n }));\n default:\n throw new Error(`toProviderTools: unsupported provider family for \"${provider}\"`);\n }\n}\n\n/** Parse a single provider-shaped tool call back into the SDK ToolCall shape. */\nexport function fromProviderToolCall(raw: unknown, provider: string): ToolCall {\n const r = raw as Record<string, unknown>;\n switch (family(provider)) {\n case \"openai\": {\n // { id, type:\"function\", function:{ name, arguments:\"<json>\" } }\n const fn = (r.function ?? {}) as { name?: string; arguments?: string };\n return {\n id: typeof r.id === \"string\" ? r.id : \"\",\n name: fn.name ?? \"\",\n arguments: parseArgs(fn.arguments),\n };\n }\n case \"gemini\": {\n // { functionCall:{ name, args } } or { name, args }\n const fc = (r.functionCall ?? r) as { name?: string; args?: unknown };\n return {\n id: \"\", // Gemini function calls have no id\n name: fc.name ?? \"\",\n arguments: (fc.args as Record<string, unknown>) ?? {},\n };\n }\n case \"anthropic\": {\n // { type:\"tool_use\", id, name, input }\n return {\n id: typeof r.id === \"string\" ? r.id : \"\",\n name: typeof r.name === \"string\" ? r.name : \"\",\n arguments: (r.input as Record<string, unknown>) ?? {},\n };\n }\n default:\n throw new Error(`fromProviderToolCall: unsupported provider family for \"${provider}\"`);\n }\n}\n\nfunction parseArgs(raw: unknown): Record<string, unknown> {\n if (raw === undefined || raw === null) return {};\n if (typeof raw === \"object\") return raw as Record<string, unknown>;\n if (typeof raw === \"string\") {\n try {\n return JSON.parse(raw) as Record<string, unknown>;\n } catch {\n return {};\n }\n }\n return {};\n}\n","// Versioned per-(provider, model) pricing. F3.6 populates the table + adds tests\n// + MiniMax coverage. F3.1 ships the type + lookup with an empty table, so\n// computeCost returns 0 for every model until F3.6 lands (calls still complete).\nexport interface PricingEntry {\n /** USD per 1M input tokens. */\n inputPer1M: number;\n /** USD per 1M output tokens. */\n outputPer1M: number;\n /** USD per 1M cache-read tokens (falls back to input rate if unset). */\n cacheReadPer1M?: number;\n /** USD per 1M cache-write/creation tokens (falls back to input rate if unset). */\n cacheWritePer1M?: number;\n /** Pricing snapshot version (date or tag) so stale entries are detectable. */\n version: string;\n}\n\n// USD per 1M tokens. Anthropic cache multipliers follow the standard model:\n// cache-read ≈ 0.1× input, cache-write ≈ 1.25× input. Verified against the\n// pricing tables in cms (packages/cms-ai/src/providers) + trail (model-lab).\n// MiniMax M2.7 is an estimate pending confirmation against OpenRouter's live\n// price page — flagged in its version string.\nconst V = \"2026-06-02\";\n// Mistral prices come straight from mistral.ai/pricing (per Christian's CD report).\nconst MS = \"2026-06-04-mistral.ai\";\n\n/** Keyed `${provider}:${model}`. Exported so the catalogue-research job (F014)\n * can enumerate every priced entry and diff it against the live provider lists. */\nexport const PRICING: Record<string, PricingEntry> = {\n // Anthropic (direct API). DEFAULT_TIER_MAP: fast/cheap=haiku, smart/vision=sonnet, powerful=opus.\n \"anthropic:claude-haiku-4-5\": {\n inputPer1M: 0.8,\n outputPer1M: 4.0,\n cacheReadPer1M: 0.08,\n cacheWritePer1M: 1.0,\n version: V,\n },\n \"anthropic:claude-sonnet-4-6\": {\n inputPer1M: 3.0,\n outputPer1M: 15.0,\n cacheReadPer1M: 0.3,\n cacheWritePer1M: 3.75,\n version: V,\n },\n \"anthropic:claude-opus-4-8\": {\n inputPer1M: 15.0,\n outputPer1M: 75.0,\n cacheReadPer1M: 1.5,\n cacheWritePer1M: 18.75,\n version: V,\n },\n\n // OpenAI. embedding default tier = text-embedding-3-small (no output tokens).\n \"openai:text-embedding-3-small\": { inputPer1M: 0.02, outputPer1M: 0, version: V },\n \"openai:text-embedding-3-large\": { inputPer1M: 0.13, outputPer1M: 0, version: V },\n \"openai:gpt-4o\": { inputPer1M: 2.5, outputPer1M: 10.0, version: V },\n \"openai:gpt-4o-mini\": { inputPer1M: 0.15, outputPer1M: 0.6, version: V },\n // Whisper is priced per minute, not per token — not representable here; transcribe\n // (F5.6) computes its own cost. Listed as 0 so token-based compute never charges it.\n \"openai:whisper-1\": { inputPer1M: 0, outputPer1M: 0, version: V },\n\n // OpenRouter (meta-router — model slugs include the upstream vendor). Slugs use\n // dots (claude-sonnet-4.6) to match OpenRouter's live ids; the dashed forms\n // never matched a real call. Caught by the F014 catalogue research.\n \"openrouter:anthropic/claude-sonnet-4.6\": { inputPer1M: 3.0, outputPer1M: 15.0, version: V },\n // OpenRouter ground-truth $1/$5 — a markup over Anthropic-direct's $0.8/$4\n // (the `anthropic:` entry above). Was masked while the slug used dashes.\n \"openrouter:anthropic/claude-haiku-4.5\": { inputPer1M: 1.0, outputPer1M: 5.0, version: \"2026-06-04\" },\n \"openrouter:google/gemini-2.5-flash\": { inputPer1M: 0.3, outputPer1M: 2.5, version: V },\n // Ground-truth from OpenRouter /api/v1/models (was a 0.3 estimate; now 0.279).\n \"openrouter:minimax/minimax-m2.7\": {\n inputPer1M: 0.279,\n outputPer1M: 1.2,\n version: \"2026-06-04\",\n },\n\n // Google Gemini (direct). Provider key is \"gemini\" — matches the adapter's\n // usage.provider + the override.provider callers pass. (Image-gen models are\n // priced per-image in the adapter, not here.)\n \"gemini:gemini-2.5-flash\": { inputPer1M: 0.3, outputPer1M: 2.5, version: V },\n // flash-lite is the default `video` tier (F019) — cheap native video understanding.\n \"gemini:gemini-2.5-flash-lite\": { inputPer1M: 0.1, outputPer1M: 0.4, version: \"2026-06-04-or-xref\" },\n\n // Mistral (direct, La Plateforme). Official prices from mistral.ai/pricing\n // (2026-06-04, per Christian's CD report). EU/Paris-hosted — the designated\n // GDPR-safe provider for client/personal-data workloads (see F015). NB:\n // medium-3.5 is the premium \"Vibe\" coding tier ($1.5/$7.5); Large 3 ($0.5/$1.5)\n // is the cheaper frontier general-purpose model despite the higher number.\n \"mistral:mistral-large-latest\": { inputPer1M: 0.5, outputPer1M: 1.5, version: MS },\n \"mistral:mistral-large-2512\": { inputPer1M: 0.5, outputPer1M: 1.5, version: MS },\n \"mistral:mistral-medium-latest\": { inputPer1M: 1.5, outputPer1M: 7.5, version: MS },\n \"mistral:mistral-medium-3.5\": { inputPer1M: 1.5, outputPer1M: 7.5, version: MS },\n \"mistral:mistral-medium-3\": { inputPer1M: 0.4, outputPer1M: 2.0, version: \"2026-06-04-or-xref\" },\n \"mistral:mistral-small-latest\": { inputPer1M: 0.1, outputPer1M: 0.3, version: MS },\n \"mistral:mistral-small-2603\": { inputPer1M: 0.1, outputPer1M: 0.3, version: MS },\n \"mistral:ministral-3b-latest\": { inputPer1M: 0.1, outputPer1M: 0.1, version: MS },\n \"mistral:ministral-8b-latest\": { inputPer1M: 0.15, outputPer1M: 0.15, version: MS },\n \"mistral:ministral-14b-latest\": { inputPer1M: 0.2, outputPer1M: 0.2, version: MS },\n \"mistral:magistral-medium-latest\": { inputPer1M: 2.0, outputPer1M: 5.0, version: MS },\n \"mistral:magistral-small-latest\": { inputPer1M: 0.5, outputPer1M: 1.5, version: MS },\n \"mistral:devstral-latest\": { inputPer1M: 0.4, outputPer1M: 2.0, version: MS },\n \"mistral:codestral-latest\": { inputPer1M: 0.3, outputPer1M: 0.9, version: MS },\n \"mistral:open-mistral-nemo\": { inputPer1M: 0.15, outputPer1M: 0.15, version: MS },\n // Moderation (F016.4) — per input token; output 0. (OCR is per-page in the adapter.)\n \"mistral:mistral-moderation-latest\": { inputPer1M: 0.1, outputPer1M: 0, version: MS },\n};\n\nexport function getPrice(provider: string, model: string): PricingEntry | undefined {\n const exact = PRICING[`${provider}:${model}`];\n if (exact) return exact;\n // Providers ship dated model snapshots, e.g. \"claude-haiku-4-5-20251001\".\n // Strip a trailing -YYYYMMDD and retry the base lookup so a dated variant\n // prices the same as its base model instead of falling through to 0 — a real\n // paid call must never be logged as $0 (F012). Covers openrouter slugs too.\n const base = model.replace(/-\\d{8}$/, \"\");\n if (base !== model) return PRICING[`${provider}:${base}`];\n return undefined;\n}\n","// Usage construction + cost computation. Real adapters (F4) build their Usage via\n// freshUsage() and fill costUsd from computeCost(). The pricing table lives in\n// ./pricing.ts (F3.6); until a model is priced, computeCost returns 0 so calls\n// still complete (cost just shows $0 rather than throwing).\nimport { getPrice } from \"./pricing.js\";\nimport type { Usage, Transport, Capability } from \"../types.js\";\n\n/**\n * Cost in USD for a call. cache-read/creation tokens are priced separately when\n * the pricing entry defines rates for them; otherwise they fall back to the\n * input rate (read) / are ignored (creation). Unknown model → 0.\n */\nexport function computeCost(\n provider: string,\n model: string,\n inputTokens: number,\n outputTokens: number,\n cacheReadTokens = 0,\n cacheCreationTokens = 0,\n): number {\n const price = getPrice(provider, model);\n if (!price) return 0;\n const perToken = (per1M: number) => per1M / 1_000_000;\n const inRate = perToken(price.inputPer1M);\n const outRate = perToken(price.outputPer1M);\n const cacheReadRate =\n price.cacheReadPer1M !== undefined ? perToken(price.cacheReadPer1M) : inRate;\n const cacheWriteRate =\n price.cacheWritePer1M !== undefined ? perToken(price.cacheWritePer1M) : inRate;\n return (\n inputTokens * inRate +\n outputTokens * outRate +\n cacheReadTokens * cacheReadRate +\n cacheCreationTokens * cacheWriteRate\n );\n}\n\n/** Build a Usage with cost computed from the pricing table. Adapters call this\n * after a successful provider call; latencyMs/ts/capability are stamped by the\n * client (call-context owner), so they default to 0/\"\"/the passed capability. */\nexport function freshUsage(args: {\n provider: string;\n model: string;\n transport: Transport;\n capability: Capability;\n inputTokens: number;\n outputTokens: number;\n cacheReadTokens?: number;\n cacheCreationTokens?: number;\n subprocess?: boolean;\n}): Usage {\n const cacheReadTokens = args.cacheReadTokens ?? 0;\n const cacheCreationTokens = args.cacheCreationTokens ?? 0;\n // Subprocess (Max plan) is never a metered charge to us — cost is always 0.\n const costUsd = args.subprocess\n ? 0\n : computeCost(\n args.provider,\n args.model,\n args.inputTokens,\n args.outputTokens,\n cacheReadTokens,\n cacheCreationTokens,\n );\n const usage: Usage = {\n provider: args.provider,\n model: args.model,\n transport: args.transport,\n inputTokens: args.inputTokens,\n outputTokens: args.outputTokens,\n cacheReadTokens,\n cacheCreationTokens,\n costUsd,\n latencyMs: 0,\n capability: args.capability,\n ts: \"\",\n };\n if (args.subprocess) usage.subprocess = true;\n return usage;\n}\n","// Anthropic adapter (F4.6) — the real one (F2.5 shipped only a stub). Two\n// transports: http (api.anthropic.com/v1/messages) and subprocess (claude -p,\n// Max plan, costUsd 0). Critical for the xrt81 vision pilot. Tools normalized\n// via F4.5. No @anthropic-ai/sdk package — plain fetch through httpTransport.\nimport { httpTransport } from \"../transport/http.js\";\nimport { subprocessTransport } from \"../transport/subprocess.js\";\nimport { streamTransport } from \"../transport/stream.js\";\nimport { toProviderTools, fromProviderToolCall } from \"./tools.js\";\nimport { freshUsage } from \"../cost/usage.js\";\nimport type {\n ProviderAdapter,\n ChatRequest,\n ChatResult,\n ChatStreamEvent,\n Message,\n ContentPart,\n ToolCall,\n} from \"../types.js\";\n\ninterface AnthropicBlock {\n type: string;\n text?: string;\n id?: string;\n name?: string;\n input?: Record<string, unknown>;\n}\ninterface AnthropicResponse {\n content?: AnthropicBlock[];\n usage?: {\n input_tokens?: number;\n output_tokens?: number;\n cache_read_input_tokens?: number;\n cache_creation_input_tokens?: number;\n };\n error?: unknown;\n}\n\nfunction contentBlocks(content: string | ContentPart[]): unknown {\n if (typeof content === \"string\") return content;\n return content.map((p) => {\n if (p.type === \"text\") return { type: \"text\", text: p.text };\n // Anthropic has no native video input — route video via a video-capable\n // provider (Gemini, F019) instead.\n if (p.type === \"video\") {\n throw new Error(\"anthropic adapter: video input is not supported — use a video provider (e.g. gemini)\");\n }\n if (typeof p.image === \"string\" && /^https?:\\/\\//.test(p.image)) {\n return { type: \"image\", source: { type: \"url\", url: p.image } };\n }\n const data =\n typeof p.image === \"string\"\n ? p.image.replace(/^data:[^;]+;base64,/, \"\")\n : Buffer.from(p.image).toString(\"base64\");\n return {\n type: \"image\",\n source: { type: \"base64\", media_type: p.mimeType ?? \"image/png\", data },\n };\n });\n}\n\n/** Flatten messages to a single prompt for the subprocess (claude -p) path. */\nfunction flattenForSubprocess(messages: Message[]): { prompt: string; system?: string } {\n const sys: string[] = [];\n const turns: string[] = [];\n for (const m of messages) {\n const text =\n typeof m.content === \"string\"\n ? m.content\n : m.content.map((p) => (p.type === \"text\" ? p.text : \"[image]\")).join(\" \");\n if (m.role === \"system\") sys.push(text);\n else turns.push(`${m.role}: ${text}`);\n }\n return { prompt: turns.join(\"\\n\\n\"), system: sys.length ? sys.join(\"\\n\") : undefined };\n}\n\nexport function anthropicAdapter(\n config: { apiKey?: string; baseUrl?: string; anthropicVersion?: string; fetch?: typeof fetch } = {},\n): ProviderAdapter {\n const baseUrl = config.baseUrl ?? \"https://api.anthropic.com\";\n const version = config.anthropicVersion ?? \"2023-06-01\";\n\n /** Build the /v1/messages body (shared by the http + stream paths). */\n function buildBody(req: ChatRequest): Record<string, unknown> {\n const system: string[] = [];\n const messages: { role: string; content: unknown }[] = [];\n for (const m of req.messages as Message[]) {\n if (m.role === \"system\") {\n system.push(typeof m.content === \"string\" ? m.content : \"\");\n continue;\n }\n // tool-result turn → a user message carrying a tool_result block (F8.7).\n if (m.role === \"tool\") {\n messages.push({\n role: \"user\",\n content: [\n {\n type: \"tool_result\",\n tool_use_id: m.toolCallId ?? \"\",\n content: typeof m.content === \"string\" ? m.content : \"\",\n },\n ],\n });\n continue;\n }\n // assistant turn that called tools → text blocks + tool_use blocks (F8.7).\n if (m.role === \"assistant\" && m.toolCalls && m.toolCalls.length > 0) {\n const blocks: unknown[] = [];\n if (typeof m.content === \"string\") {\n if (m.content.length > 0) blocks.push({ type: \"text\", text: m.content });\n } else {\n blocks.push(...(contentBlocks(m.content) as unknown[]));\n }\n for (const tc of m.toolCalls) {\n blocks.push({ type: \"tool_use\", id: tc.id, name: tc.name, input: tc.arguments });\n }\n messages.push({ role: \"assistant\", content: blocks });\n continue;\n }\n messages.push({ role: m.role === \"assistant\" ? \"assistant\" : \"user\", content: contentBlocks(m.content) });\n }\n const body: Record<string, unknown> = {\n model: req.spec.model,\n max_tokens: req.maxTokens ?? 1024, // Anthropic requires max_tokens\n messages,\n };\n if (system.length > 0) body.system = system.join(\"\\n\");\n if (req.tools) body.tools = toProviderTools(req.tools, \"anthropic\");\n if (req.temperature !== undefined) body.temperature = req.temperature;\n return body;\n }\n\n function apiKeyOrThrow(): string {\n const apiKey = config.apiKey ?? process.env.ANTHROPIC_API_KEY;\n if (!apiKey) throw new Error(\"anthropic adapter: API key not set (env ANTHROPIC_API_KEY)\");\n return apiKey;\n }\n\n async function chatHttp(req: ChatRequest): Promise<ChatResult> {\n const apiKey = apiKeyOrThrow();\n const body = buildBody(req);\n\n const res = await httpTransport({\n spec: req.spec,\n http: {\n url: `${baseUrl}/v1/messages`,\n headers: {\n \"content-type\": \"application/json\",\n \"x-api-key\": apiKey,\n \"anthropic-version\": version,\n },\n body,\n },\n });\n if (!res.ok) throw new Error(`anthropic ${res.status}: ${JSON.stringify(res.json).slice(0, 300)}`);\n\n const data = res.json as AnthropicResponse;\n const blocks = data.content ?? [];\n const text = blocks\n .filter((b) => b.type === \"text\" && typeof b.text === \"string\")\n .map((b) => b.text)\n .join(\"\");\n const toolCalls: ToolCall[] = blocks\n .filter((b) => b.type === \"tool_use\")\n .map((b) => fromProviderToolCall(b, \"anthropic\"));\n\n const usage = freshUsage({\n provider: \"anthropic\",\n model: req.spec.model,\n transport: \"http\",\n capability: \"chat\",\n inputTokens: data.usage?.input_tokens ?? 0,\n outputTokens: data.usage?.output_tokens ?? 0,\n cacheReadTokens: data.usage?.cache_read_input_tokens ?? 0,\n cacheCreationTokens: data.usage?.cache_creation_input_tokens ?? 0,\n });\n const result: ChatResult = { text, usage };\n if (toolCalls.length > 0) result.toolCalls = toolCalls;\n return result;\n }\n\n async function chatSubprocess(req: ChatRequest): Promise<ChatResult> {\n const { prompt, system } = flattenForSubprocess(req.messages as Message[]);\n const r = await subprocessTransport({ spec: req.spec, subprocess: { prompt, systemPrompt: system } });\n const usage = freshUsage({\n provider: \"anthropic\",\n model: req.spec.model,\n transport: \"subprocess\",\n capability: \"chat\",\n inputTokens: r.inputTokens,\n outputTokens: r.outputTokens,\n cacheReadTokens: r.cacheReadTokens,\n cacheCreationTokens: r.cacheCreationTokens,\n subprocess: true,\n });\n return { text: r.text, usage };\n }\n\n async function chat(req: ChatRequest): Promise<ChatResult> {\n return req.spec.transport === \"subprocess\" ? chatSubprocess(req) : chatHttp(req);\n }\n\n // Streaming chat (F8.4) over the native /v1/messages SSE. Maps\n // content_block_delta(text_delta) → text events, accumulates tool_use blocks\n // (id/name from content_block_start, input from input_json_delta) → complete\n // tool_call events, and reads usage from message_start + message_delta. Only\n // the http transport streams — `claude -p` subprocess is one-shot.\n async function* chatStream(req: ChatRequest): AsyncIterable<ChatStreamEvent> {\n if (req.spec.transport === \"subprocess\") {\n throw new Error(\"anthropic adapter: streaming is not supported over the subprocess transport\");\n }\n const apiKey = apiKeyOrThrow();\n const body = { ...buildBody(req), stream: true };\n const stream = streamTransport({\n spec: req.spec,\n fetch: config.fetch,\n http: {\n url: `${baseUrl}/v1/messages`,\n headers: {\n \"content-type\": \"application/json\",\n \"x-api-key\": apiKey,\n \"anthropic-version\": version,\n },\n body,\n },\n });\n\n let inputTokens = 0;\n let outputTokens = 0;\n let cacheReadTokens = 0;\n let cacheCreationTokens = 0;\n let stopReason: string | null = null;\n // index → accumulated tool_use block (input_json_delta fragments concatenated).\n const toolBlocks = new Map<number, { id: string; name: string; json: string }>();\n\n for await (const data of stream) {\n let ev: AnthropicStreamEvent;\n try {\n ev = JSON.parse(data) as AnthropicStreamEvent;\n } catch {\n continue;\n }\n switch (ev.type) {\n case \"message_start\": {\n const u = ev.message?.usage;\n inputTokens = u?.input_tokens ?? 0;\n cacheReadTokens = u?.cache_read_input_tokens ?? 0;\n cacheCreationTokens = u?.cache_creation_input_tokens ?? 0;\n break;\n }\n case \"content_block_start\": {\n if (ev.content_block?.type === \"tool_use\" && ev.index !== undefined) {\n toolBlocks.set(ev.index, {\n id: ev.content_block.id ?? \"\",\n name: ev.content_block.name ?? \"\",\n json: \"\",\n });\n }\n break;\n }\n case \"content_block_delta\": {\n const d = ev.delta;\n if (d?.type === \"text_delta\" && d.text) {\n yield { type: \"text\", delta: d.text };\n } else if (d?.type === \"input_json_delta\" && d.partial_json && ev.index !== undefined) {\n const b = toolBlocks.get(ev.index);\n if (b) b.json += d.partial_json;\n }\n break;\n }\n case \"message_delta\": {\n if (ev.delta?.stop_reason) stopReason = ev.delta.stop_reason;\n if (ev.usage?.output_tokens !== undefined) outputTokens = ev.usage.output_tokens;\n break;\n }\n default:\n break; // content_block_stop / message_stop / ping\n }\n }\n\n for (const [, b] of [...toolBlocks.entries()].sort((a, c) => a[0] - c[0])) {\n let args: Record<string, unknown> = {};\n try {\n args = b.json ? (JSON.parse(b.json) as Record<string, unknown>) : {};\n } catch {\n args = {};\n }\n yield { type: \"tool_call\", id: b.id, name: b.name, args };\n }\n const usage = freshUsage({\n provider: \"anthropic\",\n model: req.spec.model,\n transport: \"http\",\n capability: \"chat\",\n inputTokens,\n outputTokens,\n cacheReadTokens,\n cacheCreationTokens,\n });\n yield { type: \"usage\", costUsd: usage.costUsd, model: usage.model, usage };\n yield { type: \"finish\", reason: mapAnthropicStop(stopReason) };\n }\n\n return { name: \"anthropic\", chat, chatStream, vision: chat };\n}\n\n/** Anthropic Messages SSE event (only the fields we read). */\ninterface AnthropicStreamEvent {\n type: string;\n index?: number;\n message?: {\n usage?: {\n input_tokens?: number;\n cache_read_input_tokens?: number;\n cache_creation_input_tokens?: number;\n };\n };\n content_block?: { type?: string; id?: string; name?: string };\n delta?: { type?: string; text?: string; partial_json?: string; stop_reason?: string };\n usage?: { output_tokens?: number };\n}\n\n/** Map Anthropic stop_reason → the SDK's ChatStreamEvent finish reason. */\nfunction mapAnthropicStop(reason: string | null): \"end_turn\" | \"tool_calls\" | \"length\" | \"stop\" {\n switch (reason) {\n case \"tool_use\":\n return \"tool_calls\";\n case \"max_tokens\":\n return \"length\";\n case \"stop_sequence\":\n return \"stop\";\n default:\n return \"end_turn\";\n }\n}\n","// Shared core for OpenAI-compatible chat APIs. OpenAI (F4.1), DeepInfra (F4.3)\n// and OpenRouter (F4.4) all speak this wire format — only base URL, key and a\n// couple of headers differ. The adapter uses httpTransport (F2.4) for the wire\n// I/O and the F4.5 tool contract for tool round-tripping.\nimport { httpTransport } from \"../transport/http.js\";\nimport { streamTransport } from \"../transport/stream.js\";\nimport { toProviderTools, fromProviderToolCall } from \"./tools.js\";\nimport { freshUsage } from \"../cost/usage.js\";\nimport type {\n ProviderAdapter,\n ChatRequest,\n ChatResult,\n ChatStreamEvent,\n Message,\n ToolCall,\n} from \"../types.js\";\n\nexport interface OpenAICompatibleConfig {\n /** Provider name recorded on Usage (e.g. \"openai\", \"deepinfra\", \"openrouter\"). */\n name: string;\n /** Chat completions base, e.g. \"https://api.openai.com/v1\". */\n baseUrl: string;\n /** Resolved at call time if omitted (env var per provider). */\n apiKey?: string;\n /** Extra headers (e.g. OpenRouter's HTTP-Referer / X-Title). */\n extraHeaders?: Record<string, string>;\n /** Injectable fetch for the streaming path (tests). */\n fetch?: typeof fetch;\n /** OpenRouter ground-truth cost (F010): send `usage:{include:true}` and use the\n * response's `usage.cost` (USD) as costUsd, falling back to the pricing table.\n * Only OpenRouter returns this field — openai/deepinfra leave it false. */\n costFromResponseField?: boolean;\n}\n\ninterface OAToolCall {\n id?: string;\n function?: { name?: string; arguments?: string };\n}\ninterface OAResponse {\n choices?: { message?: { content?: string | null; tool_calls?: OAToolCall[] } }[];\n usage?: { prompt_tokens?: number; completion_tokens?: number; cost?: number };\n error?: unknown;\n}\n\n/** SDK message → OpenAI message (string content, or multimodal parts for vision).\n * Threads the normalized tool form to the wire: a `tool`-role message's\n * `toolCallId` → `tool_call_id`, and an assistant message's `toolCalls` →\n * `tool_calls:[{id,type:'function',function:{name,arguments}}]` (F8.3) so a\n * multi-turn tool conversation round-trips. Exported for serialization tests. */\nexport function toOpenAIMessage(m: Message): Record<string, unknown> {\n if (typeof m.content === \"string\") {\n const base: Record<string, unknown> = { role: m.role, content: m.content };\n if (m.toolCallId) base.tool_call_id = m.toolCallId;\n if (m.toolCalls && m.toolCalls.length > 0) {\n base.tool_calls = m.toolCalls.map((tc) => ({\n id: tc.id,\n type: \"function\",\n function: { name: tc.name, arguments: JSON.stringify(tc.arguments) },\n }));\n }\n return base;\n }\n const content = m.content.map((p) => {\n if (p.type === \"text\") return { type: \"text\", text: p.text };\n if (p.type === \"video\") {\n // F019.3 — OpenRouter video models. `video_url` mirrors `image_url`;\n // VERIFIED live 2026-06-04 against gemma-4 + nvidia-nemotron (both described\n // a real 2MB clip sent inline as a base64 data-URL).\n const url =\n typeof p.video === \"string\"\n ? p.video\n : `data:${p.mimeType ?? \"video/mp4\"};base64,${Buffer.from(p.video).toString(\"base64\")}`;\n return { type: \"video_url\", video_url: { url } };\n }\n const url =\n typeof p.image === \"string\"\n ? p.image\n : `data:${p.mimeType ?? \"image/png\"};base64,${Buffer.from(p.image).toString(\"base64\")}`;\n return { type: \"image_url\", image_url: { url } };\n });\n return { role: m.role, content };\n}\n\nexport function makeOpenAICompatibleAdapter(config: OpenAICompatibleConfig): ProviderAdapter {\n async function chat(req: ChatRequest): Promise<ChatResult> {\n const apiKey = config.apiKey ?? process.env[`${config.name.toUpperCase()}_API_KEY`];\n if (!apiKey) {\n throw new Error(`${config.name} adapter: API key not set (env ${config.name.toUpperCase()}_API_KEY)`);\n }\n const body: Record<string, unknown> = {\n model: req.spec.model,\n messages: req.messages.map(toOpenAIMessage),\n };\n if (req.tools) body.tools = toProviderTools(req.tools, \"openai\");\n if (req.maxTokens !== undefined) body.max_tokens = req.maxTokens;\n if (req.temperature !== undefined) body.temperature = req.temperature;\n if (req.responseFormat === \"json\") body.response_format = { type: \"json_object\" };\n if (config.costFromResponseField) body.usage = { include: true };\n\n const res = await httpTransport({\n spec: req.spec,\n http: {\n url: `${config.baseUrl}/chat/completions`,\n headers: {\n \"content-type\": \"application/json\",\n Authorization: `Bearer ${apiKey}`,\n ...config.extraHeaders,\n },\n body,\n },\n });\n if (!res.ok) {\n throw new Error(`${config.name} ${res.status}: ${JSON.stringify(res.json).slice(0, 300)}`);\n }\n const data = res.json as OAResponse;\n const msg = data.choices?.[0]?.message;\n const text = msg?.content ?? \"\";\n const toolCalls: ToolCall[] | undefined = msg?.tool_calls?.map((tc) =>\n fromProviderToolCall(tc, \"openai\"),\n );\n const usage = freshUsage({\n provider: config.name,\n model: req.spec.model,\n transport: \"http\",\n capability: \"chat\",\n inputTokens: data.usage?.prompt_tokens ?? 0,\n outputTokens: data.usage?.completion_tokens ?? 0,\n });\n if (config.costFromResponseField && typeof data.usage?.cost === \"number\") {\n usage.costUsd = data.usage.cost; // OpenRouter ground-truth beats the estimate\n }\n const result: ChatResult = { text, usage };\n if (toolCalls && toolCalls.length > 0) result.toolCalls = toolCalls;\n return result;\n }\n\n // Streaming chat (F8.2). Parses the OpenAI chat.completions SSE: content\n // deltas → text events, tool_calls deltas accumulated (index-keyed, arguments\n // string concatenated) → complete tool_call events at end, the include_usage\n // chunk → a usage event, finish_reason → the terminal finish (emitted last so\n // tool_calls + usage precede it).\n async function* chatStream(req: ChatRequest): AsyncIterable<ChatStreamEvent> {\n const apiKey = config.apiKey ?? process.env[`${config.name.toUpperCase()}_API_KEY`];\n if (!apiKey) {\n throw new Error(`${config.name} adapter: API key not set (env ${config.name.toUpperCase()}_API_KEY)`);\n }\n const body: Record<string, unknown> = {\n model: req.spec.model,\n messages: req.messages.map(toOpenAIMessage),\n stream: true,\n stream_options: { include_usage: true },\n };\n if (req.tools) body.tools = toProviderTools(req.tools, \"openai\");\n if (req.maxTokens !== undefined) body.max_tokens = req.maxTokens;\n if (req.temperature !== undefined) body.temperature = req.temperature;\n if (req.responseFormat === \"json\") body.response_format = { type: \"json_object\" };\n if (config.costFromResponseField) body.usage = { include: true };\n\n const stream = streamTransport({\n spec: req.spec,\n fetch: config.fetch,\n http: {\n url: `${config.baseUrl}/chat/completions`,\n headers: {\n \"content-type\": \"application/json\",\n Authorization: `Bearer ${apiKey}`,\n ...config.extraHeaders,\n },\n body,\n },\n });\n\n // index → accumulated tool call (id/name set once, arguments concatenated).\n const toolAcc = new Map<number, { id: string; name: string; args: string }>();\n let finishReason: string | null = null;\n\n for await (const data of stream) {\n let chunk: OAStreamChunk;\n try {\n chunk = JSON.parse(data) as OAStreamChunk;\n } catch {\n continue; // ignore unparseable keep-alive noise\n }\n const choice = chunk.choices?.[0];\n if (choice) {\n const delta = choice.delta ?? {};\n if (typeof delta.content === \"string\" && delta.content.length > 0) {\n yield { type: \"text\", delta: delta.content };\n }\n for (const tc of delta.tool_calls ?? []) {\n const idx = tc.index ?? 0;\n const cur = toolAcc.get(idx) ?? { id: \"\", name: \"\", args: \"\" };\n if (tc.id) cur.id = tc.id;\n if (tc.function?.name) cur.name = tc.function.name;\n if (tc.function?.arguments) cur.args += tc.function.arguments;\n toolAcc.set(idx, cur);\n }\n if (choice.finish_reason) finishReason = choice.finish_reason;\n }\n if (chunk.usage) {\n const usage = freshUsage({\n provider: config.name,\n model: req.spec.model,\n transport: \"http\",\n capability: \"chat\",\n inputTokens: chunk.usage.prompt_tokens ?? 0,\n outputTokens: chunk.usage.completion_tokens ?? 0,\n });\n if (config.costFromResponseField && typeof chunk.usage.cost === \"number\") {\n usage.costUsd = chunk.usage.cost; // OpenRouter ground-truth\n }\n yield { type: \"usage\", costUsd: usage.costUsd, model: usage.model, usage };\n }\n }\n\n // Flush accumulated tool calls (complete), then the terminal finish.\n for (const [, t] of [...toolAcc.entries()].sort((a, b) => a[0] - b[0])) {\n let args: Record<string, unknown> = {};\n try {\n args = t.args ? (JSON.parse(t.args) as Record<string, unknown>) : {};\n } catch {\n args = {};\n }\n yield { type: \"tool_call\", id: t.id, name: t.name, args };\n }\n yield { type: \"finish\", reason: mapFinishReason(finishReason) };\n }\n\n return {\n name: config.name,\n chat,\n chatStream,\n // gpt-4o-class models are multimodal — vision shares the chat path.\n vision: chat,\n };\n}\n\n/** OpenAI streaming chunk shape (only the fields we read). */\ninterface OAStreamChunk {\n choices?: {\n delta?: {\n content?: string | null;\n tool_calls?: { index?: number; id?: string; function?: { name?: string; arguments?: string } }[];\n };\n finish_reason?: string | null;\n }[];\n usage?: { prompt_tokens?: number; completion_tokens?: number; cost?: number };\n}\n\n/** Map OpenAI finish_reason → the SDK's ChatStreamEvent finish reason. */\nfunction mapFinishReason(reason: string | null): \"end_turn\" | \"tool_calls\" | \"length\" | \"stop\" {\n switch (reason) {\n case \"tool_calls\":\n return \"tool_calls\";\n case \"length\":\n return \"length\";\n case \"stop\":\n return \"stop\";\n default:\n return \"end_turn\";\n }\n}\n","// OpenAI adapter (F4.1 chat/vision + F5.4 embedding). Chat/vision come from the\n// shared OpenAI-compatible core; embedding uses the /embeddings endpoint. No\n// openai npm package — plain fetch through httpTransport.\nimport { makeOpenAICompatibleAdapter } from \"./openai-compatible.js\";\nimport { httpTransport } from \"../transport/http.js\";\nimport { freshUsage } from \"../cost/usage.js\";\nimport type {\n ProviderAdapter,\n EmbeddingRequest,\n EmbeddingResult,\n TranscribeRequest,\n TranscribeResult,\n} from \"../types.js\";\n\n/** Whisper-family per-minute USD prices (audio is not token-priced). */\nconst WHISPER_PRICE_PER_MIN: Record<string, number> = {\n \"whisper-1\": 0.006,\n};\n\nexport function openaiAdapter(\n config: { apiKey?: string; baseUrl?: string; fetch?: typeof fetch } = {},\n): ProviderAdapter {\n const baseUrl = config.baseUrl ?? \"https://api.openai.com/v1\";\n const base = makeOpenAICompatibleAdapter({ name: \"openai\", baseUrl, apiKey: config.apiKey });\n\n async function embedding(req: EmbeddingRequest): Promise<EmbeddingResult> {\n const apiKey = config.apiKey ?? process.env.OPENAI_API_KEY;\n if (!apiKey) throw new Error(\"openai adapter: API key not set (env OPENAI_API_KEY)\");\n const res = await httpTransport({\n spec: req.spec,\n http: {\n url: `${baseUrl}/embeddings`,\n headers: { \"content-type\": \"application/json\", Authorization: `Bearer ${apiKey}` },\n body: { model: req.spec.model, input: req.input },\n },\n });\n if (!res.ok) {\n throw new Error(`openai ${res.status}: ${JSON.stringify(res.json).slice(0, 300)}`);\n }\n const data = res.json as {\n data?: { embedding: number[] }[];\n usage?: { prompt_tokens?: number };\n };\n const vectors = (data.data ?? []).map((d) => d.embedding);\n const usage = freshUsage({\n provider: \"openai\",\n model: req.spec.model,\n transport: \"http\",\n capability: \"embedding\",\n inputTokens: data.usage?.prompt_tokens ?? 0,\n outputTokens: 0,\n });\n return { vectors, usage };\n }\n\n async function transcribe(req: TranscribeRequest): Promise<TranscribeResult> {\n const apiKey = config.apiKey ?? process.env.OPENAI_API_KEY;\n if (!apiKey) throw new Error(\"openai adapter: API key not set (env OPENAI_API_KEY)\");\n // Whisper is multipart/form-data — bypass httpTransport (JSON-only). Don't set\n // content-type; fetch adds the multipart boundary.\n const form = new FormData();\n form.append(\"file\", new Blob([req.audio]), \"audio\");\n form.append(\"model\", req.spec.model);\n if (req.language) form.append(\"language\", req.language);\n const fetchImpl = config.fetch ?? fetch;\n const res = await fetchImpl(`${baseUrl}/audio/transcriptions`, {\n method: \"POST\",\n headers: { Authorization: `Bearer ${apiKey}` },\n body: form,\n });\n if (!res.ok) {\n throw new Error(`openai ${res.status}: ${(await res.text().catch(() => \"\")).slice(0, 200)}`);\n }\n const data = (await res.json()) as { text?: string };\n const usage = freshUsage({\n provider: \"openai\",\n model: req.spec.model,\n transport: \"http\",\n capability: \"transcribe\",\n inputTokens: 0,\n outputTokens: 0, // Whisper is per-minute, not token-priced.\n });\n // Per-minute cost when the caller supplies the audio duration (API returns none).\n if (req.durationSec !== undefined) {\n const perMinute = WHISPER_PRICE_PER_MIN[req.spec.model] ?? 0;\n usage.costUsd = (req.durationSec / 60) * perMinute;\n }\n return { text: data.text ?? \"\", usage };\n }\n\n return { ...base, embedding, transcribe };\n}\n","// Google Gemini adapter (F4.2). generateContent REST API; API key in the query\n// param (?key=), not a header. System turns map to systemInstruction; assistant\n// maps to role \"model\". Token counts come from usageMetadata. Tools normalized\n// via F4.5. No @google/generative-ai package — plain fetch through httpTransport.\nimport { httpTransport } from \"../transport/http.js\";\nimport { streamTransport } from \"../transport/stream.js\";\nimport { toProviderTools, fromProviderToolCall } from \"./tools.js\";\nimport { freshUsage } from \"../cost/usage.js\";\nimport type {\n ProviderAdapter,\n ChatRequest,\n ChatResult,\n ChatStreamEvent,\n ImageRequest,\n ImageResult,\n Message,\n ContentPart,\n ToolCall,\n} from \"../types.js\";\n\n/** Per-image USD price for Gemini image-gen models (generateContent image output\n * is billed per image, not per token). nano-banana = $0.039. Overridable via\n * geminiAdapter config.pricePerImage. */\nconst GEMINI_IMAGE_PRICE_PER_IMAGE: Record<string, number> = {\n \"gemini-3-pro-image-preview\": 0.039,\n \"gemini-2.5-flash-image\": 0.039,\n};\n\ninterface GeminiPart {\n text?: string;\n functionCall?: { name: string; args: Record<string, unknown> };\n inlineData?: { mimeType: string; data: string };\n}\ninterface GeminiResponse {\n candidates?: { content?: { parts?: GeminiPart[] } }[];\n usageMetadata?: { promptTokenCount?: number; candidatesTokenCount?: number };\n error?: unknown;\n}\n\nfunction partsFrom(content: string | ContentPart[]): GeminiPart[] {\n if (typeof content === \"string\") return [{ text: content }];\n return content.map((p): GeminiPart => {\n if (p.type === \"text\") return { text: p.text };\n // Video (F019) and image both go inline as base64 — Gemini accepts video mime\n // types natively. (Clips over ~20MB need the Files API — not handled here.)\n if (p.type === \"video\") {\n const data =\n typeof p.video === \"string\"\n ? p.video.replace(/^data:[^;]+;base64,/, \"\")\n : Buffer.from(p.video).toString(\"base64\");\n return { inlineData: { mimeType: p.mimeType ?? \"video/mp4\", data } };\n }\n const data =\n typeof p.image === \"string\"\n ? p.image.replace(/^data:[^;]+;base64,/, \"\")\n : Buffer.from(p.image).toString(\"base64\");\n return { inlineData: { mimeType: p.mimeType ?? \"image/png\", data } };\n });\n}\n\nexport function geminiAdapter(\n config: { apiKey?: string; baseUrl?: string; fetch?: typeof fetch; pricePerImage?: number } = {},\n): ProviderAdapter {\n const baseUrl = config.baseUrl ?? \"https://generativelanguage.googleapis.com/v1beta\";\n\n function resolveKey(): string {\n const apiKey = config.apiKey ?? process.env.GOOGLE_API_KEY ?? process.env.GEMINI_API_KEY;\n if (!apiKey) throw new Error(\"gemini adapter: API key not set (env GOOGLE_API_KEY)\");\n return apiKey;\n }\n\n /** Build the generateContent body (shared by the http + stream paths). */\n function buildBody(req: ChatRequest): Record<string, unknown> {\n const systemParts: GeminiPart[] = [];\n const contents: { role: string; parts: GeminiPart[] }[] = [];\n for (const m of req.messages as Message[]) {\n if (m.role === \"system\") {\n systemParts.push(...partsFrom(m.content));\n } else {\n contents.push({\n role: m.role === \"assistant\" ? \"model\" : \"user\",\n parts: partsFrom(m.content),\n });\n }\n }\n const body: Record<string, unknown> = { contents };\n if (systemParts.length > 0) body.systemInstruction = { parts: systemParts };\n if (req.tools) body.tools = toProviderTools(req.tools, \"gemini\");\n const genConfig: Record<string, unknown> = {};\n if (req.maxTokens !== undefined) genConfig.maxOutputTokens = req.maxTokens;\n if (req.temperature !== undefined) genConfig.temperature = req.temperature;\n if (Object.keys(genConfig).length > 0) body.generationConfig = genConfig;\n return body;\n }\n\n async function chat(req: ChatRequest): Promise<ChatResult> {\n const apiKey = resolveKey();\n const body = buildBody(req);\n\n const res = await httpTransport({\n spec: req.spec,\n http: {\n url: `${baseUrl}/models/${req.spec.model}:generateContent?key=${encodeURIComponent(apiKey)}`,\n headers: { \"content-type\": \"application/json\" },\n body,\n },\n });\n if (!res.ok) {\n throw new Error(`gemini ${res.status}: ${JSON.stringify(res.json).slice(0, 300)}`);\n }\n const data = res.json as GeminiResponse;\n const parts = data.candidates?.[0]?.content?.parts ?? [];\n const text = parts\n .filter((p) => typeof p.text === \"string\")\n .map((p) => p.text)\n .join(\"\");\n const toolCalls: ToolCall[] = parts\n .filter((p) => p.functionCall)\n .map((p) => fromProviderToolCall({ functionCall: p.functionCall }, \"gemini\"));\n\n const usage = freshUsage({\n provider: \"gemini\",\n model: req.spec.model,\n transport: \"http\",\n capability: \"chat\",\n inputTokens: data.usageMetadata?.promptTokenCount ?? 0,\n outputTokens: data.usageMetadata?.candidatesTokenCount ?? 0,\n });\n const result: ChatResult = { text, usage };\n if (toolCalls.length > 0) result.toolCalls = toolCalls;\n return result;\n }\n\n // Streaming chat (F8.6) over streamGenerateContent?alt=sse. Each SSE chunk is\n // a partial GenerateContentResponse: parts[].text → text events, parts[].\n // functionCall → complete tool_call events (gemini sends each call whole), and\n // the final usageMetadata → a usage event. finishReason maps the terminal.\n async function* chatStream(req: ChatRequest): AsyncIterable<ChatStreamEvent> {\n const apiKey = resolveKey();\n const body = buildBody(req);\n const stream = streamTransport({\n spec: req.spec,\n fetch: config.fetch,\n http: {\n url: `${baseUrl}/models/${req.spec.model}:streamGenerateContent?alt=sse&key=${encodeURIComponent(apiKey)}`,\n headers: { \"content-type\": \"application/json\" },\n body,\n },\n });\n\n const toolCalls: ToolCall[] = [];\n let inputTokens = 0;\n let outputTokens = 0;\n let finishReason: string | null = null;\n\n for await (const data of stream) {\n let chunk: GeminiResponse & { candidates?: { finishReason?: string }[] };\n try {\n chunk = JSON.parse(data) as typeof chunk;\n } catch {\n continue;\n }\n const candidate = chunk.candidates?.[0];\n for (const p of candidate?.content?.parts ?? []) {\n if (typeof p.text === \"string\" && p.text.length > 0) {\n yield { type: \"text\", delta: p.text };\n } else if (p.functionCall) {\n toolCalls.push(fromProviderToolCall({ functionCall: p.functionCall }, \"gemini\"));\n }\n }\n if (candidate?.finishReason) finishReason = candidate.finishReason;\n if (chunk.usageMetadata) {\n inputTokens = chunk.usageMetadata.promptTokenCount ?? inputTokens;\n outputTokens = chunk.usageMetadata.candidatesTokenCount ?? outputTokens;\n }\n }\n\n for (const tc of toolCalls) {\n yield { type: \"tool_call\", id: tc.id, name: tc.name, args: tc.arguments };\n }\n const usage = freshUsage({\n provider: \"gemini\",\n model: req.spec.model,\n transport: \"http\",\n capability: \"chat\",\n inputTokens,\n outputTokens,\n });\n yield { type: \"usage\", costUsd: usage.costUsd, model: usage.model, usage };\n yield {\n type: \"finish\",\n reason: toolCalls.length > 0 ? \"tool_calls\" : mapGeminiFinish(finishReason),\n };\n }\n\n // Image generation (F013) via generateContent with IMAGE response modality.\n // Gemini returns the image inline as base64 (not a hosted URL like fal), so we\n // hand it back as a data: URL. Built to match cms's nano-banana request.\n async function image(req: ImageRequest): Promise<ImageResult> {\n const apiKey = resolveKey();\n // Direct fetch (injectable for tests) — generateContent is JSON in/out but\n // we read inline image bytes, so we don't route through httpTransport here.\n const fetchImpl = config.fetch ?? fetch;\n const res = await fetchImpl(`${baseUrl}/models/${req.spec.model}:generateContent?key=${encodeURIComponent(apiKey)}`, {\n method: \"POST\",\n headers: { \"content-type\": \"application/json\" },\n body: JSON.stringify({\n contents: [{ role: \"user\", parts: [{ text: req.prompt }] }],\n // The multimodal image model can return text + image; ask for both.\n generationConfig: { responseModalities: [\"TEXT\", \"IMAGE\"] },\n }),\n });\n if (!res.ok) {\n const body = await res.text().catch(() => \"\");\n throw new Error(`gemini image ${res.status}: ${body.slice(0, 300)}`);\n }\n const data = (await res.json()) as GeminiResponse & {\n candidates?: { content?: { parts?: GeminiImagePart[] } }[];\n promptFeedback?: { blockReason?: string };\n };\n if (data.promptFeedback?.blockReason) {\n throw new Error(`gemini image blocked: ${data.promptFeedback.blockReason}`);\n }\n let url: string | undefined;\n for (const p of data.candidates?.[0]?.content?.parts ?? []) {\n // Some responses use camelCase inlineData, others snake_case inline_data.\n const inline = p.inlineData ?? p.inline_data;\n const mime = inline?.mimeType ?? inline?.mime_type;\n const b64 = inline?.data;\n if (mime && b64) {\n url = `data:${mime};base64,${b64}`;\n break;\n }\n }\n if (!url) throw new Error(\"gemini image: response contained no inline image data\");\n const usage = freshUsage({\n provider: \"gemini\",\n model: req.spec.model,\n transport: \"http\",\n capability: \"image\",\n inputTokens: data.usageMetadata?.promptTokenCount ?? 0,\n outputTokens: data.usageMetadata?.candidatesTokenCount ?? 0,\n });\n usage.costUsd = config.pricePerImage ?? GEMINI_IMAGE_PRICE_PER_IMAGE[req.spec.model] ?? 0;\n return { url, usage };\n }\n\n return { name: \"gemini\", chat, chatStream, image, vision: chat };\n}\n\n/** Image part shape on a generateContent response (camel + snake aliases). */\ninterface GeminiInline {\n mimeType?: string;\n mime_type?: string;\n data?: string;\n}\ninterface GeminiImagePart {\n text?: string;\n inlineData?: GeminiInline;\n inline_data?: GeminiInline;\n}\n\n/** Map Gemini finishReason → the SDK's ChatStreamEvent finish reason. */\nfunction mapGeminiFinish(reason: string | null): \"end_turn\" | \"tool_calls\" | \"length\" | \"stop\" {\n switch (reason) {\n case \"MAX_TOKENS\":\n return \"length\";\n case \"STOP\":\n return \"end_turn\";\n default:\n return reason ? \"stop\" : \"end_turn\";\n }\n}\n","// DeepInfra adapter (F4.3). DeepInfra exposes an OpenAI-compatible endpoint, so\n// this is the shared core pointed at DeepInfra's base URL + key. No extra deps.\nimport { makeOpenAICompatibleAdapter } from \"./openai-compatible.js\";\nimport type { ProviderAdapter } from \"../types.js\";\n\nexport function deepinfraAdapter(\n config: { apiKey?: string; baseUrl?: string } = {},\n): ProviderAdapter {\n return makeOpenAICompatibleAdapter({\n name: \"deepinfra\",\n baseUrl: config.baseUrl ?? \"https://api.deepinfra.com/v1/openai\",\n apiKey: config.apiKey,\n });\n}\n","// OpenRouter adapter (F4.4). Meta-router with an OpenAI-compatible API — reuses\n// the shared core + OpenRouter's attribution headers. Any upstream model is\n// reachable by its slug, e.g. \"minimax/minimax-m2.7\", \"google/gemini-2.5-flash\".\nimport { makeOpenAICompatibleAdapter } from \"./openai-compatible.js\";\nimport type { ProviderAdapter } from \"../types.js\";\n\nexport function openrouterAdapter(\n config: { apiKey?: string; baseUrl?: string; referer?: string; title?: string } = {},\n): ProviderAdapter {\n return makeOpenAICompatibleAdapter({\n name: \"openrouter\",\n baseUrl: config.baseUrl ?? \"https://openrouter.ai/api/v1\",\n apiKey: config.apiKey,\n extraHeaders: {\n \"HTTP-Referer\": config.referer ?? \"https://broberg.ai\",\n \"X-Title\": config.title ?? \"@broberg/ai-sdk\",\n },\n // OpenRouter returns ground-truth usage.cost (USD) when usage:{include:true}\n // is set — use it over the local pricing-table estimate (F010).\n costFromResponseField: true,\n });\n}\n","// Mistral adapter. Mistral's La Plateforme exposes an OpenAI-compatible chat\n// endpoint (the shared core), plus two specialty endpoints we add here:\n// /ocr (F016.2, per-page) and /moderations (F016.4, per-token). Key resolved\n// from MISTRAL_API_KEY when not passed.\nimport { makeOpenAICompatibleAdapter } from \"./openai-compatible.js\";\nimport { freshUsage } from \"../cost/usage.js\";\nimport type {\n ProviderAdapter,\n OcrRequest,\n OcrResult,\n OcrPage,\n ModerationRequest,\n ModerationResult,\n ModerationItem,\n} from \"../types.js\";\n\n/** Per-page USD for Mistral OCR ($2 / 1000 pages). Overridable via config. */\nconst MISTRAL_OCR_PRICE_PER_PAGE = 0.002;\n\nexport function mistralAdapter(\n config: { apiKey?: string; baseUrl?: string; fetch?: typeof fetch; pricePerPage?: number } = {},\n): ProviderAdapter {\n const baseUrl = config.baseUrl ?? \"https://api.mistral.ai/v1\";\n const base = makeOpenAICompatibleAdapter({ name: \"mistral\", baseUrl, apiKey: config.apiKey });\n\n function key(): string {\n const k = config.apiKey ?? process.env.MISTRAL_API_KEY;\n if (!k) throw new Error(\"mistral adapter: API key not set (env MISTRAL_API_KEY)\");\n return k;\n }\n const fetchImpl = config.fetch ?? fetch;\n\n // OCR (F016.2) — POST /ocr. document is a URL/data-URL; image/* routes as an\n // image, anything else as a document (PDF etc.). Billed per page processed.\n async function ocr(req: OcrRequest): Promise<OcrResult> {\n const isImage = (req.mimeType ?? \"\").startsWith(\"image/\");\n const url =\n typeof req.document === \"string\"\n ? req.document\n : `data:${req.mimeType ?? \"application/pdf\"};base64,${Buffer.from(req.document).toString(\"base64\")}`;\n const document = isImage\n ? { type: \"image_url\", image_url: url }\n : { type: \"document_url\", document_url: url };\n\n const res = await fetchImpl(`${baseUrl}/ocr`, {\n method: \"POST\",\n headers: { \"content-type\": \"application/json\", authorization: `Bearer ${key()}` },\n body: JSON.stringify({ model: req.spec.model, document }),\n });\n if (!res.ok) {\n const body = await res.text().catch(() => \"\");\n throw new Error(`mistral ocr ${res.status}: ${body.slice(0, 300)}`);\n }\n const data = (await res.json()) as {\n pages?: { index?: number; markdown?: string }[];\n usage_info?: { pages_processed?: number };\n };\n const pages: OcrPage[] = (data.pages ?? []).map((p, i) => ({\n index: p.index ?? i,\n markdown: p.markdown ?? \"\",\n }));\n const pagesProcessed = data.usage_info?.pages_processed ?? pages.length;\n const usage = freshUsage({\n provider: \"mistral\",\n model: req.spec.model,\n transport: \"http\",\n capability: \"ocr\",\n inputTokens: 0,\n outputTokens: 0,\n });\n usage.costUsd = pagesProcessed * (config.pricePerPage ?? MISTRAL_OCR_PRICE_PER_PAGE);\n return { pages, usage };\n }\n\n // Moderation (F016.4) — POST /moderations. Returns per-input category booleans\n // + scores; `flagged` = any category true. Billed per input token (estimated\n // from input length when the API omits a usage count).\n async function moderate(req: ModerationRequest): Promise<ModerationResult> {\n const res = await fetchImpl(`${baseUrl}/moderations`, {\n method: \"POST\",\n headers: { \"content-type\": \"application/json\", authorization: `Bearer ${key()}` },\n body: JSON.stringify({ model: req.spec.model, input: req.input }),\n });\n if (!res.ok) {\n const body = await res.text().catch(() => \"\");\n throw new Error(`mistral moderation ${res.status}: ${body.slice(0, 300)}`);\n }\n const data = (await res.json()) as {\n results?: { categories?: Record<string, boolean>; category_scores?: Record<string, number> }[];\n usage?: { prompt_tokens?: number };\n };\n const results: ModerationItem[] = (data.results ?? []).map((r) => {\n const categories = r.categories ?? {};\n return {\n flagged: Object.values(categories).some(Boolean),\n categories,\n categoryScores: r.category_scores ?? {},\n };\n });\n // The moderation endpoint usually omits token counts → estimate from input.\n const estIn = req.input.reduce((n, s) => n + Math.ceil(s.length / 4), 0);\n const usage = freshUsage({\n provider: \"mistral\",\n model: req.spec.model,\n transport: \"http\",\n capability: \"moderation\",\n inputTokens: data.usage?.prompt_tokens ?? estIn,\n outputTokens: 0,\n });\n return { results, usage };\n }\n\n return { ...base, ocr, moderate };\n}\n","// ElevenLabs adapter (F020). Text-to-Dialogue (eleven_v3) turns a manuscript of\n// {text, voice_id} turns into ONE cohesive multi-voice audio episode — the\n// \"instant podcast\" primitive. Also single-voice TTS + voice listing. Audio out\n// is MP3 bytes; billed per character. Key from ELEVENLABS_API_KEY.\nimport { freshUsage } from \"../cost/usage.js\";\nimport type { ProviderAdapter, DialogueRequest, TtsRequest, PodcastResult } from \"../types.js\";\n\n/** USD per 1000 characters (ElevenLabs bills per char; API overage ≈ $0.10–0.18/1k). */\nconst ELEVENLABS_PRICE_PER_1K_CHARS = 0.15;\n\n/** Curated Danish voices (F020.3) — friendly name → ElevenLabs voiceId. Apps can\n * pass these names to `ai.podcast`/`ai.tts` instead of raw IDs. */\nexport const ELEVENLABS_DANISH_VOICES: Record<string, string> = {\n soren: \"xj6X4BCUsv9oxohm1E8o\",\n jesper: \"Bl1YwS3uJac5zEOSNESn\",\n mads: \"BIWC0507fYMfhPcAEIRP\",\n noam: \"V34B5u5UbLdNJVEkcgXp\",\n camilla: \"4RklGmuxoAskAbGXplXN\",\n};\n\n/** Resolve a curated voice name to its voiceId; pass a raw voiceId through unchanged. */\nexport function resolveVoice(nameOrId: string): string {\n return ELEVENLABS_DANISH_VOICES[nameOrId] ?? nameOrId;\n}\n\nexport interface ElevenLabsVoice {\n voiceId: string;\n name: string;\n language?: string;\n}\n\nexport function elevenlabsAdapter(\n config: { apiKey?: string; baseUrl?: string; fetch?: typeof fetch; pricePer1kChars?: number } = {},\n): ProviderAdapter & {\n listVoices(): Promise<ElevenLabsVoice[]>;\n} {\n const baseUrl = config.baseUrl ?? \"https://api.elevenlabs.io/v1\";\n const fetchImpl = config.fetch ?? fetch;\n\n function key(): string {\n const k = config.apiKey ?? process.env.ELEVENLABS_API_KEY;\n if (!k) throw new Error(\"elevenlabs adapter: API key not set (env ELEVENLABS_API_KEY)\");\n return k;\n }\n\n function priceFor(chars: number, model: string): ReturnType<typeof freshUsage> {\n const usage = freshUsage({\n provider: \"elevenlabs\",\n model,\n transport: \"http\",\n capability: \"podcast\",\n inputTokens: 0,\n outputTokens: 0,\n });\n usage.costUsd = (chars / 1000) * (config.pricePer1kChars ?? ELEVENLABS_PRICE_PER_1K_CHARS);\n return usage;\n }\n\n // Multi-voice dialogue → one episode. POST /text-to-dialogue.\n async function dialogue(req: DialogueRequest): Promise<PodcastResult> {\n const res = await fetchImpl(`${baseUrl}/text-to-dialogue`, {\n method: \"POST\",\n headers: { \"xi-api-key\": key(), \"content-type\": \"application/json\", accept: \"audio/mpeg\" },\n body: JSON.stringify({\n model_id: req.spec.model,\n inputs: req.inputs.map((t) => ({ text: t.text, voice_id: t.voiceId })),\n ...(req.format ? { output_format: req.format } : {}),\n }),\n });\n if (!res.ok) {\n const body = await res.text().catch(() => \"\");\n throw new Error(`elevenlabs dialogue ${res.status}: ${body.slice(0, 300)}`);\n }\n const audio = new Uint8Array(await res.arrayBuffer());\n const chars = req.inputs.reduce((n, t) => n + t.text.length, 0);\n return { audio, mimeType: \"audio/mpeg\", usage: priceFor(chars, req.spec.model) };\n }\n\n // Single-voice TTS. POST /text-to-speech/{voice_id}.\n async function tts(req: TtsRequest): Promise<PodcastResult> {\n const model = req.spec.model;\n const res = await fetchImpl(`${baseUrl}/text-to-speech/${req.voiceId}`, {\n method: \"POST\",\n headers: { \"xi-api-key\": key(), \"content-type\": \"application/json\", accept: \"audio/mpeg\" },\n body: JSON.stringify({ text: req.text, model_id: model }),\n });\n if (!res.ok) {\n const body = await res.text().catch(() => \"\");\n throw new Error(`elevenlabs tts ${res.status}: ${body.slice(0, 300)}`);\n }\n const audio = new Uint8Array(await res.arrayBuffer());\n return { audio, mimeType: \"audio/mpeg\", usage: priceFor(req.text.length, model) };\n }\n\n async function listVoices(): Promise<ElevenLabsVoice[]> {\n const res = await fetchImpl(`${baseUrl}/voices`, { headers: { \"xi-api-key\": key() } });\n if (!res.ok) throw new Error(`elevenlabs voices ${res.status}`);\n const data = (await res.json()) as { voices?: { voice_id: string; name: string; labels?: { language?: string } }[] };\n return (data.voices ?? []).map((v) => ({ voiceId: v.voice_id, name: v.name, language: v.labels?.language }));\n }\n\n return { name: \"elevenlabs\", dialogue, tts, listVoices };\n}\n","// fal.ai image adapter (F5.3). Two modes, both observed in the F1 inventory:\n// - sync : POST https://fal.run/{model}, image URL straight back (sanneandersen)\n// - queue : POST https://queue.fal.run/{model} → poll status → fetch result\n// Auth header `Authorization: Key <FAL_KEY>`. No @fal-ai/client — plain fetch.\nimport { freshUsage } from \"../cost/usage.js\";\nimport type { ProviderAdapter, ImageRequest, ImageResult } from \"../types.js\";\n\ninterface FalImagesResponse {\n images?: { url?: string }[];\n error?: unknown;\n}\ninterface FalQueueSubmit {\n request_id?: string;\n status_url?: string;\n response_url?: string;\n}\ninterface FalQueueStatus {\n status?: \"IN_QUEUE\" | \"IN_PROGRESS\" | \"COMPLETED\" | \"FAILED\";\n}\n\nexport interface FalAdapterConfig {\n apiKey?: string;\n /** \"sync\" (default — fal.run, fast models) or \"queue\" (queue.fal.run, polled). */\n mode?: \"sync\" | \"queue\";\n syncBaseUrl?: string;\n queueBaseUrl?: string;\n pollIntervalMs?: number;\n timeoutMs?: number;\n fetch?: typeof fetch;\n /** Override the per-image USD price (else a built-in estimate per model, 0 if unknown). */\n pricePerImage?: number;\n}\n\n// Per-image USD ESTIMATES (fal prices by megapixel/model and changes often —\n// verify before relying on these; override via config.pricePerImage). fal does\n// not return a price, so this is the SDK's best-effort cost for `usage.costUsd`.\nconst FAL_IMAGE_PRICE_ESTIMATE: Record<string, number> = {\n \"fal-ai/flux/schnell\": 0.003,\n \"fal-ai/flux/dev\": 0.025,\n \"fal-ai/flux-pro\": 0.05,\n \"fal-ai/flux-pro/v1.1\": 0.04,\n};\n\nconst sleep = (ms: number) => new Promise((r) => setTimeout(r, ms));\n\nexport function falAdapter(config: FalAdapterConfig = {}): ProviderAdapter {\n const doFetch = config.fetch ?? fetch;\n const syncBase = config.syncBaseUrl ?? \"https://fal.run\";\n const queueBase = config.queueBaseUrl ?? \"https://queue.fal.run\";\n const pollIntervalMs = config.pollIntervalMs ?? 2000;\n const timeoutMs = config.timeoutMs ?? 60000;\n\n async function image(req: ImageRequest): Promise<ImageResult> {\n const apiKey = config.apiKey ?? process.env.FAL_KEY;\n if (!apiKey) throw new Error(\"fal adapter: FAL_KEY not set\");\n const headers = { \"content-type\": \"application/json\", Authorization: `Key ${apiKey}` };\n\n const body: Record<string, unknown> = { prompt: req.prompt };\n if (req.width !== undefined && req.height !== undefined) {\n body.image_size = { width: req.width, height: req.height };\n }\n\n const mode = config.mode ?? \"sync\";\n const url = await (mode === \"sync\"\n ? runSync(req.spec.model, headers, body)\n : runQueue(req.spec.model, headers, body));\n\n // fal returns no price; estimate per-image (one image per call) so usage.costUsd\n // isn't silently 0. Override via config.pricePerImage.\n const usage = freshUsage({\n provider: \"fal\",\n model: req.spec.model,\n transport: \"http\",\n capability: \"image\",\n inputTokens: 0,\n outputTokens: 0,\n });\n usage.costUsd = config.pricePerImage ?? FAL_IMAGE_PRICE_ESTIMATE[req.spec.model] ?? 0;\n return { url, usage };\n }\n\n async function runSync(\n model: string,\n headers: Record<string, string>,\n body: unknown,\n ): Promise<string> {\n const res = await doFetch(`${syncBase}/${model}`, {\n method: \"POST\",\n headers,\n body: JSON.stringify(body),\n });\n if (!res.ok) {\n throw new Error(`fal ${res.status}: ${(await res.text().catch(() => \"\")).slice(0, 200)}`);\n }\n const data = (await res.json()) as FalImagesResponse;\n const out = data.images?.[0]?.url;\n if (!out) throw new Error(`fal: no image url in response`);\n return out;\n }\n\n async function runQueue(\n model: string,\n headers: Record<string, string>,\n body: unknown,\n ): Promise<string> {\n const submitRes = await doFetch(`${queueBase}/${model}`, {\n method: \"POST\",\n headers,\n body: JSON.stringify(body),\n });\n if (!submitRes.ok) {\n throw new Error(`fal queue submit ${submitRes.status}`);\n }\n const submit = (await submitRes.json()) as FalQueueSubmit;\n const statusUrl = submit.status_url;\n const responseUrl = submit.response_url;\n if (!statusUrl || !responseUrl) throw new Error(\"fal queue: missing status/response url\");\n\n const deadline = Date.now() + timeoutMs;\n for (;;) {\n const statusRes = await doFetch(statusUrl, { headers });\n const status = (await statusRes.json()) as FalQueueStatus;\n if (status.status === \"COMPLETED\") break;\n if (status.status === \"FAILED\") throw new Error(\"fal queue: generation FAILED\");\n if (Date.now() >= deadline) throw new Error(`fal queue: timed out after ${timeoutMs}ms`);\n await sleep(pollIntervalMs);\n }\n\n const resultRes = await doFetch(responseUrl, { headers });\n const result = (await resultRes.json()) as FalImagesResponse;\n const out = result.images?.[0]?.url;\n if (!out) throw new Error(\"fal queue: no image url in result\");\n return out;\n }\n\n return { name: \"fal\", image };\n}\n","// Default provider registry — the live adapters wired when AiConfig.providers is\n// absent. A bare createAI() makes real calls (keys from env). fal stays a stub\n// until F5.3 ships the real fal.ai image adapter.\nimport { anthropicAdapter } from \"./anthropic.js\";\nimport { openaiAdapter } from \"./openai.js\";\nimport { geminiAdapter } from \"./gemini.js\";\nimport { deepinfraAdapter } from \"./deepinfra.js\";\nimport { openrouterAdapter } from \"./openrouter.js\";\nimport { mistralAdapter } from \"./mistral.js\";\nimport { elevenlabsAdapter } from \"./elevenlabs.js\";\nimport { falAdapter } from \"./fal.js\";\nimport type { ProviderAdapter } from \"../types.js\";\n\nexport const defaultProviders: Record<string, ProviderAdapter> = {\n anthropic: anthropicAdapter(),\n openai: openaiAdapter(),\n gemini: geminiAdapter(),\n deepinfra: deepinfraAdapter(),\n openrouter: openrouterAdapter(),\n mistral: mistralAdapter(),\n elevenlabs: elevenlabsAdapter(),\n fal: falAdapter(),\n};\n","// Pre-flight budget guard. check() runs BEFORE the transport fires, so a call\n// that would breach a ceiling never reaches the provider. record() folds the\n// actual cost into the running total after a successful call.\nimport type { BudgetConfig, BudgetStore } from \"../types.js\";\n\n/** Default rolling-total store: in-memory, per BudgetGuard instance. */\nclass InMemoryBudgetStore implements BudgetStore {\n private spentUsd = 0;\n getSpent(): number {\n return this.spentUsd;\n }\n addSpent(usd: number): void {\n this.spentUsd += usd;\n }\n}\n\nexport class BudgetExceededError extends Error {\n readonly kind: \"per-call\" | \"rolling\";\n readonly limit: number;\n readonly spent: number;\n readonly requested: number;\n\n constructor(\n kind: \"per-call\" | \"rolling\",\n limit: number,\n spent: number,\n requested: number,\n ) {\n super(\n `Budget exceeded (${kind}): this call's estimated $${requested.toFixed(6)} ` +\n (kind === \"rolling\"\n ? `+ $${spent.toFixed(6)} already spent exceeds the $${limit.toFixed(6)} rolling ceiling`\n : `exceeds the $${limit.toFixed(6)} per-call ceiling`),\n );\n this.name = \"BudgetExceededError\";\n this.kind = kind;\n this.limit = limit;\n this.spent = spent;\n this.requested = requested;\n }\n}\n\nexport class BudgetGuard {\n private readonly store: BudgetStore;\n\n constructor(private readonly config: BudgetConfig) {\n this.store = config.store ?? new InMemoryBudgetStore();\n }\n\n /** Throws BudgetExceededError if `requested` would breach the per-call ceiling\n * or push the rolling total past its ceiling. Call before firing the request.\n * Async because a persistent store may be I/O-backed. */\n async check(requested: number): Promise<void> {\n const { perCallUsd, rollingUsd } = this.config;\n if (perCallUsd !== undefined && requested > perCallUsd) {\n throw new BudgetExceededError(\"per-call\", perCallUsd, await this.store.getSpent(), requested);\n }\n if (rollingUsd !== undefined) {\n const spent = await this.store.getSpent();\n if (spent + requested > rollingUsd) {\n throw new BudgetExceededError(\"rolling\", rollingUsd, spent, requested);\n }\n }\n }\n\n /** Add an actual cost to the running total (after a successful call). */\n async record(actual: number): Promise<void> {\n await this.store.addSpent(actual);\n }\n\n async totalSpent(): Promise<number> {\n return this.store.getSpent();\n }\n}\n","// Vision capability helper. The client owns orchestration (tier/budget/sink);\n// this module owns the vision-specific message shaping so it's unit-testable and\n// the capabilities/ layout stays meaningful. Default tier: \"vision\".\nimport type { VisionInput } from \"../schema/inputs.js\";\nimport type { Message, Tier } from \"../types.js\";\n\nexport const VISION_DEFAULT_TIER: Tier = \"vision\";\n\n/** Build the single-user multimodal message (text + image) for a vision call. */\nexport function buildVisionMessages(input: VisionInput): Message[] {\n return [\n {\n role: \"user\",\n content: [\n { type: \"text\", text: input.prompt },\n { type: \"image\", image: input.image, mimeType: input.mimeType },\n ],\n },\n ];\n}\n","// Video Vision capability (F019). Like vision, but the multimodal part is a\n// video the model watches natively (Gemini, OpenRouter video models). The client\n// owns orchestration; this module owns the message shaping. Default tier: \"video\".\nimport type { VideoInput } from \"../schema/inputs.js\";\nimport type { Message, Tier } from \"../types.js\";\n\nexport const VIDEO_DEFAULT_TIER: Tier = \"video\";\n\n/** Build the single-user message (video + prompt) for a video-analysis call. */\nexport function buildVideoMessages(input: VideoInput): Message[] {\n return [\n {\n role: \"user\",\n content: [\n { type: \"video\", video: input.video, mimeType: input.mimeType },\n { type: \"text\", text: input.prompt },\n ],\n },\n ];\n}\n","// Translate capability helper. A thin prompt-contract on top of chat — the\n// client orchestrates (tier/budget/sink); this builds the messages. Default\n// tier: \"fast\". Returns the translation only, no preamble.\nimport type { TranslateInput } from \"../schema/inputs.js\";\nimport type { Message, Tier } from \"../types.js\";\n\nexport const TRANSLATE_DEFAULT_TIER: Tier = \"fast\";\n\nconst TRANSLATE_SYSTEM =\n \"You are a translation engine. Translate the user's text only. \" +\n \"Return the translation and nothing else — no preamble, no quotes.\";\n\nexport function buildTranslateMessages(input: TranslateInput): Message[] {\n const fromClause = input.from ? ` from ${input.from}` : \"\";\n return [\n { role: \"system\", content: TRANSLATE_SYSTEM },\n { role: \"user\", content: `Translate${fromClause} to ${input.to}:\\n\\n${input.text}` },\n ];\n}\n","// Embedding capability marker. The client orchestrates; this names the default\n// tier (OpenAI text-embedding-3-small via the embedding tier).\nimport type { Tier } from \"../types.js\";\n\nexport const EMBEDDING_DEFAULT_TIER: Tier = \"embedding\";\n","// Transcribe capability. No tier in the tier map (provider-specific, like image)\n// — defaults to OpenAI Whisper, overridable per call. Synergy: cctalk Danish\n// dictation. costUsd is 0 for v1 (Whisper is priced per minute, not per token).\nimport type { TierSpec } from \"../types.js\";\n\nexport const DEFAULT_TRANSCRIBE_SPEC: TierSpec = {\n provider: \"openai\",\n model: \"whisper-1\",\n transport: \"http\",\n};\n\n/** Fetch a URL to raw bytes; pass through bytes unchanged. */\nexport async function resolveAudio(\n audio: string | Uint8Array,\n fetchImpl: typeof fetch = fetch,\n): Promise<Uint8Array> {\n if (typeof audio !== \"string\") return audio;\n if (!/^https?:\\/\\//.test(audio)) {\n throw new Error(\"transcribe: string audio must be an http(s) URL (or pass raw bytes)\");\n }\n const res = await fetchImpl(audio);\n if (!res.ok) throw new Error(`transcribe: failed to fetch audio (${res.status})`);\n return new Uint8Array(await res.arrayBuffer());\n}\n","// Prompt-contract capabilities (F5.5). Each is a fixed system prompt over\n// chat/vision; extract adds Zod output validation with one retry. Exposed as\n// ai.contracts.* — built from the client so budget/cost tracking apply.\nimport type { AiClient, VisionInput } from \"../../schema/inputs.js\";\nimport type {\n Contracts,\n MockupInput,\n MockupResult,\n DesignInput,\n DesignResult,\n ExtractInput,\n ExtractResult,\n ClassifyInput,\n ClassifyResult,\n RerankInput,\n RerankResult,\n} from \"./types.js\";\n\n/** Pull the first JSON value out of a model reply (tolerates ```json fences + prose). */\nexport function parseJsonLoose(text: string): unknown {\n const fenced = text.replace(/```(?:json)?/gi, \"\").trim();\n const start = fenced.search(/[[{]/);\n if (start === -1) throw new Error(\"no JSON found in model output\");\n const slice = fenced.slice(start);\n // Walk back from the end to the matching closing bracket.\n const lastObj = slice.lastIndexOf(\"}\");\n const lastArr = slice.lastIndexOf(\"]\");\n const end = Math.max(lastObj, lastArr);\n return JSON.parse(slice.slice(0, end + 1));\n}\n\ntype ChatVision = Pick<AiClient, \"chat\" | \"vision\">;\n\nexport function makeContracts(client: ChatVision): Contracts {\n return {\n async mockup(input: MockupInput): Promise<MockupResult> {\n const constraints = input.constraints ? `\\n\\nConstraints:\\n${input.constraints}` : \"\";\n const res = await client.chat({\n system:\n \"You are a UI mockup generator. Output a single self-contained HTML document \" +\n \"using Tailwind CSS utility classes. Return ONLY the HTML — no markdown, no prose.\",\n prompt: `Build a UI mockup for:\\n${input.description}${constraints}`,\n tier: input.tier ?? \"smart\",\n purpose: input.purpose ?? \"contract:mockup\",\n });\n return { html: res.text, usage: res.usage };\n },\n\n async design(input: DesignInput): Promise<DesignResult> {\n const res = await client.vision({\n image: input.screenshot as VisionInput[\"image\"],\n prompt:\n \"You are a design-iteration engine. Given this screenshot, apply the instructions \" +\n `and return a single self-contained HTML document (Tailwind), ONLY the HTML.\\n\\n` +\n `Instructions:\\n${input.instructions}`,\n tier: input.tier ?? \"powerful\",\n purpose: input.purpose ?? \"contract:design\",\n });\n return { html: res.text, usage: res.usage };\n },\n\n async extract<T>(input: ExtractInput<T>): Promise<ExtractResult<T>> {\n const base =\n \"You are a structured-data extractor. Extract the requested data from the text and \" +\n \"return ONLY valid JSON — no markdown, no prose.\" +\n (input.instructions ? `\\n\\n${input.instructions}` : \"\");\n const run = async (reinforce: boolean) => {\n const res = await client.chat({\n system: reinforce ? `${base}\\n\\nYour previous output was not valid JSON. Return ONLY parseable JSON.` : base,\n prompt: input.text,\n tier: input.tier ?? \"smart\",\n purpose: input.purpose ?? \"contract:extract\",\n });\n return res;\n };\n let res = await run(false);\n try {\n return { data: input.schema.parse(parseJsonLoose(res.text)), usage: res.usage };\n } catch {\n // one retry with reinforcement\n res = await run(true);\n return { data: input.schema.parse(parseJsonLoose(res.text)), usage: res.usage };\n }\n },\n\n async classify(input: ClassifyInput): Promise<ClassifyResult> {\n const res = await client.chat({\n system:\n \"You are a zero-shot classifier. Choose exactly one label from the provided list. \" +\n 'Return ONLY JSON: {\"label\": \"<one of the labels>\", \"confidence\": <0..1>}.',\n prompt: `Labels: ${JSON.stringify(input.labels)}\\n\\nText:\\n${input.text}`,\n tier: input.tier ?? \"cheap\",\n purpose: input.purpose ?? \"contract:classify\",\n });\n const parsed = parseJsonLoose(res.text) as { label?: string; confidence?: number };\n const label = input.labels.includes(parsed.label ?? \"\") ? parsed.label! : (input.labels[0] ?? \"\");\n const confidence = typeof parsed.confidence === \"number\" ? parsed.confidence : 0;\n return { label, confidence, usage: res.usage };\n },\n\n async rerank(input: RerankInput): Promise<RerankResult> {\n const res = await client.chat({\n system:\n \"You are a relevance reranker. Score each item 0..1 for relevance to the query and \" +\n 'return ONLY JSON: [{\"item\": \"<verbatim item>\", \"score\": <0..1>}], ordered by score desc.',\n prompt: `Query: ${input.query}\\n\\nItems:\\n${JSON.stringify(input.items)}`,\n tier: input.tier ?? \"fast\",\n purpose: input.purpose ?? \"contract:rerank\",\n });\n const raw = parseJsonLoose(res.text) as { item?: string; score?: number }[];\n const ranked = (Array.isArray(raw) ? raw : [])\n .map((r) => ({ item: String(r.item ?? \"\"), score: typeof r.score === \"number\" ? r.score : 0 }))\n .sort((a, b) => b.score - a.score);\n return { ranked, usage: res.usage };\n },\n };\n}\n","// Zod is the single source of truth for the public input shapes. The TypeScript\n// types are derived via z.infer — no hand-written interface duplicates them.\n// The client .parse()s every input at the boundary, so invalid input throws a\n// ZodError before any provider work happens.\nimport { z } from \"zod\";\nimport type {\n ProviderAdapter,\n CostSink,\n TranslateResult,\n ChatResult,\n ChatStreamEvent,\n ImageResult,\n EmbeddingResult,\n TranscribeResult,\n OcrResult,\n ModerationResult,\n PodcastResult,\n} from \"../types.js\";\nimport type { Contracts } from \"../capabilities/contracts/types.js\";\n\n// ── Reusable sub-schemas ───────────────────────────────────────────────────\n\nexport const transportSchema = z.enum([\"http\", \"subprocess\"]);\n\nexport const tierSchema = z.enum([\n \"fast\",\n \"smart\",\n \"powerful\",\n \"cheap\",\n \"vision\",\n \"video\",\n \"embedding\",\n]);\n\nexport const tierSpecSchema = z.object({\n provider: z.string(),\n model: z.string(),\n transport: transportSchema,\n});\n\nexport const toolSchema = z.object({\n name: z.string(),\n description: z.string(),\n parameters: z.record(z.unknown()),\n});\n\nexport const toolCallSchema = z.object({\n id: z.string(),\n name: z.string(),\n arguments: z.record(z.unknown()),\n});\n\nexport const contentPartSchema = z.union([\n z.object({ type: z.literal(\"text\"), text: z.string() }),\n z.object({\n type: z.literal(\"image\"),\n image: z.union([z.string(), z.instanceof(Uint8Array)]),\n mimeType: z.string().optional(),\n }),\n]);\n\nexport const messageSchema = z.object({\n role: z.enum([\"system\", \"user\", \"assistant\", \"tool\"]),\n content: z.union([z.string(), z.array(contentPartSchema)]),\n toolCalls: z.array(toolCallSchema).optional(),\n toolCallId: z.string().optional(),\n});\n\n/** Per-call options shared by every capability input. */\nconst callOptions = {\n tier: tierSchema.optional(),\n override: tierSpecSchema.partial().optional(),\n fallback: z.array(z.union([tierSchema, tierSpecSchema])).optional(),\n purpose: z.string().optional(),\n /** Consumer-defined attribution dimensions (e.g. {tenantId}) ridden into the\n * cost sink for per-tenant/per-customer cost breakdown (F011). */\n labels: z.record(z.string(), z.string()).optional(),\n} as const;\n\n// ── The 5 capability inputs ────────────────────────────────────────────────\n\nexport const chatInputSchema = z.object({\n prompt: z.string().optional(),\n messages: z.array(messageSchema).optional(),\n system: z.string().optional(),\n tools: z.array(toolSchema).optional(),\n maxTokens: z.number().int().positive().optional(),\n temperature: z.number().min(0).max(2).optional(),\n /** \"json\" requests JSON-object output (OpenAI-compatible response_format). */\n responseFormat: z.enum([\"json\", \"text\"]).optional(),\n ...callOptions,\n});\n\nexport const visionInputSchema = z.object({\n image: z.union([z.string(), z.instanceof(Uint8Array)]),\n prompt: z.string(),\n mimeType: z.string().optional(),\n ...callOptions,\n});\n\n// F019 — analyze a video natively (e.g. \"what's in the first 30s?\"). Same shape\n// as vision but with a video payload (URL, data-URL, or raw bytes).\nexport const videoInputSchema = z.object({\n video: z.union([z.string(), z.instanceof(Uint8Array)]),\n prompt: z.string(),\n mimeType: z.string().optional(),\n ...callOptions,\n});\n\nexport const translateInputSchema = z.object({\n text: z.string(),\n to: z.string(),\n from: z.string().optional(),\n ...callOptions,\n});\n\nexport const imageInputSchema = z.object({\n prompt: z.string(),\n width: z.number().int().positive().optional(),\n height: z.number().int().positive().optional(),\n ...callOptions,\n});\n\nexport const embeddingInputSchema = z.object({\n text: z.union([z.string(), z.array(z.string())]),\n ...callOptions,\n});\n\nexport const transcribeInputSchema = z.object({\n /** Audio URL or raw bytes. */\n audio: z.union([z.string(), z.instanceof(Uint8Array)]),\n language: z.string().optional(),\n /** Audio length in seconds — enables Whisper per-minute cost. */\n durationSec: z.number().positive().optional(),\n ...callOptions,\n});\n\n// OCR (F016.2) — document/image → structured markdown text, billed per page.\nexport const ocrInputSchema = z.object({\n /** A URL, data-URL, or raw bytes of the document/image. */\n document: z.union([z.string(), z.instanceof(Uint8Array)]),\n /** image/* → routed as an image; anything else → a document (PDF etc.). */\n mimeType: z.string().optional(),\n ...callOptions,\n});\n\n// Moderation (F016.4) — classify text against safety categories, billed per token.\nexport const moderationInputSchema = z.object({\n input: z.union([z.string(), z.array(z.string())]),\n ...callOptions,\n});\n\n// Podcast (F020) — a finished manuscript (speaker turns) + a speaker→voiceId map →\n// one finished multi-voice audio episode (ElevenLabs Text-to-Dialogue).\nexport const podcastInputSchema = z.object({\n script: z.array(z.object({ speaker: z.string(), text: z.string() })).min(1),\n voices: z.record(z.string(), z.string()),\n format: z.string().optional(),\n ...callOptions,\n});\n\n// Single-voice TTS (F020.4) — text → audio. `voice` is a curated name or a voiceId.\nexport const ttsInputSchema = z.object({\n text: z.string(),\n voice: z.string(),\n ...callOptions,\n});\n\n// ── Client config ──────────────────────────────────────────────────────────\n\nexport const budgetSchema = z.object({\n perCallUsd: z.number().positive().optional(),\n rollingUsd: z.number().positive().optional(),\n});\n\nexport const aiConfigSchema = z.object({\n defaults: z.record(tierSchema, tierSpecSchema).optional(),\n // Functions can't be deeply validated — z.custom asserts the TS type and\n // passes the value through untouched.\n providers: z.record(z.string(), z.custom<ProviderAdapter>()).optional(),\n costSink: z.custom<CostSink>().optional(),\n budget: budgetSchema.optional(),\n});\n\n// ── Derived types (z.infer is the single source) ───────────────────────────\n\nexport type ChatInput = z.infer<typeof chatInputSchema>;\nexport type VisionInput = z.infer<typeof visionInputSchema>;\nexport type VideoInput = z.infer<typeof videoInputSchema>;\nexport type TranslateInput = z.infer<typeof translateInputSchema>;\nexport type ImageInput = z.infer<typeof imageInputSchema>;\nexport type EmbeddingInput = z.infer<typeof embeddingInputSchema>;\nexport type TranscribeInput = z.infer<typeof transcribeInputSchema>;\nexport type OcrInput = z.infer<typeof ocrInputSchema>;\nexport type ModerationInput = z.infer<typeof moderationInputSchema>;\nexport type PodcastInput = z.infer<typeof podcastInputSchema>;\nexport type TtsInput = z.infer<typeof ttsInputSchema>;\nexport type AiConfig = z.infer<typeof aiConfigSchema>;\n\n/** The public facade. Defined here because it depends on the derived inputs. */\nexport interface AiClient {\n chat(input: ChatInput): Promise<ChatResult>;\n /** Streaming chat (F8) — same input as chat; yields ChatStreamEvents. The\n * caller owns the tool-loop (per-turn engine, not an agent runtime). */\n chatStream(input: ChatInput): AsyncIterable<ChatStreamEvent>;\n vision(input: VisionInput): Promise<ChatResult>;\n /** Video Vision (F019) — analyze a video natively. Default tier: \"video\". */\n video(input: VideoInput): Promise<ChatResult>;\n translate(input: TranslateInput): Promise<TranslateResult>;\n image(input: ImageInput): Promise<ImageResult>;\n embedding(input: EmbeddingInput): Promise<EmbeddingResult>;\n transcribe(input: TranscribeInput): Promise<TranscribeResult>;\n /** OCR (F016.2) — document/image → structured markdown, billed per page. Mistral. */\n ocr(input: OcrInput): Promise<OcrResult>;\n /** Moderation (F016.4) — classify text against safety categories. Mistral. */\n moderate(input: ModerationInput): Promise<ModerationResult>;\n /** Podcast (F020) — a finished manuscript → one multi-voice audio episode. ElevenLabs. */\n podcast(input: PodcastInput): Promise<PodcastResult>;\n /** Single-voice TTS (F020.4) — text → audio. `voice` = curated name or voiceId. ElevenLabs. */\n tts(input: TtsInput): Promise<PodcastResult>;\n /** Prompt-contract capabilities (F5.5) layered on chat/vision. */\n contracts: Contracts;\n}\n","// createAI() — the facade factory. Resolves routing, picks a provider adapter,\n// delegates the call, stamps call-context metadata onto Usage, and reports to the\n// cost sink. Provider specifics live in adapters; cost compute/budget land in F3.\nimport { resolveTier } from \"./routing/tier-map.js\";\nimport { defaultProviders } from \"./providers/registry.js\";\nimport { computeCost } from \"./cost/usage.js\";\nimport { BudgetGuard } from \"./cost/budget.js\";\nimport { buildVisionMessages, VISION_DEFAULT_TIER } from \"./capabilities/vision.js\";\nimport { buildVideoMessages, VIDEO_DEFAULT_TIER } from \"./capabilities/video.js\";\nimport { buildTranslateMessages, TRANSLATE_DEFAULT_TIER } from \"./capabilities/translate.js\";\nimport { EMBEDDING_DEFAULT_TIER } from \"./capabilities/embedding.js\";\nimport { DEFAULT_TRANSCRIBE_SPEC, resolveAudio } from \"./capabilities/transcribe.js\";\nimport { makeContracts } from \"./capabilities/contracts/index.js\";\nimport { resolveVoice } from \"./providers/elevenlabs.js\";\nimport {\n aiConfigSchema,\n chatInputSchema,\n visionInputSchema,\n videoInputSchema,\n translateInputSchema,\n imageInputSchema,\n embeddingInputSchema,\n transcribeInputSchema,\n ocrInputSchema,\n moderationInputSchema,\n podcastInputSchema,\n ttsInputSchema,\n} from \"./schema/inputs.js\";\nimport type {\n AiConfig,\n AiClient,\n ChatInput,\n VisionInput,\n VideoInput,\n TranslateInput,\n ImageInput,\n EmbeddingInput,\n TranscribeInput,\n OcrInput,\n ModerationInput,\n PodcastInput,\n TtsInput,\n} from \"./schema/inputs.js\";\nimport type {\n ChatResult,\n ChatStreamEvent,\n ImageResult,\n EmbeddingResult,\n TranscribeResult,\n OcrResult,\n ModerationResult,\n PodcastResult,\n TranslateResult,\n ProviderAdapter,\n Message,\n Capability,\n Tier,\n TierSpec,\n Usage,\n} from \"./types.js\";\n\n/** Built-in image route (no image tier in the tier map — fal owns its routing). */\nconst DEFAULT_IMAGE_SPEC: TierSpec = {\n provider: \"fal\",\n model: \"fal-ai/flux/schnell\",\n transport: \"http\",\n};\n\n/** OCR + moderation are Mistral specialty endpoints (F016) — no tier, route by default. */\nconst DEFAULT_OCR_SPEC: TierSpec = { provider: \"mistral\", model: \"mistral-ocr-latest\", transport: \"http\" };\nconst DEFAULT_MODERATION_SPEC: TierSpec = { provider: \"mistral\", model: \"mistral-moderation-latest\", transport: \"http\" };\n/** Podcast route (F020) — ElevenLabs Text-to-Dialogue, eleven_v3 (multi-voice, multilingual). */\nconst DEFAULT_PODCAST_SPEC: TierSpec = { provider: \"elevenlabs\", model: \"eleven_v3\", transport: \"http\" };\n/** Single-voice TTS route (F020.4) — ElevenLabs eleven_multilingual_v2 (good Danish). */\nconst DEFAULT_TTS_SPEC: TierSpec = { provider: \"elevenlabs\", model: \"eleven_multilingual_v2\", transport: \"http\" };\n\nexport function createAI(config: AiConfig = {}): AiClient {\n // Validate config at the boundary (throws ZodError on bad shape).\n const cfg = aiConfigSchema.parse(config);\n const providers = cfg.providers ?? defaultProviders;\n const budget = cfg.budget ? new BudgetGuard(cfg.budget) : undefined;\n\n const estTokens = (s: string): number => Math.ceil(s.length / 4);\n\n /** Pre-flight budget check. Estimates this call's cost and throws\n * BudgetExceededError before the transport fires. No-op without a budget. */\n async function preflight(spec: TierSpec, estInTokens: number, estOutTokens: number): Promise<void> {\n if (!budget) return;\n await budget.check(computeCost(spec.provider, spec.model, estInTokens, estOutTokens));\n }\n\n /** Fold the actual cost into the rolling total after a successful call. */\n async function settle(usage: Usage): Promise<void> {\n if (budget) await budget.record(usage.costUsd);\n }\n\n function pickProvider(name: string): ProviderAdapter {\n const adapter = providers[name];\n if (!adapter) {\n throw new Error(\n `createAI: no provider adapter registered for \"${name}\". Registered: ${Object.keys(providers).join(\", \") || \"(none)\"}`,\n );\n }\n return adapter;\n }\n\n /** Stamp call-context metadata the client owns onto the adapter's Usage:\n * capability, tier, purpose, the wall-clock latency, and the timestamp. */\n function enrich(\n usage: Usage,\n capability: Capability,\n tier: Tier | undefined,\n purpose: string | undefined,\n latencyMs: number,\n labels: Record<string, string> | undefined,\n ): Usage {\n usage.capability = capability;\n if (tier) usage.tier = tier;\n if (purpose) usage.purpose = purpose;\n if (labels && Object.keys(labels).length > 0) usage.labels = labels;\n usage.latencyMs = Math.round(latencyMs);\n if (!usage.ts) usage.ts = new Date().toISOString();\n return usage;\n }\n\n async function report(usage: Usage): Promise<void> {\n if (!cfg.costSink) return;\n try {\n await cfg.costSink.record(usage);\n } catch {\n // A broken sink must never crash a real AI call (F3.3 invariant).\n }\n }\n\n function toMessages(input: ChatInput): Message[] {\n if (input.messages && input.messages.length > 0) return input.messages;\n const msgs: Message[] = [];\n if (input.system) msgs.push({ role: \"system\", content: input.system });\n msgs.push({ role: \"user\", content: input.prompt ?? \"\" });\n return msgs;\n }\n\n /** Run a capability with an optional fallback chain. Tries the primary route,\n * then each fallback (Tier or TierSpec) in order if the call errors. A budget\n * breach propagates immediately (not a fallback trigger). On the first\n * success: stamp Usage, settle the budget, report to the sink, return. */\n async function runCapability<R extends { usage: Usage }>(opts: {\n primary: TierSpec;\n fallback?: (Tier | TierSpec)[];\n capability: Capability;\n tier?: Tier;\n purpose?: string;\n labels?: Record<string, string>;\n estIn: number;\n estOut: number;\n invoke: (spec: TierSpec) => Promise<R>;\n }): Promise<R> {\n const routes: TierSpec[] = [\n opts.primary,\n ...(opts.fallback ?? []).map((f) =>\n typeof f === \"string\" ? resolveTier(f, undefined, cfg.defaults) : f,\n ),\n ];\n let lastErr: unknown;\n for (let i = 0; i < routes.length; i++) {\n const spec = routes[i]!;\n await preflight(spec, opts.estIn, opts.estOut); // BudgetExceededError propagates\n try {\n const t0 = performance.now();\n const res = await opts.invoke(spec);\n enrich(res.usage, opts.capability, i === 0 ? opts.tier : undefined, opts.purpose, performance.now() - t0, opts.labels);\n await settle(res.usage);\n await report(res.usage);\n return res;\n } catch (e) {\n lastErr = e; // try the next fallback route\n }\n }\n throw lastErr;\n }\n\n /** Whether a pre-first-token streaming error should fall back to the next\n * route. Eligible: network/timeout/parse (no status) + 429 + 5xx. Hard 4xx\n * bubbles up (no silent re-route) — sa contract #2565. */\n function eligibleForFallback(e: unknown): boolean {\n const status = (e as { status?: number } | null)?.status;\n if (status === undefined) return true;\n return status === 429 || status >= 500;\n }\n\n function errorEvent(e: unknown): ChatStreamEvent {\n const ev: ChatStreamEvent = {\n type: \"error\",\n message: e instanceof Error ? e.message : String(e),\n };\n const status = (e as { status?: number } | null)?.status;\n if (status !== undefined) ev.status = status;\n return ev;\n }\n\n /** Streaming chat with pre-stream fallback (F8.1). Yields ChatStreamEvents as\n * the turn unfolds. Fallback re-routes only BEFORE the first text/tool_call\n * event (deltas can't be un-emitted); once streaming has begun, an error is\n * surfaced as an error event and the stream ends. Budget breaches propagate. */\n async function* chatStreamImpl(input: ChatInput): AsyncIterable<ChatStreamEvent> {\n input = chatInputSchema.parse(input);\n const tier = input.tier ?? \"smart\";\n const messages = toMessages(input);\n const estIn = messages.reduce(\n (n, m) => n + estTokens(typeof m.content === \"string\" ? m.content : JSON.stringify(m.content)),\n 0,\n );\n const estOut = input.maxTokens ?? 512;\n const routes: TierSpec[] = [\n resolveTier(tier, input.override, cfg.defaults),\n ...(input.fallback ?? []).map((f) =>\n typeof f === \"string\" ? resolveTier(f, undefined, cfg.defaults) : f,\n ),\n ];\n\n let lastErr: unknown;\n for (let i = 0; i < routes.length; i++) {\n const spec = routes[i]!;\n await preflight(spec, estIn, estOut); // BudgetExceededError propagates\n const adapter = pickProvider(spec.provider);\n if (!adapter.chatStream) {\n throw new Error(`createAI: provider \"${spec.provider}\" does not support streaming`);\n }\n const t0 = performance.now();\n let emitted = false;\n try {\n for await (const ev of adapter.chatStream({\n messages,\n spec,\n tools: input.tools,\n maxTokens: input.maxTokens,\n temperature: input.temperature,\n responseFormat: input.responseFormat,\n })) {\n if (ev.type === \"text\" || ev.type === \"tool_call\") emitted = true;\n if (ev.type === \"usage\") {\n enrich(ev.usage, \"chat\", i === 0 ? tier : undefined, input.purpose, performance.now() - t0, input.labels);\n await settle(ev.usage);\n await report(ev.usage);\n }\n yield ev;\n }\n return; // stream completed cleanly\n } catch (e) {\n lastErr = e;\n if (emitted || !eligibleForFallback(e)) {\n yield errorEvent(e); // mid-stream or hard error → surface + stop\n return;\n }\n // pre-first-token eligible error → try the next route\n }\n }\n yield errorEvent(lastErr);\n }\n\n const client: AiClient = {\n async chat(input: ChatInput): Promise<ChatResult> {\n input = chatInputSchema.parse(input);\n const tier = input.tier ?? \"smart\";\n const messages = toMessages(input);\n const estIn = messages.reduce(\n (n, m) => n + estTokens(typeof m.content === \"string\" ? m.content : JSON.stringify(m.content)),\n 0,\n );\n return runCapability({\n primary: resolveTier(tier, input.override, cfg.defaults),\n fallback: input.fallback,\n capability: \"chat\",\n tier,\n purpose: input.purpose,\n labels: input.labels,\n estIn,\n estOut: input.maxTokens ?? 512,\n invoke: async (spec) => {\n const adapter = pickProvider(spec.provider);\n if (!adapter.chat) throw new Error(`createAI: provider \"${spec.provider}\" does not support chat`);\n return adapter.chat({ messages, spec, tools: input.tools, maxTokens: input.maxTokens, temperature: input.temperature, responseFormat: input.responseFormat });\n },\n });\n },\n\n chatStream: chatStreamImpl,\n\n async vision(input: VisionInput): Promise<ChatResult> {\n input = visionInputSchema.parse(input);\n const tier = input.tier ?? VISION_DEFAULT_TIER;\n const messages: Message[] = buildVisionMessages(input);\n return runCapability({\n primary: resolveTier(tier, input.override, cfg.defaults),\n fallback: input.fallback,\n capability: \"vision\",\n tier,\n purpose: input.purpose,\n labels: input.labels,\n estIn: estTokens(input.prompt) + 1000, // prompt + ~1k image payload\n estOut: 512,\n invoke: async (spec) => {\n const adapter = pickProvider(spec.provider);\n if (!adapter.vision) throw new Error(`createAI: provider \"${spec.provider}\" does not support vision`);\n return adapter.vision({ messages, spec });\n },\n });\n },\n\n async video(input: VideoInput): Promise<ChatResult> {\n input = videoInputSchema.parse(input);\n const tier = input.tier ?? VIDEO_DEFAULT_TIER;\n const messages: Message[] = buildVideoMessages(input);\n return runCapability({\n primary: resolveTier(tier, input.override, cfg.defaults),\n fallback: input.fallback,\n capability: \"video\",\n tier,\n purpose: input.purpose,\n labels: input.labels,\n estIn: estTokens(input.prompt) + 4000, // prompt + video tokens (native video ≈ frames)\n estOut: 512,\n invoke: async (spec) => {\n const adapter = pickProvider(spec.provider);\n // Video routes through the vision method — same multimodal message path.\n if (!adapter.vision) throw new Error(`createAI: provider \"${spec.provider}\" does not support video`);\n return adapter.vision({ messages, spec });\n },\n });\n },\n\n async translate(input: TranslateInput): Promise<TranslateResult> {\n input = translateInputSchema.parse(input);\n const tier = input.tier ?? TRANSLATE_DEFAULT_TIER;\n const messages: Message[] = buildTranslateMessages(input);\n const estIn = estTokens(input.text) + 40;\n const res = await runCapability<ChatResult>({\n primary: resolveTier(tier, input.override, cfg.defaults),\n fallback: input.fallback,\n capability: \"translate\",\n tier,\n purpose: input.purpose,\n labels: input.labels,\n estIn,\n estOut: estIn,\n invoke: async (spec) => {\n const adapter = pickProvider(spec.provider);\n if (!adapter.chat) throw new Error(`createAI: provider \"${spec.provider}\" does not support chat (translate routes through chat)`);\n return adapter.chat({ messages, spec });\n },\n });\n return { text: res.text, usage: res.usage };\n },\n\n async image(input: ImageInput): Promise<ImageResult> {\n input = imageInputSchema.parse(input);\n return runCapability({\n primary: { ...DEFAULT_IMAGE_SPEC, ...input.override },\n fallback: input.fallback,\n capability: \"image\",\n purpose: input.purpose,\n labels: input.labels,\n estIn: 0, // image cost is not token-based\n estOut: 0,\n invoke: async (spec) => {\n const adapter = pickProvider(spec.provider);\n if (!adapter.image) throw new Error(`createAI: provider \"${spec.provider}\" does not support image`);\n return adapter.image({ prompt: input.prompt, spec, width: input.width, height: input.height });\n },\n });\n },\n\n async ocr(input: OcrInput): Promise<OcrResult> {\n input = ocrInputSchema.parse(input);\n return runCapability({\n primary: { ...DEFAULT_OCR_SPEC, ...input.override },\n fallback: input.fallback,\n capability: \"ocr\",\n purpose: input.purpose,\n labels: input.labels,\n estIn: 0, // OCR cost is per-page, not token-based\n estOut: 0,\n invoke: async (spec) => {\n const adapter = pickProvider(spec.provider);\n if (!adapter.ocr) throw new Error(`createAI: provider \"${spec.provider}\" does not support ocr`);\n return adapter.ocr({ document: input.document, mimeType: input.mimeType, spec });\n },\n });\n },\n\n async moderate(input: ModerationInput): Promise<ModerationResult> {\n input = moderationInputSchema.parse(input);\n const items = Array.isArray(input.input) ? input.input : [input.input];\n return runCapability({\n primary: { ...DEFAULT_MODERATION_SPEC, ...input.override },\n fallback: input.fallback,\n capability: \"moderation\",\n purpose: input.purpose,\n labels: input.labels,\n estIn: items.reduce((n, s) => n + estTokens(s), 0),\n estOut: 0,\n invoke: async (spec) => {\n const adapter = pickProvider(spec.provider);\n if (!adapter.moderate) throw new Error(`createAI: provider \"${spec.provider}\" does not support moderation`);\n return adapter.moderate({ input: items, spec });\n },\n });\n },\n\n async podcast(input: PodcastInput): Promise<PodcastResult> {\n input = podcastInputSchema.parse(input);\n // Map each manuscript turn to a {text, voiceId} dialogue input.\n const inputs = input.script.map((turn) => {\n const mapped = input.voices[turn.speaker];\n if (!mapped) throw new Error(`ai.podcast: no voice mapped for speaker \"${turn.speaker}\"`);\n return { text: turn.text, voiceId: resolveVoice(mapped) }; // curated name → voiceId\n });\n const chars = input.script.reduce((n, t) => n + t.text.length, 0);\n return runCapability({\n primary: { ...DEFAULT_PODCAST_SPEC, ...input.override },\n fallback: input.fallback,\n capability: \"podcast\",\n purpose: input.purpose,\n labels: input.labels,\n estIn: chars, // per-character cost (not token-based)\n estOut: 0,\n invoke: async (spec) => {\n const adapter = pickProvider(spec.provider);\n if (!adapter.dialogue) throw new Error(`createAI: provider \"${spec.provider}\" does not support podcast/dialogue`);\n return adapter.dialogue({ inputs, format: input.format, spec });\n },\n });\n },\n\n async tts(input: TtsInput): Promise<PodcastResult> {\n input = ttsInputSchema.parse(input);\n return runCapability({\n primary: { ...DEFAULT_TTS_SPEC, ...input.override },\n fallback: input.fallback,\n capability: \"tts\",\n purpose: input.purpose,\n labels: input.labels,\n estIn: input.text.length, // per-character cost\n estOut: 0,\n invoke: async (spec) => {\n const adapter = pickProvider(spec.provider);\n if (!adapter.tts) throw new Error(`createAI: provider \"${spec.provider}\" does not support tts`);\n return adapter.tts({ text: input.text, voiceId: resolveVoice(input.voice), spec });\n },\n });\n },\n\n async embedding(input: EmbeddingInput): Promise<EmbeddingResult> {\n input = embeddingInputSchema.parse(input);\n const tier = input.tier ?? EMBEDDING_DEFAULT_TIER;\n const text = Array.isArray(input.text) ? input.text : [input.text];\n return runCapability({\n primary: resolveTier(tier, input.override, cfg.defaults),\n fallback: input.fallback,\n capability: \"embedding\",\n tier,\n purpose: input.purpose,\n labels: input.labels,\n estIn: text.reduce((n, t) => n + estTokens(t), 0),\n estOut: 0,\n invoke: async (spec) => {\n const adapter = pickProvider(spec.provider);\n if (!adapter.embedding) throw new Error(`createAI: provider \"${spec.provider}\" does not support embedding`);\n return adapter.embedding({ input: text, spec });\n },\n });\n },\n\n async transcribe(input: TranscribeInput): Promise<TranscribeResult> {\n input = transcribeInputSchema.parse(input);\n const audio = await resolveAudio(input.audio);\n return runCapability({\n primary: { ...DEFAULT_TRANSCRIBE_SPEC, ...input.override },\n fallback: input.fallback,\n capability: \"transcribe\",\n purpose: input.purpose,\n labels: input.labels,\n estIn: 0,\n estOut: 0,\n invoke: async (spec) => {\n const adapter = pickProvider(spec.provider);\n if (!adapter.transcribe) throw new Error(`createAI: provider \"${spec.provider}\" does not support transcribe`);\n return adapter.transcribe({ audio, language: input.language, durationSec: input.durationSec, spec });\n },\n });\n },\n\n // Replaced below with the real prompt-contracts (needs the client itself).\n contracts: undefined as unknown as AiClient[\"contracts\"],\n };\n\n client.contracts = makeContracts(client);\n return client;\n}\n","// Stub provider adapters (F2.5). They satisfy ProviderAdapter so the client wires\n// up and resolves without real network calls. Real implementations land in F4\n// (anthropic/openai/gemini/openrouter/deepinfra) and F5.3 (fal image). The stub\n// usage carries zero tokens/cost — F3.1 fills real numbers in the live adapters.\nimport type {\n ProviderAdapter,\n ChatRequest,\n ChatResult,\n ImageRequest,\n ImageResult,\n EmbeddingRequest,\n EmbeddingResult,\n Usage,\n Capability,\n} from \"../types.js\";\n\nfunction stubUsage(\n provider: string,\n model: string,\n transport: \"http\" | \"subprocess\",\n capability: Capability,\n): Usage {\n return {\n provider,\n model,\n transport,\n inputTokens: 0,\n outputTokens: 0,\n cacheReadTokens: 0,\n cacheCreationTokens: 0,\n costUsd: 0,\n latencyMs: 0,\n capability,\n // ts is supplied by the caller-side at real call time; stub uses a fixed marker\n // ('' avoids Date.now() — keeps the stub pure/deterministic for tests).\n ts: \"\",\n };\n}\n\nfunction lastUserText(req: ChatRequest): string {\n for (let i = req.messages.length - 1; i >= 0; i--) {\n const m = req.messages[i];\n if (m && m.role === \"user\") {\n return typeof m.content === \"string\"\n ? m.content\n : m.content.map((p) => (p.type === \"text\" ? p.text : \"[image]\")).join(\" \");\n }\n }\n return \"\";\n}\n\n/** Anthropic adapter stub (HTTP path). */\nexport const anthropicApiAdapter: ProviderAdapter = {\n name: \"anthropic\",\n async chat(req: ChatRequest): Promise<ChatResult> {\n return {\n text: `[stub:anthropic-api] ${lastUserText(req)}`,\n usage: stubUsage(\"anthropic\", req.spec.model, \"http\", \"chat\"),\n };\n },\n async vision(req: ChatRequest): Promise<ChatResult> {\n return {\n text: `[stub:anthropic-api:vision] ${lastUserText(req)}`,\n usage: stubUsage(\"anthropic\", req.spec.model, \"http\", \"vision\"),\n };\n },\n};\n\n/** Anthropic adapter stub (subprocess / `claude -p` path). */\nexport const anthropicSubprocessAdapter: ProviderAdapter = {\n name: \"anthropic\",\n async chat(req: ChatRequest): Promise<ChatResult> {\n const usage = stubUsage(\"anthropic\", req.spec.model, \"subprocess\", \"chat\");\n usage.subprocess = true;\n return { text: `[stub:anthropic-subprocess] ${lastUserText(req)}`, usage };\n },\n};\n\n/** OpenAI adapter stub — covers the embedding default tier + a chat fallback. */\nexport const openaiStubAdapter: ProviderAdapter = {\n name: \"openai\",\n async chat(req: ChatRequest): Promise<ChatResult> {\n return {\n text: `[stub:openai] ${lastUserText(req)}`,\n usage: stubUsage(\"openai\", req.spec.model, \"http\", \"chat\"),\n };\n },\n async embedding(req: EmbeddingRequest): Promise<EmbeddingResult> {\n return {\n vectors: req.input.map(() => [0, 0, 0]),\n usage: stubUsage(\"openai\", req.spec.model, \"http\", \"embedding\"),\n };\n },\n};\n\n/** fal.ai adapter stub — image generation (real one in fal.ts, F5.3). */\nexport const falStubAdapter: ProviderAdapter = {\n name: \"fal\",\n async image(req: ImageRequest): Promise<ImageResult> {\n return {\n url: `https://stub.fal/${encodeURIComponent(req.prompt).slice(0, 32)}.png`,\n usage: stubUsage(\"fal\", req.spec.model, \"http\", \"image\"),\n };\n },\n};\n\n/** Stub provider registry — deterministic, no network. Used by tests via\n * createAI({ providers: stubProviders }). The real default registry (registry.ts)\n * wires the live adapters. */\nexport const stubProviders: Record<string, ProviderAdapter> = {\n anthropic: anthropicApiAdapter,\n openai: openaiStubAdapter,\n fal: falStubAdapter,\n};\n","// AUTO-GENERATED by scripts/gen-version.mjs — do not edit, do not commit.\nexport const VERSION = \"0.8.0\" as const;\nexport const SDK_TAG = \"@broberg/ai-sdk@0.8.0\" as const;\n","// Persistent BudgetStore backed by bun:sqlite (F7.1). The rolling total survives\n// process restarts and is shared by every process pointing at the same file, so\n// a budget ceiling is a real production guard — not a per-process counter that\n// resets on deploy. bun:sqlite is imported lazily (Node-safe import, like sqliteSink).\nimport type { BudgetStore } from \"../types.js\";\n\nexport interface SqliteBudgetStoreConfig {\n /** SQLite file path, e.g. \"./ai-budget.db\". */\n dbPath: string;\n /** Window/bucket key — use e.g. a day-stamp for a daily budget. Default \"default\". */\n key?: string;\n}\n\nexport function sqliteBudgetStore(config: SqliteBudgetStoreConfig): BudgetStore {\n const key = config.key ?? \"default\";\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n let ready: Promise<any> | null = null;\n const open = async () => {\n const { Database } = await import(\"bun:sqlite\");\n const db = new Database(config.dbPath);\n db.run(\n `CREATE TABLE IF NOT EXISTS budget_spend (key TEXT PRIMARY KEY, spent_usd REAL NOT NULL DEFAULT 0)`,\n );\n return db;\n };\n\n return {\n async getSpent(): Promise<number> {\n const db = await (ready ??= open());\n const row = db\n .query(`SELECT spent_usd FROM budget_spend WHERE key = $key`)\n .get({ $key: key }) as { spent_usd: number } | null;\n return row?.spent_usd ?? 0;\n },\n async addSpent(usd: number): Promise<void> {\n const db = await (ready ??= open());\n db.run(\n `INSERT INTO budget_spend (key, spent_usd) VALUES ($key, $usd)\n ON CONFLICT(key) DO UPDATE SET spent_usd = spent_usd + $usd`,\n { $key: key, $usd: usd },\n );\n },\n };\n}\n","import type { CostSink } from \"../../types.js\";\n\n/** A sink that does nothing. The default when no costSink is configured. */\nexport const noopSink: CostSink = {\n record() {\n // intentionally empty\n },\n};\n","import type { CostSink, Usage } from \"../../types.js\";\n\n/** Fan a Usage out to several sinks. Uses allSettled so one failing sink never\n * prevents the others from recording (and never propagates to the caller). */\nexport function multiSink(sinks: CostSink[]): CostSink {\n return {\n async record(usage: Usage): Promise<void> {\n // async wrapper turns a synchronous throw in s.record into a rejected\n // promise, so allSettled isolates it (a sync throw would otherwise escape\n // the .map before allSettled ran).\n await Promise.allSettled(sinks.map(async (s) => s.record(usage)));\n },\n };\n}\n","// upmetricsSink — the canonical cost sink. Forwards each Usage to the upmetrics\n// agent-run ingest (POST /api/agent, mode:\"record\"). Field mapping follows\n// upmetrics/docs/AGENT-SCHEMA.md \"For cost-sink authors\" exactly:\n// - agent_kind / agent_name are injected (not in Usage; required by ingest)\n// - camelCase Usage → snake_case wire fields\n// - capability + transport ride in tags (no top-level column)\n// - toolCalls[].errorCount → tool_calls[].error_count (deep rename)\n// - latencyMs → duration_ms; ts → started_at; ended_at = ts + latency\n// Errors never propagate (CostSink invariant). Do NOT use @upmetrics/agent\n// wrapAnthropic here — the SDK already owns the provider call.\nimport { SDK_TAG } from \"../../version.js\";\nimport type { CostSink, Usage } from \"../../types.js\";\n\nexport interface UpmetricsSinkConfig {\n /** Ingest base URL, e.g. https://upmetrics.org */\n baseUrl: string;\n /** Per-project api_key → sent as the X-Upmetrics-Key header. */\n apiKey: string;\n /** Consumer name dashboards group by (e.g. \"cms\", \"trail\", \"xrt81\") — NOT the\n * capability. */\n agentName: string;\n /** Defaults to \"chatbot\" (\"embedding\" auto-selected for embedding calls). */\n agentKind?: string;\n /** When true, guarantees no prompt/response content is ever sent (the sink\n * sends none regardless — Usage carries no excerpts — so this is belt-and-\n * suspenders for GDPR-health projects). */\n complianceMode?: boolean;\n /** Injectable fetch for testing; defaults to global fetch. */\n fetch?: typeof fetch;\n /** Optional error hook (errors are otherwise swallowed silently). */\n onError?: (err: unknown) => void;\n}\n\nexport function upmetricsSink(config: UpmetricsSinkConfig): CostSink {\n const doFetch = config.fetch ?? fetch;\n const url = `${config.baseUrl.replace(/\\/$/, \"\")}/api/agent`;\n\n return {\n async record(usage: Usage): Promise<void> {\n try {\n const startedAt = usage.ts || new Date().toISOString();\n const endedAt = new Date(\n new Date(startedAt).getTime() + (usage.latencyMs || 0),\n ).toISOString();\n\n const agentKind =\n config.agentKind ?? (usage.capability === \"embedding\" ? \"embedding\" : \"chatbot\");\n\n const body: Record<string, unknown> = {\n mode: \"record\",\n agent_kind: agentKind,\n agent_name: config.agentName,\n provider: usage.provider,\n model: usage.model,\n status: \"success\",\n input_tokens: usage.inputTokens,\n output_tokens: usage.outputTokens,\n cache_read_tokens: usage.cacheReadTokens,\n cache_creation_tokens: usage.cacheCreationTokens,\n cost_usd: usage.costUsd,\n duration_ms: usage.latencyMs,\n started_at: startedAt,\n ended_at: endedAt,\n tags: {\n // Consumer attribution labels (e.g. tenantId) ride in tags so no new\n // top-level field risks the strict-shape ingest schema (F011). The\n // SDK-owned keys win — a label can never clobber capability/transport/sdk.\n ...usage.labels,\n capability: usage.capability,\n transport: usage.transport,\n sdk: SDK_TAG,\n },\n };\n if (usage.tier !== undefined) body.tier = usage.tier;\n if (usage.purpose !== undefined) body.purpose = usage.purpose;\n if (usage.toolCalls) {\n body.tool_calls = usage.toolCalls.map((t) => ({\n name: t.name,\n count: t.count,\n error_count: t.errorCount ?? 0,\n }));\n }\n // complianceMode is a no-op today (we never send excerpts) but documents intent.\n void config.complianceMode;\n\n const res = await doFetch(url, {\n method: \"POST\",\n headers: {\n \"content-type\": \"application/json\",\n \"X-Upmetrics-Key\": config.apiKey,\n },\n body: JSON.stringify(body),\n });\n if (!res.ok) {\n const text = await res.text().catch(() => \"\");\n config.onError?.(\n new Error(`upmetricsSink: ingest returned ${res.status}: ${text.slice(0, 200)}`),\n );\n }\n } catch (err) {\n // Never let a sink failure crash a real AI call.\n config.onError?.(err);\n }\n },\n };\n}\n","// discordSink — posts a per-call cost embed to a Discord webhook. Secondary sink\n// (upmetricsSink is canonical); handy for repos not wired to Upmetrics or for an\n// at-a-glance spend feed. Plain fetch, no Discord SDK. Errors never propagate.\nimport type { CostSink, Usage } from \"../../types.js\";\n\nexport interface DiscordSinkConfig {\n webhookUrl: string;\n /** Skip posting paid calls below this USD threshold (anti-spam). Subprocess\n * (Max-plan free) calls always post so the \"free\" feed stays visible.\n * Default 0 → post everything. */\n minUsd?: number;\n fetch?: typeof fetch;\n onError?: (err: unknown) => void;\n}\n\nexport function discordSink(config: DiscordSinkConfig): CostSink {\n const doFetch = config.fetch ?? fetch;\n const minUsd = config.minUsd ?? 0;\n\n return {\n async record(usage: Usage): Promise<void> {\n try {\n // Skip cheap PAID calls; always show subprocess (free) calls.\n if (!usage.subprocess && usage.costUsd < minUsd) return;\n\n const costLabel = usage.subprocess\n ? \"Max plan (free)\"\n : `$${usage.costUsd.toFixed(6)}`;\n\n const embed = {\n title: `AI call — ${usage.capability}`,\n fields: [\n { name: \"Provider\", value: usage.provider, inline: true },\n { name: \"Model\", value: usage.model, inline: true },\n { name: \"Transport\", value: usage.transport, inline: true },\n { name: \"Cost\", value: costLabel, inline: true },\n {\n name: \"Tokens\",\n value: `${usage.inputTokens} in / ${usage.outputTokens} out`,\n inline: true,\n },\n { name: \"Latency\", value: `${usage.latencyMs} ms`, inline: true },\n ],\n timestamp: usage.ts || new Date().toISOString(),\n };\n\n const res = await doFetch(config.webhookUrl, {\n method: \"POST\",\n headers: { \"content-type\": \"application/json\" },\n body: JSON.stringify({ embeds: [embed] }),\n });\n if (!res.ok) {\n config.onError?.(new Error(`discordSink: webhook returned ${res.status}`));\n }\n } catch (err) {\n config.onError?.(err);\n }\n },\n };\n}\n","// sqliteSink — persists every Usage to a local bun:sqlite DB. Secondary/offline\n// sink (upmetricsSink is canonical). No npm dependency — bun:sqlite is built in.\n//\n// IMPORTANT: bun:sqlite is imported LAZILY (dynamic import on first use), not at\n// module top level. A static `import \"bun:sqlite\"` would leak into the package\n// entry and crash every Node consumer (`ERR_UNSUPPORTED_ESM_URL_SCHEME`). With\n// the lazy import, importing @broberg/ai-sdk works everywhere; bun:sqlite only\n// loads when sqliteSink/getCostSummary actually run (Bun only).\nimport type { CostSink, Usage } from \"../../types.js\";\n\nexport interface SqliteSinkConfig {\n /** Path to the SQLite file, e.g. \"./ai-cost.db\" (or \":memory:\"). */\n dbPath: string;\n}\n\nconst CREATE_TABLE = `\nCREATE TABLE IF NOT EXISTS ai_usage (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n ts TEXT NOT NULL,\n provider TEXT NOT NULL,\n model TEXT NOT NULL,\n tier TEXT,\n transport TEXT NOT NULL,\n capability TEXT NOT NULL,\n purpose TEXT,\n input_tokens INTEGER NOT NULL,\n output_tokens INTEGER NOT NULL,\n cache_read_tokens INTEGER NOT NULL,\n cache_creation_tokens INTEGER NOT NULL,\n cost_usd REAL NOT NULL,\n latency_ms INTEGER NOT NULL,\n subprocess INTEGER NOT NULL DEFAULT 0\n)`;\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nasync function openDb(dbPath: string, readonly = false): Promise<any> {\n const { Database } = await import(\"bun:sqlite\");\n return new Database(dbPath, readonly ? { readonly: true } : undefined);\n}\n\nexport function sqliteSink(config: SqliteSinkConfig): CostSink {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n let ready: Promise<any> | null = null;\n const init = async () => {\n const db = await openDb(config.dbPath);\n db.run(CREATE_TABLE);\n const insert = db.prepare(\n `INSERT INTO ai_usage\n (ts, provider, model, tier, transport, capability, purpose,\n input_tokens, output_tokens, cache_read_tokens, cache_creation_tokens,\n cost_usd, latency_ms, subprocess)\n VALUES ($ts, $provider, $model, $tier, $transport, $capability, $purpose,\n $input, $output, $cacheRead, $cacheCreation, $cost, $latency, $subprocess)`,\n );\n return insert;\n };\n\n return {\n async record(usage: Usage): Promise<void> {\n const insert = await (ready ??= init());\n insert.run({\n $ts: usage.ts || new Date().toISOString(),\n $provider: usage.provider,\n $model: usage.model,\n $tier: usage.tier ?? null,\n $transport: usage.transport,\n $capability: usage.capability,\n $purpose: usage.purpose ?? null,\n $input: usage.inputTokens,\n $output: usage.outputTokens,\n $cacheRead: usage.cacheReadTokens,\n $cacheCreation: usage.cacheCreationTokens,\n $cost: usage.costUsd,\n $latency: usage.latencyMs,\n $subprocess: usage.subprocess ? 1 : 0,\n });\n },\n };\n}\n\nexport interface CostSummary {\n totalUsd: number;\n byProvider: Record<string, number>;\n byCapability: Record<string, number>;\n}\n\n/** Aggregate the recorded spend from a sqliteSink DB. Creates the table if the\n * DB has never been written to, so an empty DB summarises cleanly to 0. */\nexport async function getCostSummary(dbPath: string): Promise<CostSummary> {\n const db = await openDb(dbPath);\n db.run(CREATE_TABLE);\n const total = db\n .query(`SELECT SUM(cost_usd) AS total FROM ai_usage`)\n .get() as { total: number | null };\n const byProvider: Record<string, number> = {};\n for (const row of db\n .query(`SELECT provider, SUM(cost_usd) AS sum FROM ai_usage GROUP BY provider`)\n .all() as { provider: string; sum: number }[]) {\n byProvider[row.provider] = row.sum;\n }\n const byCapability: Record<string, number> = {};\n for (const row of db\n .query(`SELECT capability, SUM(cost_usd) AS sum FROM ai_usage GROUP BY capability`)\n .all() as { capability: string; sum: number }[]) {\n byCapability[row.capability] = row.sum;\n }\n return { totalUsd: total?.total ?? 0, byProvider, byCapability };\n}\n"],"mappings":"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","names":["url","data","res"]}