@jambonz/llm 0.6.8 → 0.6.9

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.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/registry.ts","../src/adapters/openai/adapter.ts","../src/validate.ts","../src/adapters/openai/_streaming.ts","../src/adapters/_metadata.ts","../src/adapters/openai/manifest.ts","../src/adapters/openai/factory.ts","../src/adapters/anthropic/adapter.ts","../src/adapters/anthropic/manifest.ts","../src/adapters/anthropic/factory.ts","../src/adapters/google/adapter.ts","../src/adapters/google/_streaming.ts","../src/adapters/google/manifest.ts","../src/adapters/google/factory.ts","../src/adapters/vertex-gemini/adapter.ts","../src/adapters/vertex-gemini/manifest.ts","../src/adapters/vertex-gemini/factory.ts","../src/adapters/vertex-openai/adapter.ts","../src/adapters/vertex-openai/manifest.ts","../src/adapters/vertex-openai/factory.ts","../src/adapters/bedrock/adapter.ts","../src/adapters/bedrock/manifest.ts","../src/adapters/bedrock/factory.ts","../src/adapters/azure-openai/adapter.ts","../src/adapters/azure-openai/manifest.ts","../src/adapters/azure-openai/factory.ts","../src/adapters/groq/manifest.ts","../src/adapters/groq/adapter.ts","../src/adapters/groq/factory.ts","../src/adapters/huggingface/manifest.ts","../src/adapters/huggingface/adapter.ts","../src/adapters/huggingface/factory.ts","../src/adapters/openrouter/manifest.ts","../src/adapters/openrouter/adapter.ts","../src/adapters/openrouter/factory.ts","../src/vendors/harness.ts","../src/adapters/index.ts","../src/normalize-auth.ts","../src/pick-auth-kind.ts"],"sourcesContent":["/**\n * @jambonz/llm — voice-oriented LLM adapter library.\n *\n * Public entry point. Importing this module auto-registers all bundled adapters\n * via the side-effectful import of `./adapters/index.js`.\n *\n * Consumers use:\n * - `createLlm({vendor, auth, client?})` to get a ready-to-stream adapter instance.\n * - `getManifest()` to enumerate registered vendors (used by api-server).\n * - `getVendorManifest(vendor)` for one vendor's manifest, including\n * credential-only vendors (e.g. `harness`) that have no adapter.\n * - `normalizeAuth(vendor, rawCred)` to convert DB-shape creds to AuthSpec.\n * - `pickAuthKind(vendor, rawCred)` to pick the right manifest authKind for\n * a raw credential (used by api-server's `encryptCredential`).\n * - `registerAdapter(factory)` to add a custom adapter at runtime.\n */\n\n// Side effect: register all bundled adapters. Must come first.\nimport './adapters/index.js';\n\nimport { getAdapterFactory } from './registry.js';\nimport type {\n AuthSpec,\n CreateLlmArgs,\n LlmAdapter,\n} from './types.js';\n\nexport async function createLlm<A extends AuthSpec = AuthSpec>(\n args: CreateLlmArgs<A>,\n): Promise<LlmAdapter<A>> {\n const factory = getAdapterFactory<A>(args.vendor);\n if (!factory.manifest.authKinds.some((k) => k.kind === args.auth.kind)) {\n const accepted = factory.manifest.authKinds.map((k) => k.kind).join(', ');\n throw new Error(\n `Vendor '${args.vendor}' does not accept auth kind '${args.auth.kind}'. ` +\n `Accepted kinds: ${accepted}`,\n );\n }\n const instance = factory.create();\n await Promise.resolve(instance.init(args.auth, args.client));\n return instance;\n}\n\n// Re-export the full public surface.\nexport type {\n AdapterFactory,\n AdapterManifest,\n ApiKeyAuth,\n AuthKind,\n AuthKindSchema,\n AuthSpec,\n AzureOpenAIApiKeyAuth,\n BedrockApiKeyAuth,\n BedrockIamAuth,\n ClientOptions,\n ContentBlock,\n CreateLlmArgs,\n FinishReason,\n FormField,\n FormFieldType,\n GoogleApiKeyAuth,\n GoogleServiceAccountAuth,\n JsonSchema,\n LlmAdapter,\n LlmEvent,\n Message,\n ModelCapabilities,\n ModelInfo,\n PromptRequest,\n Role,\n ServiceAccountJson,\n Tool,\n ToolCallEvent,\n Usage,\n VertexServiceAccountAuth,\n} from './types.js';\n\nexport { normalizeAuth } from './normalize-auth.js';\nexport type { RawCredential } from './normalize-auth.js';\n\nexport { pickAuthKind } from './pick-auth-kind.js';\nexport type { RawCredentialLoose } from './pick-auth-kind.js';\n\nexport { assertValidRequest } from './validate.js';\n\nexport {\n getAdapterFactory,\n getManifest,\n getVendorManifest,\n listVendors,\n registerAdapter,\n replaceAdapter,\n unregisterAdapter,\n} from './registry.js';\n","import type { AdapterFactory, AdapterManifest, AuthSpec } from './types.js';\n\n/**\n * Module-scope registry of adapter factories, keyed by vendor id.\n *\n * Adapters register themselves at import time via `registerAdapter`. Consumers\n * of the library then call `createLlm({vendor, auth})` and the factory for\n * that vendor is looked up here.\n */\nconst registry = new Map<string, AdapterFactory>();\n\n/**\n * Vendors jambonz stores a credential for that have no adapter here\n * (`manifest.credentialOnly`). They appear in `getManifest()` and\n * `getVendorManifest()`, never in `getAdapterFactory()`.\n */\nconst credentialVendors = new Map<string, AdapterManifest>();\n\n/**\n * Register an adapter factory. Called once per adapter at module load.\n *\n * Throws if a factory is already registered for the same vendor id — this\n * catches accidental double-registration and typos in `src/adapters/index.ts`.\n *\n * Use `replaceAdapter` if you deliberately need to override a registered adapter\n * (primarily useful in tests).\n */\nexport function registerAdapter(factory: AdapterFactory): void {\n if (registry.has(factory.vendor) || credentialVendors.has(factory.vendor)) {\n throw new Error(\n `Adapter already registered for vendor '${factory.vendor}'. ` +\n `Use replaceAdapter() if you intended to override.`,\n );\n }\n if (factory.vendor !== factory.manifest.vendor) {\n throw new Error(\n `Adapter factory vendor '${factory.vendor}' does not match ` +\n `manifest.vendor '${factory.manifest.vendor}'.`,\n );\n }\n registry.set(factory.vendor, factory);\n}\n\n/**\n * Register a credential-only vendor: a manifest with no adapter. Throws if\n * the id is already taken or the manifest is not marked `credentialOnly`.\n */\nexport function registerCredentialVendor(manifest: AdapterManifest): void {\n if (!manifest.credentialOnly) {\n throw new Error(`Vendor '${manifest.vendor}' manifest is not marked credentialOnly.`);\n }\n if (registry.has(manifest.vendor) || credentialVendors.has(manifest.vendor)) {\n throw new Error(`Vendor '${manifest.vendor}' is already registered.`);\n }\n credentialVendors.set(manifest.vendor, manifest);\n}\n\n/**\n * Replace an already-registered adapter. Intended for test overrides.\n */\nexport function replaceAdapter(factory: AdapterFactory): void {\n registry.set(factory.vendor, factory);\n}\n\n/**\n * Remove an adapter from the registry. Intended for test cleanup.\n */\nexport function unregisterAdapter(vendor: string): void {\n registry.delete(vendor);\n}\n\n/**\n * Get a registered adapter factory. Throws if unknown vendor.\n */\nexport function getAdapterFactory<A extends AuthSpec = AuthSpec>(\n vendor: string,\n): AdapterFactory<A> {\n const factory = registry.get(vendor);\n if (!factory) {\n if (credentialVendors.has(vendor)) {\n throw new Error(\n `Vendor '${vendor}' is credential-only: @jambonz/llm has no adapter for it.`,\n );\n }\n const known = Array.from(registry.keys()).sort().join(', ') || '(none)';\n throw new Error(\n `Unknown vendor '${vendor}'. Registered vendors: ${known}`,\n );\n }\n return factory as AdapterFactory<A>;\n}\n\n/**\n * Get the manifest for any registered vendor, adapter-backed or\n * credential-only. Throws if unknown vendor. Use this (not\n * `getAdapterFactory`) where only the credential shape matters.\n */\nexport function getVendorManifest(vendor: string): AdapterManifest {\n const manifest = registry.get(vendor)?.manifest ?? credentialVendors.get(vendor);\n if (!manifest) {\n const known =\n [...registry.keys(), ...credentialVendors.keys()].sort().join(', ') || '(none)';\n throw new Error(`Unknown vendor '${vendor}'. Registered vendors: ${known}`);\n }\n return manifest;\n}\n\n/**\n * List all registered adapter vendor ids, sorted alphabetically.\n * Credential-only vendors are not included: they cannot be passed to `createLlm`.\n */\nexport function listVendors(): string[] {\n return Array.from(registry.keys()).sort();\n}\n\n/**\n * Return an aggregated manifest for all registered vendors, credential-only\n * ones included. Used by api-server's /llm-vendors/manifest endpoint.\n */\nexport function getManifest(): { vendors: AdapterManifest[] } {\n const vendors = [\n ...Array.from(registry.values()).map((f) => f.manifest),\n ...credentialVendors.values(),\n ]\n .sort((a, b) => a.vendor.localeCompare(b.vendor));\n return { vendors };\n}\n\n/**\n * Test-only: reset the registry. Exposed for unit tests that register/unregister\n * adapters and need a clean slate.\n */\nexport function _resetRegistryForTests(): void {\n registry.clear();\n credentialVendors.clear();\n}\n","import OpenAI from 'openai';\nimport type {\n ApiKeyAuth,\n ClientOptions,\n LlmAdapter,\n LlmEvent,\n Message,\n ModelInfo,\n PromptRequest,\n ToolCallEvent,\n} from '../../types.js';\nimport {\n appendOpenAIAssistantToolCall,\n appendOpenAIToolResult,\n listOpenAICompatibleModels,\n streamFromOpenAI,\n} from './_streaming.js';\nimport { makeMetadataExtractor } from '../_metadata.js';\nimport { openAIManifest } from './manifest.js';\n\n/**\n * OpenAI response-header diagnostics surfaced as `vendorMetadata` on the\n * `end` event. `request_id` is essential for support tickets;\n * `processing_ms` separates vendor inference time from network time;\n * the rate-limit headers help operators spot when an account is trending\n * toward exhaustion within a single call.\n */\nconst OPENAI_METADATA_EXTRACTOR = makeMetadataExtractor([\n { header: 'x-request-id', key: 'request_id' },\n { header: 'openai-processing-ms', key: 'processing_ms', numeric: true },\n { header: 'x-ratelimit-remaining-requests', key: 'requests_remaining', numeric: true },\n { header: 'x-ratelimit-remaining-tokens', key: 'tokens_remaining', numeric: true },\n]);\n\n/**\n * Adapter for OpenAI (and OpenAI-compatible endpoints: DeepSeek, LM Studio,\n * Ollama, vLLM, custom gateways).\n *\n * Wire translation lives in `_streaming.ts` and is shared with the\n * Vertex-OpenAI adapter — both use the same `openai` SDK with the same\n * on-wire shape; only client construction (auth, baseURL, fetch wrapper)\n * differs.\n */\nexport class OpenAIAdapter implements LlmAdapter<ApiKeyAuth> {\n readonly vendor = openAIManifest.vendor;\n readonly acceptedAuth = ['apiKey'] as const;\n\n protected client: OpenAI | undefined;\n /** baseURL is OpenRouter: enables its automatic prompt caching for Anthropic models. */\n protected isOpenRouter = false;\n\n init(auth: ApiKeyAuth, client?: ClientOptions): void {\n if (!auth.apiKey) {\n throw new Error('OpenAIAdapter: apiKey is required');\n }\n this.isOpenRouter = /(^|\\/\\/|\\.)openrouter\\.ai(\\/|:|$)/i.test(auth.baseURL ?? '');\n this.client = new OpenAI({\n apiKey: auth.apiKey,\n ...(auth.baseURL ? { baseURL: auth.baseURL } : {}),\n ...(client?.timeout !== undefined ? { timeout: client.timeout } : {}),\n ...(client?.maxRetries !== undefined ? { maxRetries: client.maxRetries } : {}),\n });\n }\n\n stream(req: PromptRequest): AsyncIterable<LlmEvent> {\n return streamFromOpenAI(this.ensureClient(), req, {\n knownModels: this.knownModels(),\n vendorMetadataExtractor: OPENAI_METADATA_EXTRACTOR,\n includeCacheKey: this.forwardCacheKey(),\n openRouterAutoCache: this.isOpenRouter,\n });\n }\n\n appendAssistantToolCall(\n history: Message[],\n toolCalls: ReadonlyArray<ToolCallEvent>,\n assistantText?: string,\n ): Message[] {\n return appendOpenAIAssistantToolCall(history, toolCalls, assistantText);\n }\n\n appendToolResult(history: Message[], toolCallId: string, result: unknown): Message[] {\n return appendOpenAIToolResult(history, toolCallId, result);\n }\n\n async listAvailableModels(): Promise<ModelInfo[]> {\n return listOpenAICompatibleModels(this.ensureClient(), this.knownModels());\n }\n\n /**\n * Capability table used to enrich both `stream()` (for tools/vision gating)\n * and `listAvailableModels()` (for filling capability flags on live entries).\n * Subclasses backed by the same OpenAI wire (DeepSeek, Baseten, …) override\n * this so their own manifest entries are consulted instead of OpenAI's.\n */\n protected knownModels(): ReadonlyArray<ModelInfo> {\n return openAIManifest.knownModels;\n }\n\n /**\n * Whether to forward `req.cacheKey` as OpenAI's `prompt_cache_key` request\n * param. Default true — verified accepted by OpenAI, Azure OpenAI,\n * Vertex-OpenAI, and Baseten. OpenAI-compatible vendors whose param\n * handling is strict or unverified (DeepSeek, Moonshot, Zai, xAI — and\n * Groq via its own stream override) override to false: a strict backend\n * rejects the whole request on an unknown body param, which is far worse\n * than forgoing a cache-routing hint. Flip a vendor to true only after\n * verifying its endpoint (including any proxy in front of it, e.g.\n * Bedrock Mantle) tolerates the param.\n */\n protected forwardCacheKey(): boolean {\n return true;\n }\n\n async testCredential(): Promise<void> {\n // /v1/models is the cheapest authenticated GET on the OpenAI API.\n // Works for OpenAI proper and most compatible backends (DeepSeek included).\n await this.ensureClient().models.list();\n }\n\n async warmup(): Promise<void> {\n const client = this.ensureClient();\n await client.models.list().catch(() => undefined);\n }\n\n protected ensureClient(): OpenAI {\n if (!this.client) {\n throw new Error('OpenAIAdapter: init() must be called before stream()/listAvailableModels()');\n }\n return this.client;\n }\n}\n","import type { PromptRequest } from './types.js';\n\n/**\n * Validate a PromptRequest against the library's universal preconditions.\n *\n * Adapters should call this at the top of `stream()` to get consistent error\n * messages. The contract test-kit's check #18 verifies empty messages are\n * rejected, so adapters that skip this helper must implement the equivalent\n * validation themselves.\n *\n * Rules enforced:\n * - `model` is a non-empty string.\n * - `messages` is a non-empty array.\n * - `messages` does not contain `role: 'system'` turns (use `system` top-level).\n * - `cacheKey`, when present, is a non-empty string.\n */\nexport function assertValidRequest(req: PromptRequest): void {\n if (!req || typeof req !== 'object') {\n throw new Error('PromptRequest must be an object');\n }\n if (typeof req.model !== 'string' || req.model.length === 0) {\n throw new Error('PromptRequest.model must be a non-empty string');\n }\n if (!Array.isArray(req.messages) || req.messages.length === 0) {\n throw new Error('PromptRequest.messages must be a non-empty array');\n }\n if (req.messages.some((m) => m.role === 'system')) {\n throw new Error(\n 'PromptRequest.messages must not contain role: \\'system\\'. ' +\n 'Pass the system prompt via PromptRequest.system instead.',\n );\n }\n if (req.cacheKey !== undefined && (typeof req.cacheKey !== 'string' || req.cacheKey.length === 0)) {\n throw new Error('PromptRequest.cacheKey must be a non-empty string');\n }\n}\n","import type OpenAI from 'openai';\nimport type { ChatCompletionCreateParamsStreaming } from 'openai/resources/chat/completions';\nimport type {\n FinishReason,\n LlmEvent,\n Message,\n ModelCapabilities,\n ModelInfo,\n PromptRequest,\n Tool,\n} from '../../types.js';\nimport { assertValidRequest } from '../../validate.js';\n\n/**\n * OpenAI wire translation, shared between the native OpenAI adapter and the\n * Vertex-OpenAI adapter (which talks to third-party models hosted on Vertex AI\n * via the OpenAI-compatible endpoint).\n */\nexport async function* streamFromOpenAI(\n client: OpenAI,\n req: PromptRequest,\n options: {\n knownModels: ReadonlyArray<ModelInfo>;\n /**\n * Whether to set `stream_options: { include_usage: true }` on the\n * request. Defaults to `true` for OpenAI's native API. Set to `false`\n * for third-party OpenAI-compatible endpoints (e.g. Vertex AI's OpenAI\n * endpoint for partner models) that reject unknown extensions with a\n * 400 error. When disabled, the `end` event's `usage` field is omitted.\n */\n includeStreamOptions?: boolean;\n /**\n * If the caller did not supply `maxTokens`, use this value. Set by the\n * Vertex-OpenAI adapter because Vertex AI's Llama MaaS endpoint returns\n * an empty assistant message (zero tokens, `finish_reason: stop`) when\n * `max_tokens` is omitted. Leave undefined for OpenAI's native API,\n * which defaults correctly on its own.\n */\n defaultMaxTokens?: number;\n /**\n * Which wire parameter to use for the max-output cap. Defaults to a\n * per-request heuristic on `req.model` (see {@link needsMaxCompletionTokens}):\n * OpenAI's o-series reasoning models and gpt-5 family require\n * `max_completion_tokens`; everything else uses legacy `max_tokens`.\n *\n * Override when:\n * - The model id doesn't reflect the underlying model (Azure OpenAI\n * deployment names are arbitrary) — pass `'max_completion_tokens'`.\n * - Talking to an older OpenAI-compat endpoint that only knows\n * `max_tokens` (Vertex Llama MaaS, some local servers) — pass\n * `'max_tokens'` to pin the legacy name.\n */\n tokensParam?: 'max_tokens' | 'max_completion_tokens';\n /**\n * Whether to forward `req.cacheKey` as the `prompt_cache_key` request\n * param. Defaults to `true` (OpenAI/Azure/Vertex-OpenAI/Baseten all\n * accept it). Set to `false` for Groq, which caches automatically\n * server-side and does not document this param (per Groq's strict\n * OpenAI-compat param handling).\n */\n includeCacheKey?: boolean;\n /**\n * The endpoint is OpenRouter. With `req.cacheKey` set and an Anthropic\n * model (`anthropic/...`), adds OpenRouter's top-level\n * `cache_control: {type: 'ephemeral'}` (\"automatic\" prompt caching: it\n * places the breakpoint on the last cacheable block and moves it forward\n * as the conversation grows). Anthropic models ignore `prompt_cache_key`,\n * so without this nothing is cached. Gated on OpenRouter because a strict\n * OpenAI-compatible backend rejects the whole request on an unknown field.\n */\n openRouterAutoCache?: boolean;\n /**\n * Optional adapter-supplied extractor that pulls vendor-specific\n * diagnostic data off the upstream HTTP response headers (request\n * id, rate-limit remaining, routing info, etc.) and returns it as\n * a flat key/value record.\n *\n * Called once per stream after the underlying `Response` is\n * available (via the OpenAI SDK's `.withResponse()` pattern). The\n * returned record is attached to the `end` event as\n * `vendorMetadata` if non-empty. Each adapter declares its own\n * allowlist — see the `huggingface`, `azure-openai`, `groq` etc.\n * adapters for examples.\n */\n vendorMetadataExtractor?: (\n headers: Headers,\n ) => Record<string, string | number>;\n },\n): AsyncIterable<LlmEvent> {\n assertValidRequest(req);\n\n if (req.signal?.aborted) {\n yield { type: 'end', finishReason: 'aborted' };\n return;\n }\n\n const capabilities = capabilitiesFor(req.model, options.knownModels);\n const useTools = req.tools && req.tools.length > 0 && capabilities.tools;\n\n const messages = buildWireMessages(req);\n const tools = useTools ? formatTools(req.tools!) : undefined;\n\n const body: ChatCompletionCreateParamsStreaming = {\n model: req.model,\n messages: messages as ChatCompletionCreateParamsStreaming['messages'],\n stream: true,\n ...(options.includeStreamOptions !== false\n ? { stream_options: { include_usage: true } }\n : {}),\n };\n if (tools) {\n body.tools = tools as unknown as ChatCompletionCreateParamsStreaming['tools'];\n body.tool_choice = 'auto';\n }\n if (req.temperature !== undefined) body.temperature = req.temperature;\n if (req.cacheKey && options.includeCacheKey !== false) {\n (body as unknown as Record<string, unknown>).prompt_cache_key = req.cacheKey;\n }\n if (req.cacheKey && options.openRouterAutoCache && /^~?anthropic\\//.test(req.model)) {\n (body as unknown as Record<string, unknown>).cache_control = { type: 'ephemeral' };\n }\n const effectiveMaxTokens = req.maxTokens ?? options.defaultMaxTokens;\n if (effectiveMaxTokens !== undefined) {\n const param =\n options.tokensParam ??\n (needsMaxCompletionTokens(req.model) ? 'max_completion_tokens' : 'max_tokens');\n (body as unknown as Record<string, unknown>)[param] = effectiveMaxTokens;\n }\n\n // Merge caller-supplied provider-specific params (e.g. Kimi's\n // chat_template_kwargs). Add-only: never overwrite a library-managed field,\n // so this can extend the request but not corrupt its core shape.\n if (req.providerParams) {\n const bodyRecord = body as unknown as Record<string, unknown>;\n for (const [key, value] of Object.entries(req.providerParams)) {\n if (!(key in bodyRecord)) bodyRecord[key] = value;\n }\n }\n\n // hrtime markers for client-side timing breakdown attached to the end event:\n // t0 = before SDK call\n // t1 = response headers received (after withResponse resolves)\n // t2 = first content token yielded back to caller\n // `clientTiming` is omitted when t1 was never reached (error before headers).\n const t0 = process.hrtime.bigint();\n let t1: bigint | undefined;\n let t2: bigint | undefined;\n\n let stream;\n let responseHeaders: Headers | undefined;\n try {\n // Production: `.withResponse()` on the OpenAI SDK's APIPromise surfaces\n // the underlying HTTP `Response` so adapters that supply a\n // `vendorMetadataExtractor` can read response headers. Test mocks\n // typically return the stream directly (no APIPromise wrapper); fall\n // through to a plain await when `.withResponse` isn't present, so\n // existing test infrastructure keeps working unchanged.\n const apiPromise = client.chat.completions.create(body, { signal: req.signal });\n const maybeWithResponse = (apiPromise as unknown as {\n withResponse?: () => Promise<{\n data: Awaited<typeof apiPromise>;\n response: { headers?: Headers };\n }>;\n }).withResponse;\n if (typeof maybeWithResponse === 'function') {\n const result = await maybeWithResponse.call(apiPromise);\n stream = result.data;\n responseHeaders = result.response?.headers;\n } else {\n stream = await apiPromise;\n }\n t1 = process.hrtime.bigint();\n } catch (err) {\n if (isAbortError(err)) {\n yield { type: 'end', finishReason: 'aborted' };\n return;\n }\n throw err;\n }\n\n const pending: Record<number, PendingToolCall> = {};\n const startedIds = new Set<string>();\n const toolCallsEmitted = new Set<string>();\n let usage: { inputTokens?: number; outputTokens?: number; totalTokens?: number } | undefined;\n let finalFinishReason: FinishReason | null = null;\n let finalRawReason: string | undefined;\n let sawContent = false;\n\n try {\n for await (const chunk of stream) {\n if (req.signal?.aborted) {\n yield { type: 'end', finishReason: 'aborted' };\n return;\n }\n\n // Some OpenAI-compatible backends report failures as a single SSE event\n // carrying a top-level `error` (instead of a non-2xx status the SDK would\n // throw on). Surface it rather than silently ending with no output.\n const chunkError = (chunk as { error?: unknown }).error;\n if (chunkError) {\n const message =\n chunkError && typeof chunkError === 'object' && 'message' in chunkError\n ? String((chunkError as { message?: unknown }).message)\n : JSON.stringify(chunkError);\n throw new Error(`OpenAI-compatible stream returned an error: ${message}`);\n }\n\n if (chunk.usage) {\n // OpenAI's prompt_tokens INCLUDES cached tokens (cached_tokens is a\n // sub-detail). Subtract it out so inputTokens means UNCACHED input,\n // per the library's additive Usage convention. OpenRouter also reports\n // cache_write_tokens (Anthropic-family models), likewise included in\n // prompt_tokens, so it is subtracted too and surfaced separately.\n const details = chunk.usage.prompt_tokens_details as\n | { cached_tokens?: number; cache_write_tokens?: number }\n | undefined;\n const cachedTokens = details?.cached_tokens;\n const cacheWriteTokens = details?.cache_write_tokens;\n usage = {\n ...(chunk.usage.prompt_tokens !== undefined\n ? {\n inputTokens: Math.max(\n 0,\n chunk.usage.prompt_tokens - (cachedTokens ?? 0) - (cacheWriteTokens ?? 0),\n ),\n }\n : {}),\n ...(chunk.usage.completion_tokens !== undefined\n ? { outputTokens: chunk.usage.completion_tokens }\n : {}),\n ...(chunk.usage.total_tokens !== undefined\n ? { totalTokens: chunk.usage.total_tokens }\n : {}),\n ...(cachedTokens !== undefined ? { cacheReadTokens: cachedTokens } : {}),\n ...(cacheWriteTokens !== undefined ? { cacheWriteTokens } : {}),\n };\n }\n\n const choice = chunk.choices?.[0];\n if (!choice) continue;\n\n const delta = choice.delta;\n const finishReason = choice.finish_reason;\n\n if (delta?.content) {\n if (t2 === undefined) t2 = process.hrtime.bigint();\n sawContent = true;\n yield { type: 'token', text: delta.content };\n }\n\n if (delta?.tool_calls) {\n for (const tc of delta.tool_calls) {\n const idx = tc.index;\n if (!pending[idx]) {\n pending[idx] = { id: '', name: '', arguments: '' };\n }\n if (tc.id) pending[idx].id += tc.id;\n if (tc.function?.name) pending[idx].name += tc.function.name;\n if (tc.function?.arguments) pending[idx].arguments += tc.function.arguments;\n\n if (pending[idx].id && pending[idx].name && !startedIds.has(pending[idx].id)) {\n startedIds.add(pending[idx].id);\n yield {\n type: 'toolCallStart',\n id: pending[idx].id,\n name: pending[idx].name,\n };\n }\n }\n }\n\n if (finishReason === 'tool_calls') {\n if (req.signal?.aborted) {\n yield { type: 'end', finishReason: 'aborted' };\n return;\n }\n for (const tc of Object.values(pending)) {\n if (!tc.id || !tc.name) continue;\n if (toolCallsEmitted.has(tc.id)) continue;\n toolCallsEmitted.add(tc.id);\n let args: unknown = {};\n try {\n args = tc.arguments ? JSON.parse(tc.arguments) : {};\n } catch {\n args = {};\n }\n yield {\n type: 'toolCall',\n id: tc.id,\n name: tc.name,\n arguments: args,\n };\n }\n finalFinishReason = 'tool';\n finalRawReason = finishReason;\n } else if (finishReason) {\n finalFinishReason = mapFinishReason(finishReason);\n finalRawReason = finishReason;\n }\n }\n } catch (err) {\n if (isAbortError(err)) {\n yield { type: 'end', finishReason: 'aborted' };\n return;\n }\n throw err;\n }\n\n // A valid completion stream always emits at least a finish_reason. If we got\n // through the whole stream with no content, no tool calls, no usage, and no\n // finish reason, the response was not a real completion — typically a\n // misconfigured base URL or a vendor error returned inside an HTTP 200 body\n // (which the SDK does not treat as an error). Fail loudly instead of\n // returning a silent empty turn that a caller would forward to TTS.\n const producedNothing =\n finalFinishReason === null &&\n !sawContent &&\n toolCallsEmitted.size === 0 &&\n startedIds.size === 0 &&\n usage === undefined;\n if (producedNothing) {\n throw new Error(\n 'OpenAI-compatible stream produced no data (no content, tool calls, usage, or finish ' +\n 'reason). This usually means a misconfigured base URL or a vendor error returned in an ' +\n 'HTTP 200 body. Verify the base URL and credentials.',\n );\n }\n\n const endEvent: Extract<LlmEvent, { type: 'end' }> = {\n type: 'end',\n finishReason: finalFinishReason ?? 'stop',\n ...(usage ? { usage } : {}),\n ...(finalRawReason ? { rawReason: finalRawReason } : {}),\n };\n\n if (options.vendorMetadataExtractor && responseHeaders) {\n const metadata = options.vendorMetadataExtractor(responseHeaders);\n if (metadata && Object.keys(metadata).length > 0) {\n endEvent.vendorMetadata = metadata;\n }\n }\n\n if (t1 !== undefined) {\n const t3 = process.hrtime.bigint();\n endEvent.clientTiming = {\n requestToHeadersMs: Number(t1 - t0) / 1e6,\n ...(t2 !== undefined\n ? { headersToFirstTokenMs: Number(t2 - t1) / 1e6 }\n : {}),\n totalMs: Number(t3 - t0) / 1e6,\n };\n }\n\n yield endEvent;\n}\n\nexport function appendOpenAIAssistantToolCall(\n history: Message[],\n toolCalls: ReadonlyArray<Extract<LlmEvent, { type: 'toolCall' }>>,\n assistantText?: string,\n): Message[] {\n const text = assistantText?.trim() ? assistantText : null;\n const wireMessage = {\n role: 'assistant',\n content: text,\n tool_calls: toolCalls.map((tc) => ({\n id: tc.id,\n type: 'function',\n function: {\n name: tc.name,\n arguments: typeof tc.arguments === 'string'\n ? tc.arguments\n : JSON.stringify(tc.arguments ?? {}),\n },\n })),\n };\n return [\n ...history,\n {\n role: 'assistant',\n content: text ?? '',\n vendorRaw: wireMessage,\n },\n ];\n}\n\nexport function appendOpenAIToolResult(\n history: Message[],\n toolCallId: string,\n result: unknown,\n): Message[] {\n const content = typeof result === 'string' ? result : JSON.stringify(result);\n const wireMessage = {\n role: 'tool',\n tool_call_id: toolCallId,\n content,\n };\n return [\n ...history,\n {\n role: 'tool',\n content,\n vendorRaw: wireMessage,\n },\n ];\n}\n\n/**\n * Call `models.list()` and normalise results, merging capabilities from a\n * known-models table when possible.\n */\nexport async function listOpenAICompatibleModels(\n client: OpenAI,\n knownModels: ReadonlyArray<ModelInfo>,\n): Promise<ModelInfo[]> {\n const result = await client.models.list();\n const out: ModelInfo[] = [];\n for (const m of result.data) {\n const known = knownModels.find((k) => k.id === m.id);\n if (known) {\n out.push(known);\n } else {\n out.push({\n id: m.id,\n capabilities: defaultCapabilitiesForUnknown(m.id),\n });\n }\n }\n return out;\n}\n\n// ---------------------------------------------------------------------------\n// Helpers (internal)\n// ---------------------------------------------------------------------------\n\ninterface PendingToolCall {\n id: string;\n name: string;\n arguments: string;\n}\n\nfunction buildWireMessages(req: PromptRequest): unknown[] {\n const out: unknown[] = [];\n if (req.system) {\n out.push({ role: 'system', content: req.system });\n }\n for (const msg of req.messages) {\n if (msg.vendorRaw && typeof msg.vendorRaw === 'object') {\n out.push(msg.vendorRaw);\n } else {\n out.push({ role: msg.role, content: msg.content });\n }\n }\n return out;\n}\n\nfunction formatTools(tools: Tool[]): Array<Record<string, unknown>> {\n return tools.map((t) => ({\n type: 'function',\n function: {\n name: t.name,\n description: t.description ?? '',\n parameters: t.parameters ?? { type: 'object', properties: {} },\n },\n }));\n}\n\nfunction capabilitiesFor(\n modelId: string,\n knownModels: ReadonlyArray<ModelInfo>,\n): ModelCapabilities {\n const known = knownModels.find((k) => k.id === modelId);\n if (known) return known.capabilities;\n return defaultCapabilitiesForUnknown(modelId);\n}\n\n/**\n * Does this model id require `max_completion_tokens` instead of legacy\n * `max_tokens`? OpenAI's reasoning family (o1, o3, o4) and gpt-5 dropped\n * `max_tokens` and return a 400 `Unsupported parameter` when it's sent.\n * Older chat models (gpt-4, gpt-4o, gpt-3.5-turbo) still accept `max_tokens`,\n * so we only switch when the model id matches the newer prefixes.\n *\n * Exposed so adapter authors (and tests) can rely on the same heuristic.\n */\nexport function needsMaxCompletionTokens(modelId: string): boolean {\n return /^(o\\d|gpt-5)/i.test(modelId);\n}\n\nexport function defaultCapabilitiesForUnknown(modelId: string): ModelCapabilities {\n const isReasoning = /^o[13]([-/]|$)/i.test(modelId);\n if (isReasoning) {\n return {\n streaming: false,\n tools: false,\n vision: false,\n systemPrompt: false,\n };\n }\n return {\n streaming: true,\n tools: true,\n vision: false,\n systemPrompt: true,\n };\n}\n\nfunction mapFinishReason(r: string): FinishReason {\n switch (r) {\n case 'stop': return 'stop';\n case 'tool_calls': return 'tool';\n case 'function_call': return 'tool';\n case 'length': return 'length';\n case 'content_filter': return 'filtered';\n default: return 'stop';\n }\n}\n\nfunction isAbortError(err: unknown): boolean {\n if (!err || typeof err !== 'object') return false;\n const e = err as { name?: string; code?: string; message?: string };\n return (\n e.name === 'APIUserAbortError' ||\n e.name === 'AbortError' ||\n e.code === 'ABORT_ERR' ||\n (typeof e.message === 'string' && /aborted/i.test(e.message))\n );\n}\n","/**\n * Shared helpers for vendor-metadata extractors.\n *\n * Each adapter that wants to surface response-header diagnostics (request\n * id, rate-limit remaining, routing/region, vendor processing time, cache\n * counts) declares an allowlist of `header-name` → `output-key` pairs\n * here. The extractor walks the allowlist, reads each header, parses\n * numeric values, and returns a flat record. Empty/absent headers are\n * dropped — never emit `null`.\n *\n * Output shape is `Record<string, string | number>` so consumers\n * (feature-server, webapp) can render it as a key/value table without\n * per-vendor knowledge.\n */\n\nexport interface MetadataField {\n /** Lowercase HTTP header name to read. */\n header: string;\n /** Key under which the value is exposed in `vendorMetadata`. */\n key: string;\n /** Parse numeric values to `number` instead of leaving as `string`. */\n numeric?: boolean;\n}\n\n/**\n * Build a `vendorMetadataExtractor` from a static field list. Adapters\n * import this and pass the result to `streamFromOpenAI` (or call directly\n * for native-SDK adapters).\n */\nexport function makeMetadataExtractor(\n fields: ReadonlyArray<MetadataField>,\n): (headers: Headers) => Record<string, string | number> {\n return (headers: Headers) => {\n const out: Record<string, string | number> = {};\n for (const f of fields) {\n const raw = headers.get(f.header);\n if (raw === null || raw === undefined || raw === '') continue;\n if (f.numeric) {\n const n = Number(raw);\n if (Number.isFinite(n)) out[f.key] = n;\n } else {\n out[f.key] = raw;\n }\n }\n return out;\n };\n}\n\n/**\n * Convenience: run the extractor against a generic header source (a\n * `Headers` instance, a record, or AWS-SDK-style `httpHeaders`) by\n * normalizing first. Used by native-SDK adapters whose response shapes\n * don't expose a real `Headers` object.\n */\nexport function extractMetadata(\n fields: ReadonlyArray<MetadataField>,\n headers: Record<string, string | string[] | undefined> | Headers,\n): Record<string, string | number> {\n const headersInstance =\n headers instanceof Headers ? headers : recordToHeaders(headers);\n return makeMetadataExtractor(fields)(headersInstance);\n}\n\nfunction recordToHeaders(\n record: Record<string, string | string[] | undefined>,\n): Headers {\n const h = new Headers();\n for (const [name, value] of Object.entries(record)) {\n if (value === undefined) continue;\n if (Array.isArray(value)) {\n for (const v of value) h.append(name, v);\n } else {\n h.set(name, value);\n }\n }\n return h;\n}\n","import type { AdapterManifest, ModelInfo } from '../../types.js';\n\n/**\n * Known OpenAI models with capability flags.\n *\n * Model listing via `listAvailableModels()` hits the live `/v1/models` endpoint,\n * so this curated list is for the admin-UI dropdown and for capability\n * validation (e.g., rejecting tools on reasoning-only models).\n */\nconst OPENAI_KNOWN_MODELS: ModelInfo[] = [\n {\n id: 'gpt-4o',\n displayName: 'GPT-4o',\n capabilities: {\n streaming: true,\n tools: true,\n vision: true,\n systemPrompt: true,\n maxContextTokens: 128_000,\n },\n },\n {\n id: 'gpt-4o-mini',\n displayName: 'GPT-4o mini',\n capabilities: {\n streaming: true,\n tools: true,\n vision: true,\n systemPrompt: true,\n maxContextTokens: 128_000,\n },\n },\n {\n id: 'gpt-4-turbo',\n displayName: 'GPT-4 Turbo',\n capabilities: {\n streaming: true,\n tools: true,\n vision: true,\n systemPrompt: true,\n maxContextTokens: 128_000,\n },\n },\n {\n id: 'gpt-3.5-turbo',\n displayName: 'GPT-3.5 Turbo',\n capabilities: {\n streaming: true,\n tools: true,\n vision: false,\n systemPrompt: true,\n maxContextTokens: 16_385,\n },\n },\n {\n id: 'o1-preview',\n displayName: 'o1 preview (reasoning)',\n capabilities: {\n streaming: false,\n tools: false,\n vision: false,\n systemPrompt: false,\n maxContextTokens: 128_000,\n },\n },\n {\n id: 'o1-mini',\n displayName: 'o1 mini (reasoning)',\n capabilities: {\n streaming: false,\n tools: false,\n vision: false,\n systemPrompt: false,\n maxContextTokens: 128_000,\n },\n },\n];\n\nexport const openAIManifest: AdapterManifest = {\n vendor: 'openai',\n displayName: 'OpenAI',\n authKinds: [\n {\n kind: 'apiKey',\n displayName: 'API Key',\n fields: [\n {\n name: 'apiKey',\n label: 'API Key',\n type: 'password',\n required: true,\n help: 'Get an API key from https://platform.openai.com/api-keys',\n },\n {\n name: 'baseURL',\n label: 'Base URL',\n type: 'url',\n required: false,\n default: 'https://api.openai.com/v1',\n help: 'Override for OpenAI-compatible endpoints (LM Studio, Ollama, vLLM, proxies).',\n },\n ],\n },\n ],\n knownModels: OPENAI_KNOWN_MODELS,\n supportsModelListing: true,\n docsUrl: 'https://platform.openai.com/docs/api-reference',\n};\n","import type { AdapterFactory, AdapterManifest, ApiKeyAuth } from '../../types.js';\nimport { OpenAIAdapter } from './adapter.js';\nimport { openAIManifest } from './manifest.js';\n\nexport const openAIFactory: AdapterFactory<ApiKeyAuth> = {\n vendor: openAIManifest.vendor,\n manifest: openAIManifest,\n create: () => new OpenAIAdapter(),\n};\n\n/**\n * DeepSeek alias factory. Wraps the OpenAI adapter but advertises itself as\n * `deepseek` and ships a DeepSeek-specific manifest (different default\n * `baseURL`, different known models, different docsUrl).\n *\n * Consumers call `createLlm({vendor: 'deepseek', auth: {kind: 'apiKey', apiKey}})`\n * and get the OpenAI wire adapter pointed at the DeepSeek endpoint.\n */\nconst deepseekManifest: AdapterManifest = {\n vendor: 'deepseek',\n displayName: 'DeepSeek',\n authKinds: [\n {\n kind: 'apiKey',\n displayName: 'API Key',\n fields: [\n {\n name: 'apiKey',\n label: 'API Key',\n type: 'password',\n required: true,\n help: 'Get an API key from https://platform.deepseek.com/api_keys',\n },\n {\n name: 'baseURL',\n label: 'Base URL',\n type: 'url',\n required: false,\n default: 'https://api.deepseek.com/v1',\n help: 'Override for self-hosted DeepSeek or proxy endpoints.',\n },\n ],\n },\n ],\n knownModels: [\n {\n id: 'deepseek-v4-flash',\n displayName: 'DeepSeek V4 Flash',\n capabilities: {\n streaming: true,\n tools: true,\n vision: false,\n systemPrompt: true,\n maxContextTokens: 1_000_000,\n },\n },\n {\n id: 'deepseek-v4-pro',\n displayName: 'DeepSeek V4 Pro',\n capabilities: {\n streaming: true,\n tools: true,\n vision: false,\n systemPrompt: true,\n maxContextTokens: 1_000_000,\n },\n },\n {\n id: 'deepseek-chat',\n displayName: 'DeepSeek Chat',\n capabilities: {\n streaming: true,\n tools: true,\n vision: false,\n systemPrompt: true,\n maxContextTokens: 64_000,\n },\n deprecated: true,\n },\n {\n id: 'deepseek-reasoner',\n displayName: 'DeepSeek Reasoner',\n capabilities: {\n streaming: true,\n tools: false,\n vision: false,\n systemPrompt: true,\n maxContextTokens: 64_000,\n },\n deprecated: true,\n },\n ],\n supportsModelListing: true,\n docsUrl: 'https://api-docs.deepseek.com/',\n};\n\nclass DeepSeekAdapter extends OpenAIAdapter {\n readonly vendor = deepseekManifest.vendor;\n\n override init(auth: ApiKeyAuth, client?: Parameters<OpenAIAdapter['init']>[1]): void {\n super.init(\n {\n ...auth,\n baseURL: auth.baseURL ?? 'https://api.deepseek.com/v1',\n },\n client,\n );\n }\n\n protected override knownModels() {\n return deepseekManifest.knownModels;\n }\n\n // DeepSeek caches automatically server-side; prompt_cache_key is\n // unverified against its param handling — do not forward.\n protected override forwardCacheKey(): boolean {\n return false;\n }\n}\n\nexport const deepseekFactory: AdapterFactory<ApiKeyAuth> = {\n vendor: deepseekManifest.vendor,\n manifest: deepseekManifest,\n create: () => new DeepSeekAdapter(),\n};\n\n/**\n * Baseten alias factory. Wraps the OpenAI adapter but advertises itself as\n * `baseten` and ships a Baseten-specific manifest (different default\n * `baseURL`, different known models, different docsUrl).\n *\n * Baseten exposes two OpenAI-compatible surfaces:\n * - Model APIs (default): `https://inference.baseten.co/v1` — shared,\n * curated catalog (DeepSeek, GLM, Kimi, GPT-OSS, etc.). `/v1/models`\n * returns the live catalog.\n * - Bridge / Direct: `https://bridge.baseten.co/v1/direct` — routes to a\n * user's dedicated deployment. Users override `baseURL` for this case.\n *\n * Consumers call `createLlm({vendor: 'baseten', auth: {kind: 'apiKey', apiKey}})`\n * and get the OpenAI wire adapter pointed at the Baseten endpoint.\n */\nconst basetenManifest: AdapterManifest = {\n vendor: 'baseten',\n displayName: 'Baseten',\n authKinds: [\n {\n kind: 'apiKey',\n displayName: 'API Key',\n fields: [\n {\n name: 'apiKey',\n label: 'API Key',\n type: 'password',\n required: true,\n help: 'Get an API key from https://app.baseten.co/settings/api_keys',\n },\n {\n name: 'baseURL',\n label: 'Base URL',\n type: 'url',\n required: false,\n default: 'https://inference.baseten.co/v1',\n help: 'Defaults to Baseten Model APIs. Set to https://bridge.baseten.co/v1/direct to route to a dedicated deployment.',\n },\n ],\n },\n ],\n knownModels: [\n {\n id: 'deepseek-ai/DeepSeek-V3.1',\n displayName: 'DeepSeek V3.1',\n capabilities: {\n streaming: true,\n tools: true,\n vision: false,\n systemPrompt: true,\n maxContextTokens: 163_840,\n },\n },\n {\n id: 'deepseek-ai/DeepSeek-V4-Pro',\n displayName: 'DeepSeek V4 Pro',\n capabilities: {\n streaming: true,\n tools: true,\n vision: false,\n systemPrompt: true,\n maxContextTokens: 131_072,\n },\n },\n {\n id: 'zai-org/GLM-4.7',\n displayName: 'GLM 4.7',\n capabilities: {\n streaming: true,\n tools: true,\n vision: false,\n systemPrompt: true,\n maxContextTokens: 200_000,\n },\n },\n {\n id: 'zai-org/GLM-5',\n displayName: 'GLM 5',\n capabilities: {\n streaming: true,\n tools: true,\n vision: false,\n systemPrompt: true,\n maxContextTokens: 202_800,\n },\n },\n {\n id: 'moonshotai/Kimi-K2.5',\n displayName: 'Kimi K2.5',\n capabilities: {\n streaming: true,\n tools: true,\n vision: true,\n systemPrompt: true,\n maxContextTokens: 262_000,\n },\n },\n {\n id: 'moonshotai/Kimi-K2.6',\n displayName: 'Kimi K2.6',\n capabilities: {\n streaming: true,\n tools: true,\n vision: true,\n systemPrompt: true,\n maxContextTokens: 262_000,\n },\n },\n {\n id: 'MiniMaxAI/MiniMax-M2.5',\n displayName: 'MiniMax M2.5',\n capabilities: {\n streaming: true,\n tools: true,\n vision: false,\n systemPrompt: true,\n maxContextTokens: 204_000,\n },\n },\n {\n id: 'nvidia/Nemotron-120B-A12B',\n displayName: 'Nemotron Super',\n capabilities: {\n streaming: true,\n tools: true,\n vision: false,\n systemPrompt: true,\n maxContextTokens: 202_800,\n },\n },\n {\n id: 'openai/gpt-oss-120b',\n displayName: 'OpenAI GPT 120B',\n capabilities: {\n streaming: true,\n tools: true,\n vision: false,\n systemPrompt: true,\n maxContextTokens: 128_072,\n },\n },\n ],\n supportsModelListing: true,\n docsUrl: 'https://docs.baseten.co/inference/model-apis/overview',\n};\n\nclass BasetenAdapter extends OpenAIAdapter {\n readonly vendor = basetenManifest.vendor;\n\n override init(auth: ApiKeyAuth, client?: Parameters<OpenAIAdapter['init']>[1]): void {\n super.init(\n {\n ...auth,\n baseURL: auth.baseURL ?? 'https://inference.baseten.co/v1',\n },\n client,\n );\n }\n\n protected override knownModels() {\n return basetenManifest.knownModels;\n }\n}\n\nexport const basetenFactory: AdapterFactory<ApiKeyAuth> = {\n vendor: basetenManifest.vendor,\n manifest: basetenManifest,\n create: () => new BasetenAdapter(),\n};\n\n/**\n * Moonshot (Kimi) alias factory. Moonshot exposes an OpenAI-compatible\n * Chat Completions surface; the only differences from OpenAI are the default\n * `baseURL` and the model catalog.\n *\n * Note: Moonshot serves a global endpoint (`api.moonshot.ai`) and a China\n * endpoint (`api.moonshot.cn`). We default to the global one; users override\n * `baseURL` for `.cn`. Moonshot only accepts the `tools` calling format (the\n * deprecated `functions` param is unsupported), which is what we already emit.\n *\n * Consumers call `createLlm({vendor: 'moonshot', auth: {kind: 'apiKey', apiKey}})`.\n */\nconst moonshotManifest: AdapterManifest = {\n vendor: 'moonshot',\n displayName: 'Moonshot (Kimi)',\n authKinds: [\n {\n kind: 'apiKey',\n displayName: 'API Key',\n fields: [\n {\n name: 'apiKey',\n label: 'API Key',\n type: 'password',\n required: true,\n help: 'Get an API key from https://platform.moonshot.ai/console/api-keys',\n },\n {\n name: 'baseURL',\n label: 'Base URL',\n type: 'url',\n required: false,\n default: 'https://api.moonshot.ai/v1',\n help: 'Defaults to the global endpoint. Set to https://api.moonshot.cn/v1 for the China endpoint.',\n },\n ],\n },\n ],\n knownModels: [\n {\n id: 'kimi-k2.6',\n displayName: 'Kimi K2.6',\n capabilities: {\n streaming: true,\n tools: true,\n vision: true,\n systemPrompt: true,\n maxContextTokens: 262_144,\n },\n },\n {\n id: 'kimi-k2.5',\n displayName: 'Kimi K2.5',\n capabilities: {\n streaming: true,\n tools: true,\n vision: true,\n systemPrompt: true,\n maxContextTokens: 262_144,\n },\n },\n ],\n supportsModelListing: true,\n docsUrl: 'https://platform.moonshot.ai/docs',\n};\n\nclass MoonshotAdapter extends OpenAIAdapter {\n readonly vendor = moonshotManifest.vendor;\n\n override init(auth: ApiKeyAuth, client?: Parameters<OpenAIAdapter['init']>[1]): void {\n super.init(\n {\n ...auth,\n baseURL: auth.baseURL ?? 'https://api.moonshot.ai/v1',\n },\n client,\n );\n }\n\n protected override knownModels() {\n return moonshotManifest.knownModels;\n }\n\n // Moonshot's param handling is strict (e.g. it rejects unknown template\n // kwargs) and prompt_cache_key is unverified against both the native\n // endpoint and Bedrock Mantle deployments — do not forward.\n protected override forwardCacheKey(): boolean {\n return false;\n }\n}\n\nexport const moonshotFactory: AdapterFactory<ApiKeyAuth> = {\n vendor: moonshotManifest.vendor,\n manifest: moonshotManifest,\n create: () => new MoonshotAdapter(),\n};\n\n/**\n * Z.ai (GLM) alias factory. Z.ai's `/api/paas/v4` surface is OpenAI-compatible\n * for chat completions (it accepts the OpenAI request shape and is what the\n * OpenAI SDK should target as its baseURL). Note there is NO OpenAI-style\n * `/models` listing endpoint, so `supportsModelListing` is false and we serve\n * the static known-models list.\n *\n * Note: Coding-Plan subscriptions are served from a *different* endpoint\n * (`https://api.z.ai/api/coding/paas/v4`), not the general one. Users on a\n * Coding Plan must override `baseURL` accordingly.\n *\n * Consumers call `createLlm({vendor: 'zai', auth: {kind: 'apiKey', apiKey}})`.\n */\nconst zaiManifest: AdapterManifest = {\n vendor: 'zai',\n displayName: 'Z.ai (GLM)',\n authKinds: [\n {\n kind: 'apiKey',\n displayName: 'API Key',\n fields: [\n {\n name: 'apiKey',\n label: 'API Key',\n type: 'password',\n required: true,\n help: 'Get an API key from https://z.ai/manage-apikey/apikey-list',\n },\n {\n name: 'baseURL',\n label: 'Base URL',\n type: 'url',\n required: false,\n default: 'https://api.z.ai/api/paas/v4',\n help: 'Defaults to the general API. Coding-Plan keys must use https://api.z.ai/api/coding/paas/v4.',\n },\n ],\n },\n ],\n knownModels: [\n {\n id: 'glm-5.2',\n displayName: 'GLM-5.2',\n capabilities: {\n streaming: true,\n tools: true,\n vision: false,\n systemPrompt: true,\n maxContextTokens: 1_000_000,\n },\n },\n {\n id: 'glm-4.7',\n displayName: 'GLM-4.7',\n capabilities: {\n streaming: true,\n tools: true,\n vision: false,\n systemPrompt: true,\n maxContextTokens: 200_000,\n },\n },\n ],\n supportsModelListing: false,\n docsUrl: 'https://docs.z.ai/',\n};\n\nclass ZaiAdapter extends OpenAIAdapter {\n readonly vendor = zaiManifest.vendor;\n\n override init(auth: ApiKeyAuth, client?: Parameters<OpenAIAdapter['init']>[1]): void {\n super.init(\n {\n ...auth,\n baseURL: auth.baseURL ?? 'https://api.z.ai/api/paas/v4',\n },\n client,\n );\n }\n\n protected override knownModels() {\n return zaiManifest.knownModels;\n }\n\n // prompt_cache_key is unverified against Zai's OpenAI-compat endpoint —\n // do not forward.\n protected override forwardCacheKey(): boolean {\n return false;\n }\n}\n\nexport const zaiFactory: AdapterFactory<ApiKeyAuth> = {\n vendor: zaiManifest.vendor,\n manifest: zaiManifest,\n create: () => new ZaiAdapter(),\n};\n\n/**\n * xAI (Grok) alias factory. xAI serves an OpenAI-compatible Chat Completions\n * surface; the only differences from OpenAI are the default `baseURL` and\n * the model catalog.\n *\n * Consumers call `createLlm({vendor: 'xai', auth: {kind: 'apiKey', apiKey}})`.\n */\nconst xaiManifest: AdapterManifest = {\n vendor: 'xai',\n displayName: 'xAI (Grok)',\n authKinds: [\n {\n kind: 'apiKey',\n displayName: 'API Key',\n fields: [\n {\n name: 'apiKey',\n label: 'API Key',\n type: 'password',\n required: true,\n help: 'Get an API key from https://console.x.ai/team/default/api-keys',\n },\n {\n name: 'baseURL',\n label: 'Base URL',\n type: 'url',\n required: false,\n default: 'https://api.x.ai/v1',\n help: 'Override for proxy endpoints. Defaults to xAI production.',\n },\n ],\n },\n ],\n knownModels: [\n {\n id: 'grok-4.3',\n displayName: 'Grok 4.3',\n capabilities: {\n streaming: true,\n tools: true,\n vision: true,\n systemPrompt: true,\n maxContextTokens: 1_000_000,\n },\n },\n {\n id: 'grok-4.20-0309-reasoning',\n displayName: 'Grok 4.20 (Reasoning)',\n capabilities: {\n streaming: true,\n tools: true,\n vision: true,\n systemPrompt: true,\n maxContextTokens: 1_000_000,\n },\n },\n {\n id: 'grok-4.20-0309-non-reasoning',\n displayName: 'Grok 4.20 (Non-Reasoning)',\n capabilities: {\n streaming: true,\n tools: true,\n vision: true,\n systemPrompt: true,\n maxContextTokens: 1_000_000,\n },\n },\n {\n id: 'grok-4.20-multi-agent-0309',\n displayName: 'Grok 4.20 Multi-Agent',\n capabilities: {\n streaming: true,\n tools: true,\n vision: true,\n systemPrompt: true,\n maxContextTokens: 1_000_000,\n },\n },\n ],\n supportsModelListing: true,\n docsUrl: 'https://docs.x.ai/',\n};\n\nclass XaiAdapter extends OpenAIAdapter {\n readonly vendor = xaiManifest.vendor;\n\n override init(auth: ApiKeyAuth, client?: Parameters<OpenAIAdapter['init']>[1]): void {\n super.init(\n {\n ...auth,\n baseURL: auth.baseURL ?? 'https://api.x.ai/v1',\n },\n client,\n );\n }\n\n protected override knownModels() {\n return xaiManifest.knownModels;\n }\n\n // xAI caches automatically server-side; prompt_cache_key is unverified\n // against its param handling — do not forward.\n protected override forwardCacheKey(): boolean {\n return false;\n }\n}\n\nexport const xaiFactory: AdapterFactory<ApiKeyAuth> = {\n vendor: xaiManifest.vendor,\n manifest: xaiManifest,\n create: () => new XaiAdapter(),\n};\n\n/**\n * AWS Bedrock \"Mantle\" alias factory — Bedrock's OpenAI-compatible surface,\n * which resells third-party open-weight models (Z.ai GLM, Moonshot Kimi, xAI\n * Grok, DeepSeek, MiniMax, Qwen, …) behind ONE endpoint and ONE Bedrock API\n * key. This is deliberately vendor-neutral: the model id carries the provider\n * (`zai.glm-5`, `moonshotai.kimi-k2.5`), so a newly-launched Bedrock model is\n * usable by setting `model` — no adapter change and no library release.\n *\n * Prefer this over the per-provider aliases (`zai`, `moonshot`, `xai`) when the\n * credential is a Bedrock API key rather than a native vendor key. Those\n * aliases differ from this one only in their default `baseURL`.\n *\n * Note the path split: most models are served on `/v1`, but xAI models are\n * served ONLY on `/openai/v1`. A `401 \"Berm is not enabled\"` means the wrong\n * path, not a missing entitlement — override `baseURL` for those.\n *\n * This is NOT the `bedrock` adapter, which speaks Bedrock's native Converse\n * API via the AWS SDK and supports SigV4/IAM auth. Use that one for Anthropic\n * and Amazon Nova models; use this one for the OpenAI-compatible catalog.\n *\n * Consumers call `createLlm({vendor: 'bedrock-mantle', auth: {kind: 'apiKey', apiKey}})`.\n */\nconst BEDROCK_MANTLE_DEFAULT_BASE_URL = 'https://bedrock-mantle.us-east-1.api.aws/v1';\n\nconst bedrockMantleManifest: AdapterManifest = {\n vendor: 'bedrock-mantle',\n displayName: 'AWS Bedrock (OpenAI-compatible)',\n authKinds: [\n {\n kind: 'apiKey',\n displayName: 'API Key',\n fields: [\n {\n name: 'apiKey',\n label: 'Bedrock API Key',\n type: 'password',\n required: true,\n help: 'Generate a long-term Bedrock API key in the AWS console (Amazon Bedrock → API keys).',\n },\n {\n name: 'baseURL',\n label: 'Base URL',\n type: 'url',\n required: false,\n default: BEDROCK_MANTLE_DEFAULT_BASE_URL,\n help: 'Change the region to match your key. xAI models are served only on the /openai/v1 path.',\n },\n ],\n },\n ],\n /* A convenience seed, NOT the source of truth: the live `/v1/models`\n * endpoint is authoritative and grows continuously, which is why\n * `supportsModelListing` is true. Any model the endpoint lists can be used\n * by id without appearing here.\n *\n * AWS publishes no context-window metadata (neither `/v1/models` nor\n * `GetFoundationModel` returns it), so these limits are carried over from\n * the native-vendor manifests above for the same underlying models. Vision\n * follows Bedrock's `inputModalities`. */\n knownModels: [\n {\n id: 'zai.glm-5',\n displayName: 'GLM 5',\n capabilities: {\n streaming: true,\n tools: true,\n vision: false,\n systemPrompt: true,\n maxContextTokens: 202_800,\n },\n },\n {\n id: 'zai.glm-4.7',\n displayName: 'GLM 4.7',\n capabilities: {\n streaming: true,\n tools: true,\n vision: false,\n systemPrompt: true,\n maxContextTokens: 200_000,\n },\n },\n {\n id: 'moonshotai.kimi-k2.5',\n displayName: 'Kimi K2.5',\n capabilities: {\n streaming: true,\n tools: true,\n vision: true,\n systemPrompt: true,\n maxContextTokens: 262_144,\n },\n },\n {\n id: 'xai.grok-4.3',\n displayName: 'Grok 4.3',\n capabilities: {\n streaming: true,\n tools: true,\n vision: true,\n systemPrompt: true,\n maxContextTokens: 1_000_000,\n },\n },\n ],\n supportsModelListing: true,\n docsUrl: 'https://docs.aws.amazon.com/bedrock/latest/userguide/inference-chat-completions.html',\n};\n\nclass BedrockMantleAdapter extends OpenAIAdapter {\n readonly vendor = bedrockMantleManifest.vendor;\n\n override init(auth: ApiKeyAuth, client?: Parameters<OpenAIAdapter['init']>[1]): void {\n super.init(\n {\n ...auth,\n baseURL: auth.baseURL ?? BEDROCK_MANTLE_DEFAULT_BASE_URL,\n },\n client,\n );\n }\n\n protected override knownModels() {\n return bedrockMantleManifest.knownModels;\n }\n\n // Mantle fronts many third-party runtimes with differing param strictness,\n // and prompt_cache_key is unverified against all of them — do not forward.\n protected override forwardCacheKey(): boolean {\n return false;\n }\n}\n\nexport const bedrockMantleFactory: AdapterFactory<ApiKeyAuth> = {\n vendor: bedrockMantleManifest.vendor,\n manifest: bedrockMantleManifest,\n create: () => new BedrockMantleAdapter(),\n};\n","import Anthropic from '@anthropic-ai/sdk';\nimport type {\n ApiKeyAuth,\n ClientOptions,\n FinishReason,\n LlmAdapter,\n LlmEvent,\n Message,\n ModelInfo,\n PromptRequest,\n Tool,\n ToolCallEvent,\n} from '../../types.js';\nimport { assertValidRequest } from '../../validate.js';\nimport { makeMetadataExtractor } from '../_metadata.js';\nimport { anthropicManifest } from './manifest.js';\n\n/**\n * Anthropic response-header diagnostics. `request-id` is the support-ticket\n * id; the rate-limit headers help operators see when an account is\n * approaching limits across turns within a call.\n */\nconst ANTHROPIC_METADATA_EXTRACTOR = makeMetadataExtractor([\n { header: 'request-id', key: 'request_id' },\n { header: 'anthropic-ratelimit-requests-remaining', key: 'requests_remaining', numeric: true },\n { header: 'anthropic-ratelimit-input-tokens-remaining', key: 'input_tokens_remaining', numeric: true },\n { header: 'anthropic-ratelimit-output-tokens-remaining', key: 'output_tokens_remaining', numeric: true },\n]);\n\n/**\n * Adapter for Anthropic Claude.\n *\n * Key wire-shape differences from OpenAI:\n * - `system` is a top-level request parameter, not a message.\n * - Tool schema is `{name, description, input_schema}` (not `parameters`).\n * - Tool results are `{role: 'user', content: [{type: 'tool_result', tool_use_id, content}]}`\n * — note role: 'user', not 'tool'.\n * - Assistant messages with tool calls carry `content: [{type: 'tool_use', id, name, input}]`\n * — content is an array of blocks, not a string or a separate tool_calls array.\n * - Stream events are content-block based (content_block_start/delta/stop + message_*).\n * - `max_tokens` is REQUIRED; we default to 4096 if the caller doesn't set one.\n */\nexport class AnthropicAdapter implements LlmAdapter<ApiKeyAuth> {\n readonly vendor = anthropicManifest.vendor;\n readonly acceptedAuth = ['apiKey'] as const;\n\n private client: Anthropic | undefined;\n\n init(auth: ApiKeyAuth, client?: ClientOptions): void {\n if (!auth.apiKey) {\n throw new Error('AnthropicAdapter: apiKey is required');\n }\n this.client = new Anthropic({\n apiKey: auth.apiKey,\n ...(auth.baseURL ? { baseURL: auth.baseURL } : {}),\n ...(client?.timeout !== undefined ? { timeout: client.timeout } : {}),\n ...(client?.maxRetries !== undefined ? { maxRetries: client.maxRetries } : {}),\n });\n }\n\n async *stream(req: PromptRequest): AsyncIterable<LlmEvent> {\n assertValidRequest(req);\n const client = this.ensureClient();\n\n if (req.signal?.aborted) {\n yield { type: 'end', finishReason: 'aborted' };\n return;\n }\n\n const messages = buildWireMessages(req);\n const tools = req.tools && req.tools.length > 0 ? formatTools(req.tools) : undefined;\n\n const body: Record<string, unknown> = {\n model: req.model,\n messages,\n max_tokens: req.maxTokens ?? 4_096,\n stream: true,\n };\n if (req.system) body.system = req.system;\n if (tools) body.tools = tools;\n if (req.temperature !== undefined) body.temperature = req.temperature;\n\n if (req.cacheKey) {\n if (req.system) {\n body.system = [{ type: 'text', text: req.system, cache_control: { type: 'ephemeral' } }];\n }\n if (tools) {\n const lastTool = tools[tools.length - 1];\n lastTool.cache_control = { type: 'ephemeral' };\n }\n // Third breakpoint on the final message so the ENTIRE conversation\n // prefix is cached, not just system + tools. In the append-only\n // conversation pattern each turn's request extends the previous one,\n // so the moving breakpoint hits the prior turn's cache via Anthropic's\n // longest-prefix matching. Without this, the growing history — the\n // bulk of mid-call input tokens — is re-billed at full price every turn.\n markLastMessageForCaching(messages);\n }\n\n let stream;\n let responseHeaders: Headers | undefined;\n try {\n // Production: `.withResponse()` on the Anthropic SDK's APIPromise\n // exposes the underlying HTTP `Response` for header diagnostics.\n // Test mocks return the stream directly with no APIPromise wrapper;\n // fall through to plain await when `.withResponse` isn't present.\n const apiPromise = client.messages.create(\n body as unknown as Parameters<typeof client.messages.create>[0],\n { signal: req.signal },\n );\n const maybeWithResponse = (apiPromise as unknown as {\n withResponse?: () => Promise<{\n data: Awaited<typeof apiPromise>;\n response: { headers?: Headers };\n }>;\n }).withResponse;\n if (typeof maybeWithResponse === 'function') {\n const result = await maybeWithResponse.call(apiPromise);\n stream = result.data;\n responseHeaders = result.response?.headers;\n } else {\n stream = await apiPromise;\n }\n } catch (err) {\n if (isAbortError(err)) {\n yield { type: 'end', finishReason: 'aborted' };\n return;\n }\n throw err;\n }\n\n let currentToolUse: PendingToolUse | null = null;\n const completedToolCalls: CompletedToolCall[] = [];\n let stopReason: string | undefined;\n let inputTokens: number | undefined;\n let outputTokens: number | undefined;\n let cacheReadTokens: number | undefined;\n let cacheWriteTokens: number | undefined;\n\n try {\n for await (const event of stream as unknown as AsyncIterable<AnthropicStreamEvent>) {\n if (req.signal?.aborted) {\n yield { type: 'end', finishReason: 'aborted' };\n return;\n }\n\n switch (event.type) {\n case 'message_start':\n // Anthropic's input_tokens EXCLUDES cache activity — the read and\n // write classes arrive in their own fields, matching the library's\n // additive Usage convention with no adjustment needed.\n inputTokens = event.message?.usage?.input_tokens;\n cacheReadTokens = event.message?.usage?.cache_read_input_tokens;\n cacheWriteTokens = event.message?.usage?.cache_creation_input_tokens;\n break;\n\n case 'content_block_start': {\n const block = event.content_block;\n if (block?.type === 'tool_use') {\n currentToolUse = {\n id: block.id ?? '',\n name: block.name ?? '',\n argumentsText: '',\n };\n if (currentToolUse.id && currentToolUse.name) {\n yield {\n type: 'toolCallStart',\n id: currentToolUse.id,\n name: currentToolUse.name,\n };\n }\n }\n break;\n }\n\n case 'content_block_delta': {\n const delta = event.delta;\n if (delta?.type === 'text_delta' && delta.text) {\n yield { type: 'token', text: delta.text };\n } else if (delta?.type === 'input_json_delta' && currentToolUse && delta.partial_json) {\n currentToolUse.argumentsText += delta.partial_json;\n }\n break;\n }\n\n case 'content_block_stop':\n if (currentToolUse && currentToolUse.id && currentToolUse.name) {\n let parsed: unknown = {};\n try {\n parsed = currentToolUse.argumentsText\n ? JSON.parse(currentToolUse.argumentsText)\n : {};\n } catch {\n parsed = {};\n }\n completedToolCalls.push({\n id: currentToolUse.id,\n name: currentToolUse.name,\n arguments: parsed,\n });\n }\n currentToolUse = null;\n break;\n\n case 'message_delta':\n if (event.delta?.stop_reason) {\n stopReason = event.delta.stop_reason;\n }\n if (event.usage?.output_tokens !== undefined) {\n outputTokens = event.usage.output_tokens;\n }\n break;\n\n case 'message_stop':\n // No-op — we synthesize the `end` event after the loop completes.\n break;\n\n default:\n // Ignore unknown event types (forward compat).\n break;\n }\n }\n } catch (err) {\n if (isAbortError(err)) {\n yield { type: 'end', finishReason: 'aborted' };\n return;\n }\n throw err;\n }\n\n if (req.signal?.aborted) {\n yield { type: 'end', finishReason: 'aborted' };\n return;\n }\n\n // Emit accumulated tool calls before the end event.\n for (const tc of completedToolCalls) {\n yield {\n type: 'toolCall',\n id: tc.id,\n name: tc.name,\n arguments: tc.arguments,\n };\n }\n\n const finishReason = mapStopReason(stopReason, completedToolCalls.length > 0);\n const usage =\n inputTokens !== undefined || outputTokens !== undefined\n ? {\n ...(inputTokens !== undefined ? { inputTokens } : {}),\n ...(outputTokens !== undefined ? { outputTokens } : {}),\n ...(inputTokens !== undefined && outputTokens !== undefined\n ? {\n totalTokens:\n inputTokens + outputTokens + (cacheReadTokens ?? 0) + (cacheWriteTokens ?? 0),\n }\n : {}),\n ...(cacheReadTokens !== undefined ? { cacheReadTokens } : {}),\n ...(cacheWriteTokens !== undefined ? { cacheWriteTokens } : {}),\n }\n : undefined;\n\n const endEvent: Extract<LlmEvent, { type: 'end' }> = {\n type: 'end',\n finishReason,\n ...(usage ? { usage } : {}),\n ...(stopReason ? { rawReason: stopReason } : {}),\n };\n\n if (responseHeaders) {\n const metadata = ANTHROPIC_METADATA_EXTRACTOR(responseHeaders);\n if (Object.keys(metadata).length > 0) {\n endEvent.vendorMetadata = metadata;\n }\n }\n\n yield endEvent;\n }\n\n appendAssistantToolCall(\n history: Message[],\n toolCalls: ReadonlyArray<ToolCallEvent>,\n assistantText?: string,\n ): Message[] {\n // A text block may precede tool_use blocks in the same assistant turn.\n // Anthropic rejects an empty text block, so it is only included when the\n // model actually said something before calling the tool.\n const text = assistantText?.trim() ? assistantText : null;\n const wireMessage = {\n role: 'assistant',\n content: [\n ...(text ? [{ type: 'text', text }] : []),\n ...toolCalls.map((tc) => ({\n type: 'tool_use',\n id: tc.id,\n name: tc.name,\n input: tc.arguments ?? {},\n })),\n ],\n };\n return [\n ...history,\n {\n role: 'assistant',\n content: text ?? '',\n vendorRaw: wireMessage,\n },\n ];\n }\n\n appendToolResult(history: Message[], toolCallId: string, result: unknown): Message[] {\n const content = typeof result === 'string' ? result : JSON.stringify(result);\n const wireMessage = {\n role: 'user',\n content: [\n {\n type: 'tool_result',\n tool_use_id: toolCallId,\n content,\n },\n ],\n };\n return [\n ...history,\n {\n role: 'tool',\n content,\n vendorRaw: wireMessage,\n },\n ];\n }\n\n async listAvailableModels(): Promise<ModelInfo[]> {\n const client = this.ensureClient();\n const result = await client.models.list();\n const models: ModelInfo[] = [];\n for (const m of result.data) {\n const known = anthropicManifest.knownModels.find((k) => k.id === m.id);\n if (known) {\n models.push(known);\n } else {\n models.push({\n id: m.id,\n displayName: m.display_name ?? undefined,\n capabilities: defaultClaudeCapabilities(),\n });\n }\n }\n return models;\n }\n\n async testCredential(): Promise<void> {\n // Anthropic's /v1/models is authenticated and costs nothing.\n await this.ensureClient().models.list();\n }\n\n async warmup(): Promise<void> {\n const client = this.ensureClient();\n await client.models.list().catch(() => undefined);\n }\n\n private ensureClient(): Anthropic {\n if (!this.client) {\n throw new Error('AnthropicAdapter: init() must be called before stream()/listAvailableModels()');\n }\n return this.client;\n }\n}\n\n// ---------------------------------------------------------------------------\n// Internal types\n// ---------------------------------------------------------------------------\n\ninterface PendingToolUse {\n id: string;\n name: string;\n argumentsText: string;\n}\n\ninterface CompletedToolCall {\n id: string;\n name: string;\n arguments: unknown;\n}\n\ninterface AnthropicStreamEvent {\n type: string;\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?: {\n type?: string;\n text?: string;\n partial_json?: string;\n stop_reason?: string;\n };\n usage?: { output_tokens?: number };\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction buildWireMessages(req: PromptRequest): unknown[] {\n const out: unknown[] = [];\n for (const msg of req.messages) {\n if (msg.vendorRaw && typeof msg.vendorRaw === 'object') {\n out.push(msg.vendorRaw);\n } else {\n out.push({ role: msg.role, content: msg.content });\n }\n }\n return out;\n}\n\n/**\n * Replace the last wire message with a copy whose final content block\n * carries `cache_control: {type: 'ephemeral'}`. COPY, never mutate: the\n * `vendorRaw` entries in `messages` are the caller's history objects, and a\n * marker persisted there would accumulate one breakpoint per turn — past\n * Anthropic's 4-breakpoint limit the request is rejected outright.\n */\nfunction markLastMessageForCaching(messages: unknown[]): void {\n if (messages.length === 0) return;\n const last = messages[messages.length - 1] as { content?: unknown };\n const cacheControl = { cache_control: { type: 'ephemeral' } };\n if (typeof last.content === 'string' && last.content.length > 0) {\n messages[messages.length - 1] = {\n ...last,\n content: [{ type: 'text', text: last.content, ...cacheControl }],\n };\n } else if (Array.isArray(last.content) && last.content.length > 0) {\n const blocks = last.content as Array<Record<string, unknown>>;\n messages[messages.length - 1] = {\n ...last,\n content: [...blocks.slice(0, -1), { ...blocks[blocks.length - 1], ...cacheControl }],\n };\n }\n // Empty content (e.g. a bare assistant placeholder) is left unmarked —\n // an empty text block with cache_control would be rejected by the API.\n}\n\nfunction formatTools(tools: Tool[]): Array<Record<string, unknown>> {\n return tools.map((t) => ({\n name: t.name,\n description: t.description ?? '',\n input_schema: t.parameters ?? { type: 'object', properties: {} },\n }));\n}\n\nfunction mapStopReason(r: string | undefined, hadToolCalls: boolean): FinishReason {\n if (hadToolCalls) return 'tool';\n switch (r) {\n case 'end_turn':\n case 'stop_sequence':\n return 'stop';\n case 'tool_use':\n return 'tool';\n case 'max_tokens':\n return 'length';\n default:\n return 'stop';\n }\n}\n\nfunction defaultClaudeCapabilities() {\n return {\n streaming: true,\n tools: true,\n vision: true,\n systemPrompt: true,\n };\n}\n\nfunction isAbortError(err: unknown): boolean {\n if (!err || typeof err !== 'object') return false;\n const e = err as { name?: string; code?: string; message?: string };\n return (\n e.name === 'APIUserAbortError' ||\n e.name === 'AbortError' ||\n e.code === 'ABORT_ERR' ||\n (typeof e.message === 'string' && /aborted/i.test(e.message))\n );\n}\n","import type { AdapterManifest, ModelInfo } from '../../types.js';\n\n/**\n * Known Claude models. Model listing via `listAvailableModels()` hits\n * Anthropic's live `/v1/models` endpoint; this curated list drives the\n * admin-UI dropdown and capability validation.\n *\n * All Claude models in this list support tools, streaming, system prompts,\n * and vision. There is no reasoning-only / tool-less variant to special-case\n * the way OpenAI's o1 family does.\n */\nconst ANTHROPIC_KNOWN_MODELS: ModelInfo[] = [\n {\n id: 'claude-opus-4-7',\n displayName: 'Claude Opus 4.7',\n capabilities: {\n streaming: true,\n tools: true,\n vision: true,\n systemPrompt: true,\n maxContextTokens: 200_000,\n },\n },\n {\n id: 'claude-sonnet-4-6',\n displayName: 'Claude Sonnet 4.6',\n capabilities: {\n streaming: true,\n tools: true,\n vision: true,\n systemPrompt: true,\n maxContextTokens: 200_000,\n },\n },\n {\n id: 'claude-haiku-4-5-20251001',\n displayName: 'Claude Haiku 4.5',\n capabilities: {\n streaming: true,\n tools: true,\n vision: true,\n systemPrompt: true,\n maxContextTokens: 200_000,\n },\n },\n {\n id: 'claude-3-7-sonnet-20250219',\n displayName: 'Claude 3.7 Sonnet',\n capabilities: {\n streaming: true,\n tools: true,\n vision: true,\n systemPrompt: true,\n maxContextTokens: 200_000,\n },\n },\n {\n id: 'claude-3-5-sonnet-20241022',\n displayName: 'Claude 3.5 Sonnet',\n capabilities: {\n streaming: true,\n tools: true,\n vision: true,\n systemPrompt: true,\n maxContextTokens: 200_000,\n },\n },\n {\n id: 'claude-3-5-haiku-20241022',\n displayName: 'Claude 3.5 Haiku',\n capabilities: {\n streaming: true,\n tools: true,\n vision: false,\n systemPrompt: true,\n maxContextTokens: 200_000,\n },\n },\n];\n\nexport const anthropicManifest: AdapterManifest = {\n vendor: 'anthropic',\n displayName: 'Anthropic Claude',\n authKinds: [\n {\n kind: 'apiKey',\n displayName: 'API Key',\n fields: [\n {\n name: 'apiKey',\n label: 'API Key',\n type: 'password',\n required: true,\n help: 'Get an API key from https://console.anthropic.com/settings/keys',\n },\n {\n name: 'baseURL',\n label: 'Base URL',\n type: 'url',\n required: false,\n default: 'https://api.anthropic.com',\n help: 'Override for proxies or enterprise deployments.',\n },\n ],\n },\n ],\n knownModels: ANTHROPIC_KNOWN_MODELS,\n supportsModelListing: true,\n docsUrl: 'https://docs.anthropic.com/en/api/overview',\n};\n","import type { AdapterFactory, ApiKeyAuth } from '../../types.js';\nimport { AnthropicAdapter } from './adapter.js';\nimport { anthropicManifest } from './manifest.js';\n\nexport const anthropicFactory: AdapterFactory<ApiKeyAuth> = {\n vendor: anthropicManifest.vendor,\n manifest: anthropicManifest,\n create: () => new AnthropicAdapter(),\n};\n","import { GoogleGenAI } from '@google/genai';\nimport type {\n ClientOptions,\n GoogleApiKeyAuth,\n LlmAdapter,\n LlmEvent,\n Message,\n ModelInfo,\n PromptRequest,\n ToolCallEvent,\n} from '../../types.js';\nimport {\n appendGeminiAssistantToolCall,\n appendGeminiToolResult,\n listGeminiModels,\n streamFromGemini,\n} from './_streaming.js';\nimport { googleManifest } from './manifest.js';\n\n/**\n * Adapter for Google Gemini via AI Studio (`@google/genai`, API key auth).\n *\n * Wire translation lives in `_streaming.ts` and is shared with the\n * Vertex-Gemini adapter — both use the same `@google/genai` SDK and the\n * same on-wire shape; only client construction differs.\n *\n * For service-account auth on Vertex AI, see the `vertex-gemini` adapter.\n */\nexport class GoogleAdapter implements LlmAdapter<GoogleApiKeyAuth> {\n readonly vendor = googleManifest.vendor;\n readonly acceptedAuth = ['googleApiKey'] as const;\n\n private client: GoogleGenAI | undefined;\n\n init(auth: GoogleApiKeyAuth, _client?: ClientOptions): void {\n if (auth.kind !== 'googleApiKey') {\n throw new Error(\n `GoogleAdapter: unsupported auth kind '${(auth as { kind: string }).kind}'`,\n );\n }\n if (!auth.apiKey) {\n throw new Error('GoogleAdapter: apiKey is required');\n }\n this.client = new GoogleGenAI({ apiKey: auth.apiKey });\n }\n\n stream(req: PromptRequest): AsyncIterable<LlmEvent> {\n return streamFromGemini(this.ensureClient(), req);\n }\n\n appendAssistantToolCall(\n history: Message[],\n toolCalls: ReadonlyArray<ToolCallEvent>,\n assistantText?: string,\n ): Message[] {\n return appendGeminiAssistantToolCall(history, toolCalls, assistantText);\n }\n\n appendToolResult(history: Message[], toolCallId: string, result: unknown): Message[] {\n return appendGeminiToolResult(history, toolCallId, result);\n }\n\n async listAvailableModels(): Promise<ModelInfo[]> {\n return listGeminiModels(this.ensureClient(), googleManifest.knownModels);\n }\n\n async testCredential(): Promise<void> {\n // Model listing authenticates; no stream needed.\n await listGeminiModels(this.ensureClient(), googleManifest.knownModels);\n }\n\n async warmup(): Promise<void> {\n // @google/genai has no cheap idempotent warmup endpoint. No-op.\n }\n\n private ensureClient(): GoogleGenAI {\n if (!this.client) {\n throw new Error('GoogleAdapter: init() must be called before stream()/listAvailableModels()');\n }\n return this.client;\n }\n}\n","import type { GoogleGenAI } from '@google/genai';\nimport type {\n FinishReason,\n LlmEvent,\n Message,\n ModelInfo,\n PromptRequest,\n Tool,\n} from '../../types.js';\nimport { assertValidRequest } from '../../validate.js';\n\n/**\n * Gemini wire translation, shared between the Google AI Studio adapter\n * and the Vertex-Gemini adapter. Both use the same `@google/genai` SDK\n * with the same on-wire shape — only the client construction differs.\n */\nexport async function* streamFromGemini(\n client: GoogleGenAI,\n req: PromptRequest,\n): AsyncIterable<LlmEvent> {\n assertValidRequest(req);\n\n if (req.signal?.aborted) {\n yield { type: 'end', finishReason: 'aborted' };\n return;\n }\n\n const contents = buildWireContents(req);\n const tools = req.tools && req.tools.length > 0 ? formatTools(req.tools) : undefined;\n\n const config: Record<string, unknown> = {};\n if (req.system) {\n config.systemInstruction = { parts: [{ text: req.system }] };\n }\n if (tools) config.tools = tools;\n if (req.temperature !== undefined) config.temperature = req.temperature;\n if (req.maxTokens !== undefined) config.maxOutputTokens = req.maxTokens;\n if (req.signal) config.abortSignal = req.signal;\n\n // Merge caller-supplied provider-specific params into the generation\n // config (e.g. Gemini 3's thinkingConfig). Add-only: never overwrite a\n // library-managed field, so this can extend the request but not corrupt\n // its core shape.\n if (req.providerParams) {\n for (const [key, value] of Object.entries(req.providerParams)) {\n if (!(key in config)) config[key] = value;\n }\n }\n\n // req.cacheKey is intentionally NOT applied here.\n // Gemini 2.5 models perform implicit prompt caching server-side automatically —\n // no request parameter is needed or accepted. Explicit context caching via\n // `cachedContent` requires a stateful create/TTL/delete lifecycle that cannot\n // be driven by a single stateless request field, so it is out of scope for\n // cacheKey. This preserves the library's silent-ignore contract: adapters\n // without a native per-request cache mechanism simply leave cacheKey unread.\n // Note: this helper is shared by both the Google AI Studio adapter and the\n // Vertex-Gemini adapter; the same reasoning applies to both.\n\n let stream;\n try {\n stream = await client.models.generateContentStream({\n model: req.model,\n contents: contents as Parameters<typeof client.models.generateContentStream>[0]['contents'],\n config,\n });\n } catch (err) {\n if (isAbortError(err)) {\n yield { type: 'end', finishReason: 'aborted' };\n return;\n }\n throw err;\n }\n\n const toolCallCounter = new Map<string, number>();\n const completedToolCalls: Array<{ id: string; name: string; arguments: unknown }> = [];\n let stopReason: string | undefined;\n let inputTokens: number | undefined;\n let outputTokens: number | undefined;\n let totalTokens: number | undefined;\n let cacheReadTokens: number | undefined;\n\n try {\n for await (const chunk of stream) {\n if (req.signal?.aborted) {\n yield { type: 'end', finishReason: 'aborted' };\n return;\n }\n\n const usage = chunk.usageMetadata;\n if (usage) {\n // Gemini's promptTokenCount INCLUDES implicitly-cached tokens\n // (cachedContentTokenCount is a sub-detail). Subtract it out so\n // inputTokens means UNCACHED input, per the library's additive\n // Usage convention.\n if (usage.cachedContentTokenCount !== undefined) {\n cacheReadTokens = usage.cachedContentTokenCount;\n }\n if (usage.promptTokenCount !== undefined) {\n inputTokens = usage.promptTokenCount - (usage.cachedContentTokenCount ?? 0);\n }\n if (usage.candidatesTokenCount !== undefined) outputTokens = usage.candidatesTokenCount;\n if (usage.totalTokenCount !== undefined) totalTokens = usage.totalTokenCount;\n }\n\n const candidate = chunk.candidates?.[0];\n if (!candidate?.content?.parts) {\n if (candidate?.finishReason) stopReason = candidate.finishReason;\n continue;\n }\n\n for (const part of candidate.content.parts) {\n if (typeof part.text === 'string' && part.text.length > 0) {\n yield { type: 'token', text: part.text };\n }\n if (part.functionCall) {\n const name = part.functionCall.name ?? '';\n if (!name) continue;\n const count = toolCallCounter.get(name) ?? 0;\n toolCallCounter.set(name, count + 1);\n const id = count === 0 ? name : `${name}#${count}`;\n yield { type: 'toolCallStart', id, name };\n completedToolCalls.push({\n id,\n name,\n arguments: part.functionCall.args ?? {},\n });\n }\n }\n\n if (candidate.finishReason) {\n stopReason = candidate.finishReason;\n }\n }\n } catch (err) {\n if (isAbortError(err)) {\n yield { type: 'end', finishReason: 'aborted' };\n return;\n }\n throw err;\n }\n\n if (req.signal?.aborted) {\n yield { type: 'end', finishReason: 'aborted' };\n return;\n }\n\n for (const tc of completedToolCalls) {\n yield {\n type: 'toolCall',\n id: tc.id,\n name: tc.name,\n arguments: tc.arguments,\n };\n }\n\n const finishReason = mapFinishReason(stopReason, completedToolCalls.length > 0);\n const usage =\n inputTokens !== undefined || outputTokens !== undefined || totalTokens !== undefined\n ? {\n ...(inputTokens !== undefined ? { inputTokens } : {}),\n ...(outputTokens !== undefined ? { outputTokens } : {}),\n ...(totalTokens !== undefined ? { totalTokens } : {}),\n ...(cacheReadTokens !== undefined ? { cacheReadTokens } : {}),\n }\n : undefined;\n\n const endEvent: Extract<LlmEvent, { type: 'end' }> = {\n type: 'end',\n finishReason,\n ...(usage ? { usage } : {}),\n ...(stopReason ? { rawReason: stopReason } : {}),\n };\n yield endEvent;\n}\n\n/**\n * Build an assistant-with-tool-call turn in the Gemini wire shape (role:\n * 'model', parts: [{functionCall, ...}]). Shared between Google AI Studio\n * and Vertex-Gemini adapters.\n */\nexport function appendGeminiAssistantToolCall(\n history: Message[],\n toolCalls: ReadonlyArray<Extract<LlmEvent, { type: 'toolCall' }>>,\n assistantText?: string,\n): Message[] {\n // A text part may precede functionCall parts in the same model turn.\n const text = assistantText?.trim() ? assistantText : null;\n const wireMessage = {\n role: 'model',\n parts: [\n ...(text ? [{ text }] : []),\n ...toolCalls.map((tc) => ({\n functionCall: {\n name: parseToolName(tc.id),\n args: tc.arguments ?? {},\n },\n })),\n ],\n };\n return [\n ...history,\n {\n role: 'assistant',\n content: text ?? '',\n vendorRaw: wireMessage,\n },\n ];\n}\n\n/**\n * Build a tool-result message in the Gemini wire shape. Shared between\n * Google AI Studio and Vertex-Gemini adapters.\n */\nexport function appendGeminiToolResult(\n history: Message[],\n toolCallId: string,\n result: unknown,\n): Message[] {\n const name = parseToolName(toolCallId);\n const content = typeof result === 'string' ? result : JSON.stringify(result);\n const wireMessage = {\n role: 'user',\n parts: [\n {\n functionResponse: {\n name,\n response: { result: content },\n },\n },\n ],\n };\n return [\n ...history,\n {\n role: 'tool',\n content,\n vendorRaw: wireMessage,\n },\n ];\n}\n\n/**\n * Call the models.list() pager and return normalised `ModelInfo` records,\n * merging capabilities from a known-models table when possible.\n */\nexport async function listGeminiModels(\n client: GoogleGenAI,\n knownModels: ReadonlyArray<ModelInfo>,\n): Promise<ModelInfo[]> {\n const out: ModelInfo[] = [];\n const pager = await client.models.list();\n for await (const m of pager as AsyncIterable<{ name?: string; displayName?: string }>) {\n const id = stripModelPrefix(m.name ?? '');\n if (!id) continue;\n const known = knownModels.find((k) => k.id === id);\n if (known) {\n out.push(known);\n } else {\n out.push({\n id,\n displayName: m.displayName ?? undefined,\n capabilities: defaultGeminiCapabilities(),\n });\n }\n }\n return out;\n}\n\n// ---------------------------------------------------------------------------\n// Internal helpers (exported for adapter-local reuse only; not public)\n// ---------------------------------------------------------------------------\n\nfunction buildWireContents(req: PromptRequest): unknown[] {\n const out: unknown[] = [];\n for (const msg of req.messages) {\n if (msg.vendorRaw && typeof msg.vendorRaw === 'object') {\n out.push(msg.vendorRaw);\n continue;\n }\n const text = typeof msg.content === 'string' ? msg.content : JSON.stringify(msg.content);\n out.push({\n role: toGeminiRole(msg.role),\n parts: [{ text }],\n });\n }\n return out;\n}\n\nfunction toGeminiRole(role: string): 'user' | 'model' {\n return role === 'assistant' || role === 'model' ? 'model' : 'user';\n}\n\nfunction formatTools(tools: Tool[]): Array<Record<string, unknown>> {\n return [\n {\n functionDeclarations: tools.map((t) => ({\n name: t.name,\n description: t.description ?? '',\n parameters: t.parameters ?? { type: 'object', properties: {} },\n })),\n },\n ];\n}\n\nfunction mapFinishReason(r: string | undefined, hadToolCalls: boolean): FinishReason {\n if (hadToolCalls && (r === 'STOP' || r === 'TOOL_CALLS' || !r)) return 'tool';\n switch (r) {\n case 'STOP':\n return 'stop';\n case 'MAX_TOKENS':\n return 'length';\n case 'SAFETY':\n case 'RECITATION':\n return 'filtered';\n case 'TOOL_CALLS':\n return 'tool';\n default:\n return 'stop';\n }\n}\n\nfunction parseToolName(id: string): string {\n const hashIdx = id.lastIndexOf('#');\n if (hashIdx === -1) return id;\n const suffix = id.slice(hashIdx + 1);\n if (/^\\d+$/.test(suffix)) return id.slice(0, hashIdx);\n return id;\n}\n\nfunction stripModelPrefix(name: string): string {\n return name.startsWith('models/') ? name.slice('models/'.length) : name;\n}\n\nexport function defaultGeminiCapabilities() {\n return {\n streaming: true,\n tools: true,\n vision: true,\n systemPrompt: true,\n };\n}\n\nfunction isAbortError(err: unknown): boolean {\n if (!err || typeof err !== 'object') return false;\n const e = err as { name?: string; code?: string; message?: string };\n return (\n e.name === 'APIUserAbortError' ||\n e.name === 'AbortError' ||\n e.code === 'ABORT_ERR' ||\n (typeof e.message === 'string' && /aborted/i.test(e.message))\n );\n}\n","import type { AdapterManifest, ModelInfo } from '../../types.js';\n\n/**\n * Known Gemini models. Model listing via `listAvailableModels()` hits the\n * live endpoint; this curated list drives the admin-UI dropdown.\n *\n * All Gemini models in this list support tools and streaming. Only\n * `gemini-2.0-flash-lite` loses vision support — the 3.x `-lite` variants\n * are fully multimodal.\n */\nconst GOOGLE_KNOWN_MODELS: ModelInfo[] = [\n {\n id: 'gemini-3.6-flash',\n displayName: 'Gemini 3.6 Flash',\n capabilities: {\n streaming: true,\n tools: true,\n vision: true,\n systemPrompt: true,\n maxContextTokens: 1_000_000,\n },\n },\n {\n id: 'gemini-3.5-flash',\n displayName: 'Gemini 3.5 Flash',\n capabilities: {\n streaming: true,\n tools: true,\n vision: true,\n systemPrompt: true,\n maxContextTokens: 1_000_000,\n },\n },\n {\n id: 'gemini-3.5-flash-lite',\n displayName: 'Gemini 3.5 Flash-Lite',\n capabilities: {\n streaming: true,\n tools: true,\n vision: true,\n systemPrompt: true,\n maxContextTokens: 1_000_000,\n },\n },\n {\n id: 'gemini-2.5-pro',\n displayName: 'Gemini 2.5 Pro',\n capabilities: {\n streaming: true,\n tools: true,\n vision: true,\n systemPrompt: true,\n maxContextTokens: 1_000_000,\n },\n },\n {\n id: 'gemini-2.5-flash',\n displayName: 'Gemini 2.5 Flash',\n capabilities: {\n streaming: true,\n tools: true,\n vision: true,\n systemPrompt: true,\n maxContextTokens: 1_000_000,\n },\n },\n {\n id: 'gemini-2.0-flash',\n displayName: 'Gemini 2.0 Flash',\n capabilities: {\n streaming: true,\n tools: true,\n vision: true,\n systemPrompt: true,\n maxContextTokens: 1_000_000,\n },\n },\n {\n id: 'gemini-2.0-flash-lite',\n displayName: 'Gemini 2.0 Flash Lite',\n capabilities: {\n streaming: true,\n tools: true,\n vision: false,\n systemPrompt: true,\n maxContextTokens: 1_000_000,\n },\n },\n {\n id: 'gemini-1.5-pro',\n displayName: 'Gemini 1.5 Pro',\n capabilities: {\n streaming: true,\n tools: true,\n vision: true,\n systemPrompt: true,\n maxContextTokens: 2_000_000,\n },\n },\n {\n id: 'gemini-1.5-flash',\n displayName: 'Gemini 1.5 Flash',\n capabilities: {\n streaming: true,\n tools: true,\n vision: true,\n systemPrompt: true,\n maxContextTokens: 1_000_000,\n },\n },\n];\n\nexport const googleManifest: AdapterManifest = {\n vendor: 'google',\n displayName: 'Google Gemini',\n authKinds: [\n {\n kind: 'googleApiKey',\n displayName: 'API Key',\n fields: [\n {\n name: 'apiKey',\n label: 'API Key',\n type: 'password',\n required: true,\n help: 'Get an API key from https://aistudio.google.com/apikey',\n },\n ],\n },\n ],\n knownModels: GOOGLE_KNOWN_MODELS,\n supportsModelListing: true,\n docsUrl: 'https://ai.google.dev/gemini-api/docs',\n};\n\n","import type { AdapterFactory, GoogleApiKeyAuth } from '../../types.js';\nimport { GoogleAdapter } from './adapter.js';\nimport { googleManifest } from './manifest.js';\n\nexport const googleFactory: AdapterFactory<GoogleApiKeyAuth> = {\n vendor: googleManifest.vendor,\n manifest: googleManifest,\n create: () => new GoogleAdapter(),\n};\n","import { GoogleGenAI } from '@google/genai';\nimport type {\n ClientOptions,\n LlmAdapter,\n LlmEvent,\n Message,\n ModelInfo,\n PromptRequest,\n ToolCallEvent,\n VertexServiceAccountAuth,\n} from '../../types.js';\nimport {\n appendGeminiAssistantToolCall,\n appendGeminiToolResult,\n listGeminiModels,\n streamFromGemini,\n} from '../google/_streaming.js';\nimport { vertexGeminiManifest } from './manifest.js';\n\n/**\n * Adapter for Gemini models running on Vertex AI.\n *\n * Wire shape is identical to the `google` adapter — both use `@google/genai`\n * and speak the same contents/parts protocol. The only differences are:\n * - Client is constructed with `vertexai: true` plus project/location.\n * - Auth uses a GCP service account (pass through `googleAuthOptions`).\n *\n * For third-party models hosted on Vertex (Mistral, Llama, etc.) that speak\n * the OpenAI-compatible protocol, see the `vertex-openai` adapter.\n */\nexport class VertexGeminiAdapter implements LlmAdapter<VertexServiceAccountAuth> {\n readonly vendor = vertexGeminiManifest.vendor;\n readonly acceptedAuth = ['vertexServiceAccount'] as const;\n\n private client: GoogleGenAI | undefined;\n\n init(auth: VertexServiceAccountAuth, _client?: ClientOptions): void {\n if (auth.kind !== 'vertexServiceAccount') {\n throw new Error(\n `VertexGeminiAdapter: unsupported auth kind '${(auth as { kind: string }).kind}'`,\n );\n }\n if (!auth.credentials) {\n throw new Error('VertexGeminiAdapter: service-account credentials are required');\n }\n if (!auth.projectId) {\n throw new Error('VertexGeminiAdapter: projectId is required');\n }\n if (!auth.location) {\n throw new Error('VertexGeminiAdapter: location is required');\n }\n\n this.client = new GoogleGenAI({\n vertexai: true,\n project: auth.projectId,\n location: auth.location,\n googleAuthOptions: {\n credentials: auth.credentials as Record<string, unknown>,\n },\n });\n }\n\n stream(req: PromptRequest): AsyncIterable<LlmEvent> {\n return streamFromGemini(this.ensureClient(), req);\n }\n\n appendAssistantToolCall(\n history: Message[],\n toolCalls: ReadonlyArray<ToolCallEvent>,\n assistantText?: string,\n ): Message[] {\n return appendGeminiAssistantToolCall(history, toolCalls, assistantText);\n }\n\n appendToolResult(history: Message[], toolCallId: string, result: unknown): Message[] {\n return appendGeminiToolResult(history, toolCallId, result);\n }\n\n async listAvailableModels(): Promise<ModelInfo[]> {\n return listGeminiModels(this.ensureClient(), vertexGeminiManifest.knownModels);\n }\n\n async testCredential(): Promise<void> {\n // Listing models authenticates via the service-account bearer.\n await listGeminiModels(this.ensureClient(), vertexGeminiManifest.knownModels);\n }\n\n async warmup(): Promise<void> {\n // No cheap idempotent warmup endpoint. No-op.\n }\n\n private ensureClient(): GoogleGenAI {\n if (!this.client) {\n throw new Error(\n 'VertexGeminiAdapter: init() must be called before stream()/listAvailableModels()',\n );\n }\n return this.client;\n }\n}\n","import type { AdapterManifest, ModelInfo } from '../../types.js';\n\n/**\n * Known Gemini models available on Vertex AI.\n *\n * Vertex-hosted Gemini models often use the `-001` / `-002` versioning\n * suffix (vs AI Studio's bare id). We list both conventions so the admin-UI\n * dropdown covers common deployments.\n */\nconst VERTEX_GEMINI_KNOWN_MODELS: ModelInfo[] = [\n {\n id: 'gemini-3.6-flash',\n displayName: 'Gemini 3.6 Flash',\n capabilities: {\n streaming: true,\n tools: true,\n vision: true,\n systemPrompt: true,\n maxContextTokens: 1_000_000,\n },\n },\n {\n id: 'gemini-3.5-flash',\n displayName: 'Gemini 3.5 Flash',\n capabilities: {\n streaming: true,\n tools: true,\n vision: true,\n systemPrompt: true,\n maxContextTokens: 1_000_000,\n },\n },\n {\n id: 'gemini-3.5-flash-lite',\n displayName: 'Gemini 3.5 Flash-Lite',\n capabilities: {\n streaming: true,\n tools: true,\n vision: true,\n systemPrompt: true,\n maxContextTokens: 1_000_000,\n },\n },\n {\n id: 'gemini-2.5-pro',\n displayName: 'Gemini 2.5 Pro',\n capabilities: {\n streaming: true,\n tools: true,\n vision: true,\n systemPrompt: true,\n maxContextTokens: 1_000_000,\n },\n },\n {\n id: 'gemini-2.5-flash',\n displayName: 'Gemini 2.5 Flash',\n capabilities: {\n streaming: true,\n tools: true,\n vision: true,\n systemPrompt: true,\n maxContextTokens: 1_000_000,\n },\n },\n {\n id: 'gemini-2.0-flash',\n displayName: 'Gemini 2.0 Flash',\n capabilities: {\n streaming: true,\n tools: true,\n vision: true,\n systemPrompt: true,\n maxContextTokens: 1_000_000,\n },\n },\n {\n id: 'gemini-1.5-pro',\n displayName: 'Gemini 1.5 Pro',\n capabilities: {\n streaming: true,\n tools: true,\n vision: true,\n systemPrompt: true,\n maxContextTokens: 2_000_000,\n },\n },\n {\n id: 'gemini-1.5-flash',\n displayName: 'Gemini 1.5 Flash',\n capabilities: {\n streaming: true,\n tools: true,\n vision: true,\n systemPrompt: true,\n maxContextTokens: 1_000_000,\n },\n },\n];\n\nexport const vertexGeminiManifest: AdapterManifest = {\n vendor: 'vertex-gemini',\n displayName: 'Vertex AI — Gemini',\n authKinds: [\n {\n kind: 'vertexServiceAccount',\n displayName: 'Service Account JSON',\n fields: [\n {\n name: 'credentials',\n label: 'Service Account Key (JSON)',\n type: 'json-file',\n required: true,\n help: 'Upload the service account key JSON from Google Cloud Console.',\n },\n {\n name: 'projectId',\n label: 'Project ID',\n type: 'text',\n required: true,\n help: 'GCP project that hosts the Vertex AI deployment.',\n },\n {\n name: 'location',\n label: 'Region',\n type: 'select',\n required: true,\n default: 'us-central1',\n options: [\n { value: 'us-central1', label: 'us-central1' },\n { value: 'us-east1', label: 'us-east1' },\n { value: 'us-east4', label: 'us-east4' },\n { value: 'us-west1', label: 'us-west1' },\n { value: 'us-west4', label: 'us-west4' },\n { value: 'europe-west1', label: 'europe-west1' },\n { value: 'europe-west2', label: 'europe-west2' },\n { value: 'europe-west3', label: 'europe-west3' },\n { value: 'europe-west4', label: 'europe-west4' },\n { value: 'asia-east1', label: 'asia-east1' },\n { value: 'asia-northeast1', label: 'asia-northeast1' },\n { value: 'asia-southeast1', label: 'asia-southeast1' },\n ],\n },\n ],\n },\n ],\n knownModels: VERTEX_GEMINI_KNOWN_MODELS,\n supportsModelListing: true,\n docsUrl: 'https://cloud.google.com/vertex-ai/generative-ai/docs',\n};\n","import type { AdapterFactory, VertexServiceAccountAuth } from '../../types.js';\nimport { VertexGeminiAdapter } from './adapter.js';\nimport { vertexGeminiManifest } from './manifest.js';\n\nexport const vertexGeminiFactory: AdapterFactory<VertexServiceAccountAuth> = {\n vendor: vertexGeminiManifest.vendor,\n manifest: vertexGeminiManifest,\n create: () => new VertexGeminiAdapter(),\n};\n","import OpenAI from 'openai';\nimport { GoogleAuth } from 'google-auth-library';\nimport type {\n ClientOptions,\n LlmAdapter,\n LlmEvent,\n Message,\n ModelInfo,\n PromptRequest,\n ToolCallEvent,\n VertexServiceAccountAuth,\n} from '../../types.js';\nimport {\n appendOpenAIAssistantToolCall,\n appendOpenAIToolResult,\n streamFromOpenAI,\n} from '../openai/_streaming.js';\nimport { makeMetadataExtractor } from '../_metadata.js';\nimport { vertexOpenAIManifest } from './manifest.js';\n\n/**\n * Vertex partner-model response-header diagnostics. Sparse —\n * Google's compat layer mostly returns standard request id and\n * little else useful for client-side observability.\n */\nconst VERTEX_OPENAI_METADATA_EXTRACTOR = makeMetadataExtractor([\n { header: 'x-request-id', key: 'request_id' },\n]);\n\n/**\n * Adapter for third-party models on Vertex AI (Mistral, Llama, etc.) that\n * expose an OpenAI-compatible endpoint. Shares all wire translation with\n * the native OpenAI adapter; only the client differs — `baseURL` is\n * Vertex-specific and a custom `fetch` wraps each request to inject a GCP\n * Bearer token from a service account.\n */\nexport class VertexOpenAIAdapter implements LlmAdapter<VertexServiceAccountAuth> {\n readonly vendor = vertexOpenAIManifest.vendor;\n readonly acceptedAuth = ['vertexServiceAccount'] as const;\n\n private client: OpenAI | undefined;\n private googleAuth: GoogleAuth | undefined;\n\n init(auth: VertexServiceAccountAuth, client?: ClientOptions): void {\n if (auth.kind !== 'vertexServiceAccount') {\n throw new Error(\n `VertexOpenAIAdapter: unsupported auth kind '${(auth as { kind: string }).kind}'`,\n );\n }\n if (!auth.credentials) {\n throw new Error('VertexOpenAIAdapter: service-account credentials are required');\n }\n if (!auth.projectId) {\n throw new Error('VertexOpenAIAdapter: projectId is required');\n }\n if (!auth.location) {\n throw new Error('VertexOpenAIAdapter: location is required');\n }\n\n // Vertex AI's OpenAI-compatible endpoint is at /v1beta1/ — documented in\n // Google's SDK examples (google-cloud-aiplatform) and Google Cloud docs.\n // A /v1/ variant returns 404; do not use.\n const baseURL =\n `https://${auth.location}-aiplatform.googleapis.com/v1beta1/projects/` +\n `${auth.projectId}/locations/${auth.location}/endpoints/openapi`;\n\n this.googleAuth = new GoogleAuth({\n credentials: auth.credentials as Record<string, unknown>,\n scopes: ['https://www.googleapis.com/auth/cloud-platform'],\n });\n\n const authedFetch: typeof fetch = async (input, init) => {\n const googleClient = await this.googleAuth!.getClient();\n const token = await googleClient.getAccessToken();\n const headers = new Headers(init?.headers);\n headers.set('Authorization', `Bearer ${token.token ?? ''}`);\n const response = await fetch(input, { ...init, headers });\n if (!response.ok) {\n return surfaceErrorBody(response, input);\n }\n return response;\n };\n\n this.client = new OpenAI({\n apiKey: 'vertex-ai',\n baseURL,\n fetch: authedFetch as never,\n ...(client?.timeout !== undefined ? { timeout: client.timeout } : {}),\n ...(client?.maxRetries !== undefined ? { maxRetries: client.maxRetries } : {}),\n });\n }\n\n stream(req: PromptRequest): AsyncIterable<LlmEvent> {\n // Vertex AI's Llama MaaS endpoint returns an empty assistant message\n // (zero tokens, finish_reason: stop) when max_tokens is not set. Apply\n // a sensible default so callers don't have to know this quirk.\n return streamFromOpenAI(this.ensureClient(), req, {\n knownModels: vertexOpenAIManifest.knownModels,\n defaultMaxTokens: 4096,\n // Pin legacy `max_tokens`: Vertex's OpenAI-compat partner-model\n // endpoint predates `max_completion_tokens` and may not recognize it.\n // The model-id heuristic wouldn't catch a partner model named in the\n // OpenAI style (unlikely today, but defensive).\n tokensParam: 'max_tokens',\n vendorMetadataExtractor: VERTEX_OPENAI_METADATA_EXTRACTOR,\n });\n }\n\n appendAssistantToolCall(\n history: Message[],\n toolCalls: ReadonlyArray<ToolCallEvent>,\n assistantText?: string,\n ): Message[] {\n return appendOpenAIAssistantToolCall(history, toolCalls, assistantText);\n }\n\n appendToolResult(history: Message[], toolCallId: string, result: unknown): Message[] {\n return appendOpenAIToolResult(history, toolCallId, result);\n }\n\n async listAvailableModels(): Promise<ModelInfo[]> {\n // The Vertex OpenAI-compatible endpoint does not expose a models list.\n // Return the curated set from the manifest.\n return [...vertexOpenAIManifest.knownModels];\n }\n\n async testCredential(): Promise<void> {\n // The OpenAI-compat endpoint has no list-models or other zero-cost\n // authenticated endpoint. Chat probes against a specific model are a\n // bad proxy: they require that partner model (Mistral, Llama, …) to be\n // granted in the caller's GCP project, which is independent of whether\n // the service-account credentials themselves are valid.\n //\n // Minting a Google access token from the service-account is sufficient\n // and vendor-appropriate: it verifies the credential JSON is well-formed,\n // the service account exists, and the key is active. If the token mints\n // but the caller hasn't enabled Vertex AI or a specific partner model in\n // the project, the first stream() call will tell them — credential\n // validity and model entitlement are properly separated concerns.\n if (!this.googleAuth) {\n throw new Error('VertexOpenAIAdapter: init() must be called before testCredential()');\n }\n const googleClient = await this.googleAuth.getClient();\n const token = await googleClient.getAccessToken();\n if (!token.token) {\n throw new Error('VertexOpenAIAdapter: service account did not mint an access token');\n }\n }\n\n async warmup(): Promise<void> {\n // No cheap idempotent warmup endpoint. No-op.\n }\n\n private ensureClient(): OpenAI {\n if (!this.client) {\n throw new Error(\n 'VertexOpenAIAdapter: init() must be called before stream()/listAvailableModels()',\n );\n }\n return this.client;\n }\n}\n\n/**\n * On a non-2xx response, read the Vertex error body and reconstruct the\n * Response so the OpenAI SDK can include the body in its thrown error.\n *\n * Why this is necessary: the OpenAI SDK v6 drops the body on some error\n * responses (the ones delivered gzipped, which Vertex does) — callers see\n * \"404 status code (no body)\" with no indication of root cause. Vertex's\n * real body for the model-in-wrong-region case carries useful text naming\n * the model and region. Reading the body here (before the SDK's parser gets\n * it) lets us pass it through as plain text; the SDK then surfaces it\n * verbatim in `err.message`.\n */\nasync function surfaceErrorBody(\n response: Response,\n input: Parameters<typeof fetch>[0],\n): Promise<Response> {\n let body = '';\n try {\n body = await response.text();\n } catch {\n // Body already consumed or unreadable — fall through with empty body.\n }\n\n const url = typeof input === 'string' ? input : input instanceof URL ? input.toString() : input.url;\n const hint =\n response.status === 404 && !body\n ? ' (no body returned — most commonly means the requested model is not hosted in this region; ' +\n 'check Google\\'s partner-model availability matrix)'\n : '';\n\n // Log so operators see the full vendor text in api-server / feature-server\n // logs regardless of how the thrown error is formatted downstream.\n if (typeof console !== 'undefined' && console.warn) {\n console.warn(\n `[vertex-openai] ${response.status} ${response.statusText} from ${url}: ` +\n `${body || '(empty body)'}${hint}`,\n );\n }\n\n // Vertex wraps errors in a single-element JSON array: `[{error: {...}}]`.\n // The OpenAI SDK expects a bare object `{error: {...}}`, so when parsing\n // the array it fails to find `.error` and throws \"no body\". Unwrap the\n // array so the SDK's error.message carries the vendor's own text.\n const normalizedBody = unwrapVertexErrorArray(body) + hint;\n\n // Drop encoding headers so the SDK doesn't try to decompress plain text.\n const headers = new Headers(response.headers);\n headers.delete('content-encoding');\n headers.delete('content-length');\n\n return new Response(normalizedBody, {\n status: response.status,\n statusText: response.statusText,\n headers,\n });\n}\n\nfunction unwrapVertexErrorArray(body: string): string {\n if (!body) return body;\n const trimmed = body.trim();\n if (!trimmed.startsWith('[')) return body;\n try {\n const parsed = JSON.parse(trimmed);\n if (Array.isArray(parsed) && parsed.length === 1 && parsed[0]?.error) {\n return JSON.stringify(parsed[0]);\n }\n } catch {\n // not JSON; leave as-is\n }\n return body;\n}\n","import type { AdapterManifest, ModelInfo } from '../../types.js';\n\n/**\n * Known third-party models available via Vertex AI's OpenAI-compatible\n * endpoint. This is NOT an exhaustive list — Vertex offers many publisher\n * models from Mistral, Meta, AI21, etc. — but it covers the common options\n * so the admin-UI dropdown is useful out of the box.\n */\nconst VERTEX_OPENAI_KNOWN_MODELS: ModelInfo[] = [\n {\n id: 'mistral-large',\n displayName: 'Mistral Large (on Vertex)',\n capabilities: {\n streaming: true,\n tools: true,\n vision: false,\n systemPrompt: true,\n maxContextTokens: 128_000,\n },\n },\n {\n id: 'mistral-small',\n displayName: 'Mistral Small (on Vertex)',\n capabilities: {\n streaming: true,\n tools: true,\n vision: false,\n systemPrompt: true,\n maxContextTokens: 32_000,\n },\n },\n {\n id: 'meta/llama-3.3-70b-instruct-maas',\n displayName: 'Llama 3.3 70B Instruct (on Vertex)',\n capabilities: {\n streaming: true,\n tools: true,\n vision: false,\n systemPrompt: true,\n maxContextTokens: 128_000,\n },\n },\n {\n id: 'meta/llama-3.1-405b-instruct-maas',\n displayName: 'Llama 3.1 405B Instruct (on Vertex)',\n capabilities: {\n streaming: true,\n tools: true,\n vision: false,\n systemPrompt: true,\n maxContextTokens: 128_000,\n },\n },\n];\n\nexport const vertexOpenAIManifest: AdapterManifest = {\n vendor: 'vertex-openai',\n displayName: 'Vertex AI — OpenAI-compatible',\n authKinds: [\n {\n kind: 'vertexServiceAccount',\n displayName: 'Service Account JSON',\n fields: [\n {\n name: 'credentials',\n label: 'Service Account Key (JSON)',\n type: 'json-file',\n required: true,\n help: 'Upload the service account key JSON from Google Cloud Console.',\n },\n {\n name: 'projectId',\n label: 'Project ID',\n type: 'text',\n required: true,\n help: 'GCP project that hosts the Vertex AI deployment.',\n },\n {\n name: 'location',\n label: 'Region',\n type: 'select',\n required: true,\n default: 'us-central1',\n // Same region set as vertex-gemini plus us-east5 (where Google\n // hosts Llama partner models). Partner-model availability varies\n // per region; Google's docs for each model are the source of truth.\n options: [\n { value: 'us-central1', label: 'us-central1' },\n { value: 'us-east1', label: 'us-east1' },\n { value: 'us-east4', label: 'us-east4' },\n { value: 'us-east5', label: 'us-east5' },\n { value: 'us-west1', label: 'us-west1' },\n { value: 'us-west4', label: 'us-west4' },\n { value: 'europe-west1', label: 'europe-west1' },\n { value: 'europe-west2', label: 'europe-west2' },\n { value: 'europe-west3', label: 'europe-west3' },\n { value: 'europe-west4', label: 'europe-west4' },\n { value: 'asia-east1', label: 'asia-east1' },\n { value: 'asia-northeast1', label: 'asia-northeast1' },\n { value: 'asia-southeast1', label: 'asia-southeast1' },\n ],\n },\n ],\n },\n ],\n knownModels: VERTEX_OPENAI_KNOWN_MODELS,\n // The OpenAI-compatible endpoint on Vertex does not expose a /models list.\n supportsModelListing: false,\n docsUrl: 'https://cloud.google.com/vertex-ai/generative-ai/docs/partner-models/use-openai',\n};\n","import type { AdapterFactory, VertexServiceAccountAuth } from '../../types.js';\nimport { VertexOpenAIAdapter } from './adapter.js';\nimport { vertexOpenAIManifest } from './manifest.js';\n\nexport const vertexOpenAIFactory: AdapterFactory<VertexServiceAccountAuth> = {\n vendor: vertexOpenAIManifest.vendor,\n manifest: vertexOpenAIManifest,\n create: () => new VertexOpenAIAdapter(),\n};\n","import {\n BedrockRuntimeClient,\n ConverseStreamCommand,\n} from '@aws-sdk/client-bedrock-runtime';\nimport {\n BedrockClient,\n ListFoundationModelsCommand,\n} from '@aws-sdk/client-bedrock';\nimport type {\n BedrockApiKeyAuth,\n BedrockIamAuth,\n ClientOptions,\n FinishReason,\n LlmAdapter,\n LlmEvent,\n Message,\n ModelInfo,\n PromptRequest,\n Tool,\n ToolCallEvent,\n} from '../../types.js';\nimport { assertValidRequest } from '../../validate.js';\nimport { extractMetadata } from '../_metadata.js';\nimport { bedrockManifest } from './manifest.js';\n\ntype BedrockAuthSpec = BedrockApiKeyAuth | BedrockIamAuth;\n\n/**\n * Adapter for AWS Bedrock via the Converse API.\n *\n * Bedrock's Converse wire shape diverges from the other adapters:\n * - Messages use `{role, content: [ContentBlock, ...]}` where content is\n * ALWAYS an array. Text blocks are `{text}`; tool-use blocks are\n * `{toolUse: {toolUseId, name, input}}`; tool results are\n * `{toolResult: {toolUseId, content: [{text}]}}` carried on role `user`.\n * - System prompt is `system: [{text}]` at the top level (array).\n * - Tools go in `toolConfig: {tools: [{toolSpec: {name, description,\n * inputSchema: {json}}}]}`.\n * - Conversations must start with a `user` message; adjacent same-role\n * messages are rejected by the service (the library does not validate —\n * the caller is responsible for ordering).\n * - Streaming events are different too:\n * messageStart → (contentBlockStart → contentBlockDelta* →\n * contentBlockStop)* → messageStop → metadata\n * - Auth has two modes: bedrockApiKey (bearer token) or bedrockIam\n * (accessKeyId + secretAccessKey [+ sessionToken]).\n */\nexport class BedrockAdapter implements LlmAdapter<BedrockAuthSpec> {\n readonly vendor = bedrockManifest.vendor;\n readonly acceptedAuth = ['bedrockApiKey', 'bedrockIam'] as const;\n\n private client: BedrockRuntimeClient | undefined;\n private controlClientConfig: Record<string, unknown> | undefined;\n\n init(auth: BedrockAuthSpec, client?: ClientOptions): void {\n if (!auth.region) {\n throw new Error('BedrockAdapter: region is required');\n }\n\n const config: Record<string, unknown> = {\n region: auth.region,\n ...(client?.endpoint ? { endpoint: client.endpoint } : {}),\n ...(client?.maxRetries !== undefined ? { maxAttempts: client.maxRetries + 1 } : {}),\n };\n\n if (auth.kind === 'bedrockApiKey') {\n if (!auth.apiKey) {\n throw new Error('BedrockAdapter: apiKey is required for bedrockApiKey auth');\n }\n // Bedrock API key is a bearer token — must be preferred over SigV4 so\n // it wins against ambient credentials (e.g., EC2 instance role).\n config.token = { token: auth.apiKey };\n config.authSchemePreference = ['httpBearerAuth'];\n } else if (auth.kind === 'bedrockIam') {\n if (!auth.accessKeyId || !auth.secretAccessKey) {\n throw new Error('BedrockAdapter: accessKeyId and secretAccessKey required for bedrockIam auth');\n }\n config.credentials = {\n accessKeyId: auth.accessKeyId,\n secretAccessKey: auth.secretAccessKey,\n ...(auth.sessionToken ? { sessionToken: auth.sessionToken } : {}),\n };\n } else {\n throw new Error(\n `BedrockAdapter: unsupported auth kind '${(auth as { kind: string }).kind}'`,\n );\n }\n\n this.client = new BedrockRuntimeClient(config);\n // Stash the same config so testCredential can spin up a control-plane\n // client on demand. `@aws-sdk/client-bedrock` accepts the same auth\n // shape as the runtime client.\n this.controlClientConfig = config;\n }\n\n async *stream(req: PromptRequest): AsyncIterable<LlmEvent> {\n assertValidRequest(req);\n const client = this.ensureClient();\n\n if (req.signal?.aborted) {\n yield { type: 'end', finishReason: 'aborted' };\n return;\n }\n\n const messages = buildWireMessages(req);\n const tools =\n req.tools && req.tools.length > 0 ? { tools: formatTools(req.tools) } : undefined;\n\n const inferenceConfig: Record<string, unknown> = {};\n if (req.maxTokens !== undefined) inferenceConfig.maxTokens = req.maxTokens;\n if (req.temperature !== undefined) inferenceConfig.temperature = req.temperature;\n\n const commandInput: Record<string, unknown> = {\n modelId: req.model,\n messages,\n };\n if (req.system) commandInput.system = [{ text: req.system }];\n if (tools) commandInput.toolConfig = tools;\n if (Object.keys(inferenceConfig).length > 0) {\n commandInput.inferenceConfig = inferenceConfig;\n }\n\n const caching = req.cacheKey ? cachePointSupport(req.model) : undefined;\n if (caching) {\n if (commandInput.system) {\n (commandInput.system as unknown[]).push({ cachePoint: { type: 'default' } });\n }\n if (tools && caching.tools) {\n (tools.tools as unknown[]).push({ cachePoint: { type: 'default' } });\n }\n // Third cache point after the final message's content so the ENTIRE\n // conversation prefix is cached, not just system + tools. In the\n // append-only conversation pattern each turn's request extends the\n // previous one, so the moving cache point hits the prior turn's cache\n // via longest-prefix matching. Without this, the growing history — the\n // bulk of mid-call input tokens — is re-billed at full price every turn.\n markLastMessageForCaching(messages);\n }\n\n const command = new ConverseStreamCommand(\n commandInput as unknown as ConstructorParameters<typeof ConverseStreamCommand>[0],\n );\n\n let response;\n try {\n response = await client.send(command, { abortSignal: req.signal });\n } catch (err) {\n if (isAbortError(err)) {\n yield { type: 'end', finishReason: 'aborted' };\n return;\n }\n throw err;\n }\n\n if (!response.stream) {\n yield { type: 'end', finishReason: 'stop' };\n return;\n }\n\n let currentToolUse: PendingToolUse | null = null;\n const completedToolCalls: Array<{ id: string; name: string; arguments: unknown }> = [];\n let stopReason: string | undefined;\n let inputTokens: number | undefined;\n let outputTokens: number | undefined;\n let totalTokens: number | undefined;\n let cacheReadTokens: number | undefined;\n let cacheWriteTokens: number | undefined;\n\n try {\n for await (const event of response.stream as AsyncIterable<BedrockStreamEvent>) {\n if (req.signal?.aborted) {\n yield { type: 'end', finishReason: 'aborted' };\n return;\n }\n\n if (event.contentBlockStart) {\n const start = event.contentBlockStart.start;\n if (start?.toolUse) {\n currentToolUse = {\n id: start.toolUse.toolUseId ?? '',\n name: start.toolUse.name ?? '',\n inputText: '',\n };\n if (currentToolUse.id && currentToolUse.name) {\n yield {\n type: 'toolCallStart',\n id: currentToolUse.id,\n name: currentToolUse.name,\n };\n }\n }\n } else if (event.contentBlockDelta) {\n const delta = event.contentBlockDelta.delta;\n if (delta?.text) {\n yield { type: 'token', text: delta.text };\n }\n if (delta?.toolUse && currentToolUse && typeof delta.toolUse.input === 'string') {\n currentToolUse.inputText += delta.toolUse.input;\n }\n } else if (event.contentBlockStop) {\n if (currentToolUse && currentToolUse.id && currentToolUse.name) {\n let parsed: unknown = {};\n try {\n parsed = currentToolUse.inputText ? JSON.parse(currentToolUse.inputText) : {};\n } catch {\n parsed = {};\n }\n completedToolCalls.push({\n id: currentToolUse.id,\n name: currentToolUse.name,\n arguments: parsed,\n });\n }\n currentToolUse = null;\n } else if (event.messageStop) {\n stopReason = event.messageStop.stopReason;\n } else if (event.metadata) {\n if (event.metadata.usage) {\n // Converse's inputTokens EXCLUDES cache activity — the read and\n // write classes arrive in their own fields, matching the\n // library's additive Usage convention with no adjustment needed.\n inputTokens = event.metadata.usage.inputTokens;\n outputTokens = event.metadata.usage.outputTokens;\n totalTokens = event.metadata.usage.totalTokens;\n cacheReadTokens = event.metadata.usage.cacheReadInputTokens;\n cacheWriteTokens = event.metadata.usage.cacheWriteInputTokens;\n }\n }\n }\n } catch (err) {\n if (isAbortError(err)) {\n yield { type: 'end', finishReason: 'aborted' };\n return;\n }\n throw err;\n }\n\n if (req.signal?.aborted) {\n yield { type: 'end', finishReason: 'aborted' };\n return;\n }\n\n for (const tc of completedToolCalls) {\n yield {\n type: 'toolCall',\n id: tc.id,\n name: tc.name,\n arguments: tc.arguments,\n };\n }\n\n const finishReason = mapStopReason(stopReason, completedToolCalls.length > 0);\n const usage =\n inputTokens !== undefined || outputTokens !== undefined || totalTokens !== undefined\n ? {\n ...(inputTokens !== undefined ? { inputTokens } : {}),\n ...(outputTokens !== undefined ? { outputTokens } : {}),\n ...(totalTokens !== undefined ? { totalTokens } : {}),\n ...(cacheReadTokens !== undefined ? { cacheReadTokens } : {}),\n ...(cacheWriteTokens !== undefined ? { cacheWriteTokens } : {}),\n }\n : undefined;\n\n const endEvent: Extract<LlmEvent, { type: 'end' }> = {\n type: 'end',\n finishReason,\n ...(usage ? { usage } : {}),\n ...(stopReason ? { rawReason: stopReason } : {}),\n };\n\n // Bedrock-specific response-header diagnostics. AWS surfaces them on\n // `response.$metadata.httpHeaders` rather than a standards-compliant\n // `Headers` instance — and the AWS SDK's TypeScript types don't include\n // the field, so cast through unknown. Useful signals:\n // `x-amzn-bedrock-invocation-latency` (vendor-side latency),\n // `x-amzn-bedrock-cache-{read,write}-input-token-count` (prompt-cache\n // effectiveness), `x-amzn-bedrock-trace-id` (support tickets).\n const httpHeaders = (response.$metadata as unknown as\n | { httpHeaders?: Record<string, string> }\n | undefined)?.httpHeaders;\n if (httpHeaders) {\n const metadata = extractMetadata(\n [\n { header: 'x-amzn-bedrock-invocation-latency', key: 'invocation_latency_ms', numeric: true },\n { header: 'x-amzn-bedrock-cache-read-input-token-count', key: 'cache_read_input_tokens', numeric: true },\n { header: 'x-amzn-bedrock-cache-write-input-token-count', key: 'cache_write_input_tokens', numeric: true },\n { header: 'x-amzn-bedrock-trace-id', key: 'trace_id' },\n ],\n httpHeaders,\n );\n if (Object.keys(metadata).length > 0) {\n endEvent.vendorMetadata = metadata;\n }\n }\n\n yield endEvent;\n }\n\n appendAssistantToolCall(\n history: Message[],\n toolCalls: ReadonlyArray<ToolCallEvent>,\n assistantText?: string,\n ): Message[] {\n // Converse allows a text block before toolUse blocks in the same turn;\n // an empty one is rejected, so it is only included when non-blank.\n const text = assistantText?.trim() ? assistantText : null;\n const wireMessage = {\n role: 'assistant',\n content: [\n ...(text ? [{ text }] : []),\n ...toolCalls.map((tc) => ({\n toolUse: {\n toolUseId: tc.id,\n name: tc.name,\n input: tc.arguments ?? {},\n },\n })),\n ],\n };\n return [\n ...history,\n {\n role: 'assistant',\n content: text ?? '',\n vendorRaw: wireMessage,\n },\n ];\n }\n\n appendToolResult(history: Message[], toolCallId: string, result: unknown): Message[] {\n const text = typeof result === 'string' ? result : JSON.stringify(result);\n const wireMessage = {\n role: 'user',\n content: [\n {\n toolResult: {\n toolUseId: toolCallId,\n content: [{ text }],\n },\n },\n ],\n };\n return [\n ...history,\n {\n role: 'tool',\n content: text,\n vendorRaw: wireMessage,\n },\n ];\n }\n\n async listAvailableModels(): Promise<ModelInfo[]> {\n // The bedrock-runtime client has no /models endpoint. We don't call the\n // control-plane client here because listFoundationModels returns every\n // model AWS offers, not models the account has access to — that distinction\n // is what `ModelInfo.deprecated` surfaces in the manifest.\n return [...bedrockManifest.knownModels];\n }\n\n async testCredential(): Promise<void> {\n // Use the control-plane client (`@aws-sdk/client-bedrock`) with the same\n // credential config as the runtime client. `ListFoundationModels` is the\n // cheapest authenticated GET and works regardless of which specific\n // models the account has granted — an auth check, not an access check.\n if (!this.controlClientConfig) {\n throw new Error('BedrockAdapter: init() must be called before testCredential()');\n }\n const control = new BedrockClient(this.controlClientConfig);\n try {\n await control.send(new ListFoundationModelsCommand({}));\n } finally {\n control.destroy();\n }\n }\n\n async warmup(): Promise<void> {\n // No cheap idempotent warmup. No-op.\n }\n\n private ensureClient(): BedrockRuntimeClient {\n if (!this.client) {\n throw new Error(\n 'BedrockAdapter: init() must be called before stream()/listAvailableModels()',\n );\n }\n return this.client;\n }\n}\n\n// ---------------------------------------------------------------------------\n// Internal types\n// ---------------------------------------------------------------------------\n\ninterface PendingToolUse {\n id: string;\n name: string;\n inputText: string;\n}\n\ninterface BedrockStreamEvent {\n messageStart?: { role?: string };\n contentBlockStart?: {\n start?: {\n toolUse?: { toolUseId?: string; name?: string };\n };\n contentBlockIndex?: number;\n };\n contentBlockDelta?: {\n delta?: {\n text?: string;\n toolUse?: { input?: string };\n };\n contentBlockIndex?: number;\n };\n contentBlockStop?: { contentBlockIndex?: number };\n messageStop?: { stopReason?: string };\n metadata?: {\n usage?: {\n inputTokens?: number;\n outputTokens?: number;\n totalTokens?: number;\n cacheReadInputTokens?: number;\n cacheWriteInputTokens?: number;\n };\n };\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction buildWireMessages(req: PromptRequest): unknown[] {\n const out: unknown[] = [];\n for (const msg of req.messages) {\n if (msg.vendorRaw && typeof msg.vendorRaw === 'object') {\n out.push(msg.vendorRaw);\n continue;\n }\n // Normalize plain-string messages to Converse's content-block array shape.\n const text = typeof msg.content === 'string' ? msg.content : JSON.stringify(msg.content);\n // Bedrock Converse does not accept role:'tool' — tool results must be\n // carried as content blocks on a role:'user' message. Without vendorRaw\n // we fall back to a text block.\n const role = msg.role === 'tool' ? 'user' : msg.role;\n out.push({\n role,\n content: [{ text }],\n });\n }\n return out;\n}\n\n/**\n * Which Converse fields accept an explicit `cachePoint` for this model, or\n * undefined if the model doesn't support explicit prompt caching at all.\n * Per the Bedrock prompt-caching docs, Anthropic Claude models accept cache\n * points in system, messages and tools; Amazon Nova only in system and\n * messages (a cachePoint in toolConfig.tools is rejected as an extraneous\n * key). Other models get none — they rely on implicit caching, if any.\n * Matched by substring so cross-region profile IDs (`us.`, `global.`, ...)\n * resolve to the underlying model.\n */\nfunction cachePointSupport(model: string): { tools: boolean } | undefined {\n if (model.includes('anthropic.claude')) return { tools: true };\n if (model.includes('amazon.nova')) return { tools: false };\n return undefined;\n}\n\n/**\n * Replace the last wire message with a copy whose content array gains a\n * trailing `{cachePoint: {type: 'default'}}` block. COPY, never mutate: the\n * `vendorRaw` entries in `messages` are the caller's history objects, and a\n * cache point persisted there would accumulate one per turn — past the\n * service's 4-cache-point limit the request is rejected outright.\n */\nfunction markLastMessageForCaching(messages: unknown[]): void {\n if (messages.length === 0) return;\n const last = messages[messages.length - 1] as { content?: unknown };\n if (Array.isArray(last.content) && last.content.length > 0) {\n messages[messages.length - 1] = {\n ...last,\n content: [...last.content, { cachePoint: { type: 'default' } }],\n };\n }\n}\n\nfunction formatTools(tools: Tool[]): Array<Record<string, unknown>> {\n return tools.map((t) => ({\n toolSpec: {\n name: t.name,\n // Bedrock rejects empty-string descriptions; fall back to a single space.\n description: t.description && t.description.length > 0 ? t.description : ' ',\n inputSchema: {\n json: t.parameters ?? { type: 'object', properties: {} },\n },\n },\n }));\n}\n\nfunction mapStopReason(r: string | undefined, hadToolCalls: boolean): FinishReason {\n if (hadToolCalls) return 'tool';\n switch (r) {\n case 'end_turn':\n case 'stop_sequence':\n return 'stop';\n case 'tool_use':\n return 'tool';\n case 'max_tokens':\n return 'length';\n case 'content_filtered':\n case 'guardrail_intervened':\n return 'filtered';\n default:\n return 'stop';\n }\n}\n\nfunction isAbortError(err: unknown): boolean {\n if (!err || typeof err !== 'object') return false;\n const e = err as { name?: string; code?: string; message?: string };\n return (\n e.name === 'AbortError' ||\n e.name === 'APIUserAbortError' ||\n e.code === 'ABORT_ERR' ||\n (typeof e.message === 'string' && /aborted/i.test(e.message))\n );\n}\n","import type { AdapterManifest, ModelInfo } from '../../types.js';\n\n/**\n * Known Bedrock models spanning the main publisher families available via the\n * Converse API. Model ids on Bedrock include a publisher prefix and version\n * suffix (e.g. `anthropic.claude-3-5-sonnet-20241022-v2:0`).\n *\n * Bedrock also supports cross-region inference profile ids (e.g.\n * `us.anthropic.claude-3-5-sonnet-20241022-v2:0`) — users should enter those\n * directly when needed; the adapter passes `model` through unchanged.\n *\n * Ordering matters: the first entry is used as the default probe model by\n * api-server's GET /LlmCredentials/:sid/test when `supportsModelListing` is\n * false. Amazon Nova Micro is first — AWS's own cheapest-per-token model,\n * broadly available across regions, and (unlike third-party Claude/Llama\n * models) not subject to provider-led \"legacy\" lifecycles that can revoke\n * access. Operators can override via `JAMBONZ_LLM_BEDROCK_PROBE_MODEL`.\n *\n * `deprecated: true` signals a model AWS may reject with\n * `ResourceNotFoundException: \"This Model is marked by provider as Legacy\"`\n * on accounts that haven't invoked it in the last 30 days. The id is kept in\n * the manifest so accounts that *have* been using it can still select it;\n * the webapp should badge/sort deprecated entries accordingly.\n *\n * Claude 4.x ids carry the `us.` cross-region inference profile prefix\n * because on-demand invocation of plain `anthropic.claude-*-4-*` ids is no\n * longer available in most regions — Bedrock requires the profile. Operators\n * in EU/APAC should edit to `eu.`/`apac.` or enter a region-specific id.\n *\n * FORMAT CONTRACT: `scripts/check-bedrock-models.ts --write` edits this file\n * in place by text substitution. Each entry MUST preserve the current shape:\n * an object literal whose first line is ` id: '<id>',` (two-space indent\n * plus trailing comma) and whose closing brace is on a line with exactly two\n * spaces of indent. If you restructure this array (e.g. move to JSON import),\n * update the script's edit strategy.\n */\nconst BEDROCK_KNOWN_MODELS: ModelInfo[] = [\n {\n id: 'amazon.nova-micro-v1:0',\n displayName: 'Amazon Nova Micro',\n capabilities: {\n streaming: true,\n tools: true,\n vision: false,\n systemPrompt: true,\n maxContextTokens: 128_000,\n },\n },\n {\n id: 'amazon.nova-lite-v1:0',\n displayName: 'Amazon Nova Lite',\n capabilities: {\n streaming: true,\n tools: true,\n vision: true,\n systemPrompt: true,\n maxContextTokens: 300_000,\n },\n },\n {\n id: 'amazon.nova-pro-v1:0',\n displayName: 'Amazon Nova Pro',\n capabilities: {\n streaming: true,\n tools: true,\n vision: true,\n systemPrompt: true,\n maxContextTokens: 300_000,\n },\n },\n {\n id: 'us.anthropic.claude-haiku-4-5-20251001-v1:0',\n displayName: 'Claude Haiku 4.5 (on Bedrock)',\n capabilities: {\n streaming: true,\n tools: true,\n vision: true,\n systemPrompt: true,\n maxContextTokens: 200_000,\n },\n },\n {\n id: 'us.anthropic.claude-sonnet-4-5-20250929-v1:0',\n displayName: 'Claude Sonnet 4.5 (on Bedrock)',\n capabilities: {\n streaming: true,\n tools: true,\n vision: true,\n systemPrompt: true,\n maxContextTokens: 200_000,\n },\n },\n {\n id: 'anthropic.claude-3-5-haiku-20241022-v1:0',\n displayName: 'Claude 3.5 Haiku (on Bedrock)',\n capabilities: {\n streaming: true,\n tools: true,\n vision: false,\n systemPrompt: true,\n maxContextTokens: 200_000,\n },\n deprecated: true,\n },\n {\n id: 'anthropic.claude-3-5-sonnet-20240620-v1:0',\n displayName: 'Claude 3.5 Sonnet (on Bedrock)',\n capabilities: {\n streaming: true,\n tools: true,\n vision: true,\n systemPrompt: true,\n maxContextTokens: 200_000,\n },\n deprecated: true,\n },\n {\n id: 'anthropic.claude-3-5-sonnet-20241022-v2:0',\n displayName: 'Claude 3.5 Sonnet v2 (on Bedrock)',\n capabilities: {\n streaming: true,\n tools: true,\n vision: true,\n systemPrompt: true,\n maxContextTokens: 200_000,\n },\n deprecated: true,\n },\n {\n id: 'anthropic.claude-3-7-sonnet-20250219-v1:0',\n displayName: 'Claude 3.7 Sonnet (on Bedrock)',\n capabilities: {\n streaming: true,\n tools: true,\n vision: true,\n systemPrompt: true,\n maxContextTokens: 200_000,\n },\n deprecated: true,\n },\n {\n id: 'meta.llama3-3-70b-instruct-v1:0',\n displayName: 'Llama 3.3 70B Instruct (on Bedrock)',\n capabilities: {\n streaming: true,\n tools: true,\n vision: false,\n systemPrompt: true,\n maxContextTokens: 128_000,\n },\n },\n {\n id: 'mistral.mistral-large-2407-v1:0',\n displayName: 'Mistral Large (on Bedrock)',\n capabilities: {\n streaming: true,\n tools: true,\n vision: false,\n systemPrompt: true,\n maxContextTokens: 128_000,\n },\n deprecated: true,\n },\n];\n\n// Common Bedrock regions. Not exhaustive — users can enter others via 'Other'\n// or (later) a free-text region field. The library does not validate against\n// this list; it's purely a UI aid.\nconst BEDROCK_REGIONS: Array<{ value: string; label: string }> = [\n { value: 'us-east-1', label: 'us-east-1 (N. Virginia)' },\n { value: 'us-east-2', label: 'us-east-2 (Ohio)' },\n { value: 'us-west-2', label: 'us-west-2 (Oregon)' },\n { value: 'eu-west-1', label: 'eu-west-1 (Ireland)' },\n { value: 'eu-west-3', label: 'eu-west-3 (Paris)' },\n { value: 'eu-central-1', label: 'eu-central-1 (Frankfurt)' },\n { value: 'ap-northeast-1', label: 'ap-northeast-1 (Tokyo)' },\n { value: 'ap-south-1', label: 'ap-south-1 (Mumbai)' },\n { value: 'ap-southeast-1', label: 'ap-southeast-1 (Singapore)' },\n { value: 'ap-southeast-2', label: 'ap-southeast-2 (Sydney)' },\n { value: 'ca-central-1', label: 'ca-central-1 (Canada)' },\n];\n\nexport const bedrockManifest: AdapterManifest = {\n vendor: 'bedrock',\n displayName: 'AWS Bedrock',\n authKinds: [\n {\n kind: 'bedrockApiKey',\n displayName: 'API Key',\n fields: [\n {\n name: 'apiKey',\n label: 'API Key',\n type: 'password',\n required: true,\n help: 'Bedrock API key (bearer token). Create one in the AWS console under Amazon Bedrock → API keys.',\n },\n {\n name: 'region',\n label: 'Region',\n type: 'select',\n required: true,\n default: 'us-east-1',\n options: BEDROCK_REGIONS,\n },\n ],\n },\n {\n kind: 'bedrockIam',\n displayName: 'IAM Credentials',\n fields: [\n {\n name: 'accessKeyId',\n label: 'Access Key ID',\n type: 'text',\n required: true,\n },\n {\n name: 'secretAccessKey',\n label: 'Secret Access Key',\n type: 'password',\n required: true,\n },\n {\n name: 'sessionToken',\n label: 'Session Token',\n type: 'password',\n required: false,\n help: 'Only required when using temporary credentials (e.g., STS).',\n },\n {\n name: 'region',\n label: 'Region',\n type: 'select',\n required: true,\n default: 'us-east-1',\n options: BEDROCK_REGIONS,\n },\n ],\n },\n ],\n knownModels: BEDROCK_KNOWN_MODELS,\n // The Bedrock runtime client does not expose a `/models` listing — model\n // enumeration lives in `@aws-sdk/client-bedrock` (control plane), which we\n // don't pull in. Return the curated set from the manifest.\n supportsModelListing: false,\n docsUrl: 'https://docs.aws.amazon.com/bedrock/latest/userguide/conversation-inference.html',\n};\n","import type {\n AdapterFactory,\n BedrockApiKeyAuth,\n BedrockIamAuth,\n} from '../../types.js';\nimport { BedrockAdapter } from './adapter.js';\nimport { bedrockManifest } from './manifest.js';\n\nexport const bedrockFactory: AdapterFactory<BedrockApiKeyAuth | BedrockIamAuth> = {\n vendor: bedrockManifest.vendor,\n manifest: bedrockManifest,\n create: () => new BedrockAdapter(),\n};\n","import { AzureOpenAI } from 'openai';\nimport type {\n AzureOpenAIApiKeyAuth,\n ClientOptions,\n LlmAdapter,\n LlmEvent,\n Message,\n ModelInfo,\n PromptRequest,\n ToolCallEvent,\n} from '../../types.js';\nimport {\n appendOpenAIAssistantToolCall,\n appendOpenAIToolResult,\n streamFromOpenAI,\n} from '../openai/_streaming.js';\nimport { makeMetadataExtractor } from '../_metadata.js';\nimport { azureOpenAIManifest } from './manifest.js';\n\n/**\n * Azure OpenAI response-header diagnostics.\n *\n * `x-ms-region` confirms which datacenter served (operators sometimes\n * provision multi-region deployments and want to verify routing).\n * `x-ms-deployment-name` confirms the deployment that served — useful\n * because Azure deployment names are arbitrary user strings and a\n * misconfigured credential could be pointed at a different deployment\n * than expected. `apim-request-id` is for support tickets;\n * `azureml-model-session` is the underlying model session id.\n */\nconst AZURE_OPENAI_METADATA_EXTRACTOR = makeMetadataExtractor([\n { header: 'x-ms-region', key: 'region' },\n { header: 'x-ms-deployment-name', key: 'deployment' },\n { header: 'apim-request-id', key: 'request_id' },\n { header: 'azureml-model-session', key: 'model_session' },\n { header: 'x-ratelimit-remaining-requests', key: 'requests_remaining', numeric: true },\n { header: 'x-ratelimit-remaining-tokens', key: 'tokens_remaining', numeric: true },\n]);\n\n/**\n * Adapter for Azure OpenAI Service.\n *\n * Azure speaks an OpenAI-compatible wire protocol for chat completions, so the\n * adapter reuses `streamFromOpenAI` / `appendOpenAI*` from the OpenAI adapter.\n * What differs is client construction:\n * - Auth is an `api-key` header, not `Authorization: Bearer`.\n * - The URL embeds the *deployment* name, not the model id:\n * `https://{endpoint}/openai/deployments/{deployment}/chat/completions?api-version={version}`\n * - The `model` field on the wire is ignored by Azure — the deployment in the\n * URL determines which model runs.\n *\n * The `AzureOpenAI` class exported from the `openai` SDK handles all three\n * quirks for us. It extends `OpenAI`, so passing it to `streamFromOpenAI()`\n * works without translation.\n */\nexport class AzureOpenAIAdapter implements LlmAdapter<AzureOpenAIApiKeyAuth> {\n readonly vendor = azureOpenAIManifest.vendor;\n readonly acceptedAuth = ['azureOpenAIApiKey'] as const;\n\n private client: AzureOpenAI | undefined;\n\n init(auth: AzureOpenAIApiKeyAuth, client?: ClientOptions): void {\n if (auth.kind !== 'azureOpenAIApiKey') {\n throw new Error(\n `AzureOpenAIAdapter: unsupported auth kind '${(auth as { kind: string }).kind}'`,\n );\n }\n if (!auth.apiKey) {\n throw new Error('AzureOpenAIAdapter: apiKey is required');\n }\n if (!auth.endpoint) {\n throw new Error('AzureOpenAIAdapter: endpoint is required');\n }\n if (!auth.deployment) {\n throw new Error('AzureOpenAIAdapter: deployment is required');\n }\n if (!auth.apiVersion) {\n throw new Error('AzureOpenAIAdapter: apiVersion is required');\n }\n\n this.client = new AzureOpenAI({\n apiKey: auth.apiKey,\n endpoint: auth.endpoint,\n apiVersion: auth.apiVersion,\n deployment: auth.deployment,\n ...(client?.timeout !== undefined ? { timeout: client.timeout } : {}),\n ...(client?.maxRetries !== undefined ? { maxRetries: client.maxRetries } : {}),\n });\n }\n\n stream(req: PromptRequest): AsyncIterable<LlmEvent> {\n // Azure deployment names are arbitrary user strings (e.g. `prod-gpt-4o`,\n // `my-assistant`, `gpt-5.4-mini`) — the model-id heuristic in\n // streamFromOpenAI can't see the underlying model, so pin the newer\n // parameter name. Microsoft's current Azure OpenAI backend accepts\n // `max_completion_tokens` for gpt-4o-family and requires it for\n // gpt-5-family / o-series reasoning models.\n return streamFromOpenAI(this.ensureClient(), req, {\n knownModels: azureOpenAIManifest.knownModels,\n tokensParam: 'max_completion_tokens',\n vendorMetadataExtractor: AZURE_OPENAI_METADATA_EXTRACTOR,\n });\n }\n\n appendAssistantToolCall(\n history: Message[],\n toolCalls: ReadonlyArray<ToolCallEvent>,\n assistantText?: string,\n ): Message[] {\n return appendOpenAIAssistantToolCall(history, toolCalls, assistantText);\n }\n\n appendToolResult(history: Message[], toolCallId: string, result: unknown): Message[] {\n return appendOpenAIToolResult(history, toolCallId, result);\n }\n\n async listAvailableModels(): Promise<ModelInfo[]> {\n // Azure's data-plane API doesn't expose a list-models endpoint; deployment\n // listing lives on the control plane (ARM) and requires AAD. Return the\n // manifest's curated set.\n return [...azureOpenAIManifest.knownModels];\n }\n\n async testCredential(): Promise<void> {\n // No cheap authenticated GET available on the data plane — `/models` on\n // Azure returns the account's deployments only if the key has the right\n // role, and is 404 on many configurations. A minimal chat-completions\n // call is the reliable probe: success proves the api-key authenticates\n // AND that the endpoint+deployment+api-version combination resolves.\n const client = this.ensureClient();\n await client.chat.completions.create({\n // Azure ignores `model` when a deployment is in the URL, but the SDK\n // still requires it as a parameter.\n model: 'probe',\n messages: [{ role: 'user', content: 'ping' }],\n // Use `max_completion_tokens` (not legacy `max_tokens`): gpt-5 family\n // and o-series reasoning models return 400 on the legacy parameter.\n // The newer name is a superset — also accepted by gpt-4o, gpt-4-turbo,\n // and gpt-3.5-turbo deployments — so it's the safe choice for a probe\n // that has to work regardless of the underlying deployment model.\n //\n // 256 (not 1): reasoning models consume reasoning tokens BEFORE\n // visible output, all counted against this cap. With 1 the model\n // can't produce any output and Azure returns\n // `400 Could not finish the message because max_tokens or model\n // output limit was reached`. 256 is comfortable headroom for\n // reasoning + a \"pong\"-sized reply on every model we ship in the\n // manifest, while still bounded so the probe can't run away on a\n // misconfigured deployment.\n max_completion_tokens: 256,\n stream: false,\n } as Parameters<typeof client.chat.completions.create>[0]);\n }\n\n async warmup(): Promise<void> {\n // No idempotent cheap endpoint on the data plane. No-op.\n }\n\n private ensureClient(): AzureOpenAI {\n if (!this.client) {\n throw new Error(\n 'AzureOpenAIAdapter: init() must be called before stream()/listAvailableModels()',\n );\n }\n return this.client;\n }\n}\n","import type { AdapterManifest, ModelInfo } from '../../types.js';\n\n/**\n * Known models that customers commonly deploy to Azure OpenAI Service.\n *\n * Unlike `api.openai.com`, Azure doesn't pick the model from the `model`\n * request field — the deployment name in the URL determines which model runs.\n * The manifest's model list is therefore keyed by the underlying *model* so\n * capability flags can be looked up by whichever model the user's deployment\n * points at. Common Azure deployment names mirror the model id (e.g. a\n * deployment called `gpt-4o` running `gpt-4o`), but customers may use arbitrary\n * names like `prod-chat` or `my-assistant` — that's fine; capability flags\n * default to something reasonable if the deployment name doesn't match.\n *\n * Azure's fine-tune deployments and private-preview model ids are out of scope.\n */\nconst AZURE_OPENAI_KNOWN_MODELS: ModelInfo[] = [\n {\n id: 'gpt-4o',\n displayName: 'GPT-4o (on Azure)',\n capabilities: {\n streaming: true,\n tools: true,\n vision: true,\n systemPrompt: true,\n maxContextTokens: 128_000,\n },\n },\n {\n id: 'gpt-4o-mini',\n displayName: 'GPT-4o mini (on Azure)',\n capabilities: {\n streaming: true,\n tools: true,\n vision: true,\n systemPrompt: true,\n maxContextTokens: 128_000,\n },\n },\n {\n id: 'gpt-4-turbo',\n displayName: 'GPT-4 Turbo (on Azure)',\n capabilities: {\n streaming: true,\n tools: true,\n vision: true,\n systemPrompt: true,\n maxContextTokens: 128_000,\n },\n },\n {\n // Azure spells it `gpt-35-turbo` (no dot). Keep their spelling for the id\n // so capability lookups against deployment names that echo the Azure id\n // hit.\n id: 'gpt-35-turbo',\n displayName: 'GPT-3.5 Turbo (on Azure)',\n capabilities: {\n streaming: true,\n tools: true,\n vision: false,\n systemPrompt: true,\n maxContextTokens: 16_385,\n },\n },\n {\n id: 'o1-preview',\n displayName: 'o1 preview — reasoning (on Azure)',\n capabilities: {\n streaming: false,\n tools: false,\n vision: false,\n systemPrompt: false,\n maxContextTokens: 128_000,\n },\n },\n {\n id: 'o1-mini',\n displayName: 'o1 mini — reasoning (on Azure)',\n capabilities: {\n streaming: false,\n tools: false,\n vision: false,\n systemPrompt: false,\n maxContextTokens: 128_000,\n },\n },\n];\n\nexport const azureOpenAIManifest: AdapterManifest = {\n vendor: 'azure-openai',\n displayName: 'Azure OpenAI',\n authKinds: [\n {\n kind: 'azureOpenAIApiKey',\n displayName: 'API Key',\n fields: [\n {\n name: 'apiKey',\n label: 'API Key',\n type: 'password',\n required: true,\n help:\n 'In Azure AI Foundry, open the deployment and copy the Key from ' +\n 'the Endpoint panel (eye icon to reveal). Same key is shown in ' +\n 'the Azure portal under your OpenAI resource → Keys and Endpoint.',\n },\n {\n name: 'endpoint',\n label: 'Endpoint',\n type: 'url',\n required: true,\n help:\n 'Resource hostname only — no path, no query string. Example: ' +\n 'https://my-resource.openai.azure.com. The Foundry deployment ' +\n 'page shows a Target URI like ' +\n 'https://my-resource.openai.azure.com/openai/responses?api-version=… ' +\n 'Strip everything from /openai/ onward and paste only the part ' +\n 'before it.',\n },\n {\n name: 'deployment',\n label: 'Deployment Name',\n type: 'text',\n required: true,\n help:\n 'The Name shown at the top of the deployment page in Azure AI ' +\n 'Foundry (also under Deployment info → Name). NOT the underlying ' +\n 'model id — deployments can be named anything you chose at create time.',\n },\n {\n name: 'apiVersion',\n label: 'API Version',\n type: 'text',\n required: true,\n default: '2025-03-01-preview',\n help:\n 'Data-plane api-version. Visible in Foundry as the ?api-version=… ' +\n 'query string in the Target URI, or the api_version=… line in the ' +\n 'Python sample. The default 2025-03-01-preview is the minimum that ' +\n 'works with gpt-5 / o-series deployments — Azure routes those ' +\n 'through the Responses API internally and rejects older versions.',\n },\n ],\n },\n ],\n knownModels: AZURE_OPENAI_KNOWN_MODELS,\n // Azure's list-deployments endpoint is on the control plane (ARM) and\n // requires AAD credentials the data-plane API key doesn't carry. Return\n // the curated set from the manifest.\n supportsModelListing: false,\n docsUrl: 'https://learn.microsoft.com/en-us/azure/ai-services/openai/reference',\n};\n","import type { AdapterFactory, AzureOpenAIApiKeyAuth } from '../../types.js';\nimport { AzureOpenAIAdapter } from './adapter.js';\nimport { azureOpenAIManifest } from './manifest.js';\n\nexport const azureOpenAIFactory: AdapterFactory<AzureOpenAIApiKeyAuth> = {\n vendor: azureOpenAIManifest.vendor,\n manifest: azureOpenAIManifest,\n create: () => new AzureOpenAIAdapter(),\n};\n","import type { AdapterManifest, ModelInfo } from '../../types.js';\n\n/**\n * Curated production-recommended Groq models. The live `/openai/v1/models`\n * endpoint returns the full catalog (which churns frequently); this list\n * seeds the admin-UI dropdown and capability flags.\n *\n * All entries here are tool-capable — Groq's catalog also includes\n * vision-only and safety-classifier models that we deliberately exclude\n * from the curated set because they don't make sense as the primary LLM\n * for a voice agent.\n */\nconst GROQ_KNOWN_MODELS: ModelInfo[] = [\n {\n id: 'llama-3.3-70b-versatile',\n displayName: 'Llama 3.3 70B Versatile (Groq)',\n capabilities: {\n streaming: true,\n tools: true,\n vision: false,\n systemPrompt: true,\n maxContextTokens: 128_000,\n },\n },\n {\n id: 'llama-3.1-8b-instant',\n displayName: 'Llama 3.1 8B Instant (Groq)',\n capabilities: {\n streaming: true,\n tools: true,\n vision: false,\n systemPrompt: true,\n maxContextTokens: 128_000,\n },\n },\n {\n id: 'gemma2-9b-it',\n displayName: 'Gemma 2 9B (Groq)',\n capabilities: {\n streaming: true,\n tools: true,\n vision: false,\n systemPrompt: true,\n maxContextTokens: 8_192,\n },\n },\n];\n\nexport const groqManifest: AdapterManifest = {\n vendor: 'groq',\n displayName: 'Groq',\n authKinds: [\n {\n kind: 'apiKey',\n displayName: 'API Key',\n fields: [\n {\n name: 'apiKey',\n label: 'API Key',\n type: 'password',\n required: true,\n help: 'Get an API key from https://console.groq.com/keys (sign in first if needed)',\n },\n {\n name: 'baseURL',\n label: 'Base URL',\n type: 'url',\n required: false,\n default: 'https://api.groq.com/openai/v1',\n help:\n 'Override only for proxies. Default points at Groq\\'s production endpoint.',\n },\n ],\n },\n ],\n knownModels: GROQ_KNOWN_MODELS,\n // Groq exposes /openai/v1/models with the same auth as chat completions.\n supportsModelListing: true,\n docsUrl: 'https://console.groq.com/docs/api-reference',\n};\n","import { OpenAIAdapter } from '../openai/adapter.js';\nimport { streamFromOpenAI } from '../openai/_streaming.js';\nimport type { ApiKeyAuth, ClientOptions, LlmEvent, PromptRequest } from '../../types.js';\nimport { makeMetadataExtractor } from '../_metadata.js';\nimport { groqManifest } from './manifest.js';\n\n/**\n * Groq response-header diagnostics. `x-groq-region` names the Groq\n * datacenter that served the request — useful for latency analysis.\n * `openai-processing-ms` is forwarded by Groq (they're OpenAI-wire-\n * compatible) and reports their server-side processing time, which\n * can be compared against wall-clock to spot infrastructure queueing\n * not counted in the model-server timer. Rate-limit headers help\n * operators spot when a workload is trending toward exhaustion\n * across turns within a call.\n */\nconst GROQ_METADATA_EXTRACTOR = makeMetadataExtractor([\n { header: 'x-request-id', key: 'request_id' },\n { header: 'x-groq-region', key: 'region' },\n { header: 'openai-processing-ms', key: 'processing_ms', numeric: true },\n { header: 'x-ratelimit-remaining-requests', key: 'requests_remaining', numeric: true },\n { header: 'x-ratelimit-remaining-tokens', key: 'tokens_remaining', numeric: true },\n]);\n\n/**\n * Adapter for Groq.\n *\n * Groq's chat-completions endpoint is OpenAI-wire-compatible — same request\n * shape, same streaming SSE, same tool-call format. The adapter is therefore\n * a thin subclass of `OpenAIAdapter` that defaults the `baseURL` to\n * `https://api.groq.com/openai/v1`. All wire translation, tool-call\n * accumulation, abort handling, and history round-tripping live in the\n * shared `streamFromOpenAI` helper.\n *\n * Why a separate class (vs. an inline alias like `DeepSeekAdapter` in\n * openai/factory.ts): keeps the manifest, README, and any future\n * Groq-specific quirks co-located in `src/adapters/groq/`. The DeepSeek\n * inline alias is a legacy shape; new vendors get their own directory.\n */\nexport class GroqAdapter extends OpenAIAdapter {\n override readonly vendor = groqManifest.vendor;\n\n override init(auth: ApiKeyAuth, client?: ClientOptions): void {\n super.init(\n {\n ...auth,\n baseURL: auth.baseURL ?? 'https://api.groq.com/openai/v1',\n },\n client,\n );\n }\n\n override stream(req: PromptRequest): AsyncIterable<LlmEvent> {\n // Override so we can pass Groq's own metadata extractor; otherwise\n // we'd inherit OpenAI's, which misses `x-groq-region`.\n return streamFromOpenAI(this.ensureClient(), req, {\n knownModels: groqManifest.knownModels,\n vendorMetadataExtractor: GROQ_METADATA_EXTRACTOR,\n // Groq caches automatically server-side and rejects/ignores undocumented\n // OpenAI params — do not forward prompt_cache_key.\n includeCacheKey: false,\n });\n }\n}\n","import type { AdapterFactory, ApiKeyAuth } from '../../types.js';\nimport { GroqAdapter } from './adapter.js';\nimport { groqManifest } from './manifest.js';\n\nexport const groqFactory: AdapterFactory<ApiKeyAuth> = {\n vendor: groqManifest.vendor,\n manifest: groqManifest,\n create: () => new GroqAdapter(),\n};\n","import type { AdapterManifest, ModelInfo } from '../../types.js';\n\n/**\n * Curated HuggingFace Inference Providers `knownModels`.\n *\n * Keyed by canonical HF model id (`<org>/<model>`). Customers can append a\n * `:provider-name` (`:fireworks-ai`, `:cerebras`, `:nebius`, etc.) or\n * `:fastest` suffix at request time to influence routing — those suffixed\n * variants are NOT enumerated here because the suffixed id is just a\n * routing hint, not a different model. The library's\n * `defaultCapabilitiesForUnknown` returns sensible defaults for any\n * suffixed id the heuristic doesn't recognize.\n *\n * The full live catalog is available via `listAvailableModels()` against\n * `/v1/models` — this list seeds the admin-UI dropdown with the most\n * common picks.\n */\nconst HF_KNOWN_MODELS: ModelInfo[] = [\n {\n id: 'meta-llama/Llama-3.3-70B-Instruct',\n displayName: 'Llama 3.3 70B Instruct (HF Providers)',\n capabilities: {\n streaming: true,\n tools: true,\n vision: false,\n systemPrompt: true,\n maxContextTokens: 128_000,\n },\n },\n {\n id: 'meta-llama/Llama-3.1-8B-Instruct',\n displayName: 'Llama 3.1 8B Instruct (HF Providers)',\n capabilities: {\n streaming: true,\n tools: true,\n vision: false,\n systemPrompt: true,\n maxContextTokens: 128_000,\n },\n },\n {\n id: 'Qwen/Qwen2.5-72B-Instruct',\n displayName: 'Qwen 2.5 72B Instruct (HF Providers)',\n capabilities: {\n streaming: true,\n tools: true,\n vision: false,\n systemPrompt: true,\n maxContextTokens: 128_000,\n },\n },\n {\n id: 'mistralai/Mistral-7B-Instruct-v0.3',\n displayName: 'Mistral 7B Instruct v0.3 (HF Providers)',\n capabilities: {\n streaming: true,\n tools: true,\n vision: false,\n systemPrompt: true,\n maxContextTokens: 32_000,\n },\n },\n {\n id: 'deepseek-ai/DeepSeek-V3',\n displayName: 'DeepSeek V3 (HF Providers)',\n capabilities: {\n streaming: true,\n tools: true,\n vision: false,\n systemPrompt: true,\n maxContextTokens: 64_000,\n },\n },\n];\n\nexport const huggingfaceManifest: AdapterManifest = {\n vendor: 'huggingface',\n displayName: 'HuggingFace Inference Providers',\n authKinds: [\n {\n kind: 'apiKey',\n displayName: 'API Key',\n fields: [\n {\n name: 'apiKey',\n label: 'HuggingFace Token',\n type: 'password',\n required: true,\n help:\n 'Get a token from https://huggingface.co/settings/tokens (Read scope is sufficient). ' +\n 'Inference Providers requires a credit balance — claim the free monthly tier or attach ' +\n 'a payment method at https://huggingface.co/billing.',\n },\n {\n name: 'baseURL',\n label: 'Base URL',\n type: 'url',\n required: false,\n default: 'https://router.huggingface.co/v1',\n help: 'Override only for proxies. Default is the HF Providers router endpoint.',\n },\n ],\n },\n ],\n knownModels: HF_KNOWN_MODELS,\n // The HF router exposes /v1/models with the same Bearer auth.\n supportsModelListing: true,\n docsUrl: 'https://huggingface.co/docs/inference-providers',\n};\n","import { OpenAIAdapter } from '../openai/adapter.js';\nimport { streamFromOpenAI } from '../openai/_streaming.js';\nimport type { ApiKeyAuth, ClientOptions, LlmEvent, PromptRequest } from '../../types.js';\nimport { makeMetadataExtractor } from '../_metadata.js';\nimport { huggingfaceManifest } from './manifest.js';\n\n/**\n * HuggingFace Inference Providers response-header diagnostics.\n *\n * `x-inference-provider` is the killer signal — names the actual\n * backend (Groq, Cerebras, Together, Fireworks, etc.) that served\n * the request. Useful for diagnosing latency anomalies and confirming\n * provider routing for `:fastest` / `:provider-name` model suffixes.\n */\nconst HUGGINGFACE_METADATA_EXTRACTOR = makeMetadataExtractor([\n { header: 'x-inference-provider', key: 'provider' },\n { header: 'x-request-id', key: 'request_id' },\n]);\n\n/**\n * Adapter for HuggingFace Inference Providers.\n *\n * HF Providers is a multi-provider broker: one HF token at\n * https://router.huggingface.co/v1 routes requests to whichever inference\n * shop hosts the requested model — Groq, Together, Fireworks, Cerebras,\n * Nebius, Hyperbolic, SambaNova, etc. The wire is OpenAI-compatible (chat\n * completions, streaming, tools, Bearer auth), so the adapter is a thin\n * subclass of `OpenAIAdapter` that defaults the `baseURL`.\n *\n * Model field syntax: customers pass canonical HF model ids\n * (`meta-llama/Llama-3.3-70B-Instruct`). They MAY append a routing\n * hint:\n * - `:fireworks-ai`, `:cerebras`, `:groq`, etc. — pin a specific provider\n * - `:fastest` — let HF route to the fastest available backend\n * Suffixes pass through to HF unchanged. The library's capability lookup\n * falls back to `defaultCapabilitiesForUnknown` for suffixed ids.\n */\nexport class HuggingfaceAdapter extends OpenAIAdapter {\n override readonly vendor = huggingfaceManifest.vendor;\n\n override init(auth: ApiKeyAuth, client?: ClientOptions): void {\n super.init(\n {\n ...auth,\n baseURL: auth.baseURL ?? 'https://router.huggingface.co/v1',\n },\n client,\n );\n }\n\n override stream(req: PromptRequest): AsyncIterable<LlmEvent> {\n return streamFromOpenAI(this.ensureClient(), req, {\n knownModels: huggingfaceManifest.knownModels,\n vendorMetadataExtractor: HUGGINGFACE_METADATA_EXTRACTOR,\n // The HF router fronts many third-party inference providers;\n // prompt_cache_key is unverified against them — do not forward.\n includeCacheKey: false,\n });\n }\n}\n","import type { AdapterFactory, ApiKeyAuth } from '../../types.js';\nimport { HuggingfaceAdapter } from './adapter.js';\nimport { huggingfaceManifest } from './manifest.js';\n\nexport const huggingfaceFactory: AdapterFactory<ApiKeyAuth> = {\n vendor: huggingfaceManifest.vendor,\n manifest: huggingfaceManifest,\n create: () => new HuggingfaceAdapter(),\n};\n","import type { AdapterManifest, ModelInfo } from '../../types.js';\n\n/**\n * Curated OpenRouter models for the admin-UI dropdown: fast, tool-capable\n * models that suit a voice agent. OpenRouter's live catalog (~450 models,\n * churning weekly) is returned by `listAvailableModels()` with capability\n * flags taken from its own `/models` metadata, so any model id works — this\n * list only seeds the dropdown.\n */\nconst OPENROUTER_KNOWN_MODELS: ModelInfo[] = [\n {\n id: 'anthropic/claude-haiku-5.5',\n displayName: 'Claude Haiku 5.5 (OpenRouter)',\n capabilities: {\n streaming: true,\n tools: true,\n vision: true,\n systemPrompt: true,\n maxContextTokens: 1_000_000,\n },\n },\n {\n id: 'anthropic/claude-sonnet-5.5',\n displayName: 'Claude Sonnet 5.5 (OpenRouter)',\n capabilities: {\n streaming: true,\n tools: true,\n vision: true,\n systemPrompt: true,\n maxContextTokens: 1_000_000,\n },\n },\n {\n id: 'openai/gpt-5.4-mini',\n displayName: 'GPT-5.4 Mini (OpenRouter)',\n capabilities: {\n streaming: true,\n tools: true,\n vision: true,\n systemPrompt: true,\n maxContextTokens: 400_000,\n },\n },\n {\n id: 'openai/gpt-4.1-mini',\n displayName: 'GPT-4.1 Mini (OpenRouter)',\n capabilities: {\n streaming: true,\n tools: true,\n vision: true,\n systemPrompt: true,\n maxContextTokens: 1_047_576,\n },\n },\n {\n id: 'google/gemini-3.5-flash',\n displayName: 'Gemini 3.5 Flash (OpenRouter)',\n capabilities: {\n streaming: true,\n tools: true,\n vision: true,\n systemPrompt: true,\n maxContextTokens: 1_048_576,\n },\n },\n {\n id: 'meta-llama/llama-3.3-70b-instruct',\n displayName: 'Llama 3.3 70B Instruct (OpenRouter)',\n capabilities: {\n streaming: true,\n tools: true,\n vision: false,\n systemPrompt: true,\n maxContextTokens: 131_072,\n },\n },\n];\n\nexport const openRouterManifest: AdapterManifest = {\n vendor: 'openrouter',\n displayName: 'OpenRouter',\n authKinds: [\n {\n kind: 'apiKey',\n displayName: 'API Key',\n fields: [\n {\n name: 'apiKey',\n label: 'API Key',\n type: 'password',\n required: true,\n help: 'Get an API key from https://openrouter.ai/settings/keys',\n },\n {\n name: 'baseURL',\n label: 'Base URL',\n type: 'url',\n required: false,\n default: 'https://openrouter.ai/api/v1',\n help: 'Override only for proxies. Default points at OpenRouter\\'s production endpoint.',\n },\n ],\n },\n ],\n knownModels: OPENROUTER_KNOWN_MODELS,\n // /models is public; the adapter enriches it with OpenRouter's own capability metadata.\n supportsModelListing: true,\n docsUrl: 'https://openrouter.ai/docs/api_reference/overview',\n};\n","import { OpenAIAdapter } from '../openai/adapter.js';\nimport { streamFromOpenAI } from '../openai/_streaming.js';\nimport type { ApiKeyAuth, ClientOptions, LlmEvent, ModelInfo, PromptRequest } from '../../types.js';\nimport { makeMetadataExtractor } from '../_metadata.js';\nimport { openRouterManifest } from './manifest.js';\n\n/**\n * OpenRouter response-header diagnostics. `x-generation-id` is the id\n * OpenRouter support asks for, and the key to `/api/v1/generation` for\n * per-request cost and upstream-provider stats.\n */\nconst OPENROUTER_METADATA_EXTRACTOR = makeMetadataExtractor([\n { header: 'x-generation-id', key: 'request_id' },\n]);\n\n/**\n * OpenRouter app attribution: credits this traffic to jambonz on\n * OpenRouter's public app rankings and model pages. No effect on routing,\n * pricing or rate limits. `HTTP-Referer` is the app's identity; the title\n * is its display name.\n */\nconst OPENROUTER_ATTRIBUTION_HEADERS = {\n 'HTTP-Referer': 'https://jambonz.org',\n 'X-OpenRouter-Title': 'jambonz',\n};\n\n/** The subset of OpenRouter's `/models` entry this adapter reads. */\ninterface OpenRouterModel {\n id: string;\n name?: string;\n context_length?: number;\n architecture?: { input_modalities?: string[]; output_modalities?: string[] };\n supported_parameters?: string[];\n}\n\n/**\n * Adapter for OpenRouter.\n *\n * OpenRouter's chat-completions endpoint is OpenAI-wire-compatible, so this\n * is a thin subclass of `OpenAIAdapter` that defaults the `baseURL` to\n * `https://openrouter.ai/api/v1`. Anthropic prompt caching on OpenRouter is\n * handled by the base class, which detects the openrouter.ai baseURL (so it\n * also works for OpenAI credentials pointed at OpenRouter).\n *\n * Every request carries jambonz's app-attribution headers.\n *\n * Two overrides exist because OpenRouter's `/models` is public:\n * - `testCredential()` probes the authenticated `/key` endpoint instead —\n * `/models` returns 200 for any key, bogus or not.\n * - `listAvailableModels()` uses the capability metadata `/models` carries\n * (tool support, vision, context length) rather than guessing by id.\n */\nexport class OpenRouterAdapter extends OpenAIAdapter {\n override readonly vendor = openRouterManifest.vendor;\n\n override init(auth: ApiKeyAuth, client?: ClientOptions): void {\n super.init(\n {\n ...auth,\n baseURL: auth.baseURL ?? 'https://openrouter.ai/api/v1',\n },\n client,\n );\n this.client = this.ensureClient().withOptions({\n defaultHeaders: OPENROUTER_ATTRIBUTION_HEADERS,\n });\n }\n\n override stream(req: PromptRequest): AsyncIterable<LlmEvent> {\n // Override so we can pass OpenRouter's own metadata extractor.\n return streamFromOpenAI(this.ensureClient(), req, {\n knownModels: this.knownModels(),\n vendorMetadataExtractor: OPENROUTER_METADATA_EXTRACTOR,\n // Verified accepted by OpenRouter (forwarded to OpenAI-family upstreams).\n includeCacheKey: true,\n openRouterAutoCache: this.isOpenRouter,\n });\n }\n\n override async listAvailableModels(): Promise<ModelInfo[]> {\n const result = await this.ensureClient().models.list();\n const out: ModelInfo[] = [];\n for (const m of result.data as unknown as OpenRouterModel[]) {\n // `:batch` variants are async-only; image-generation models emit no text.\n if (m.id.endsWith(':batch')) continue;\n const outputs = m.architecture?.output_modalities;\n if (outputs && !outputs.includes('text')) continue;\n const known = this.knownModels().find((k) => k.id === m.id);\n if (known) {\n out.push(known);\n continue;\n }\n out.push({\n id: m.id,\n ...(m.name ? { displayName: m.name } : {}),\n capabilities: {\n streaming: true,\n tools: m.supported_parameters?.includes('tools') ?? true,\n vision: m.architecture?.input_modalities?.includes('image') ?? false,\n systemPrompt: true,\n ...(m.context_length ? { maxContextTokens: m.context_length } : {}),\n },\n });\n }\n return out;\n }\n\n override async testCredential(): Promise<void> {\n // GET /key is authenticated (401 on a bad key) and free.\n await this.ensureClient().get('/key');\n }\n\n protected override knownModels(): ReadonlyArray<ModelInfo> {\n return openRouterManifest.knownModels;\n }\n}\n","import type { AdapterFactory, ApiKeyAuth } from '../../types.js';\nimport { OpenRouterAdapter } from './adapter.js';\nimport { openRouterManifest } from './manifest.js';\n\nexport const openRouterFactory: AdapterFactory<ApiKeyAuth> = {\n vendor: openRouterManifest.vendor,\n manifest: openRouterManifest,\n create: () => new OpenRouterAdapter(),\n};\n","import type { AdapterManifest } from '../types.js';\n\n/**\n * The harness vendor: a customer-run WebSocket endpoint that takes the agent's\n * \"think\" step (jambonz keeps telephony, STT, turn-taking and TTS).\n *\n * Credential-only: there is no adapter here, because feature-server speaks the\n * harness protocol itself. The manifest exists so api-server can validate and\n * store the credential and the portal can render its form. Stored as\n * `{url, api_key}`; feature-server reads exactly those two fields.\n */\nexport const harnessManifest: AdapterManifest = {\n vendor: 'harness',\n displayName: 'Harness',\n authKinds: [\n {\n // Only the form schema matters for a credential-only vendor; no\n // AuthSpec is ever built from it.\n kind: 'apiKey',\n displayName: 'API Key',\n fields: [\n {\n name: 'url',\n label: 'WebSocket URL',\n type: 'url',\n required: true,\n help:\n 'wss:// URL of your harness. ws:// is accepted only for a private or localhost address.',\n },\n {\n name: 'apiKey',\n label: 'API Key',\n type: 'password',\n required: true,\n help: 'Sent to the harness as \"Authorization: Bearer <key>\" when each call connects.',\n },\n ],\n },\n ],\n knownModels: [],\n supportsModelListing: false,\n credentialOnly: true,\n};\n","/**\n * Central adapter registration.\n *\n * Each bundled vendor adapter is registered here at import time. When a new\n * vendor adapter is added under `src/adapters/<vendor>/`, add a single line\n * below to register its factory.\n *\n * The `_template` directory is intentionally NOT registered — it's a scaffold\n * for contributors to copy, not a live adapter.\n */\n\nimport { registerAdapter, registerCredentialVendor } from '../registry.js';\nimport {\n openAIFactory,\n deepseekFactory,\n basetenFactory,\n moonshotFactory,\n zaiFactory,\n xaiFactory,\n bedrockMantleFactory,\n} from './openai/index.js';\nimport { anthropicFactory } from './anthropic/index.js';\nimport { googleFactory } from './google/index.js';\nimport { vertexGeminiFactory } from './vertex-gemini/index.js';\nimport { vertexOpenAIFactory } from './vertex-openai/index.js';\nimport { bedrockFactory } from './bedrock/index.js';\nimport { azureOpenAIFactory } from './azure-openai/index.js';\nimport { groqFactory } from './groq/index.js';\nimport { huggingfaceFactory } from './huggingface/index.js';\nimport { openRouterFactory } from './openrouter/index.js';\nimport { harnessManifest } from '../vendors/harness.js';\n\nregisterAdapter(openAIFactory);\nregisterAdapter(deepseekFactory);\nregisterAdapter(basetenFactory);\nregisterAdapter(moonshotFactory);\nregisterAdapter(zaiFactory);\nregisterAdapter(xaiFactory);\nregisterAdapter(bedrockMantleFactory);\nregisterAdapter(anthropicFactory);\nregisterAdapter(googleFactory);\nregisterAdapter(vertexGeminiFactory);\nregisterAdapter(vertexOpenAIFactory);\nregisterAdapter(bedrockFactory);\nregisterAdapter(azureOpenAIFactory);\nregisterAdapter(groqFactory);\nregisterAdapter(huggingfaceFactory);\nregisterAdapter(openRouterFactory);\n\n// Credential-only vendors: a manifest for credential storage and the portal\n// form, no adapter (see src/vendors/).\nregisterCredentialVendor(harnessManifest);\n","import type {\n AuthSpec,\n AzureOpenAIApiKeyAuth,\n BedrockApiKeyAuth,\n BedrockIamAuth,\n GoogleApiKeyAuth,\n GoogleServiceAccountAuth,\n ServiceAccountJson,\n VertexServiceAccountAuth,\n} from './types.js';\n\n/**\n * The loose \"DB-shape\" input accepted by `normalizeAuth`.\n *\n * This is the shape produced by jambonz's api-server after decryption, and by\n * feature-server's `credential-mapper.js`. Snake-case is used to match the\n * legacy wire shape; the helper converts to the `AuthSpec` discriminated union.\n *\n * External callers that construct `AuthSpec` directly can skip this helper entirely.\n */\nexport interface RawCredential {\n api_key?: string | null;\n /** Either a JSON string or a parsed object. */\n service_key?: string | ServiceAccountJson | null;\n access_key_id?: string | null;\n secret_access_key?: string | null;\n session_token?: string | null;\n region?: string | null;\n api_url?: string | null;\n project_id?: string | null;\n location?: string | null;\n /** Azure OpenAI resource endpoint, e.g. `https://my-resource.openai.azure.com`. */\n endpoint?: string | null;\n /** Azure OpenAI deployment name (the user-created deployment, not the model id). */\n deployment?: string | null;\n /** Azure OpenAI data-plane api-version, e.g. `2025-03-01-preview`. */\n api_version?: string | null;\n}\n\n/**\n * Convert a vendor + raw credential into an `AuthSpec` discriminated union member.\n *\n * Supported vendors: openai, deepseek, baseten, moonshot, zai, xai, bedrock-mantle,\n * anthropic, google, vertex (alias for vertex-gemini + vertex-openai — both accept\n * the same auth shape), vertex-gemini, vertex-openai, bedrock, azure-openai, groq,\n * huggingface, openrouter.\n *\n * Throws with a clear message if the raw credential is missing required fields.\n */\nexport function normalizeAuth(vendor: string, raw: RawCredential): AuthSpec {\n switch (vendor) {\n case 'openai':\n case 'anthropic':\n case 'groq':\n case 'huggingface':\n case 'openrouter':\n case 'moonshot':\n case 'zai':\n case 'xai':\n case 'bedrock-mantle':\n // Standard ApiKeyAuth; these adapters default baseURL in init() if the\n // caller doesn't supply one (e.g. api.groq.com, router.huggingface.co, openrouter.ai/api/v1,\n // api.moonshot.ai/v1, api.z.ai/api/paas/v4, api.x.ai/v1). A user-supplied\n // api_url (e.g. Moonshot .cn, Z.ai's Coding-Plan endpoint, or a Bedrock\n // Mantle region / the /openai/v1 path xAI models require) is passed\n // through.\n return requireApiKey(vendor, raw);\n\n case 'deepseek':\n return {\n ...requireApiKey(vendor, raw),\n baseURL: raw.api_url ?? 'https://api.deepseek.com/v1',\n };\n\n case 'baseten':\n return {\n ...requireApiKey(vendor, raw),\n baseURL: raw.api_url ?? 'https://inference.baseten.co/v1',\n };\n\n case 'google':\n return normalizeGoogle(raw);\n\n case 'vertex':\n case 'vertex-gemini':\n case 'vertex-openai':\n return normalizeVertex(vendor, raw);\n\n case 'bedrock':\n return normalizeBedrock(raw);\n\n case 'azure-openai':\n return normalizeAzureOpenAI(raw);\n\n default:\n throw new Error(\n `normalizeAuth: unknown vendor '${vendor}'. ` +\n `If this is a custom adapter, construct the AuthSpec directly.`,\n );\n }\n}\n\nfunction requireApiKey(vendor: string, raw: RawCredential) {\n if (!raw.api_key) {\n throw new Error(`normalizeAuth: vendor '${vendor}' requires 'api_key'`);\n }\n const result: { kind: 'apiKey'; apiKey: string; baseURL?: string } = {\n kind: 'apiKey',\n apiKey: raw.api_key,\n };\n if (raw.api_url) {\n result.baseURL = raw.api_url;\n }\n return result;\n}\n\nfunction normalizeGoogle(raw: RawCredential): GoogleApiKeyAuth | GoogleServiceAccountAuth {\n if (raw.service_key) {\n return {\n kind: 'googleServiceAccount',\n credentials: parseServiceKey(raw.service_key),\n };\n }\n if (raw.api_key) {\n return { kind: 'googleApiKey', apiKey: raw.api_key };\n }\n throw new Error(`normalizeAuth: vendor 'google' requires either 'api_key' or 'service_key'`);\n}\n\nfunction normalizeVertex(vendor: string, raw: RawCredential): VertexServiceAccountAuth {\n if (!raw.service_key) {\n throw new Error(`normalizeAuth: vendor '${vendor}' requires 'service_key'`);\n }\n if (!raw.location) {\n throw new Error(`normalizeAuth: vendor '${vendor}' requires 'location'`);\n }\n const credentials = parseServiceKey(raw.service_key);\n const projectId = raw.project_id ?? credentials.project_id;\n if (!projectId) {\n throw new Error(\n `normalizeAuth: vendor '${vendor}' requires 'project_id' (not present ` +\n `in raw credential or service_key.project_id)`,\n );\n }\n return {\n kind: 'vertexServiceAccount',\n credentials,\n projectId,\n location: raw.location,\n };\n}\n\nfunction normalizeBedrock(raw: RawCredential): BedrockIamAuth | BedrockApiKeyAuth {\n if (!raw.region) {\n throw new Error(`normalizeAuth: vendor 'bedrock' requires 'region'`);\n }\n if (raw.access_key_id && raw.secret_access_key) {\n const result: BedrockIamAuth = {\n kind: 'bedrockIam',\n accessKeyId: raw.access_key_id,\n secretAccessKey: raw.secret_access_key,\n region: raw.region,\n };\n if (raw.session_token) {\n result.sessionToken = raw.session_token;\n }\n return result;\n }\n if (raw.api_key) {\n return {\n kind: 'bedrockApiKey',\n apiKey: raw.api_key,\n region: raw.region,\n };\n }\n throw new Error(\n `normalizeAuth: vendor 'bedrock' requires either (access_key_id + secret_access_key) or api_key`,\n );\n}\n\nfunction normalizeAzureOpenAI(raw: RawCredential): AzureOpenAIApiKeyAuth {\n if (!raw.api_key) {\n throw new Error(`normalizeAuth: vendor 'azure-openai' requires 'api_key'`);\n }\n if (!raw.endpoint) {\n throw new Error(`normalizeAuth: vendor 'azure-openai' requires 'endpoint'`);\n }\n if (!raw.deployment) {\n throw new Error(`normalizeAuth: vendor 'azure-openai' requires 'deployment'`);\n }\n if (!raw.api_version) {\n throw new Error(`normalizeAuth: vendor 'azure-openai' requires 'api_version'`);\n }\n return {\n kind: 'azureOpenAIApiKey',\n apiKey: raw.api_key,\n endpoint: raw.endpoint,\n deployment: raw.deployment,\n apiVersion: raw.api_version,\n };\n}\n\nfunction parseServiceKey(value: string | ServiceAccountJson): ServiceAccountJson {\n if (typeof value === 'string') {\n try {\n return JSON.parse(value) as ServiceAccountJson;\n } catch {\n throw new Error(`normalizeAuth: 'service_key' is not valid JSON`);\n }\n }\n return value;\n}\n","import type { RawCredential } from './normalize-auth.js';\nimport { getVendorManifest } from './registry.js';\nimport type { AuthKindSchema } from './types.js';\n\n/**\n * Given a vendor id and a raw snake_case credential blob, return the\n * `AuthKindSchema` from the vendor's manifest that matches the blob.\n *\n * Purpose: let credential-handling consumers (api-server's `encryptCredential`\n * in particular) validate and serialize the *right* set of fields for a\n * credential without carrying a per-vendor switch of their own. The\n * discriminator logic that distinguishes e.g. `bedrockApiKey` from\n * `bedrockIam` lives here, in the library, right next to `normalizeAuth`.\n *\n * Rules:\n * - Vendor with a single `authKind`: that kind is returned unconditionally.\n * - Bedrock: `access_key_id` + `secret_access_key` → `bedrockIam`; else `bedrockApiKey`.\n * - Google: `service_key` present → `googleServiceAccount`; `api_key` present → `googleApiKey`.\n *\n * Throws if the vendor is unknown or if no declared authKind matches the blob.\n */\nexport interface RawCredentialLoose extends RawCredential {\n [key: string]: unknown;\n}\n\nexport function pickAuthKind(vendor: string, raw: RawCredentialLoose): AuthKindSchema {\n const { authKinds } = getVendorManifest(vendor);\n\n if (authKinds.length === 1) {\n return authKinds[0]!;\n }\n\n switch (vendor) {\n case 'bedrock': {\n const iam = authKinds.find((k) => k.kind === 'bedrockIam');\n const apiKey = authKinds.find((k) => k.kind === 'bedrockApiKey');\n if (raw.access_key_id && raw.secret_access_key) {\n if (!iam) throw new Error(`pickAuthKind: bedrock manifest missing 'bedrockIam'`);\n return iam;\n }\n if (raw.api_key) {\n if (!apiKey) throw new Error(`pickAuthKind: bedrock manifest missing 'bedrockApiKey'`);\n return apiKey;\n }\n throw new Error(\n `pickAuthKind: bedrock credential missing both 'api_key' and ` +\n `('access_key_id' + 'secret_access_key')`,\n );\n }\n\n case 'google': {\n const svc = authKinds.find((k) => k.kind === 'googleServiceAccount');\n const apiKey = authKinds.find((k) => k.kind === 'googleApiKey');\n if (raw.service_key) {\n if (!svc) throw new Error(`pickAuthKind: google manifest missing 'googleServiceAccount'`);\n return svc;\n }\n if (raw.api_key) {\n if (!apiKey) throw new Error(`pickAuthKind: google manifest missing 'googleApiKey'`);\n return apiKey;\n }\n throw new Error(\n `pickAuthKind: google credential missing both 'api_key' and 'service_key'`,\n );\n }\n\n default:\n throw new Error(\n `pickAuthKind: vendor '${vendor}' declares ${authKinds.length} authKinds but ` +\n `has no discriminator rule. Add one in src/pick-auth-kind.ts.`,\n );\n }\n}\n"],"mappings":"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","names":["OpenAI","Anthropic","buildWireMessages","formatTools","isAbortError","formatTools","isAbortError","usage","mapFinishReason","import_genai","import_openai","OpenAI","buildWireMessages","formatTools","markLastMessageForCaching","isAbortError","mapStopReason","import_openai"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/registry.ts","../src/adapters/openai/adapter.ts","../src/validate.ts","../src/adapters/openai/_streaming.ts","../src/adapters/_metadata.ts","../src/adapters/openai/manifest.ts","../src/adapters/openai/factory.ts","../src/adapters/anthropic/adapter.ts","../src/adapters/anthropic/manifest.ts","../src/adapters/anthropic/factory.ts","../src/adapters/google/adapter.ts","../src/adapters/google/_streaming.ts","../src/adapters/google/manifest.ts","../src/adapters/google/factory.ts","../src/adapters/vertex-gemini/adapter.ts","../src/adapters/vertex-gemini/manifest.ts","../src/adapters/vertex-gemini/factory.ts","../src/adapters/vertex-openai/adapter.ts","../src/adapters/vertex-openai/manifest.ts","../src/adapters/vertex-openai/factory.ts","../src/adapters/bedrock/adapter.ts","../src/adapters/bedrock/manifest.ts","../src/adapters/bedrock/factory.ts","../src/adapters/azure-openai/adapter.ts","../src/adapters/azure-openai/manifest.ts","../src/adapters/azure-openai/factory.ts","../src/adapters/groq/manifest.ts","../src/adapters/groq/adapter.ts","../src/adapters/groq/factory.ts","../src/adapters/huggingface/manifest.ts","../src/adapters/huggingface/adapter.ts","../src/adapters/huggingface/factory.ts","../src/adapters/openrouter/manifest.ts","../src/adapters/openrouter/adapter.ts","../src/adapters/openrouter/factory.ts","../src/vendors/harness.ts","../src/vendors/dialogflow-ces.ts","../src/vendors/openai-s2s.ts","../src/adapters/index.ts","../src/normalize-auth.ts","../src/pick-auth-kind.ts"],"sourcesContent":["/**\n * @jambonz/llm — voice-oriented LLM adapter library.\n *\n * Public entry point. Importing this module auto-registers all bundled adapters\n * via the side-effectful import of `./adapters/index.js`.\n *\n * Consumers use:\n * - `createLlm({vendor, auth, client?})` to get a ready-to-stream adapter instance.\n * - `getManifest()` to enumerate registered vendors (used by api-server).\n * - `getVendorManifest(vendor)` for one vendor's manifest, including\n * credential-only vendors (e.g. `harness`) that have no adapter.\n * - `normalizeAuth(vendor, rawCred)` to convert DB-shape creds to AuthSpec.\n * - `pickAuthKind(vendor, rawCred)` to pick the right manifest authKind for\n * a raw credential (used by api-server's `encryptCredential`).\n * - `registerAdapter(factory)` to add a custom adapter at runtime.\n */\n\n// Side effect: register all bundled adapters. Must come first.\nimport './adapters/index.js';\n\nimport { getAdapterFactory } from './registry.js';\nimport type {\n AuthSpec,\n CreateLlmArgs,\n LlmAdapter,\n} from './types.js';\n\nexport async function createLlm<A extends AuthSpec = AuthSpec>(\n args: CreateLlmArgs<A>,\n): Promise<LlmAdapter<A>> {\n const factory = getAdapterFactory<A>(args.vendor);\n if (!factory.manifest.authKinds.some((k) => k.kind === args.auth.kind)) {\n const accepted = factory.manifest.authKinds.map((k) => k.kind).join(', ');\n throw new Error(\n `Vendor '${args.vendor}' does not accept auth kind '${args.auth.kind}'. ` +\n `Accepted kinds: ${accepted}`,\n );\n }\n const instance = factory.create();\n await Promise.resolve(instance.init(args.auth, args.client));\n return instance;\n}\n\n// Re-export the full public surface.\nexport type {\n AdapterFactory,\n AdapterManifest,\n VendorCategory,\n ApiKeyAuth,\n AuthKind,\n AuthKindSchema,\n AuthSpec,\n AzureOpenAIApiKeyAuth,\n BedrockApiKeyAuth,\n BedrockIamAuth,\n ClientOptions,\n ContentBlock,\n CreateLlmArgs,\n FinishReason,\n FormField,\n FormFieldType,\n GoogleApiKeyAuth,\n GoogleServiceAccountAuth,\n JsonSchema,\n LlmAdapter,\n LlmEvent,\n Message,\n ModelCapabilities,\n ModelInfo,\n PromptRequest,\n Role,\n ServiceAccountJson,\n Tool,\n ToolCallEvent,\n Usage,\n VertexServiceAccountAuth,\n} from './types.js';\n\nexport { normalizeAuth } from './normalize-auth.js';\nexport type { RawCredential } from './normalize-auth.js';\n\nexport { pickAuthKind } from './pick-auth-kind.js';\nexport type { RawCredentialLoose } from './pick-auth-kind.js';\n\nexport { assertValidRequest } from './validate.js';\n\nexport {\n getAdapterFactory,\n getManifest,\n getVendorManifest,\n listVendors,\n registerAdapter,\n replaceAdapter,\n unregisterAdapter,\n} from './registry.js';\n","import type { AdapterFactory, AdapterManifest, AuthSpec } from './types.js';\n\n/**\n * Module-scope registry of adapter factories, keyed by vendor id.\n *\n * Adapters register themselves at import time via `registerAdapter`. Consumers\n * of the library then call `createLlm({vendor, auth})` and the factory for\n * that vendor is looked up here.\n */\nconst registry = new Map<string, AdapterFactory>();\n\n/**\n * Vendors jambonz stores a credential for that have no adapter here\n * (`manifest.credentialOnly`). They appear in `getManifest()` and\n * `getVendorManifest()`, never in `getAdapterFactory()`.\n */\nconst credentialVendors = new Map<string, AdapterManifest>();\n\n/**\n * Register an adapter factory. Called once per adapter at module load.\n *\n * Throws if a factory is already registered for the same vendor id — this\n * catches accidental double-registration and typos in `src/adapters/index.ts`.\n *\n * Use `replaceAdapter` if you deliberately need to override a registered adapter\n * (primarily useful in tests).\n */\nexport function registerAdapter(factory: AdapterFactory): void {\n if (registry.has(factory.vendor) || credentialVendors.has(factory.vendor)) {\n throw new Error(\n `Adapter already registered for vendor '${factory.vendor}'. ` +\n `Use replaceAdapter() if you intended to override.`,\n );\n }\n if (factory.vendor !== factory.manifest.vendor) {\n throw new Error(\n `Adapter factory vendor '${factory.vendor}' does not match ` +\n `manifest.vendor '${factory.manifest.vendor}'.`,\n );\n }\n registry.set(factory.vendor, factory);\n}\n\n/**\n * Register a credential-only vendor: a manifest with no adapter. Throws if\n * the id is already taken or the manifest is not marked `credentialOnly`.\n */\nexport function registerCredentialVendor(manifest: AdapterManifest): void {\n if (!manifest.credentialOnly) {\n throw new Error(`Vendor '${manifest.vendor}' manifest is not marked credentialOnly.`);\n }\n if (registry.has(manifest.vendor) || credentialVendors.has(manifest.vendor)) {\n throw new Error(`Vendor '${manifest.vendor}' is already registered.`);\n }\n credentialVendors.set(manifest.vendor, manifest);\n}\n\n/**\n * Replace an already-registered adapter. Intended for test overrides.\n */\nexport function replaceAdapter(factory: AdapterFactory): void {\n registry.set(factory.vendor, factory);\n}\n\n/**\n * Remove an adapter from the registry. Intended for test cleanup.\n */\nexport function unregisterAdapter(vendor: string): void {\n registry.delete(vendor);\n}\n\n/**\n * Get a registered adapter factory. Throws if unknown vendor.\n */\nexport function getAdapterFactory<A extends AuthSpec = AuthSpec>(\n vendor: string,\n): AdapterFactory<A> {\n const factory = registry.get(vendor);\n if (!factory) {\n if (credentialVendors.has(vendor)) {\n throw new Error(\n `Vendor '${vendor}' is credential-only: @jambonz/llm has no adapter for it.`,\n );\n }\n const known = Array.from(registry.keys()).sort().join(', ') || '(none)';\n throw new Error(\n `Unknown vendor '${vendor}'. Registered vendors: ${known}`,\n );\n }\n return factory as AdapterFactory<A>;\n}\n\n/**\n * Get the manifest for any registered vendor, adapter-backed or\n * credential-only. Throws if unknown vendor. Use this (not\n * `getAdapterFactory`) where only the credential shape matters.\n */\nexport function getVendorManifest(vendor: string): AdapterManifest {\n const manifest = registry.get(vendor)?.manifest ?? credentialVendors.get(vendor);\n if (!manifest) {\n const known =\n [...registry.keys(), ...credentialVendors.keys()].sort().join(', ') || '(none)';\n throw new Error(`Unknown vendor '${vendor}'. Registered vendors: ${known}`);\n }\n return manifest;\n}\n\n/**\n * List all registered adapter vendor ids, sorted alphabetically.\n * Credential-only vendors are not included: they cannot be passed to `createLlm`.\n */\nexport function listVendors(): string[] {\n return Array.from(registry.keys()).sort();\n}\n\n/**\n * Return an aggregated manifest for all registered vendors, credential-only\n * ones included. Used by api-server's /llm-vendors/manifest endpoint.\n */\nexport function getManifest(): { vendors: AdapterManifest[] } {\n const vendors = [\n ...Array.from(registry.values()).map((f) => f.manifest),\n ...credentialVendors.values(),\n ]\n .map((m) => ({ ...m, category: m.category ?? 'llm' }))\n .sort((a, b) => a.vendor.localeCompare(b.vendor));\n return { vendors };\n}\n\n/**\n * Test-only: reset the registry. Exposed for unit tests that register/unregister\n * adapters and need a clean slate.\n */\nexport function _resetRegistryForTests(): void {\n registry.clear();\n credentialVendors.clear();\n}\n","import OpenAI from 'openai';\nimport type {\n ApiKeyAuth,\n ClientOptions,\n LlmAdapter,\n LlmEvent,\n Message,\n ModelInfo,\n PromptRequest,\n ToolCallEvent,\n} from '../../types.js';\nimport {\n appendOpenAIAssistantToolCall,\n appendOpenAIToolResult,\n listOpenAICompatibleModels,\n streamFromOpenAI,\n} from './_streaming.js';\nimport { makeMetadataExtractor } from '../_metadata.js';\nimport { openAIManifest } from './manifest.js';\n\n/**\n * OpenAI response-header diagnostics surfaced as `vendorMetadata` on the\n * `end` event. `request_id` is essential for support tickets;\n * `processing_ms` separates vendor inference time from network time;\n * the rate-limit headers help operators spot when an account is trending\n * toward exhaustion within a single call.\n */\nconst OPENAI_METADATA_EXTRACTOR = makeMetadataExtractor([\n { header: 'x-request-id', key: 'request_id' },\n { header: 'openai-processing-ms', key: 'processing_ms', numeric: true },\n { header: 'x-ratelimit-remaining-requests', key: 'requests_remaining', numeric: true },\n { header: 'x-ratelimit-remaining-tokens', key: 'tokens_remaining', numeric: true },\n]);\n\n/**\n * Adapter for OpenAI (and OpenAI-compatible endpoints: DeepSeek, LM Studio,\n * Ollama, vLLM, custom gateways).\n *\n * Wire translation lives in `_streaming.ts` and is shared with the\n * Vertex-OpenAI adapter — both use the same `openai` SDK with the same\n * on-wire shape; only client construction (auth, baseURL, fetch wrapper)\n * differs.\n */\nexport class OpenAIAdapter implements LlmAdapter<ApiKeyAuth> {\n readonly vendor = openAIManifest.vendor;\n readonly acceptedAuth = ['apiKey'] as const;\n\n protected client: OpenAI | undefined;\n /** baseURL is OpenRouter: enables its automatic prompt caching for Anthropic models. */\n protected isOpenRouter = false;\n\n init(auth: ApiKeyAuth, client?: ClientOptions): void {\n if (!auth.apiKey) {\n throw new Error('OpenAIAdapter: apiKey is required');\n }\n this.isOpenRouter = /(^|\\/\\/|\\.)openrouter\\.ai(\\/|:|$)/i.test(auth.baseURL ?? '');\n this.client = new OpenAI({\n apiKey: auth.apiKey,\n ...(auth.baseURL ? { baseURL: auth.baseURL } : {}),\n ...(client?.timeout !== undefined ? { timeout: client.timeout } : {}),\n ...(client?.maxRetries !== undefined ? { maxRetries: client.maxRetries } : {}),\n });\n }\n\n stream(req: PromptRequest): AsyncIterable<LlmEvent> {\n return streamFromOpenAI(this.ensureClient(), req, {\n knownModels: this.knownModels(),\n vendorMetadataExtractor: OPENAI_METADATA_EXTRACTOR,\n includeCacheKey: this.forwardCacheKey(),\n openRouterAutoCache: this.isOpenRouter,\n });\n }\n\n appendAssistantToolCall(\n history: Message[],\n toolCalls: ReadonlyArray<ToolCallEvent>,\n assistantText?: string,\n ): Message[] {\n return appendOpenAIAssistantToolCall(history, toolCalls, assistantText);\n }\n\n appendToolResult(history: Message[], toolCallId: string, result: unknown): Message[] {\n return appendOpenAIToolResult(history, toolCallId, result);\n }\n\n async listAvailableModels(): Promise<ModelInfo[]> {\n return listOpenAICompatibleModels(this.ensureClient(), this.knownModels());\n }\n\n /**\n * Capability table used to enrich both `stream()` (for tools/vision gating)\n * and `listAvailableModels()` (for filling capability flags on live entries).\n * Subclasses backed by the same OpenAI wire (DeepSeek, Baseten, …) override\n * this so their own manifest entries are consulted instead of OpenAI's.\n */\n protected knownModels(): ReadonlyArray<ModelInfo> {\n return openAIManifest.knownModels;\n }\n\n /**\n * Whether to forward `req.cacheKey` as OpenAI's `prompt_cache_key` request\n * param. Default true — verified accepted by OpenAI, Azure OpenAI,\n * Vertex-OpenAI, and Baseten. OpenAI-compatible vendors whose param\n * handling is strict or unverified (DeepSeek, Moonshot, Zai, xAI — and\n * Groq via its own stream override) override to false: a strict backend\n * rejects the whole request on an unknown body param, which is far worse\n * than forgoing a cache-routing hint. Flip a vendor to true only after\n * verifying its endpoint (including any proxy in front of it, e.g.\n * Bedrock Mantle) tolerates the param.\n */\n protected forwardCacheKey(): boolean {\n return true;\n }\n\n async testCredential(): Promise<void> {\n // /v1/models is the cheapest authenticated GET on the OpenAI API.\n // Works for OpenAI proper and most compatible backends (DeepSeek included).\n await this.ensureClient().models.list();\n }\n\n async warmup(): Promise<void> {\n const client = this.ensureClient();\n await client.models.list().catch(() => undefined);\n }\n\n protected ensureClient(): OpenAI {\n if (!this.client) {\n throw new Error('OpenAIAdapter: init() must be called before stream()/listAvailableModels()');\n }\n return this.client;\n }\n}\n","import type { PromptRequest } from './types.js';\n\n/**\n * Validate a PromptRequest against the library's universal preconditions.\n *\n * Adapters should call this at the top of `stream()` to get consistent error\n * messages. The contract test-kit's check #18 verifies empty messages are\n * rejected, so adapters that skip this helper must implement the equivalent\n * validation themselves.\n *\n * Rules enforced:\n * - `model` is a non-empty string.\n * - `messages` is a non-empty array.\n * - `messages` does not contain `role: 'system'` turns (use `system` top-level).\n * - `cacheKey`, when present, is a non-empty string.\n */\nexport function assertValidRequest(req: PromptRequest): void {\n if (!req || typeof req !== 'object') {\n throw new Error('PromptRequest must be an object');\n }\n if (typeof req.model !== 'string' || req.model.length === 0) {\n throw new Error('PromptRequest.model must be a non-empty string');\n }\n if (!Array.isArray(req.messages) || req.messages.length === 0) {\n throw new Error('PromptRequest.messages must be a non-empty array');\n }\n if (req.messages.some((m) => m.role === 'system')) {\n throw new Error(\n 'PromptRequest.messages must not contain role: \\'system\\'. ' +\n 'Pass the system prompt via PromptRequest.system instead.',\n );\n }\n if (req.cacheKey !== undefined && (typeof req.cacheKey !== 'string' || req.cacheKey.length === 0)) {\n throw new Error('PromptRequest.cacheKey must be a non-empty string');\n }\n}\n","import type OpenAI from 'openai';\nimport type { ChatCompletionCreateParamsStreaming } from 'openai/resources/chat/completions';\nimport type {\n FinishReason,\n LlmEvent,\n Message,\n ModelCapabilities,\n ModelInfo,\n PromptRequest,\n Tool,\n} from '../../types.js';\nimport { assertValidRequest } from '../../validate.js';\n\n/**\n * OpenAI wire translation, shared between the native OpenAI adapter and the\n * Vertex-OpenAI adapter (which talks to third-party models hosted on Vertex AI\n * via the OpenAI-compatible endpoint).\n */\nexport async function* streamFromOpenAI(\n client: OpenAI,\n req: PromptRequest,\n options: {\n knownModels: ReadonlyArray<ModelInfo>;\n /**\n * Whether to set `stream_options: { include_usage: true }` on the\n * request. Defaults to `true` for OpenAI's native API. Set to `false`\n * for third-party OpenAI-compatible endpoints (e.g. Vertex AI's OpenAI\n * endpoint for partner models) that reject unknown extensions with a\n * 400 error. When disabled, the `end` event's `usage` field is omitted.\n */\n includeStreamOptions?: boolean;\n /**\n * If the caller did not supply `maxTokens`, use this value. Set by the\n * Vertex-OpenAI adapter because Vertex AI's Llama MaaS endpoint returns\n * an empty assistant message (zero tokens, `finish_reason: stop`) when\n * `max_tokens` is omitted. Leave undefined for OpenAI's native API,\n * which defaults correctly on its own.\n */\n defaultMaxTokens?: number;\n /**\n * Which wire parameter to use for the max-output cap. Defaults to a\n * per-request heuristic on `req.model` (see {@link needsMaxCompletionTokens}):\n * OpenAI's o-series reasoning models and gpt-5 family require\n * `max_completion_tokens`; everything else uses legacy `max_tokens`.\n *\n * Override when:\n * - The model id doesn't reflect the underlying model (Azure OpenAI\n * deployment names are arbitrary) — pass `'max_completion_tokens'`.\n * - Talking to an older OpenAI-compat endpoint that only knows\n * `max_tokens` (Vertex Llama MaaS, some local servers) — pass\n * `'max_tokens'` to pin the legacy name.\n */\n tokensParam?: 'max_tokens' | 'max_completion_tokens';\n /**\n * Whether to forward `req.cacheKey` as the `prompt_cache_key` request\n * param. Defaults to `true` (OpenAI/Azure/Vertex-OpenAI/Baseten all\n * accept it). Set to `false` for Groq, which caches automatically\n * server-side and does not document this param (per Groq's strict\n * OpenAI-compat param handling).\n */\n includeCacheKey?: boolean;\n /**\n * The endpoint is OpenRouter. With `req.cacheKey` set and an Anthropic\n * model (`anthropic/...`), adds OpenRouter's top-level\n * `cache_control: {type: 'ephemeral'}` (\"automatic\" prompt caching: it\n * places the breakpoint on the last cacheable block and moves it forward\n * as the conversation grows). Anthropic models ignore `prompt_cache_key`,\n * so without this nothing is cached. Gated on OpenRouter because a strict\n * OpenAI-compatible backend rejects the whole request on an unknown field.\n */\n openRouterAutoCache?: boolean;\n /**\n * Optional adapter-supplied extractor that pulls vendor-specific\n * diagnostic data off the upstream HTTP response headers (request\n * id, rate-limit remaining, routing info, etc.) and returns it as\n * a flat key/value record.\n *\n * Called once per stream after the underlying `Response` is\n * available (via the OpenAI SDK's `.withResponse()` pattern). The\n * returned record is attached to the `end` event as\n * `vendorMetadata` if non-empty. Each adapter declares its own\n * allowlist — see the `huggingface`, `azure-openai`, `groq` etc.\n * adapters for examples.\n */\n vendorMetadataExtractor?: (\n headers: Headers,\n ) => Record<string, string | number>;\n },\n): AsyncIterable<LlmEvent> {\n assertValidRequest(req);\n\n if (req.signal?.aborted) {\n yield { type: 'end', finishReason: 'aborted' };\n return;\n }\n\n const capabilities = capabilitiesFor(req.model, options.knownModels);\n const useTools = req.tools && req.tools.length > 0 && capabilities.tools;\n\n const messages = buildWireMessages(req);\n const tools = useTools ? formatTools(req.tools!) : undefined;\n\n const body: ChatCompletionCreateParamsStreaming = {\n model: req.model,\n messages: messages as ChatCompletionCreateParamsStreaming['messages'],\n stream: true,\n ...(options.includeStreamOptions !== false\n ? { stream_options: { include_usage: true } }\n : {}),\n };\n if (tools) {\n body.tools = tools as unknown as ChatCompletionCreateParamsStreaming['tools'];\n body.tool_choice = 'auto';\n }\n if (req.temperature !== undefined) body.temperature = req.temperature;\n if (req.cacheKey && options.includeCacheKey !== false) {\n (body as unknown as Record<string, unknown>).prompt_cache_key = req.cacheKey;\n }\n if (req.cacheKey && options.openRouterAutoCache && /^~?anthropic\\//.test(req.model)) {\n (body as unknown as Record<string, unknown>).cache_control = { type: 'ephemeral' };\n }\n const effectiveMaxTokens = req.maxTokens ?? options.defaultMaxTokens;\n if (effectiveMaxTokens !== undefined) {\n const param =\n options.tokensParam ??\n (needsMaxCompletionTokens(req.model) ? 'max_completion_tokens' : 'max_tokens');\n (body as unknown as Record<string, unknown>)[param] = effectiveMaxTokens;\n }\n\n // Merge caller-supplied provider-specific params (e.g. Kimi's\n // chat_template_kwargs). Add-only: never overwrite a library-managed field,\n // so this can extend the request but not corrupt its core shape.\n if (req.providerParams) {\n const bodyRecord = body as unknown as Record<string, unknown>;\n for (const [key, value] of Object.entries(req.providerParams)) {\n if (!(key in bodyRecord)) bodyRecord[key] = value;\n }\n }\n\n // hrtime markers for client-side timing breakdown attached to the end event:\n // t0 = before SDK call\n // t1 = response headers received (after withResponse resolves)\n // t2 = first content token yielded back to caller\n // `clientTiming` is omitted when t1 was never reached (error before headers).\n const t0 = process.hrtime.bigint();\n let t1: bigint | undefined;\n let t2: bigint | undefined;\n\n let stream;\n let responseHeaders: Headers | undefined;\n try {\n // Production: `.withResponse()` on the OpenAI SDK's APIPromise surfaces\n // the underlying HTTP `Response` so adapters that supply a\n // `vendorMetadataExtractor` can read response headers. Test mocks\n // typically return the stream directly (no APIPromise wrapper); fall\n // through to a plain await when `.withResponse` isn't present, so\n // existing test infrastructure keeps working unchanged.\n const apiPromise = client.chat.completions.create(body, { signal: req.signal });\n const maybeWithResponse = (apiPromise as unknown as {\n withResponse?: () => Promise<{\n data: Awaited<typeof apiPromise>;\n response: { headers?: Headers };\n }>;\n }).withResponse;\n if (typeof maybeWithResponse === 'function') {\n const result = await maybeWithResponse.call(apiPromise);\n stream = result.data;\n responseHeaders = result.response?.headers;\n } else {\n stream = await apiPromise;\n }\n t1 = process.hrtime.bigint();\n } catch (err) {\n if (isAbortError(err)) {\n yield { type: 'end', finishReason: 'aborted' };\n return;\n }\n throw err;\n }\n\n const pending: Record<number, PendingToolCall> = {};\n const startedIds = new Set<string>();\n const toolCallsEmitted = new Set<string>();\n let usage: { inputTokens?: number; outputTokens?: number; totalTokens?: number } | undefined;\n let finalFinishReason: FinishReason | null = null;\n let finalRawReason: string | undefined;\n let sawContent = false;\n\n try {\n for await (const chunk of stream) {\n if (req.signal?.aborted) {\n yield { type: 'end', finishReason: 'aborted' };\n return;\n }\n\n // Some OpenAI-compatible backends report failures as a single SSE event\n // carrying a top-level `error` (instead of a non-2xx status the SDK would\n // throw on). Surface it rather than silently ending with no output.\n const chunkError = (chunk as { error?: unknown }).error;\n if (chunkError) {\n const message =\n chunkError && typeof chunkError === 'object' && 'message' in chunkError\n ? String((chunkError as { message?: unknown }).message)\n : JSON.stringify(chunkError);\n throw new Error(`OpenAI-compatible stream returned an error: ${message}`);\n }\n\n if (chunk.usage) {\n // OpenAI's prompt_tokens INCLUDES cached tokens (cached_tokens is a\n // sub-detail). Subtract it out so inputTokens means UNCACHED input,\n // per the library's additive Usage convention. OpenRouter also reports\n // cache_write_tokens (Anthropic-family models), likewise included in\n // prompt_tokens, so it is subtracted too and surfaced separately.\n const details = chunk.usage.prompt_tokens_details as\n | { cached_tokens?: number; cache_write_tokens?: number }\n | undefined;\n const cachedTokens = details?.cached_tokens;\n const cacheWriteTokens = details?.cache_write_tokens;\n usage = {\n ...(chunk.usage.prompt_tokens !== undefined\n ? {\n inputTokens: Math.max(\n 0,\n chunk.usage.prompt_tokens - (cachedTokens ?? 0) - (cacheWriteTokens ?? 0),\n ),\n }\n : {}),\n ...(chunk.usage.completion_tokens !== undefined\n ? { outputTokens: chunk.usage.completion_tokens }\n : {}),\n ...(chunk.usage.total_tokens !== undefined\n ? { totalTokens: chunk.usage.total_tokens }\n : {}),\n ...(cachedTokens !== undefined ? { cacheReadTokens: cachedTokens } : {}),\n ...(cacheWriteTokens !== undefined ? { cacheWriteTokens } : {}),\n };\n }\n\n const choice = chunk.choices?.[0];\n if (!choice) continue;\n\n const delta = choice.delta;\n const finishReason = choice.finish_reason;\n\n if (delta?.content) {\n if (t2 === undefined) t2 = process.hrtime.bigint();\n sawContent = true;\n yield { type: 'token', text: delta.content };\n }\n\n if (delta?.tool_calls) {\n for (const tc of delta.tool_calls) {\n const idx = tc.index;\n if (!pending[idx]) {\n pending[idx] = { id: '', name: '', arguments: '' };\n }\n if (tc.id) pending[idx].id += tc.id;\n if (tc.function?.name) pending[idx].name += tc.function.name;\n if (tc.function?.arguments) pending[idx].arguments += tc.function.arguments;\n\n if (pending[idx].id && pending[idx].name && !startedIds.has(pending[idx].id)) {\n startedIds.add(pending[idx].id);\n yield {\n type: 'toolCallStart',\n id: pending[idx].id,\n name: pending[idx].name,\n };\n }\n }\n }\n\n if (finishReason === 'tool_calls') {\n if (req.signal?.aborted) {\n yield { type: 'end', finishReason: 'aborted' };\n return;\n }\n for (const tc of Object.values(pending)) {\n if (!tc.id || !tc.name) continue;\n if (toolCallsEmitted.has(tc.id)) continue;\n toolCallsEmitted.add(tc.id);\n let args: unknown = {};\n try {\n args = tc.arguments ? JSON.parse(tc.arguments) : {};\n } catch {\n args = {};\n }\n yield {\n type: 'toolCall',\n id: tc.id,\n name: tc.name,\n arguments: args,\n };\n }\n finalFinishReason = 'tool';\n finalRawReason = finishReason;\n } else if (finishReason) {\n finalFinishReason = mapFinishReason(finishReason);\n finalRawReason = finishReason;\n }\n }\n } catch (err) {\n if (isAbortError(err)) {\n yield { type: 'end', finishReason: 'aborted' };\n return;\n }\n throw err;\n }\n\n // A valid completion stream always emits at least a finish_reason. If we got\n // through the whole stream with no content, no tool calls, no usage, and no\n // finish reason, the response was not a real completion — typically a\n // misconfigured base URL or a vendor error returned inside an HTTP 200 body\n // (which the SDK does not treat as an error). Fail loudly instead of\n // returning a silent empty turn that a caller would forward to TTS.\n const producedNothing =\n finalFinishReason === null &&\n !sawContent &&\n toolCallsEmitted.size === 0 &&\n startedIds.size === 0 &&\n usage === undefined;\n if (producedNothing) {\n throw new Error(\n 'OpenAI-compatible stream produced no data (no content, tool calls, usage, or finish ' +\n 'reason). This usually means a misconfigured base URL or a vendor error returned in an ' +\n 'HTTP 200 body. Verify the base URL and credentials.',\n );\n }\n\n const endEvent: Extract<LlmEvent, { type: 'end' }> = {\n type: 'end',\n finishReason: finalFinishReason ?? 'stop',\n ...(usage ? { usage } : {}),\n ...(finalRawReason ? { rawReason: finalRawReason } : {}),\n };\n\n if (options.vendorMetadataExtractor && responseHeaders) {\n const metadata = options.vendorMetadataExtractor(responseHeaders);\n if (metadata && Object.keys(metadata).length > 0) {\n endEvent.vendorMetadata = metadata;\n }\n }\n\n if (t1 !== undefined) {\n const t3 = process.hrtime.bigint();\n endEvent.clientTiming = {\n requestToHeadersMs: Number(t1 - t0) / 1e6,\n ...(t2 !== undefined\n ? { headersToFirstTokenMs: Number(t2 - t1) / 1e6 }\n : {}),\n totalMs: Number(t3 - t0) / 1e6,\n };\n }\n\n yield endEvent;\n}\n\nexport function appendOpenAIAssistantToolCall(\n history: Message[],\n toolCalls: ReadonlyArray<Extract<LlmEvent, { type: 'toolCall' }>>,\n assistantText?: string,\n): Message[] {\n const text = assistantText?.trim() ? assistantText : null;\n const wireMessage = {\n role: 'assistant',\n content: text,\n tool_calls: toolCalls.map((tc) => ({\n id: tc.id,\n type: 'function',\n function: {\n name: tc.name,\n arguments: typeof tc.arguments === 'string'\n ? tc.arguments\n : JSON.stringify(tc.arguments ?? {}),\n },\n })),\n };\n return [\n ...history,\n {\n role: 'assistant',\n content: text ?? '',\n vendorRaw: wireMessage,\n },\n ];\n}\n\nexport function appendOpenAIToolResult(\n history: Message[],\n toolCallId: string,\n result: unknown,\n): Message[] {\n const content = typeof result === 'string' ? result : JSON.stringify(result);\n const wireMessage = {\n role: 'tool',\n tool_call_id: toolCallId,\n content,\n };\n return [\n ...history,\n {\n role: 'tool',\n content,\n vendorRaw: wireMessage,\n },\n ];\n}\n\n/**\n * Call `models.list()` and normalise results, merging capabilities from a\n * known-models table when possible.\n */\nexport async function listOpenAICompatibleModels(\n client: OpenAI,\n knownModels: ReadonlyArray<ModelInfo>,\n): Promise<ModelInfo[]> {\n const result = await client.models.list();\n const out: ModelInfo[] = [];\n for (const m of result.data) {\n const known = knownModels.find((k) => k.id === m.id);\n if (known) {\n out.push(known);\n } else {\n out.push({\n id: m.id,\n capabilities: defaultCapabilitiesForUnknown(m.id),\n });\n }\n }\n return out;\n}\n\n// ---------------------------------------------------------------------------\n// Helpers (internal)\n// ---------------------------------------------------------------------------\n\ninterface PendingToolCall {\n id: string;\n name: string;\n arguments: string;\n}\n\nfunction buildWireMessages(req: PromptRequest): unknown[] {\n const out: unknown[] = [];\n if (req.system) {\n out.push({ role: 'system', content: req.system });\n }\n for (const msg of req.messages) {\n if (msg.vendorRaw && typeof msg.vendorRaw === 'object') {\n out.push(msg.vendorRaw);\n } else {\n out.push({ role: msg.role, content: msg.content });\n }\n }\n return out;\n}\n\nfunction formatTools(tools: Tool[]): Array<Record<string, unknown>> {\n return tools.map((t) => ({\n type: 'function',\n function: {\n name: t.name,\n description: t.description ?? '',\n parameters: t.parameters ?? { type: 'object', properties: {} },\n },\n }));\n}\n\nfunction capabilitiesFor(\n modelId: string,\n knownModels: ReadonlyArray<ModelInfo>,\n): ModelCapabilities {\n const known = knownModels.find((k) => k.id === modelId);\n if (known) return known.capabilities;\n return defaultCapabilitiesForUnknown(modelId);\n}\n\n/**\n * Does this model id require `max_completion_tokens` instead of legacy\n * `max_tokens`? OpenAI's reasoning family (o1, o3, o4) and gpt-5 dropped\n * `max_tokens` and return a 400 `Unsupported parameter` when it's sent.\n * Older chat models (gpt-4, gpt-4o, gpt-3.5-turbo) still accept `max_tokens`,\n * so we only switch when the model id matches the newer prefixes.\n *\n * Exposed so adapter authors (and tests) can rely on the same heuristic.\n */\nexport function needsMaxCompletionTokens(modelId: string): boolean {\n return /^(o\\d|gpt-5)/i.test(modelId);\n}\n\nexport function defaultCapabilitiesForUnknown(modelId: string): ModelCapabilities {\n const isReasoning = /^o[13]([-/]|$)/i.test(modelId);\n if (isReasoning) {\n return {\n streaming: false,\n tools: false,\n vision: false,\n systemPrompt: false,\n };\n }\n return {\n streaming: true,\n tools: true,\n vision: false,\n systemPrompt: true,\n };\n}\n\nfunction mapFinishReason(r: string): FinishReason {\n switch (r) {\n case 'stop': return 'stop';\n case 'tool_calls': return 'tool';\n case 'function_call': return 'tool';\n case 'length': return 'length';\n case 'content_filter': return 'filtered';\n default: return 'stop';\n }\n}\n\nfunction isAbortError(err: unknown): boolean {\n if (!err || typeof err !== 'object') return false;\n const e = err as { name?: string; code?: string; message?: string };\n return (\n e.name === 'APIUserAbortError' ||\n e.name === 'AbortError' ||\n e.code === 'ABORT_ERR' ||\n (typeof e.message === 'string' && /aborted/i.test(e.message))\n );\n}\n","/**\n * Shared helpers for vendor-metadata extractors.\n *\n * Each adapter that wants to surface response-header diagnostics (request\n * id, rate-limit remaining, routing/region, vendor processing time, cache\n * counts) declares an allowlist of `header-name` → `output-key` pairs\n * here. The extractor walks the allowlist, reads each header, parses\n * numeric values, and returns a flat record. Empty/absent headers are\n * dropped — never emit `null`.\n *\n * Output shape is `Record<string, string | number>` so consumers\n * (feature-server, webapp) can render it as a key/value table without\n * per-vendor knowledge.\n */\n\nexport interface MetadataField {\n /** Lowercase HTTP header name to read. */\n header: string;\n /** Key under which the value is exposed in `vendorMetadata`. */\n key: string;\n /** Parse numeric values to `number` instead of leaving as `string`. */\n numeric?: boolean;\n}\n\n/**\n * Build a `vendorMetadataExtractor` from a static field list. Adapters\n * import this and pass the result to `streamFromOpenAI` (or call directly\n * for native-SDK adapters).\n */\nexport function makeMetadataExtractor(\n fields: ReadonlyArray<MetadataField>,\n): (headers: Headers) => Record<string, string | number> {\n return (headers: Headers) => {\n const out: Record<string, string | number> = {};\n for (const f of fields) {\n const raw = headers.get(f.header);\n if (raw === null || raw === undefined || raw === '') continue;\n if (f.numeric) {\n const n = Number(raw);\n if (Number.isFinite(n)) out[f.key] = n;\n } else {\n out[f.key] = raw;\n }\n }\n return out;\n };\n}\n\n/**\n * Convenience: run the extractor against a generic header source (a\n * `Headers` instance, a record, or AWS-SDK-style `httpHeaders`) by\n * normalizing first. Used by native-SDK adapters whose response shapes\n * don't expose a real `Headers` object.\n */\nexport function extractMetadata(\n fields: ReadonlyArray<MetadataField>,\n headers: Record<string, string | string[] | undefined> | Headers,\n): Record<string, string | number> {\n const headersInstance =\n headers instanceof Headers ? headers : recordToHeaders(headers);\n return makeMetadataExtractor(fields)(headersInstance);\n}\n\nfunction recordToHeaders(\n record: Record<string, string | string[] | undefined>,\n): Headers {\n const h = new Headers();\n for (const [name, value] of Object.entries(record)) {\n if (value === undefined) continue;\n if (Array.isArray(value)) {\n for (const v of value) h.append(name, v);\n } else {\n h.set(name, value);\n }\n }\n return h;\n}\n","import type { AdapterManifest, ModelInfo } from '../../types.js';\n\n/**\n * Known OpenAI models with capability flags.\n *\n * Model listing via `listAvailableModels()` hits the live `/v1/models` endpoint,\n * so this curated list is for the admin-UI dropdown and for capability\n * validation (e.g., rejecting tools on reasoning-only models).\n */\nconst OPENAI_KNOWN_MODELS: ModelInfo[] = [\n {\n id: 'gpt-4o',\n displayName: 'GPT-4o',\n capabilities: {\n streaming: true,\n tools: true,\n vision: true,\n systemPrompt: true,\n maxContextTokens: 128_000,\n },\n },\n {\n id: 'gpt-4o-mini',\n displayName: 'GPT-4o mini',\n capabilities: {\n streaming: true,\n tools: true,\n vision: true,\n systemPrompt: true,\n maxContextTokens: 128_000,\n },\n },\n {\n id: 'gpt-4-turbo',\n displayName: 'GPT-4 Turbo',\n capabilities: {\n streaming: true,\n tools: true,\n vision: true,\n systemPrompt: true,\n maxContextTokens: 128_000,\n },\n },\n {\n id: 'gpt-3.5-turbo',\n displayName: 'GPT-3.5 Turbo',\n capabilities: {\n streaming: true,\n tools: true,\n vision: false,\n systemPrompt: true,\n maxContextTokens: 16_385,\n },\n },\n {\n id: 'o1-preview',\n displayName: 'o1 preview (reasoning)',\n capabilities: {\n streaming: false,\n tools: false,\n vision: false,\n systemPrompt: false,\n maxContextTokens: 128_000,\n },\n },\n {\n id: 'o1-mini',\n displayName: 'o1 mini (reasoning)',\n capabilities: {\n streaming: false,\n tools: false,\n vision: false,\n systemPrompt: false,\n maxContextTokens: 128_000,\n },\n },\n];\n\nexport const openAIManifest: AdapterManifest = {\n vendor: 'openai',\n displayName: 'OpenAI',\n authKinds: [\n {\n kind: 'apiKey',\n displayName: 'API Key',\n fields: [\n {\n name: 'apiKey',\n label: 'API Key',\n type: 'password',\n required: true,\n help: 'Get an API key from https://platform.openai.com/api-keys',\n },\n {\n name: 'baseURL',\n label: 'Base URL',\n type: 'url',\n required: false,\n default: 'https://api.openai.com/v1',\n help: 'Override for OpenAI-compatible endpoints (LM Studio, Ollama, vLLM, proxies).',\n },\n ],\n },\n ],\n knownModels: OPENAI_KNOWN_MODELS,\n supportsModelListing: true,\n docsUrl: 'https://platform.openai.com/docs/api-reference',\n};\n","import type { AdapterFactory, AdapterManifest, ApiKeyAuth } from '../../types.js';\nimport { OpenAIAdapter } from './adapter.js';\nimport { openAIManifest } from './manifest.js';\n\nexport const openAIFactory: AdapterFactory<ApiKeyAuth> = {\n vendor: openAIManifest.vendor,\n manifest: openAIManifest,\n create: () => new OpenAIAdapter(),\n};\n\n/**\n * DeepSeek alias factory. Wraps the OpenAI adapter but advertises itself as\n * `deepseek` and ships a DeepSeek-specific manifest (different default\n * `baseURL`, different known models, different docsUrl).\n *\n * Consumers call `createLlm({vendor: 'deepseek', auth: {kind: 'apiKey', apiKey}})`\n * and get the OpenAI wire adapter pointed at the DeepSeek endpoint.\n */\nconst deepseekManifest: AdapterManifest = {\n vendor: 'deepseek',\n displayName: 'DeepSeek',\n authKinds: [\n {\n kind: 'apiKey',\n displayName: 'API Key',\n fields: [\n {\n name: 'apiKey',\n label: 'API Key',\n type: 'password',\n required: true,\n help: 'Get an API key from https://platform.deepseek.com/api_keys',\n },\n {\n name: 'baseURL',\n label: 'Base URL',\n type: 'url',\n required: false,\n default: 'https://api.deepseek.com/v1',\n help: 'Override for self-hosted DeepSeek or proxy endpoints.',\n },\n ],\n },\n ],\n knownModels: [\n {\n id: 'deepseek-v4-flash',\n displayName: 'DeepSeek V4 Flash',\n capabilities: {\n streaming: true,\n tools: true,\n vision: false,\n systemPrompt: true,\n maxContextTokens: 1_000_000,\n },\n },\n {\n id: 'deepseek-v4-pro',\n displayName: 'DeepSeek V4 Pro',\n capabilities: {\n streaming: true,\n tools: true,\n vision: false,\n systemPrompt: true,\n maxContextTokens: 1_000_000,\n },\n },\n {\n id: 'deepseek-chat',\n displayName: 'DeepSeek Chat',\n capabilities: {\n streaming: true,\n tools: true,\n vision: false,\n systemPrompt: true,\n maxContextTokens: 64_000,\n },\n deprecated: true,\n },\n {\n id: 'deepseek-reasoner',\n displayName: 'DeepSeek Reasoner',\n capabilities: {\n streaming: true,\n tools: false,\n vision: false,\n systemPrompt: true,\n maxContextTokens: 64_000,\n },\n deprecated: true,\n },\n ],\n supportsModelListing: true,\n docsUrl: 'https://api-docs.deepseek.com/',\n};\n\nclass DeepSeekAdapter extends OpenAIAdapter {\n readonly vendor = deepseekManifest.vendor;\n\n override init(auth: ApiKeyAuth, client?: Parameters<OpenAIAdapter['init']>[1]): void {\n super.init(\n {\n ...auth,\n baseURL: auth.baseURL ?? 'https://api.deepseek.com/v1',\n },\n client,\n );\n }\n\n protected override knownModels() {\n return deepseekManifest.knownModels;\n }\n\n // DeepSeek caches automatically server-side; prompt_cache_key is\n // unverified against its param handling — do not forward.\n protected override forwardCacheKey(): boolean {\n return false;\n }\n}\n\nexport const deepseekFactory: AdapterFactory<ApiKeyAuth> = {\n vendor: deepseekManifest.vendor,\n manifest: deepseekManifest,\n create: () => new DeepSeekAdapter(),\n};\n\n/**\n * Baseten alias factory. Wraps the OpenAI adapter but advertises itself as\n * `baseten` and ships a Baseten-specific manifest (different default\n * `baseURL`, different known models, different docsUrl).\n *\n * Baseten exposes two OpenAI-compatible surfaces:\n * - Model APIs (default): `https://inference.baseten.co/v1` — shared,\n * curated catalog (DeepSeek, GLM, Kimi, GPT-OSS, etc.). `/v1/models`\n * returns the live catalog.\n * - Bridge / Direct: `https://bridge.baseten.co/v1/direct` — routes to a\n * user's dedicated deployment. Users override `baseURL` for this case.\n *\n * Consumers call `createLlm({vendor: 'baseten', auth: {kind: 'apiKey', apiKey}})`\n * and get the OpenAI wire adapter pointed at the Baseten endpoint.\n */\nconst basetenManifest: AdapterManifest = {\n vendor: 'baseten',\n displayName: 'Baseten',\n authKinds: [\n {\n kind: 'apiKey',\n displayName: 'API Key',\n fields: [\n {\n name: 'apiKey',\n label: 'API Key',\n type: 'password',\n required: true,\n help: 'Get an API key from https://app.baseten.co/settings/api_keys',\n },\n {\n name: 'baseURL',\n label: 'Base URL',\n type: 'url',\n required: false,\n default: 'https://inference.baseten.co/v1',\n help: 'Defaults to Baseten Model APIs. Set to https://bridge.baseten.co/v1/direct to route to a dedicated deployment.',\n },\n ],\n },\n ],\n knownModels: [\n {\n id: 'deepseek-ai/DeepSeek-V3.1',\n displayName: 'DeepSeek V3.1',\n capabilities: {\n streaming: true,\n tools: true,\n vision: false,\n systemPrompt: true,\n maxContextTokens: 163_840,\n },\n },\n {\n id: 'deepseek-ai/DeepSeek-V4-Pro',\n displayName: 'DeepSeek V4 Pro',\n capabilities: {\n streaming: true,\n tools: true,\n vision: false,\n systemPrompt: true,\n maxContextTokens: 131_072,\n },\n },\n {\n id: 'zai-org/GLM-4.7',\n displayName: 'GLM 4.7',\n capabilities: {\n streaming: true,\n tools: true,\n vision: false,\n systemPrompt: true,\n maxContextTokens: 200_000,\n },\n },\n {\n id: 'zai-org/GLM-5',\n displayName: 'GLM 5',\n capabilities: {\n streaming: true,\n tools: true,\n vision: false,\n systemPrompt: true,\n maxContextTokens: 202_800,\n },\n },\n {\n id: 'moonshotai/Kimi-K2.5',\n displayName: 'Kimi K2.5',\n capabilities: {\n streaming: true,\n tools: true,\n vision: true,\n systemPrompt: true,\n maxContextTokens: 262_000,\n },\n },\n {\n id: 'moonshotai/Kimi-K2.6',\n displayName: 'Kimi K2.6',\n capabilities: {\n streaming: true,\n tools: true,\n vision: true,\n systemPrompt: true,\n maxContextTokens: 262_000,\n },\n },\n {\n id: 'MiniMaxAI/MiniMax-M2.5',\n displayName: 'MiniMax M2.5',\n capabilities: {\n streaming: true,\n tools: true,\n vision: false,\n systemPrompt: true,\n maxContextTokens: 204_000,\n },\n },\n {\n id: 'nvidia/Nemotron-120B-A12B',\n displayName: 'Nemotron Super',\n capabilities: {\n streaming: true,\n tools: true,\n vision: false,\n systemPrompt: true,\n maxContextTokens: 202_800,\n },\n },\n {\n id: 'openai/gpt-oss-120b',\n displayName: 'OpenAI GPT 120B',\n capabilities: {\n streaming: true,\n tools: true,\n vision: false,\n systemPrompt: true,\n maxContextTokens: 128_072,\n },\n },\n ],\n supportsModelListing: true,\n docsUrl: 'https://docs.baseten.co/inference/model-apis/overview',\n};\n\nclass BasetenAdapter extends OpenAIAdapter {\n readonly vendor = basetenManifest.vendor;\n\n override init(auth: ApiKeyAuth, client?: Parameters<OpenAIAdapter['init']>[1]): void {\n super.init(\n {\n ...auth,\n baseURL: auth.baseURL ?? 'https://inference.baseten.co/v1',\n },\n client,\n );\n }\n\n protected override knownModels() {\n return basetenManifest.knownModels;\n }\n}\n\nexport const basetenFactory: AdapterFactory<ApiKeyAuth> = {\n vendor: basetenManifest.vendor,\n manifest: basetenManifest,\n create: () => new BasetenAdapter(),\n};\n\n/**\n * Moonshot (Kimi) alias factory. Moonshot exposes an OpenAI-compatible\n * Chat Completions surface; the only differences from OpenAI are the default\n * `baseURL` and the model catalog.\n *\n * Note: Moonshot serves a global endpoint (`api.moonshot.ai`) and a China\n * endpoint (`api.moonshot.cn`). We default to the global one; users override\n * `baseURL` for `.cn`. Moonshot only accepts the `tools` calling format (the\n * deprecated `functions` param is unsupported), which is what we already emit.\n *\n * Consumers call `createLlm({vendor: 'moonshot', auth: {kind: 'apiKey', apiKey}})`.\n */\nconst moonshotManifest: AdapterManifest = {\n vendor: 'moonshot',\n displayName: 'Moonshot (Kimi)',\n authKinds: [\n {\n kind: 'apiKey',\n displayName: 'API Key',\n fields: [\n {\n name: 'apiKey',\n label: 'API Key',\n type: 'password',\n required: true,\n help: 'Get an API key from https://platform.moonshot.ai/console/api-keys',\n },\n {\n name: 'baseURL',\n label: 'Base URL',\n type: 'url',\n required: false,\n default: 'https://api.moonshot.ai/v1',\n help: 'Defaults to the global endpoint. Set to https://api.moonshot.cn/v1 for the China endpoint.',\n },\n ],\n },\n ],\n knownModels: [\n {\n id: 'kimi-k2.6',\n displayName: 'Kimi K2.6',\n capabilities: {\n streaming: true,\n tools: true,\n vision: true,\n systemPrompt: true,\n maxContextTokens: 262_144,\n },\n },\n {\n id: 'kimi-k2.5',\n displayName: 'Kimi K2.5',\n capabilities: {\n streaming: true,\n tools: true,\n vision: true,\n systemPrompt: true,\n maxContextTokens: 262_144,\n },\n },\n ],\n supportsModelListing: true,\n docsUrl: 'https://platform.moonshot.ai/docs',\n};\n\nclass MoonshotAdapter extends OpenAIAdapter {\n readonly vendor = moonshotManifest.vendor;\n\n override init(auth: ApiKeyAuth, client?: Parameters<OpenAIAdapter['init']>[1]): void {\n super.init(\n {\n ...auth,\n baseURL: auth.baseURL ?? 'https://api.moonshot.ai/v1',\n },\n client,\n );\n }\n\n protected override knownModels() {\n return moonshotManifest.knownModels;\n }\n\n // Moonshot's param handling is strict (e.g. it rejects unknown template\n // kwargs) and prompt_cache_key is unverified against both the native\n // endpoint and Bedrock Mantle deployments — do not forward.\n protected override forwardCacheKey(): boolean {\n return false;\n }\n}\n\nexport const moonshotFactory: AdapterFactory<ApiKeyAuth> = {\n vendor: moonshotManifest.vendor,\n manifest: moonshotManifest,\n create: () => new MoonshotAdapter(),\n};\n\n/**\n * Z.ai (GLM) alias factory. Z.ai's `/api/paas/v4` surface is OpenAI-compatible\n * for chat completions (it accepts the OpenAI request shape and is what the\n * OpenAI SDK should target as its baseURL). Note there is NO OpenAI-style\n * `/models` listing endpoint, so `supportsModelListing` is false and we serve\n * the static known-models list.\n *\n * Note: Coding-Plan subscriptions are served from a *different* endpoint\n * (`https://api.z.ai/api/coding/paas/v4`), not the general one. Users on a\n * Coding Plan must override `baseURL` accordingly.\n *\n * Consumers call `createLlm({vendor: 'zai', auth: {kind: 'apiKey', apiKey}})`.\n */\nconst zaiManifest: AdapterManifest = {\n vendor: 'zai',\n displayName: 'Z.ai (GLM)',\n authKinds: [\n {\n kind: 'apiKey',\n displayName: 'API Key',\n fields: [\n {\n name: 'apiKey',\n label: 'API Key',\n type: 'password',\n required: true,\n help: 'Get an API key from https://z.ai/manage-apikey/apikey-list',\n },\n {\n name: 'baseURL',\n label: 'Base URL',\n type: 'url',\n required: false,\n default: 'https://api.z.ai/api/paas/v4',\n help: 'Defaults to the general API. Coding-Plan keys must use https://api.z.ai/api/coding/paas/v4.',\n },\n ],\n },\n ],\n knownModels: [\n {\n id: 'glm-5.2',\n displayName: 'GLM-5.2',\n capabilities: {\n streaming: true,\n tools: true,\n vision: false,\n systemPrompt: true,\n maxContextTokens: 1_000_000,\n },\n },\n {\n id: 'glm-4.7',\n displayName: 'GLM-4.7',\n capabilities: {\n streaming: true,\n tools: true,\n vision: false,\n systemPrompt: true,\n maxContextTokens: 200_000,\n },\n },\n ],\n supportsModelListing: false,\n docsUrl: 'https://docs.z.ai/',\n};\n\nclass ZaiAdapter extends OpenAIAdapter {\n readonly vendor = zaiManifest.vendor;\n\n override init(auth: ApiKeyAuth, client?: Parameters<OpenAIAdapter['init']>[1]): void {\n super.init(\n {\n ...auth,\n baseURL: auth.baseURL ?? 'https://api.z.ai/api/paas/v4',\n },\n client,\n );\n }\n\n protected override knownModels() {\n return zaiManifest.knownModels;\n }\n\n // prompt_cache_key is unverified against Zai's OpenAI-compat endpoint —\n // do not forward.\n protected override forwardCacheKey(): boolean {\n return false;\n }\n}\n\nexport const zaiFactory: AdapterFactory<ApiKeyAuth> = {\n vendor: zaiManifest.vendor,\n manifest: zaiManifest,\n create: () => new ZaiAdapter(),\n};\n\n/**\n * xAI (Grok) alias factory. xAI serves an OpenAI-compatible Chat Completions\n * surface; the only differences from OpenAI are the default `baseURL` and\n * the model catalog.\n *\n * Consumers call `createLlm({vendor: 'xai', auth: {kind: 'apiKey', apiKey}})`.\n */\nconst xaiManifest: AdapterManifest = {\n vendor: 'xai',\n displayName: 'xAI (Grok)',\n authKinds: [\n {\n kind: 'apiKey',\n displayName: 'API Key',\n fields: [\n {\n name: 'apiKey',\n label: 'API Key',\n type: 'password',\n required: true,\n help: 'Get an API key from https://console.x.ai/team/default/api-keys',\n },\n {\n name: 'baseURL',\n label: 'Base URL',\n type: 'url',\n required: false,\n default: 'https://api.x.ai/v1',\n help: 'Override for proxy endpoints. Defaults to xAI production.',\n },\n ],\n },\n ],\n knownModels: [\n {\n id: 'grok-4.3',\n displayName: 'Grok 4.3',\n capabilities: {\n streaming: true,\n tools: true,\n vision: true,\n systemPrompt: true,\n maxContextTokens: 1_000_000,\n },\n },\n {\n id: 'grok-4.20-0309-reasoning',\n displayName: 'Grok 4.20 (Reasoning)',\n capabilities: {\n streaming: true,\n tools: true,\n vision: true,\n systemPrompt: true,\n maxContextTokens: 1_000_000,\n },\n },\n {\n id: 'grok-4.20-0309-non-reasoning',\n displayName: 'Grok 4.20 (Non-Reasoning)',\n capabilities: {\n streaming: true,\n tools: true,\n vision: true,\n systemPrompt: true,\n maxContextTokens: 1_000_000,\n },\n },\n {\n id: 'grok-4.20-multi-agent-0309',\n displayName: 'Grok 4.20 Multi-Agent',\n capabilities: {\n streaming: true,\n tools: true,\n vision: true,\n systemPrompt: true,\n maxContextTokens: 1_000_000,\n },\n },\n ],\n supportsModelListing: true,\n docsUrl: 'https://docs.x.ai/',\n};\n\nclass XaiAdapter extends OpenAIAdapter {\n readonly vendor = xaiManifest.vendor;\n\n override init(auth: ApiKeyAuth, client?: Parameters<OpenAIAdapter['init']>[1]): void {\n super.init(\n {\n ...auth,\n baseURL: auth.baseURL ?? 'https://api.x.ai/v1',\n },\n client,\n );\n }\n\n protected override knownModels() {\n return xaiManifest.knownModels;\n }\n\n // xAI caches automatically server-side; prompt_cache_key is unverified\n // against its param handling — do not forward.\n protected override forwardCacheKey(): boolean {\n return false;\n }\n}\n\nexport const xaiFactory: AdapterFactory<ApiKeyAuth> = {\n vendor: xaiManifest.vendor,\n manifest: xaiManifest,\n create: () => new XaiAdapter(),\n};\n\n/**\n * AWS Bedrock \"Mantle\" alias factory — Bedrock's OpenAI-compatible surface,\n * which resells third-party open-weight models (Z.ai GLM, Moonshot Kimi, xAI\n * Grok, DeepSeek, MiniMax, Qwen, …) behind ONE endpoint and ONE Bedrock API\n * key. This is deliberately vendor-neutral: the model id carries the provider\n * (`zai.glm-5`, `moonshotai.kimi-k2.5`), so a newly-launched Bedrock model is\n * usable by setting `model` — no adapter change and no library release.\n *\n * Prefer this over the per-provider aliases (`zai`, `moonshot`, `xai`) when the\n * credential is a Bedrock API key rather than a native vendor key. Those\n * aliases differ from this one only in their default `baseURL`.\n *\n * Note the path split: most models are served on `/v1`, but xAI models are\n * served ONLY on `/openai/v1`. A `401 \"Berm is not enabled\"` means the wrong\n * path, not a missing entitlement — override `baseURL` for those.\n *\n * This is NOT the `bedrock` adapter, which speaks Bedrock's native Converse\n * API via the AWS SDK and supports SigV4/IAM auth. Use that one for Anthropic\n * and Amazon Nova models; use this one for the OpenAI-compatible catalog.\n *\n * Consumers call `createLlm({vendor: 'bedrock-mantle', auth: {kind: 'apiKey', apiKey}})`.\n */\nconst BEDROCK_MANTLE_DEFAULT_BASE_URL = 'https://bedrock-mantle.us-east-1.api.aws/v1';\n\nconst bedrockMantleManifest: AdapterManifest = {\n vendor: 'bedrock-mantle',\n displayName: 'AWS Bedrock (OpenAI-compatible)',\n authKinds: [\n {\n kind: 'apiKey',\n displayName: 'API Key',\n fields: [\n {\n name: 'apiKey',\n label: 'Bedrock API Key',\n type: 'password',\n required: true,\n help: 'Generate a long-term Bedrock API key in the AWS console (Amazon Bedrock → API keys).',\n },\n {\n name: 'baseURL',\n label: 'Base URL',\n type: 'url',\n required: false,\n default: BEDROCK_MANTLE_DEFAULT_BASE_URL,\n help: 'Change the region to match your key. xAI models are served only on the /openai/v1 path.',\n },\n ],\n },\n ],\n /* A convenience seed, NOT the source of truth: the live `/v1/models`\n * endpoint is authoritative and grows continuously, which is why\n * `supportsModelListing` is true. Any model the endpoint lists can be used\n * by id without appearing here.\n *\n * AWS publishes no context-window metadata (neither `/v1/models` nor\n * `GetFoundationModel` returns it), so these limits are carried over from\n * the native-vendor manifests above for the same underlying models. Vision\n * follows Bedrock's `inputModalities`. */\n knownModels: [\n {\n id: 'zai.glm-5',\n displayName: 'GLM 5',\n capabilities: {\n streaming: true,\n tools: true,\n vision: false,\n systemPrompt: true,\n maxContextTokens: 202_800,\n },\n },\n {\n id: 'zai.glm-4.7',\n displayName: 'GLM 4.7',\n capabilities: {\n streaming: true,\n tools: true,\n vision: false,\n systemPrompt: true,\n maxContextTokens: 200_000,\n },\n },\n {\n id: 'moonshotai.kimi-k2.5',\n displayName: 'Kimi K2.5',\n capabilities: {\n streaming: true,\n tools: true,\n vision: true,\n systemPrompt: true,\n maxContextTokens: 262_144,\n },\n },\n {\n id: 'xai.grok-4.3',\n displayName: 'Grok 4.3',\n capabilities: {\n streaming: true,\n tools: true,\n vision: true,\n systemPrompt: true,\n maxContextTokens: 1_000_000,\n },\n },\n ],\n supportsModelListing: true,\n docsUrl: 'https://docs.aws.amazon.com/bedrock/latest/userguide/inference-chat-completions.html',\n};\n\nclass BedrockMantleAdapter extends OpenAIAdapter {\n readonly vendor = bedrockMantleManifest.vendor;\n\n override init(auth: ApiKeyAuth, client?: Parameters<OpenAIAdapter['init']>[1]): void {\n super.init(\n {\n ...auth,\n baseURL: auth.baseURL ?? BEDROCK_MANTLE_DEFAULT_BASE_URL,\n },\n client,\n );\n }\n\n protected override knownModels() {\n return bedrockMantleManifest.knownModels;\n }\n\n // Mantle fronts many third-party runtimes with differing param strictness,\n // and prompt_cache_key is unverified against all of them — do not forward.\n protected override forwardCacheKey(): boolean {\n return false;\n }\n}\n\nexport const bedrockMantleFactory: AdapterFactory<ApiKeyAuth> = {\n vendor: bedrockMantleManifest.vendor,\n manifest: bedrockMantleManifest,\n create: () => new BedrockMantleAdapter(),\n};\n","import Anthropic from '@anthropic-ai/sdk';\nimport type {\n ApiKeyAuth,\n ClientOptions,\n FinishReason,\n LlmAdapter,\n LlmEvent,\n Message,\n ModelInfo,\n PromptRequest,\n Tool,\n ToolCallEvent,\n} from '../../types.js';\nimport { assertValidRequest } from '../../validate.js';\nimport { makeMetadataExtractor } from '../_metadata.js';\nimport { anthropicManifest } from './manifest.js';\n\n/**\n * Anthropic response-header diagnostics. `request-id` is the support-ticket\n * id; the rate-limit headers help operators see when an account is\n * approaching limits across turns within a call.\n */\nconst ANTHROPIC_METADATA_EXTRACTOR = makeMetadataExtractor([\n { header: 'request-id', key: 'request_id' },\n { header: 'anthropic-ratelimit-requests-remaining', key: 'requests_remaining', numeric: true },\n { header: 'anthropic-ratelimit-input-tokens-remaining', key: 'input_tokens_remaining', numeric: true },\n { header: 'anthropic-ratelimit-output-tokens-remaining', key: 'output_tokens_remaining', numeric: true },\n]);\n\n/**\n * Adapter for Anthropic Claude.\n *\n * Key wire-shape differences from OpenAI:\n * - `system` is a top-level request parameter, not a message.\n * - Tool schema is `{name, description, input_schema}` (not `parameters`).\n * - Tool results are `{role: 'user', content: [{type: 'tool_result', tool_use_id, content}]}`\n * — note role: 'user', not 'tool'.\n * - Assistant messages with tool calls carry `content: [{type: 'tool_use', id, name, input}]`\n * — content is an array of blocks, not a string or a separate tool_calls array.\n * - Stream events are content-block based (content_block_start/delta/stop + message_*).\n * - `max_tokens` is REQUIRED; we default to 4096 if the caller doesn't set one.\n */\nexport class AnthropicAdapter implements LlmAdapter<ApiKeyAuth> {\n readonly vendor = anthropicManifest.vendor;\n readonly acceptedAuth = ['apiKey'] as const;\n\n private client: Anthropic | undefined;\n\n init(auth: ApiKeyAuth, client?: ClientOptions): void {\n if (!auth.apiKey) {\n throw new Error('AnthropicAdapter: apiKey is required');\n }\n this.client = new Anthropic({\n apiKey: auth.apiKey,\n ...(auth.baseURL ? { baseURL: auth.baseURL } : {}),\n ...(client?.timeout !== undefined ? { timeout: client.timeout } : {}),\n ...(client?.maxRetries !== undefined ? { maxRetries: client.maxRetries } : {}),\n });\n }\n\n async *stream(req: PromptRequest): AsyncIterable<LlmEvent> {\n assertValidRequest(req);\n const client = this.ensureClient();\n\n if (req.signal?.aborted) {\n yield { type: 'end', finishReason: 'aborted' };\n return;\n }\n\n const messages = buildWireMessages(req);\n const tools = req.tools && req.tools.length > 0 ? formatTools(req.tools) : undefined;\n\n const body: Record<string, unknown> = {\n model: req.model,\n messages,\n max_tokens: req.maxTokens ?? 4_096,\n stream: true,\n };\n if (req.system) body.system = req.system;\n if (tools) body.tools = tools;\n if (req.temperature !== undefined) body.temperature = req.temperature;\n\n if (req.cacheKey) {\n if (req.system) {\n body.system = [{ type: 'text', text: req.system, cache_control: { type: 'ephemeral' } }];\n }\n if (tools) {\n const lastTool = tools[tools.length - 1];\n lastTool.cache_control = { type: 'ephemeral' };\n }\n // Third breakpoint on the final message so the ENTIRE conversation\n // prefix is cached, not just system + tools. In the append-only\n // conversation pattern each turn's request extends the previous one,\n // so the moving breakpoint hits the prior turn's cache via Anthropic's\n // longest-prefix matching. Without this, the growing history — the\n // bulk of mid-call input tokens — is re-billed at full price every turn.\n markLastMessageForCaching(messages);\n }\n\n let stream;\n let responseHeaders: Headers | undefined;\n try {\n // Production: `.withResponse()` on the Anthropic SDK's APIPromise\n // exposes the underlying HTTP `Response` for header diagnostics.\n // Test mocks return the stream directly with no APIPromise wrapper;\n // fall through to plain await when `.withResponse` isn't present.\n const apiPromise = client.messages.create(\n body as unknown as Parameters<typeof client.messages.create>[0],\n { signal: req.signal },\n );\n const maybeWithResponse = (apiPromise as unknown as {\n withResponse?: () => Promise<{\n data: Awaited<typeof apiPromise>;\n response: { headers?: Headers };\n }>;\n }).withResponse;\n if (typeof maybeWithResponse === 'function') {\n const result = await maybeWithResponse.call(apiPromise);\n stream = result.data;\n responseHeaders = result.response?.headers;\n } else {\n stream = await apiPromise;\n }\n } catch (err) {\n if (isAbortError(err)) {\n yield { type: 'end', finishReason: 'aborted' };\n return;\n }\n throw err;\n }\n\n let currentToolUse: PendingToolUse | null = null;\n const completedToolCalls: CompletedToolCall[] = [];\n let stopReason: string | undefined;\n let inputTokens: number | undefined;\n let outputTokens: number | undefined;\n let cacheReadTokens: number | undefined;\n let cacheWriteTokens: number | undefined;\n\n try {\n for await (const event of stream as unknown as AsyncIterable<AnthropicStreamEvent>) {\n if (req.signal?.aborted) {\n yield { type: 'end', finishReason: 'aborted' };\n return;\n }\n\n switch (event.type) {\n case 'message_start':\n // Anthropic's input_tokens EXCLUDES cache activity — the read and\n // write classes arrive in their own fields, matching the library's\n // additive Usage convention with no adjustment needed.\n inputTokens = event.message?.usage?.input_tokens;\n cacheReadTokens = event.message?.usage?.cache_read_input_tokens;\n cacheWriteTokens = event.message?.usage?.cache_creation_input_tokens;\n break;\n\n case 'content_block_start': {\n const block = event.content_block;\n if (block?.type === 'tool_use') {\n currentToolUse = {\n id: block.id ?? '',\n name: block.name ?? '',\n argumentsText: '',\n };\n if (currentToolUse.id && currentToolUse.name) {\n yield {\n type: 'toolCallStart',\n id: currentToolUse.id,\n name: currentToolUse.name,\n };\n }\n }\n break;\n }\n\n case 'content_block_delta': {\n const delta = event.delta;\n if (delta?.type === 'text_delta' && delta.text) {\n yield { type: 'token', text: delta.text };\n } else if (delta?.type === 'input_json_delta' && currentToolUse && delta.partial_json) {\n currentToolUse.argumentsText += delta.partial_json;\n }\n break;\n }\n\n case 'content_block_stop':\n if (currentToolUse && currentToolUse.id && currentToolUse.name) {\n let parsed: unknown = {};\n try {\n parsed = currentToolUse.argumentsText\n ? JSON.parse(currentToolUse.argumentsText)\n : {};\n } catch {\n parsed = {};\n }\n completedToolCalls.push({\n id: currentToolUse.id,\n name: currentToolUse.name,\n arguments: parsed,\n });\n }\n currentToolUse = null;\n break;\n\n case 'message_delta':\n if (event.delta?.stop_reason) {\n stopReason = event.delta.stop_reason;\n }\n if (event.usage?.output_tokens !== undefined) {\n outputTokens = event.usage.output_tokens;\n }\n break;\n\n case 'message_stop':\n // No-op — we synthesize the `end` event after the loop completes.\n break;\n\n default:\n // Ignore unknown event types (forward compat).\n break;\n }\n }\n } catch (err) {\n if (isAbortError(err)) {\n yield { type: 'end', finishReason: 'aborted' };\n return;\n }\n throw err;\n }\n\n if (req.signal?.aborted) {\n yield { type: 'end', finishReason: 'aborted' };\n return;\n }\n\n // Emit accumulated tool calls before the end event.\n for (const tc of completedToolCalls) {\n yield {\n type: 'toolCall',\n id: tc.id,\n name: tc.name,\n arguments: tc.arguments,\n };\n }\n\n const finishReason = mapStopReason(stopReason, completedToolCalls.length > 0);\n const usage =\n inputTokens !== undefined || outputTokens !== undefined\n ? {\n ...(inputTokens !== undefined ? { inputTokens } : {}),\n ...(outputTokens !== undefined ? { outputTokens } : {}),\n ...(inputTokens !== undefined && outputTokens !== undefined\n ? {\n totalTokens:\n inputTokens + outputTokens + (cacheReadTokens ?? 0) + (cacheWriteTokens ?? 0),\n }\n : {}),\n ...(cacheReadTokens !== undefined ? { cacheReadTokens } : {}),\n ...(cacheWriteTokens !== undefined ? { cacheWriteTokens } : {}),\n }\n : undefined;\n\n const endEvent: Extract<LlmEvent, { type: 'end' }> = {\n type: 'end',\n finishReason,\n ...(usage ? { usage } : {}),\n ...(stopReason ? { rawReason: stopReason } : {}),\n };\n\n if (responseHeaders) {\n const metadata = ANTHROPIC_METADATA_EXTRACTOR(responseHeaders);\n if (Object.keys(metadata).length > 0) {\n endEvent.vendorMetadata = metadata;\n }\n }\n\n yield endEvent;\n }\n\n appendAssistantToolCall(\n history: Message[],\n toolCalls: ReadonlyArray<ToolCallEvent>,\n assistantText?: string,\n ): Message[] {\n // A text block may precede tool_use blocks in the same assistant turn.\n // Anthropic rejects an empty text block, so it is only included when the\n // model actually said something before calling the tool.\n const text = assistantText?.trim() ? assistantText : null;\n const wireMessage = {\n role: 'assistant',\n content: [\n ...(text ? [{ type: 'text', text }] : []),\n ...toolCalls.map((tc) => ({\n type: 'tool_use',\n id: tc.id,\n name: tc.name,\n input: tc.arguments ?? {},\n })),\n ],\n };\n return [\n ...history,\n {\n role: 'assistant',\n content: text ?? '',\n vendorRaw: wireMessage,\n },\n ];\n }\n\n appendToolResult(history: Message[], toolCallId: string, result: unknown): Message[] {\n const content = typeof result === 'string' ? result : JSON.stringify(result);\n const wireMessage = {\n role: 'user',\n content: [\n {\n type: 'tool_result',\n tool_use_id: toolCallId,\n content,\n },\n ],\n };\n return [\n ...history,\n {\n role: 'tool',\n content,\n vendorRaw: wireMessage,\n },\n ];\n }\n\n async listAvailableModels(): Promise<ModelInfo[]> {\n const client = this.ensureClient();\n const result = await client.models.list();\n const models: ModelInfo[] = [];\n for (const m of result.data) {\n const known = anthropicManifest.knownModels.find((k) => k.id === m.id);\n if (known) {\n models.push(known);\n } else {\n models.push({\n id: m.id,\n displayName: m.display_name ?? undefined,\n capabilities: defaultClaudeCapabilities(),\n });\n }\n }\n return models;\n }\n\n async testCredential(): Promise<void> {\n // Anthropic's /v1/models is authenticated and costs nothing.\n await this.ensureClient().models.list();\n }\n\n async warmup(): Promise<void> {\n const client = this.ensureClient();\n await client.models.list().catch(() => undefined);\n }\n\n private ensureClient(): Anthropic {\n if (!this.client) {\n throw new Error('AnthropicAdapter: init() must be called before stream()/listAvailableModels()');\n }\n return this.client;\n }\n}\n\n// ---------------------------------------------------------------------------\n// Internal types\n// ---------------------------------------------------------------------------\n\ninterface PendingToolUse {\n id: string;\n name: string;\n argumentsText: string;\n}\n\ninterface CompletedToolCall {\n id: string;\n name: string;\n arguments: unknown;\n}\n\ninterface AnthropicStreamEvent {\n type: string;\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?: {\n type?: string;\n text?: string;\n partial_json?: string;\n stop_reason?: string;\n };\n usage?: { output_tokens?: number };\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction buildWireMessages(req: PromptRequest): unknown[] {\n const out: unknown[] = [];\n for (const msg of req.messages) {\n if (msg.vendorRaw && typeof msg.vendorRaw === 'object') {\n out.push(msg.vendorRaw);\n } else {\n out.push({ role: msg.role, content: msg.content });\n }\n }\n return out;\n}\n\n/**\n * Replace the last wire message with a copy whose final content block\n * carries `cache_control: {type: 'ephemeral'}`. COPY, never mutate: the\n * `vendorRaw` entries in `messages` are the caller's history objects, and a\n * marker persisted there would accumulate one breakpoint per turn — past\n * Anthropic's 4-breakpoint limit the request is rejected outright.\n */\nfunction markLastMessageForCaching(messages: unknown[]): void {\n if (messages.length === 0) return;\n const last = messages[messages.length - 1] as { content?: unknown };\n const cacheControl = { cache_control: { type: 'ephemeral' } };\n if (typeof last.content === 'string' && last.content.length > 0) {\n messages[messages.length - 1] = {\n ...last,\n content: [{ type: 'text', text: last.content, ...cacheControl }],\n };\n } else if (Array.isArray(last.content) && last.content.length > 0) {\n const blocks = last.content as Array<Record<string, unknown>>;\n messages[messages.length - 1] = {\n ...last,\n content: [...blocks.slice(0, -1), { ...blocks[blocks.length - 1], ...cacheControl }],\n };\n }\n // Empty content (e.g. a bare assistant placeholder) is left unmarked —\n // an empty text block with cache_control would be rejected by the API.\n}\n\nfunction formatTools(tools: Tool[]): Array<Record<string, unknown>> {\n return tools.map((t) => ({\n name: t.name,\n description: t.description ?? '',\n input_schema: t.parameters ?? { type: 'object', properties: {} },\n }));\n}\n\nfunction mapStopReason(r: string | undefined, hadToolCalls: boolean): FinishReason {\n if (hadToolCalls) return 'tool';\n switch (r) {\n case 'end_turn':\n case 'stop_sequence':\n return 'stop';\n case 'tool_use':\n return 'tool';\n case 'max_tokens':\n return 'length';\n default:\n return 'stop';\n }\n}\n\nfunction defaultClaudeCapabilities() {\n return {\n streaming: true,\n tools: true,\n vision: true,\n systemPrompt: true,\n };\n}\n\nfunction isAbortError(err: unknown): boolean {\n if (!err || typeof err !== 'object') return false;\n const e = err as { name?: string; code?: string; message?: string };\n return (\n e.name === 'APIUserAbortError' ||\n e.name === 'AbortError' ||\n e.code === 'ABORT_ERR' ||\n (typeof e.message === 'string' && /aborted/i.test(e.message))\n );\n}\n","import type { AdapterManifest, ModelInfo } from '../../types.js';\n\n/**\n * Known Claude models. Model listing via `listAvailableModels()` hits\n * Anthropic's live `/v1/models` endpoint; this curated list drives the\n * admin-UI dropdown and capability validation.\n *\n * All Claude models in this list support tools, streaming, system prompts,\n * and vision. There is no reasoning-only / tool-less variant to special-case\n * the way OpenAI's o1 family does.\n */\nconst ANTHROPIC_KNOWN_MODELS: ModelInfo[] = [\n {\n id: 'claude-opus-4-7',\n displayName: 'Claude Opus 4.7',\n capabilities: {\n streaming: true,\n tools: true,\n vision: true,\n systemPrompt: true,\n maxContextTokens: 200_000,\n },\n },\n {\n id: 'claude-sonnet-4-6',\n displayName: 'Claude Sonnet 4.6',\n capabilities: {\n streaming: true,\n tools: true,\n vision: true,\n systemPrompt: true,\n maxContextTokens: 200_000,\n },\n },\n {\n id: 'claude-haiku-4-5-20251001',\n displayName: 'Claude Haiku 4.5',\n capabilities: {\n streaming: true,\n tools: true,\n vision: true,\n systemPrompt: true,\n maxContextTokens: 200_000,\n },\n },\n {\n id: 'claude-3-7-sonnet-20250219',\n displayName: 'Claude 3.7 Sonnet',\n capabilities: {\n streaming: true,\n tools: true,\n vision: true,\n systemPrompt: true,\n maxContextTokens: 200_000,\n },\n },\n {\n id: 'claude-3-5-sonnet-20241022',\n displayName: 'Claude 3.5 Sonnet',\n capabilities: {\n streaming: true,\n tools: true,\n vision: true,\n systemPrompt: true,\n maxContextTokens: 200_000,\n },\n },\n {\n id: 'claude-3-5-haiku-20241022',\n displayName: 'Claude 3.5 Haiku',\n capabilities: {\n streaming: true,\n tools: true,\n vision: false,\n systemPrompt: true,\n maxContextTokens: 200_000,\n },\n },\n];\n\nexport const anthropicManifest: AdapterManifest = {\n vendor: 'anthropic',\n displayName: 'Anthropic Claude',\n authKinds: [\n {\n kind: 'apiKey',\n displayName: 'API Key',\n fields: [\n {\n name: 'apiKey',\n label: 'API Key',\n type: 'password',\n required: true,\n help: 'Get an API key from https://console.anthropic.com/settings/keys',\n },\n {\n name: 'baseURL',\n label: 'Base URL',\n type: 'url',\n required: false,\n default: 'https://api.anthropic.com',\n help: 'Override for proxies or enterprise deployments.',\n },\n ],\n },\n ],\n knownModels: ANTHROPIC_KNOWN_MODELS,\n supportsModelListing: true,\n docsUrl: 'https://docs.anthropic.com/en/api/overview',\n};\n","import type { AdapterFactory, ApiKeyAuth } from '../../types.js';\nimport { AnthropicAdapter } from './adapter.js';\nimport { anthropicManifest } from './manifest.js';\n\nexport const anthropicFactory: AdapterFactory<ApiKeyAuth> = {\n vendor: anthropicManifest.vendor,\n manifest: anthropicManifest,\n create: () => new AnthropicAdapter(),\n};\n","import { GoogleGenAI } from '@google/genai';\nimport type {\n ClientOptions,\n GoogleApiKeyAuth,\n LlmAdapter,\n LlmEvent,\n Message,\n ModelInfo,\n PromptRequest,\n ToolCallEvent,\n} from '../../types.js';\nimport {\n appendGeminiAssistantToolCall,\n appendGeminiToolResult,\n listGeminiModels,\n streamFromGemini,\n} from './_streaming.js';\nimport { googleManifest } from './manifest.js';\n\n/**\n * Adapter for Google Gemini via AI Studio (`@google/genai`, API key auth).\n *\n * Wire translation lives in `_streaming.ts` and is shared with the\n * Vertex-Gemini adapter — both use the same `@google/genai` SDK and the\n * same on-wire shape; only client construction differs.\n *\n * For service-account auth on Vertex AI, see the `vertex-gemini` adapter.\n */\nexport class GoogleAdapter implements LlmAdapter<GoogleApiKeyAuth> {\n readonly vendor = googleManifest.vendor;\n readonly acceptedAuth = ['googleApiKey'] as const;\n\n private client: GoogleGenAI | undefined;\n\n init(auth: GoogleApiKeyAuth, _client?: ClientOptions): void {\n if (auth.kind !== 'googleApiKey') {\n throw new Error(\n `GoogleAdapter: unsupported auth kind '${(auth as { kind: string }).kind}'`,\n );\n }\n if (!auth.apiKey) {\n throw new Error('GoogleAdapter: apiKey is required');\n }\n this.client = new GoogleGenAI({ apiKey: auth.apiKey });\n }\n\n stream(req: PromptRequest): AsyncIterable<LlmEvent> {\n return streamFromGemini(this.ensureClient(), req);\n }\n\n appendAssistantToolCall(\n history: Message[],\n toolCalls: ReadonlyArray<ToolCallEvent>,\n assistantText?: string,\n ): Message[] {\n return appendGeminiAssistantToolCall(history, toolCalls, assistantText);\n }\n\n appendToolResult(history: Message[], toolCallId: string, result: unknown): Message[] {\n return appendGeminiToolResult(history, toolCallId, result);\n }\n\n async listAvailableModels(): Promise<ModelInfo[]> {\n return listGeminiModels(this.ensureClient(), googleManifest.knownModels);\n }\n\n async testCredential(): Promise<void> {\n // Model listing authenticates; no stream needed.\n await listGeminiModels(this.ensureClient(), googleManifest.knownModels);\n }\n\n async warmup(): Promise<void> {\n // @google/genai has no cheap idempotent warmup endpoint. No-op.\n }\n\n private ensureClient(): GoogleGenAI {\n if (!this.client) {\n throw new Error('GoogleAdapter: init() must be called before stream()/listAvailableModels()');\n }\n return this.client;\n }\n}\n","import type { GoogleGenAI } from '@google/genai';\nimport type {\n FinishReason,\n LlmEvent,\n Message,\n ModelInfo,\n PromptRequest,\n Tool,\n} from '../../types.js';\nimport { assertValidRequest } from '../../validate.js';\n\n/**\n * Gemini wire translation, shared between the Google AI Studio adapter\n * and the Vertex-Gemini adapter. Both use the same `@google/genai` SDK\n * with the same on-wire shape — only the client construction differs.\n */\nexport async function* streamFromGemini(\n client: GoogleGenAI,\n req: PromptRequest,\n): AsyncIterable<LlmEvent> {\n assertValidRequest(req);\n\n if (req.signal?.aborted) {\n yield { type: 'end', finishReason: 'aborted' };\n return;\n }\n\n const contents = buildWireContents(req);\n const tools = req.tools && req.tools.length > 0 ? formatTools(req.tools) : undefined;\n\n const config: Record<string, unknown> = {};\n if (req.system) {\n config.systemInstruction = { parts: [{ text: req.system }] };\n }\n if (tools) config.tools = tools;\n if (req.temperature !== undefined) config.temperature = req.temperature;\n if (req.maxTokens !== undefined) config.maxOutputTokens = req.maxTokens;\n if (req.signal) config.abortSignal = req.signal;\n\n // Merge caller-supplied provider-specific params into the generation\n // config (e.g. Gemini 3's thinkingConfig). Add-only: never overwrite a\n // library-managed field, so this can extend the request but not corrupt\n // its core shape.\n if (req.providerParams) {\n for (const [key, value] of Object.entries(req.providerParams)) {\n if (!(key in config)) config[key] = value;\n }\n }\n\n // req.cacheKey is intentionally NOT applied here.\n // Gemini 2.5 models perform implicit prompt caching server-side automatically —\n // no request parameter is needed or accepted. Explicit context caching via\n // `cachedContent` requires a stateful create/TTL/delete lifecycle that cannot\n // be driven by a single stateless request field, so it is out of scope for\n // cacheKey. This preserves the library's silent-ignore contract: adapters\n // without a native per-request cache mechanism simply leave cacheKey unread.\n // Note: this helper is shared by both the Google AI Studio adapter and the\n // Vertex-Gemini adapter; the same reasoning applies to both.\n\n let stream;\n try {\n stream = await client.models.generateContentStream({\n model: req.model,\n contents: contents as Parameters<typeof client.models.generateContentStream>[0]['contents'],\n config,\n });\n } catch (err) {\n if (isAbortError(err)) {\n yield { type: 'end', finishReason: 'aborted' };\n return;\n }\n throw err;\n }\n\n const toolCallCounter = new Map<string, number>();\n const completedToolCalls: Array<{ id: string; name: string; arguments: unknown }> = [];\n let stopReason: string | undefined;\n let inputTokens: number | undefined;\n let outputTokens: number | undefined;\n let totalTokens: number | undefined;\n let cacheReadTokens: number | undefined;\n\n try {\n for await (const chunk of stream) {\n if (req.signal?.aborted) {\n yield { type: 'end', finishReason: 'aborted' };\n return;\n }\n\n const usage = chunk.usageMetadata;\n if (usage) {\n // Gemini's promptTokenCount INCLUDES implicitly-cached tokens\n // (cachedContentTokenCount is a sub-detail). Subtract it out so\n // inputTokens means UNCACHED input, per the library's additive\n // Usage convention.\n if (usage.cachedContentTokenCount !== undefined) {\n cacheReadTokens = usage.cachedContentTokenCount;\n }\n if (usage.promptTokenCount !== undefined) {\n inputTokens = usage.promptTokenCount - (usage.cachedContentTokenCount ?? 0);\n }\n if (usage.candidatesTokenCount !== undefined) outputTokens = usage.candidatesTokenCount;\n if (usage.totalTokenCount !== undefined) totalTokens = usage.totalTokenCount;\n }\n\n const candidate = chunk.candidates?.[0];\n if (!candidate?.content?.parts) {\n if (candidate?.finishReason) stopReason = candidate.finishReason;\n continue;\n }\n\n for (const part of candidate.content.parts) {\n if (typeof part.text === 'string' && part.text.length > 0) {\n yield { type: 'token', text: part.text };\n }\n if (part.functionCall) {\n const name = part.functionCall.name ?? '';\n if (!name) continue;\n const count = toolCallCounter.get(name) ?? 0;\n toolCallCounter.set(name, count + 1);\n const id = count === 0 ? name : `${name}#${count}`;\n yield { type: 'toolCallStart', id, name };\n completedToolCalls.push({\n id,\n name,\n arguments: part.functionCall.args ?? {},\n });\n }\n }\n\n if (candidate.finishReason) {\n stopReason = candidate.finishReason;\n }\n }\n } catch (err) {\n if (isAbortError(err)) {\n yield { type: 'end', finishReason: 'aborted' };\n return;\n }\n throw err;\n }\n\n if (req.signal?.aborted) {\n yield { type: 'end', finishReason: 'aborted' };\n return;\n }\n\n for (const tc of completedToolCalls) {\n yield {\n type: 'toolCall',\n id: tc.id,\n name: tc.name,\n arguments: tc.arguments,\n };\n }\n\n const finishReason = mapFinishReason(stopReason, completedToolCalls.length > 0);\n const usage =\n inputTokens !== undefined || outputTokens !== undefined || totalTokens !== undefined\n ? {\n ...(inputTokens !== undefined ? { inputTokens } : {}),\n ...(outputTokens !== undefined ? { outputTokens } : {}),\n ...(totalTokens !== undefined ? { totalTokens } : {}),\n ...(cacheReadTokens !== undefined ? { cacheReadTokens } : {}),\n }\n : undefined;\n\n const endEvent: Extract<LlmEvent, { type: 'end' }> = {\n type: 'end',\n finishReason,\n ...(usage ? { usage } : {}),\n ...(stopReason ? { rawReason: stopReason } : {}),\n };\n yield endEvent;\n}\n\n/**\n * Build an assistant-with-tool-call turn in the Gemini wire shape (role:\n * 'model', parts: [{functionCall, ...}]). Shared between Google AI Studio\n * and Vertex-Gemini adapters.\n */\nexport function appendGeminiAssistantToolCall(\n history: Message[],\n toolCalls: ReadonlyArray<Extract<LlmEvent, { type: 'toolCall' }>>,\n assistantText?: string,\n): Message[] {\n // A text part may precede functionCall parts in the same model turn.\n const text = assistantText?.trim() ? assistantText : null;\n const wireMessage = {\n role: 'model',\n parts: [\n ...(text ? [{ text }] : []),\n ...toolCalls.map((tc) => ({\n functionCall: {\n name: parseToolName(tc.id),\n args: tc.arguments ?? {},\n },\n })),\n ],\n };\n return [\n ...history,\n {\n role: 'assistant',\n content: text ?? '',\n vendorRaw: wireMessage,\n },\n ];\n}\n\n/**\n * Build a tool-result message in the Gemini wire shape. Shared between\n * Google AI Studio and Vertex-Gemini adapters.\n */\nexport function appendGeminiToolResult(\n history: Message[],\n toolCallId: string,\n result: unknown,\n): Message[] {\n const name = parseToolName(toolCallId);\n const content = typeof result === 'string' ? result : JSON.stringify(result);\n const wireMessage = {\n role: 'user',\n parts: [\n {\n functionResponse: {\n name,\n response: { result: content },\n },\n },\n ],\n };\n return [\n ...history,\n {\n role: 'tool',\n content,\n vendorRaw: wireMessage,\n },\n ];\n}\n\n/**\n * Call the models.list() pager and return normalised `ModelInfo` records,\n * merging capabilities from a known-models table when possible.\n */\nexport async function listGeminiModels(\n client: GoogleGenAI,\n knownModels: ReadonlyArray<ModelInfo>,\n): Promise<ModelInfo[]> {\n const out: ModelInfo[] = [];\n const pager = await client.models.list();\n for await (const m of pager as AsyncIterable<{ name?: string; displayName?: string }>) {\n const id = stripModelPrefix(m.name ?? '');\n if (!id) continue;\n const known = knownModels.find((k) => k.id === id);\n if (known) {\n out.push(known);\n } else {\n out.push({\n id,\n displayName: m.displayName ?? undefined,\n capabilities: defaultGeminiCapabilities(),\n });\n }\n }\n return out;\n}\n\n// ---------------------------------------------------------------------------\n// Internal helpers (exported for adapter-local reuse only; not public)\n// ---------------------------------------------------------------------------\n\nfunction buildWireContents(req: PromptRequest): unknown[] {\n const out: unknown[] = [];\n for (const msg of req.messages) {\n if (msg.vendorRaw && typeof msg.vendorRaw === 'object') {\n out.push(msg.vendorRaw);\n continue;\n }\n const text = typeof msg.content === 'string' ? msg.content : JSON.stringify(msg.content);\n out.push({\n role: toGeminiRole(msg.role),\n parts: [{ text }],\n });\n }\n return out;\n}\n\nfunction toGeminiRole(role: string): 'user' | 'model' {\n return role === 'assistant' || role === 'model' ? 'model' : 'user';\n}\n\nfunction formatTools(tools: Tool[]): Array<Record<string, unknown>> {\n return [\n {\n functionDeclarations: tools.map((t) => ({\n name: t.name,\n description: t.description ?? '',\n parameters: t.parameters ?? { type: 'object', properties: {} },\n })),\n },\n ];\n}\n\nfunction mapFinishReason(r: string | undefined, hadToolCalls: boolean): FinishReason {\n if (hadToolCalls && (r === 'STOP' || r === 'TOOL_CALLS' || !r)) return 'tool';\n switch (r) {\n case 'STOP':\n return 'stop';\n case 'MAX_TOKENS':\n return 'length';\n case 'SAFETY':\n case 'RECITATION':\n return 'filtered';\n case 'TOOL_CALLS':\n return 'tool';\n default:\n return 'stop';\n }\n}\n\nfunction parseToolName(id: string): string {\n const hashIdx = id.lastIndexOf('#');\n if (hashIdx === -1) return id;\n const suffix = id.slice(hashIdx + 1);\n if (/^\\d+$/.test(suffix)) return id.slice(0, hashIdx);\n return id;\n}\n\nfunction stripModelPrefix(name: string): string {\n return name.startsWith('models/') ? name.slice('models/'.length) : name;\n}\n\nexport function defaultGeminiCapabilities() {\n return {\n streaming: true,\n tools: true,\n vision: true,\n systemPrompt: true,\n };\n}\n\nfunction isAbortError(err: unknown): boolean {\n if (!err || typeof err !== 'object') return false;\n const e = err as { name?: string; code?: string; message?: string };\n return (\n e.name === 'APIUserAbortError' ||\n e.name === 'AbortError' ||\n e.code === 'ABORT_ERR' ||\n (typeof e.message === 'string' && /aborted/i.test(e.message))\n );\n}\n","import type { AdapterManifest, ModelInfo } from '../../types.js';\n\n/**\n * Known Gemini models. Model listing via `listAvailableModels()` hits the\n * live endpoint; this curated list drives the admin-UI dropdown.\n *\n * All Gemini models in this list support tools and streaming. Only\n * `gemini-2.0-flash-lite` loses vision support — the 3.x `-lite` variants\n * are fully multimodal.\n */\nconst GOOGLE_KNOWN_MODELS: ModelInfo[] = [\n {\n id: 'gemini-3.6-flash',\n displayName: 'Gemini 3.6 Flash',\n capabilities: {\n streaming: true,\n tools: true,\n vision: true,\n systemPrompt: true,\n maxContextTokens: 1_000_000,\n },\n },\n {\n id: 'gemini-3.5-flash',\n displayName: 'Gemini 3.5 Flash',\n capabilities: {\n streaming: true,\n tools: true,\n vision: true,\n systemPrompt: true,\n maxContextTokens: 1_000_000,\n },\n },\n {\n id: 'gemini-3.5-flash-lite',\n displayName: 'Gemini 3.5 Flash-Lite',\n capabilities: {\n streaming: true,\n tools: true,\n vision: true,\n systemPrompt: true,\n maxContextTokens: 1_000_000,\n },\n },\n {\n id: 'gemini-2.5-pro',\n displayName: 'Gemini 2.5 Pro',\n capabilities: {\n streaming: true,\n tools: true,\n vision: true,\n systemPrompt: true,\n maxContextTokens: 1_000_000,\n },\n },\n {\n id: 'gemini-2.5-flash',\n displayName: 'Gemini 2.5 Flash',\n capabilities: {\n streaming: true,\n tools: true,\n vision: true,\n systemPrompt: true,\n maxContextTokens: 1_000_000,\n },\n },\n {\n id: 'gemini-2.0-flash',\n displayName: 'Gemini 2.0 Flash',\n capabilities: {\n streaming: true,\n tools: true,\n vision: true,\n systemPrompt: true,\n maxContextTokens: 1_000_000,\n },\n },\n {\n id: 'gemini-2.0-flash-lite',\n displayName: 'Gemini 2.0 Flash Lite',\n capabilities: {\n streaming: true,\n tools: true,\n vision: false,\n systemPrompt: true,\n maxContextTokens: 1_000_000,\n },\n },\n {\n id: 'gemini-1.5-pro',\n displayName: 'Gemini 1.5 Pro',\n capabilities: {\n streaming: true,\n tools: true,\n vision: true,\n systemPrompt: true,\n maxContextTokens: 2_000_000,\n },\n },\n {\n id: 'gemini-1.5-flash',\n displayName: 'Gemini 1.5 Flash',\n capabilities: {\n streaming: true,\n tools: true,\n vision: true,\n systemPrompt: true,\n maxContextTokens: 1_000_000,\n },\n },\n];\n\nexport const googleManifest: AdapterManifest = {\n vendor: 'google',\n displayName: 'Google Gemini',\n authKinds: [\n {\n kind: 'googleApiKey',\n displayName: 'API Key',\n fields: [\n {\n name: 'apiKey',\n label: 'API Key',\n type: 'password',\n required: true,\n help: 'Get an API key from https://aistudio.google.com/apikey',\n },\n ],\n },\n ],\n knownModels: GOOGLE_KNOWN_MODELS,\n supportsModelListing: true,\n docsUrl: 'https://ai.google.dev/gemini-api/docs',\n};\n\n","import type { AdapterFactory, GoogleApiKeyAuth } from '../../types.js';\nimport { GoogleAdapter } from './adapter.js';\nimport { googleManifest } from './manifest.js';\n\nexport const googleFactory: AdapterFactory<GoogleApiKeyAuth> = {\n vendor: googleManifest.vendor,\n manifest: googleManifest,\n create: () => new GoogleAdapter(),\n};\n","import { GoogleGenAI } from '@google/genai';\nimport type {\n ClientOptions,\n LlmAdapter,\n LlmEvent,\n Message,\n ModelInfo,\n PromptRequest,\n ToolCallEvent,\n VertexServiceAccountAuth,\n} from '../../types.js';\nimport {\n appendGeminiAssistantToolCall,\n appendGeminiToolResult,\n listGeminiModels,\n streamFromGemini,\n} from '../google/_streaming.js';\nimport { vertexGeminiManifest } from './manifest.js';\n\n/**\n * Adapter for Gemini models running on Vertex AI.\n *\n * Wire shape is identical to the `google` adapter — both use `@google/genai`\n * and speak the same contents/parts protocol. The only differences are:\n * - Client is constructed with `vertexai: true` plus project/location.\n * - Auth uses a GCP service account (pass through `googleAuthOptions`).\n *\n * For third-party models hosted on Vertex (Mistral, Llama, etc.) that speak\n * the OpenAI-compatible protocol, see the `vertex-openai` adapter.\n */\nexport class VertexGeminiAdapter implements LlmAdapter<VertexServiceAccountAuth> {\n readonly vendor = vertexGeminiManifest.vendor;\n readonly acceptedAuth = ['vertexServiceAccount'] as const;\n\n private client: GoogleGenAI | undefined;\n\n init(auth: VertexServiceAccountAuth, _client?: ClientOptions): void {\n if (auth.kind !== 'vertexServiceAccount') {\n throw new Error(\n `VertexGeminiAdapter: unsupported auth kind '${(auth as { kind: string }).kind}'`,\n );\n }\n if (!auth.credentials) {\n throw new Error('VertexGeminiAdapter: service-account credentials are required');\n }\n if (!auth.projectId) {\n throw new Error('VertexGeminiAdapter: projectId is required');\n }\n if (!auth.location) {\n throw new Error('VertexGeminiAdapter: location is required');\n }\n\n this.client = new GoogleGenAI({\n vertexai: true,\n project: auth.projectId,\n location: auth.location,\n googleAuthOptions: {\n credentials: auth.credentials as Record<string, unknown>,\n },\n });\n }\n\n stream(req: PromptRequest): AsyncIterable<LlmEvent> {\n return streamFromGemini(this.ensureClient(), req);\n }\n\n appendAssistantToolCall(\n history: Message[],\n toolCalls: ReadonlyArray<ToolCallEvent>,\n assistantText?: string,\n ): Message[] {\n return appendGeminiAssistantToolCall(history, toolCalls, assistantText);\n }\n\n appendToolResult(history: Message[], toolCallId: string, result: unknown): Message[] {\n return appendGeminiToolResult(history, toolCallId, result);\n }\n\n async listAvailableModels(): Promise<ModelInfo[]> {\n return listGeminiModels(this.ensureClient(), vertexGeminiManifest.knownModels);\n }\n\n async testCredential(): Promise<void> {\n // Listing models authenticates via the service-account bearer.\n await listGeminiModels(this.ensureClient(), vertexGeminiManifest.knownModels);\n }\n\n async warmup(): Promise<void> {\n // No cheap idempotent warmup endpoint. No-op.\n }\n\n private ensureClient(): GoogleGenAI {\n if (!this.client) {\n throw new Error(\n 'VertexGeminiAdapter: init() must be called before stream()/listAvailableModels()',\n );\n }\n return this.client;\n }\n}\n","import type { AdapterManifest, ModelInfo } from '../../types.js';\n\n/**\n * Known Gemini models available on Vertex AI.\n *\n * Vertex-hosted Gemini models often use the `-001` / `-002` versioning\n * suffix (vs AI Studio's bare id). We list both conventions so the admin-UI\n * dropdown covers common deployments.\n */\nconst VERTEX_GEMINI_KNOWN_MODELS: ModelInfo[] = [\n {\n id: 'gemini-3.6-flash',\n displayName: 'Gemini 3.6 Flash',\n capabilities: {\n streaming: true,\n tools: true,\n vision: true,\n systemPrompt: true,\n maxContextTokens: 1_000_000,\n },\n },\n {\n id: 'gemini-3.5-flash',\n displayName: 'Gemini 3.5 Flash',\n capabilities: {\n streaming: true,\n tools: true,\n vision: true,\n systemPrompt: true,\n maxContextTokens: 1_000_000,\n },\n },\n {\n id: 'gemini-3.5-flash-lite',\n displayName: 'Gemini 3.5 Flash-Lite',\n capabilities: {\n streaming: true,\n tools: true,\n vision: true,\n systemPrompt: true,\n maxContextTokens: 1_000_000,\n },\n },\n {\n id: 'gemini-2.5-pro',\n displayName: 'Gemini 2.5 Pro',\n capabilities: {\n streaming: true,\n tools: true,\n vision: true,\n systemPrompt: true,\n maxContextTokens: 1_000_000,\n },\n },\n {\n id: 'gemini-2.5-flash',\n displayName: 'Gemini 2.5 Flash',\n capabilities: {\n streaming: true,\n tools: true,\n vision: true,\n systemPrompt: true,\n maxContextTokens: 1_000_000,\n },\n },\n {\n id: 'gemini-2.0-flash',\n displayName: 'Gemini 2.0 Flash',\n capabilities: {\n streaming: true,\n tools: true,\n vision: true,\n systemPrompt: true,\n maxContextTokens: 1_000_000,\n },\n },\n {\n id: 'gemini-1.5-pro',\n displayName: 'Gemini 1.5 Pro',\n capabilities: {\n streaming: true,\n tools: true,\n vision: true,\n systemPrompt: true,\n maxContextTokens: 2_000_000,\n },\n },\n {\n id: 'gemini-1.5-flash',\n displayName: 'Gemini 1.5 Flash',\n capabilities: {\n streaming: true,\n tools: true,\n vision: true,\n systemPrompt: true,\n maxContextTokens: 1_000_000,\n },\n },\n];\n\nexport const vertexGeminiManifest: AdapterManifest = {\n vendor: 'vertex-gemini',\n displayName: 'Vertex AI — Gemini',\n authKinds: [\n {\n kind: 'vertexServiceAccount',\n displayName: 'Service Account JSON',\n fields: [\n {\n name: 'credentials',\n label: 'Service Account Key (JSON)',\n type: 'json-file',\n required: true,\n help: 'Upload the service account key JSON from Google Cloud Console.',\n },\n {\n name: 'projectId',\n label: 'Project ID',\n type: 'text',\n required: true,\n help: 'GCP project that hosts the Vertex AI deployment.',\n },\n {\n name: 'location',\n label: 'Region',\n type: 'select',\n required: true,\n default: 'us-central1',\n options: [\n { value: 'us-central1', label: 'us-central1' },\n { value: 'us-east1', label: 'us-east1' },\n { value: 'us-east4', label: 'us-east4' },\n { value: 'us-west1', label: 'us-west1' },\n { value: 'us-west4', label: 'us-west4' },\n { value: 'europe-west1', label: 'europe-west1' },\n { value: 'europe-west2', label: 'europe-west2' },\n { value: 'europe-west3', label: 'europe-west3' },\n { value: 'europe-west4', label: 'europe-west4' },\n { value: 'asia-east1', label: 'asia-east1' },\n { value: 'asia-northeast1', label: 'asia-northeast1' },\n { value: 'asia-southeast1', label: 'asia-southeast1' },\n ],\n },\n ],\n },\n ],\n knownModels: VERTEX_GEMINI_KNOWN_MODELS,\n supportsModelListing: true,\n docsUrl: 'https://cloud.google.com/vertex-ai/generative-ai/docs',\n};\n","import type { AdapterFactory, VertexServiceAccountAuth } from '../../types.js';\nimport { VertexGeminiAdapter } from './adapter.js';\nimport { vertexGeminiManifest } from './manifest.js';\n\nexport const vertexGeminiFactory: AdapterFactory<VertexServiceAccountAuth> = {\n vendor: vertexGeminiManifest.vendor,\n manifest: vertexGeminiManifest,\n create: () => new VertexGeminiAdapter(),\n};\n","import OpenAI from 'openai';\nimport { GoogleAuth } from 'google-auth-library';\nimport type {\n ClientOptions,\n LlmAdapter,\n LlmEvent,\n Message,\n ModelInfo,\n PromptRequest,\n ToolCallEvent,\n VertexServiceAccountAuth,\n} from '../../types.js';\nimport {\n appendOpenAIAssistantToolCall,\n appendOpenAIToolResult,\n streamFromOpenAI,\n} from '../openai/_streaming.js';\nimport { makeMetadataExtractor } from '../_metadata.js';\nimport { vertexOpenAIManifest } from './manifest.js';\n\n/**\n * Vertex partner-model response-header diagnostics. Sparse —\n * Google's compat layer mostly returns standard request id and\n * little else useful for client-side observability.\n */\nconst VERTEX_OPENAI_METADATA_EXTRACTOR = makeMetadataExtractor([\n { header: 'x-request-id', key: 'request_id' },\n]);\n\n/**\n * Adapter for third-party models on Vertex AI (Mistral, Llama, etc.) that\n * expose an OpenAI-compatible endpoint. Shares all wire translation with\n * the native OpenAI adapter; only the client differs — `baseURL` is\n * Vertex-specific and a custom `fetch` wraps each request to inject a GCP\n * Bearer token from a service account.\n */\nexport class VertexOpenAIAdapter implements LlmAdapter<VertexServiceAccountAuth> {\n readonly vendor = vertexOpenAIManifest.vendor;\n readonly acceptedAuth = ['vertexServiceAccount'] as const;\n\n private client: OpenAI | undefined;\n private googleAuth: GoogleAuth | undefined;\n\n init(auth: VertexServiceAccountAuth, client?: ClientOptions): void {\n if (auth.kind !== 'vertexServiceAccount') {\n throw new Error(\n `VertexOpenAIAdapter: unsupported auth kind '${(auth as { kind: string }).kind}'`,\n );\n }\n if (!auth.credentials) {\n throw new Error('VertexOpenAIAdapter: service-account credentials are required');\n }\n if (!auth.projectId) {\n throw new Error('VertexOpenAIAdapter: projectId is required');\n }\n if (!auth.location) {\n throw new Error('VertexOpenAIAdapter: location is required');\n }\n\n // Vertex AI's OpenAI-compatible endpoint is at /v1beta1/ — documented in\n // Google's SDK examples (google-cloud-aiplatform) and Google Cloud docs.\n // A /v1/ variant returns 404; do not use.\n const baseURL =\n `https://${auth.location}-aiplatform.googleapis.com/v1beta1/projects/` +\n `${auth.projectId}/locations/${auth.location}/endpoints/openapi`;\n\n this.googleAuth = new GoogleAuth({\n credentials: auth.credentials as Record<string, unknown>,\n scopes: ['https://www.googleapis.com/auth/cloud-platform'],\n });\n\n const authedFetch: typeof fetch = async (input, init) => {\n const googleClient = await this.googleAuth!.getClient();\n const token = await googleClient.getAccessToken();\n const headers = new Headers(init?.headers);\n headers.set('Authorization', `Bearer ${token.token ?? ''}`);\n const response = await fetch(input, { ...init, headers });\n if (!response.ok) {\n return surfaceErrorBody(response, input);\n }\n return response;\n };\n\n this.client = new OpenAI({\n apiKey: 'vertex-ai',\n baseURL,\n fetch: authedFetch as never,\n ...(client?.timeout !== undefined ? { timeout: client.timeout } : {}),\n ...(client?.maxRetries !== undefined ? { maxRetries: client.maxRetries } : {}),\n });\n }\n\n stream(req: PromptRequest): AsyncIterable<LlmEvent> {\n // Vertex AI's Llama MaaS endpoint returns an empty assistant message\n // (zero tokens, finish_reason: stop) when max_tokens is not set. Apply\n // a sensible default so callers don't have to know this quirk.\n return streamFromOpenAI(this.ensureClient(), req, {\n knownModels: vertexOpenAIManifest.knownModels,\n defaultMaxTokens: 4096,\n // Pin legacy `max_tokens`: Vertex's OpenAI-compat partner-model\n // endpoint predates `max_completion_tokens` and may not recognize it.\n // The model-id heuristic wouldn't catch a partner model named in the\n // OpenAI style (unlikely today, but defensive).\n tokensParam: 'max_tokens',\n vendorMetadataExtractor: VERTEX_OPENAI_METADATA_EXTRACTOR,\n });\n }\n\n appendAssistantToolCall(\n history: Message[],\n toolCalls: ReadonlyArray<ToolCallEvent>,\n assistantText?: string,\n ): Message[] {\n return appendOpenAIAssistantToolCall(history, toolCalls, assistantText);\n }\n\n appendToolResult(history: Message[], toolCallId: string, result: unknown): Message[] {\n return appendOpenAIToolResult(history, toolCallId, result);\n }\n\n async listAvailableModels(): Promise<ModelInfo[]> {\n // The Vertex OpenAI-compatible endpoint does not expose a models list.\n // Return the curated set from the manifest.\n return [...vertexOpenAIManifest.knownModels];\n }\n\n async testCredential(): Promise<void> {\n // The OpenAI-compat endpoint has no list-models or other zero-cost\n // authenticated endpoint. Chat probes against a specific model are a\n // bad proxy: they require that partner model (Mistral, Llama, …) to be\n // granted in the caller's GCP project, which is independent of whether\n // the service-account credentials themselves are valid.\n //\n // Minting a Google access token from the service-account is sufficient\n // and vendor-appropriate: it verifies the credential JSON is well-formed,\n // the service account exists, and the key is active. If the token mints\n // but the caller hasn't enabled Vertex AI or a specific partner model in\n // the project, the first stream() call will tell them — credential\n // validity and model entitlement are properly separated concerns.\n if (!this.googleAuth) {\n throw new Error('VertexOpenAIAdapter: init() must be called before testCredential()');\n }\n const googleClient = await this.googleAuth.getClient();\n const token = await googleClient.getAccessToken();\n if (!token.token) {\n throw new Error('VertexOpenAIAdapter: service account did not mint an access token');\n }\n }\n\n async warmup(): Promise<void> {\n // No cheap idempotent warmup endpoint. No-op.\n }\n\n private ensureClient(): OpenAI {\n if (!this.client) {\n throw new Error(\n 'VertexOpenAIAdapter: init() must be called before stream()/listAvailableModels()',\n );\n }\n return this.client;\n }\n}\n\n/**\n * On a non-2xx response, read the Vertex error body and reconstruct the\n * Response so the OpenAI SDK can include the body in its thrown error.\n *\n * Why this is necessary: the OpenAI SDK v6 drops the body on some error\n * responses (the ones delivered gzipped, which Vertex does) — callers see\n * \"404 status code (no body)\" with no indication of root cause. Vertex's\n * real body for the model-in-wrong-region case carries useful text naming\n * the model and region. Reading the body here (before the SDK's parser gets\n * it) lets us pass it through as plain text; the SDK then surfaces it\n * verbatim in `err.message`.\n */\nasync function surfaceErrorBody(\n response: Response,\n input: Parameters<typeof fetch>[0],\n): Promise<Response> {\n let body = '';\n try {\n body = await response.text();\n } catch {\n // Body already consumed or unreadable — fall through with empty body.\n }\n\n const url = typeof input === 'string' ? input : input instanceof URL ? input.toString() : input.url;\n const hint =\n response.status === 404 && !body\n ? ' (no body returned — most commonly means the requested model is not hosted in this region; ' +\n 'check Google\\'s partner-model availability matrix)'\n : '';\n\n // Log so operators see the full vendor text in api-server / feature-server\n // logs regardless of how the thrown error is formatted downstream.\n if (typeof console !== 'undefined' && console.warn) {\n console.warn(\n `[vertex-openai] ${response.status} ${response.statusText} from ${url}: ` +\n `${body || '(empty body)'}${hint}`,\n );\n }\n\n // Vertex wraps errors in a single-element JSON array: `[{error: {...}}]`.\n // The OpenAI SDK expects a bare object `{error: {...}}`, so when parsing\n // the array it fails to find `.error` and throws \"no body\". Unwrap the\n // array so the SDK's error.message carries the vendor's own text.\n const normalizedBody = unwrapVertexErrorArray(body) + hint;\n\n // Drop encoding headers so the SDK doesn't try to decompress plain text.\n const headers = new Headers(response.headers);\n headers.delete('content-encoding');\n headers.delete('content-length');\n\n return new Response(normalizedBody, {\n status: response.status,\n statusText: response.statusText,\n headers,\n });\n}\n\nfunction unwrapVertexErrorArray(body: string): string {\n if (!body) return body;\n const trimmed = body.trim();\n if (!trimmed.startsWith('[')) return body;\n try {\n const parsed = JSON.parse(trimmed);\n if (Array.isArray(parsed) && parsed.length === 1 && parsed[0]?.error) {\n return JSON.stringify(parsed[0]);\n }\n } catch {\n // not JSON; leave as-is\n }\n return body;\n}\n","import type { AdapterManifest, ModelInfo } from '../../types.js';\n\n/**\n * Known third-party models available via Vertex AI's OpenAI-compatible\n * endpoint. This is NOT an exhaustive list — Vertex offers many publisher\n * models from Mistral, Meta, AI21, etc. — but it covers the common options\n * so the admin-UI dropdown is useful out of the box.\n */\nconst VERTEX_OPENAI_KNOWN_MODELS: ModelInfo[] = [\n {\n id: 'mistral-large',\n displayName: 'Mistral Large (on Vertex)',\n capabilities: {\n streaming: true,\n tools: true,\n vision: false,\n systemPrompt: true,\n maxContextTokens: 128_000,\n },\n },\n {\n id: 'mistral-small',\n displayName: 'Mistral Small (on Vertex)',\n capabilities: {\n streaming: true,\n tools: true,\n vision: false,\n systemPrompt: true,\n maxContextTokens: 32_000,\n },\n },\n {\n id: 'meta/llama-3.3-70b-instruct-maas',\n displayName: 'Llama 3.3 70B Instruct (on Vertex)',\n capabilities: {\n streaming: true,\n tools: true,\n vision: false,\n systemPrompt: true,\n maxContextTokens: 128_000,\n },\n },\n {\n id: 'meta/llama-3.1-405b-instruct-maas',\n displayName: 'Llama 3.1 405B Instruct (on Vertex)',\n capabilities: {\n streaming: true,\n tools: true,\n vision: false,\n systemPrompt: true,\n maxContextTokens: 128_000,\n },\n },\n];\n\nexport const vertexOpenAIManifest: AdapterManifest = {\n vendor: 'vertex-openai',\n displayName: 'Vertex AI — OpenAI-compatible',\n authKinds: [\n {\n kind: 'vertexServiceAccount',\n displayName: 'Service Account JSON',\n fields: [\n {\n name: 'credentials',\n label: 'Service Account Key (JSON)',\n type: 'json-file',\n required: true,\n help: 'Upload the service account key JSON from Google Cloud Console.',\n },\n {\n name: 'projectId',\n label: 'Project ID',\n type: 'text',\n required: true,\n help: 'GCP project that hosts the Vertex AI deployment.',\n },\n {\n name: 'location',\n label: 'Region',\n type: 'select',\n required: true,\n default: 'us-central1',\n // Same region set as vertex-gemini plus us-east5 (where Google\n // hosts Llama partner models). Partner-model availability varies\n // per region; Google's docs for each model are the source of truth.\n options: [\n { value: 'us-central1', label: 'us-central1' },\n { value: 'us-east1', label: 'us-east1' },\n { value: 'us-east4', label: 'us-east4' },\n { value: 'us-east5', label: 'us-east5' },\n { value: 'us-west1', label: 'us-west1' },\n { value: 'us-west4', label: 'us-west4' },\n { value: 'europe-west1', label: 'europe-west1' },\n { value: 'europe-west2', label: 'europe-west2' },\n { value: 'europe-west3', label: 'europe-west3' },\n { value: 'europe-west4', label: 'europe-west4' },\n { value: 'asia-east1', label: 'asia-east1' },\n { value: 'asia-northeast1', label: 'asia-northeast1' },\n { value: 'asia-southeast1', label: 'asia-southeast1' },\n ],\n },\n ],\n },\n ],\n knownModels: VERTEX_OPENAI_KNOWN_MODELS,\n // The OpenAI-compatible endpoint on Vertex does not expose a /models list.\n supportsModelListing: false,\n docsUrl: 'https://cloud.google.com/vertex-ai/generative-ai/docs/partner-models/use-openai',\n};\n","import type { AdapterFactory, VertexServiceAccountAuth } from '../../types.js';\nimport { VertexOpenAIAdapter } from './adapter.js';\nimport { vertexOpenAIManifest } from './manifest.js';\n\nexport const vertexOpenAIFactory: AdapterFactory<VertexServiceAccountAuth> = {\n vendor: vertexOpenAIManifest.vendor,\n manifest: vertexOpenAIManifest,\n create: () => new VertexOpenAIAdapter(),\n};\n","import {\n BedrockRuntimeClient,\n ConverseStreamCommand,\n} from '@aws-sdk/client-bedrock-runtime';\nimport {\n BedrockClient,\n ListFoundationModelsCommand,\n} from '@aws-sdk/client-bedrock';\nimport type {\n BedrockApiKeyAuth,\n BedrockIamAuth,\n ClientOptions,\n FinishReason,\n LlmAdapter,\n LlmEvent,\n Message,\n ModelInfo,\n PromptRequest,\n Tool,\n ToolCallEvent,\n} from '../../types.js';\nimport { assertValidRequest } from '../../validate.js';\nimport { extractMetadata } from '../_metadata.js';\nimport { bedrockManifest } from './manifest.js';\n\ntype BedrockAuthSpec = BedrockApiKeyAuth | BedrockIamAuth;\n\n/**\n * Adapter for AWS Bedrock via the Converse API.\n *\n * Bedrock's Converse wire shape diverges from the other adapters:\n * - Messages use `{role, content: [ContentBlock, ...]}` where content is\n * ALWAYS an array. Text blocks are `{text}`; tool-use blocks are\n * `{toolUse: {toolUseId, name, input}}`; tool results are\n * `{toolResult: {toolUseId, content: [{text}]}}` carried on role `user`.\n * - System prompt is `system: [{text}]` at the top level (array).\n * - Tools go in `toolConfig: {tools: [{toolSpec: {name, description,\n * inputSchema: {json}}}]}`.\n * - Conversations must start with a `user` message; adjacent same-role\n * messages are rejected by the service (the library does not validate —\n * the caller is responsible for ordering).\n * - Streaming events are different too:\n * messageStart → (contentBlockStart → contentBlockDelta* →\n * contentBlockStop)* → messageStop → metadata\n * - Auth has two modes: bedrockApiKey (bearer token) or bedrockIam\n * (accessKeyId + secretAccessKey [+ sessionToken]).\n */\nexport class BedrockAdapter implements LlmAdapter<BedrockAuthSpec> {\n readonly vendor = bedrockManifest.vendor;\n readonly acceptedAuth = ['bedrockApiKey', 'bedrockIam'] as const;\n\n private client: BedrockRuntimeClient | undefined;\n private controlClientConfig: Record<string, unknown> | undefined;\n\n init(auth: BedrockAuthSpec, client?: ClientOptions): void {\n if (!auth.region) {\n throw new Error('BedrockAdapter: region is required');\n }\n\n const config: Record<string, unknown> = {\n region: auth.region,\n ...(client?.endpoint ? { endpoint: client.endpoint } : {}),\n ...(client?.maxRetries !== undefined ? { maxAttempts: client.maxRetries + 1 } : {}),\n };\n\n if (auth.kind === 'bedrockApiKey') {\n if (!auth.apiKey) {\n throw new Error('BedrockAdapter: apiKey is required for bedrockApiKey auth');\n }\n // Bedrock API key is a bearer token — must be preferred over SigV4 so\n // it wins against ambient credentials (e.g., EC2 instance role).\n config.token = { token: auth.apiKey };\n config.authSchemePreference = ['httpBearerAuth'];\n } else if (auth.kind === 'bedrockIam') {\n if (!auth.accessKeyId || !auth.secretAccessKey) {\n throw new Error('BedrockAdapter: accessKeyId and secretAccessKey required for bedrockIam auth');\n }\n config.credentials = {\n accessKeyId: auth.accessKeyId,\n secretAccessKey: auth.secretAccessKey,\n ...(auth.sessionToken ? { sessionToken: auth.sessionToken } : {}),\n };\n } else {\n throw new Error(\n `BedrockAdapter: unsupported auth kind '${(auth as { kind: string }).kind}'`,\n );\n }\n\n this.client = new BedrockRuntimeClient(config);\n // Stash the same config so testCredential can spin up a control-plane\n // client on demand. `@aws-sdk/client-bedrock` accepts the same auth\n // shape as the runtime client.\n this.controlClientConfig = config;\n }\n\n async *stream(req: PromptRequest): AsyncIterable<LlmEvent> {\n assertValidRequest(req);\n const client = this.ensureClient();\n\n if (req.signal?.aborted) {\n yield { type: 'end', finishReason: 'aborted' };\n return;\n }\n\n const messages = buildWireMessages(req);\n const tools =\n req.tools && req.tools.length > 0 ? { tools: formatTools(req.tools) } : undefined;\n\n const inferenceConfig: Record<string, unknown> = {};\n if (req.maxTokens !== undefined) inferenceConfig.maxTokens = req.maxTokens;\n if (req.temperature !== undefined) inferenceConfig.temperature = req.temperature;\n\n const commandInput: Record<string, unknown> = {\n modelId: req.model,\n messages,\n };\n if (req.system) commandInput.system = [{ text: req.system }];\n if (tools) commandInput.toolConfig = tools;\n if (Object.keys(inferenceConfig).length > 0) {\n commandInput.inferenceConfig = inferenceConfig;\n }\n\n const caching = req.cacheKey ? cachePointSupport(req.model) : undefined;\n if (caching) {\n if (commandInput.system) {\n (commandInput.system as unknown[]).push({ cachePoint: { type: 'default' } });\n }\n if (tools && caching.tools) {\n (tools.tools as unknown[]).push({ cachePoint: { type: 'default' } });\n }\n // Third cache point after the final message's content so the ENTIRE\n // conversation prefix is cached, not just system + tools. In the\n // append-only conversation pattern each turn's request extends the\n // previous one, so the moving cache point hits the prior turn's cache\n // via longest-prefix matching. Without this, the growing history — the\n // bulk of mid-call input tokens — is re-billed at full price every turn.\n markLastMessageForCaching(messages);\n }\n\n const command = new ConverseStreamCommand(\n commandInput as unknown as ConstructorParameters<typeof ConverseStreamCommand>[0],\n );\n\n let response;\n try {\n response = await client.send(command, { abortSignal: req.signal });\n } catch (err) {\n if (isAbortError(err)) {\n yield { type: 'end', finishReason: 'aborted' };\n return;\n }\n throw err;\n }\n\n if (!response.stream) {\n yield { type: 'end', finishReason: 'stop' };\n return;\n }\n\n let currentToolUse: PendingToolUse | null = null;\n const completedToolCalls: Array<{ id: string; name: string; arguments: unknown }> = [];\n let stopReason: string | undefined;\n let inputTokens: number | undefined;\n let outputTokens: number | undefined;\n let totalTokens: number | undefined;\n let cacheReadTokens: number | undefined;\n let cacheWriteTokens: number | undefined;\n\n try {\n for await (const event of response.stream as AsyncIterable<BedrockStreamEvent>) {\n if (req.signal?.aborted) {\n yield { type: 'end', finishReason: 'aborted' };\n return;\n }\n\n if (event.contentBlockStart) {\n const start = event.contentBlockStart.start;\n if (start?.toolUse) {\n currentToolUse = {\n id: start.toolUse.toolUseId ?? '',\n name: start.toolUse.name ?? '',\n inputText: '',\n };\n if (currentToolUse.id && currentToolUse.name) {\n yield {\n type: 'toolCallStart',\n id: currentToolUse.id,\n name: currentToolUse.name,\n };\n }\n }\n } else if (event.contentBlockDelta) {\n const delta = event.contentBlockDelta.delta;\n if (delta?.text) {\n yield { type: 'token', text: delta.text };\n }\n if (delta?.toolUse && currentToolUse && typeof delta.toolUse.input === 'string') {\n currentToolUse.inputText += delta.toolUse.input;\n }\n } else if (event.contentBlockStop) {\n if (currentToolUse && currentToolUse.id && currentToolUse.name) {\n let parsed: unknown = {};\n try {\n parsed = currentToolUse.inputText ? JSON.parse(currentToolUse.inputText) : {};\n } catch {\n parsed = {};\n }\n completedToolCalls.push({\n id: currentToolUse.id,\n name: currentToolUse.name,\n arguments: parsed,\n });\n }\n currentToolUse = null;\n } else if (event.messageStop) {\n stopReason = event.messageStop.stopReason;\n } else if (event.metadata) {\n if (event.metadata.usage) {\n // Converse's inputTokens EXCLUDES cache activity — the read and\n // write classes arrive in their own fields, matching the\n // library's additive Usage convention with no adjustment needed.\n inputTokens = event.metadata.usage.inputTokens;\n outputTokens = event.metadata.usage.outputTokens;\n totalTokens = event.metadata.usage.totalTokens;\n cacheReadTokens = event.metadata.usage.cacheReadInputTokens;\n cacheWriteTokens = event.metadata.usage.cacheWriteInputTokens;\n }\n }\n }\n } catch (err) {\n if (isAbortError(err)) {\n yield { type: 'end', finishReason: 'aborted' };\n return;\n }\n throw err;\n }\n\n if (req.signal?.aborted) {\n yield { type: 'end', finishReason: 'aborted' };\n return;\n }\n\n for (const tc of completedToolCalls) {\n yield {\n type: 'toolCall',\n id: tc.id,\n name: tc.name,\n arguments: tc.arguments,\n };\n }\n\n const finishReason = mapStopReason(stopReason, completedToolCalls.length > 0);\n const usage =\n inputTokens !== undefined || outputTokens !== undefined || totalTokens !== undefined\n ? {\n ...(inputTokens !== undefined ? { inputTokens } : {}),\n ...(outputTokens !== undefined ? { outputTokens } : {}),\n ...(totalTokens !== undefined ? { totalTokens } : {}),\n ...(cacheReadTokens !== undefined ? { cacheReadTokens } : {}),\n ...(cacheWriteTokens !== undefined ? { cacheWriteTokens } : {}),\n }\n : undefined;\n\n const endEvent: Extract<LlmEvent, { type: 'end' }> = {\n type: 'end',\n finishReason,\n ...(usage ? { usage } : {}),\n ...(stopReason ? { rawReason: stopReason } : {}),\n };\n\n // Bedrock-specific response-header diagnostics. AWS surfaces them on\n // `response.$metadata.httpHeaders` rather than a standards-compliant\n // `Headers` instance — and the AWS SDK's TypeScript types don't include\n // the field, so cast through unknown. Useful signals:\n // `x-amzn-bedrock-invocation-latency` (vendor-side latency),\n // `x-amzn-bedrock-cache-{read,write}-input-token-count` (prompt-cache\n // effectiveness), `x-amzn-bedrock-trace-id` (support tickets).\n const httpHeaders = (response.$metadata as unknown as\n | { httpHeaders?: Record<string, string> }\n | undefined)?.httpHeaders;\n if (httpHeaders) {\n const metadata = extractMetadata(\n [\n { header: 'x-amzn-bedrock-invocation-latency', key: 'invocation_latency_ms', numeric: true },\n { header: 'x-amzn-bedrock-cache-read-input-token-count', key: 'cache_read_input_tokens', numeric: true },\n { header: 'x-amzn-bedrock-cache-write-input-token-count', key: 'cache_write_input_tokens', numeric: true },\n { header: 'x-amzn-bedrock-trace-id', key: 'trace_id' },\n ],\n httpHeaders,\n );\n if (Object.keys(metadata).length > 0) {\n endEvent.vendorMetadata = metadata;\n }\n }\n\n yield endEvent;\n }\n\n appendAssistantToolCall(\n history: Message[],\n toolCalls: ReadonlyArray<ToolCallEvent>,\n assistantText?: string,\n ): Message[] {\n // Converse allows a text block before toolUse blocks in the same turn;\n // an empty one is rejected, so it is only included when non-blank.\n const text = assistantText?.trim() ? assistantText : null;\n const wireMessage = {\n role: 'assistant',\n content: [\n ...(text ? [{ text }] : []),\n ...toolCalls.map((tc) => ({\n toolUse: {\n toolUseId: tc.id,\n name: tc.name,\n input: tc.arguments ?? {},\n },\n })),\n ],\n };\n return [\n ...history,\n {\n role: 'assistant',\n content: text ?? '',\n vendorRaw: wireMessage,\n },\n ];\n }\n\n appendToolResult(history: Message[], toolCallId: string, result: unknown): Message[] {\n const text = typeof result === 'string' ? result : JSON.stringify(result);\n const wireMessage = {\n role: 'user',\n content: [\n {\n toolResult: {\n toolUseId: toolCallId,\n content: [{ text }],\n },\n },\n ],\n };\n return [\n ...history,\n {\n role: 'tool',\n content: text,\n vendorRaw: wireMessage,\n },\n ];\n }\n\n async listAvailableModels(): Promise<ModelInfo[]> {\n // The bedrock-runtime client has no /models endpoint. We don't call the\n // control-plane client here because listFoundationModels returns every\n // model AWS offers, not models the account has access to — that distinction\n // is what `ModelInfo.deprecated` surfaces in the manifest.\n return [...bedrockManifest.knownModels];\n }\n\n async testCredential(): Promise<void> {\n // Use the control-plane client (`@aws-sdk/client-bedrock`) with the same\n // credential config as the runtime client. `ListFoundationModels` is the\n // cheapest authenticated GET and works regardless of which specific\n // models the account has granted — an auth check, not an access check.\n if (!this.controlClientConfig) {\n throw new Error('BedrockAdapter: init() must be called before testCredential()');\n }\n const control = new BedrockClient(this.controlClientConfig);\n try {\n await control.send(new ListFoundationModelsCommand({}));\n } finally {\n control.destroy();\n }\n }\n\n async warmup(): Promise<void> {\n // No cheap idempotent warmup. No-op.\n }\n\n private ensureClient(): BedrockRuntimeClient {\n if (!this.client) {\n throw new Error(\n 'BedrockAdapter: init() must be called before stream()/listAvailableModels()',\n );\n }\n return this.client;\n }\n}\n\n// ---------------------------------------------------------------------------\n// Internal types\n// ---------------------------------------------------------------------------\n\ninterface PendingToolUse {\n id: string;\n name: string;\n inputText: string;\n}\n\ninterface BedrockStreamEvent {\n messageStart?: { role?: string };\n contentBlockStart?: {\n start?: {\n toolUse?: { toolUseId?: string; name?: string };\n };\n contentBlockIndex?: number;\n };\n contentBlockDelta?: {\n delta?: {\n text?: string;\n toolUse?: { input?: string };\n };\n contentBlockIndex?: number;\n };\n contentBlockStop?: { contentBlockIndex?: number };\n messageStop?: { stopReason?: string };\n metadata?: {\n usage?: {\n inputTokens?: number;\n outputTokens?: number;\n totalTokens?: number;\n cacheReadInputTokens?: number;\n cacheWriteInputTokens?: number;\n };\n };\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction buildWireMessages(req: PromptRequest): unknown[] {\n const out: unknown[] = [];\n for (const msg of req.messages) {\n if (msg.vendorRaw && typeof msg.vendorRaw === 'object') {\n out.push(msg.vendorRaw);\n continue;\n }\n // Normalize plain-string messages to Converse's content-block array shape.\n const text = typeof msg.content === 'string' ? msg.content : JSON.stringify(msg.content);\n // Bedrock Converse does not accept role:'tool' — tool results must be\n // carried as content blocks on a role:'user' message. Without vendorRaw\n // we fall back to a text block.\n const role = msg.role === 'tool' ? 'user' : msg.role;\n out.push({\n role,\n content: [{ text }],\n });\n }\n return out;\n}\n\n/**\n * Which Converse fields accept an explicit `cachePoint` for this model, or\n * undefined if the model doesn't support explicit prompt caching at all.\n * Per the Bedrock prompt-caching docs, Anthropic Claude models accept cache\n * points in system, messages and tools; Amazon Nova only in system and\n * messages (a cachePoint in toolConfig.tools is rejected as an extraneous\n * key). Other models get none — they rely on implicit caching, if any.\n * Matched by substring so cross-region profile IDs (`us.`, `global.`, ...)\n * resolve to the underlying model.\n */\nfunction cachePointSupport(model: string): { tools: boolean } | undefined {\n if (model.includes('anthropic.claude')) return { tools: true };\n if (model.includes('amazon.nova')) return { tools: false };\n return undefined;\n}\n\n/**\n * Replace the last wire message with a copy whose content array gains a\n * trailing `{cachePoint: {type: 'default'}}` block. COPY, never mutate: the\n * `vendorRaw` entries in `messages` are the caller's history objects, and a\n * cache point persisted there would accumulate one per turn — past the\n * service's 4-cache-point limit the request is rejected outright.\n */\nfunction markLastMessageForCaching(messages: unknown[]): void {\n if (messages.length === 0) return;\n const last = messages[messages.length - 1] as { content?: unknown };\n if (Array.isArray(last.content) && last.content.length > 0) {\n messages[messages.length - 1] = {\n ...last,\n content: [...last.content, { cachePoint: { type: 'default' } }],\n };\n }\n}\n\nfunction formatTools(tools: Tool[]): Array<Record<string, unknown>> {\n return tools.map((t) => ({\n toolSpec: {\n name: t.name,\n // Bedrock rejects empty-string descriptions; fall back to a single space.\n description: t.description && t.description.length > 0 ? t.description : ' ',\n inputSchema: {\n json: t.parameters ?? { type: 'object', properties: {} },\n },\n },\n }));\n}\n\nfunction mapStopReason(r: string | undefined, hadToolCalls: boolean): FinishReason {\n if (hadToolCalls) return 'tool';\n switch (r) {\n case 'end_turn':\n case 'stop_sequence':\n return 'stop';\n case 'tool_use':\n return 'tool';\n case 'max_tokens':\n return 'length';\n case 'content_filtered':\n case 'guardrail_intervened':\n return 'filtered';\n default:\n return 'stop';\n }\n}\n\nfunction isAbortError(err: unknown): boolean {\n if (!err || typeof err !== 'object') return false;\n const e = err as { name?: string; code?: string; message?: string };\n return (\n e.name === 'AbortError' ||\n e.name === 'APIUserAbortError' ||\n e.code === 'ABORT_ERR' ||\n (typeof e.message === 'string' && /aborted/i.test(e.message))\n );\n}\n","import type { AdapterManifest, ModelInfo } from '../../types.js';\n\n/**\n * Known Bedrock models spanning the main publisher families available via the\n * Converse API. Model ids on Bedrock include a publisher prefix and version\n * suffix (e.g. `anthropic.claude-3-5-sonnet-20241022-v2:0`).\n *\n * Bedrock also supports cross-region inference profile ids (e.g.\n * `us.anthropic.claude-3-5-sonnet-20241022-v2:0`) — users should enter those\n * directly when needed; the adapter passes `model` through unchanged.\n *\n * Ordering matters: the first entry is used as the default probe model by\n * api-server's GET /LlmCredentials/:sid/test when `supportsModelListing` is\n * false. Amazon Nova Micro is first — AWS's own cheapest-per-token model,\n * broadly available across regions, and (unlike third-party Claude/Llama\n * models) not subject to provider-led \"legacy\" lifecycles that can revoke\n * access. Operators can override via `JAMBONZ_LLM_BEDROCK_PROBE_MODEL`.\n *\n * `deprecated: true` signals a model AWS may reject with\n * `ResourceNotFoundException: \"This Model is marked by provider as Legacy\"`\n * on accounts that haven't invoked it in the last 30 days. The id is kept in\n * the manifest so accounts that *have* been using it can still select it;\n * the webapp should badge/sort deprecated entries accordingly.\n *\n * Claude 4.x ids carry the `us.` cross-region inference profile prefix\n * because on-demand invocation of plain `anthropic.claude-*-4-*` ids is no\n * longer available in most regions — Bedrock requires the profile. Operators\n * in EU/APAC should edit to `eu.`/`apac.` or enter a region-specific id.\n *\n * FORMAT CONTRACT: `scripts/check-bedrock-models.ts --write` edits this file\n * in place by text substitution. Each entry MUST preserve the current shape:\n * an object literal whose first line is ` id: '<id>',` (two-space indent\n * plus trailing comma) and whose closing brace is on a line with exactly two\n * spaces of indent. If you restructure this array (e.g. move to JSON import),\n * update the script's edit strategy.\n */\nconst BEDROCK_KNOWN_MODELS: ModelInfo[] = [\n {\n id: 'amazon.nova-micro-v1:0',\n displayName: 'Amazon Nova Micro',\n capabilities: {\n streaming: true,\n tools: true,\n vision: false,\n systemPrompt: true,\n maxContextTokens: 128_000,\n },\n },\n {\n id: 'amazon.nova-lite-v1:0',\n displayName: 'Amazon Nova Lite',\n capabilities: {\n streaming: true,\n tools: true,\n vision: true,\n systemPrompt: true,\n maxContextTokens: 300_000,\n },\n },\n {\n id: 'amazon.nova-pro-v1:0',\n displayName: 'Amazon Nova Pro',\n capabilities: {\n streaming: true,\n tools: true,\n vision: true,\n systemPrompt: true,\n maxContextTokens: 300_000,\n },\n },\n {\n id: 'us.anthropic.claude-haiku-4-5-20251001-v1:0',\n displayName: 'Claude Haiku 4.5 (on Bedrock)',\n capabilities: {\n streaming: true,\n tools: true,\n vision: true,\n systemPrompt: true,\n maxContextTokens: 200_000,\n },\n },\n {\n id: 'us.anthropic.claude-sonnet-4-5-20250929-v1:0',\n displayName: 'Claude Sonnet 4.5 (on Bedrock)',\n capabilities: {\n streaming: true,\n tools: true,\n vision: true,\n systemPrompt: true,\n maxContextTokens: 200_000,\n },\n },\n {\n id: 'anthropic.claude-3-5-haiku-20241022-v1:0',\n displayName: 'Claude 3.5 Haiku (on Bedrock)',\n capabilities: {\n streaming: true,\n tools: true,\n vision: false,\n systemPrompt: true,\n maxContextTokens: 200_000,\n },\n deprecated: true,\n },\n {\n id: 'anthropic.claude-3-5-sonnet-20240620-v1:0',\n displayName: 'Claude 3.5 Sonnet (on Bedrock)',\n capabilities: {\n streaming: true,\n tools: true,\n vision: true,\n systemPrompt: true,\n maxContextTokens: 200_000,\n },\n deprecated: true,\n },\n {\n id: 'anthropic.claude-3-5-sonnet-20241022-v2:0',\n displayName: 'Claude 3.5 Sonnet v2 (on Bedrock)',\n capabilities: {\n streaming: true,\n tools: true,\n vision: true,\n systemPrompt: true,\n maxContextTokens: 200_000,\n },\n deprecated: true,\n },\n {\n id: 'anthropic.claude-3-7-sonnet-20250219-v1:0',\n displayName: 'Claude 3.7 Sonnet (on Bedrock)',\n capabilities: {\n streaming: true,\n tools: true,\n vision: true,\n systemPrompt: true,\n maxContextTokens: 200_000,\n },\n deprecated: true,\n },\n {\n id: 'meta.llama3-3-70b-instruct-v1:0',\n displayName: 'Llama 3.3 70B Instruct (on Bedrock)',\n capabilities: {\n streaming: true,\n tools: true,\n vision: false,\n systemPrompt: true,\n maxContextTokens: 128_000,\n },\n },\n {\n id: 'mistral.mistral-large-2407-v1:0',\n displayName: 'Mistral Large (on Bedrock)',\n capabilities: {\n streaming: true,\n tools: true,\n vision: false,\n systemPrompt: true,\n maxContextTokens: 128_000,\n },\n deprecated: true,\n },\n];\n\n// Common Bedrock regions. Not exhaustive — users can enter others via 'Other'\n// or (later) a free-text region field. The library does not validate against\n// this list; it's purely a UI aid.\nconst BEDROCK_REGIONS: Array<{ value: string; label: string }> = [\n { value: 'us-east-1', label: 'us-east-1 (N. Virginia)' },\n { value: 'us-east-2', label: 'us-east-2 (Ohio)' },\n { value: 'us-west-2', label: 'us-west-2 (Oregon)' },\n { value: 'eu-west-1', label: 'eu-west-1 (Ireland)' },\n { value: 'eu-west-3', label: 'eu-west-3 (Paris)' },\n { value: 'eu-central-1', label: 'eu-central-1 (Frankfurt)' },\n { value: 'ap-northeast-1', label: 'ap-northeast-1 (Tokyo)' },\n { value: 'ap-south-1', label: 'ap-south-1 (Mumbai)' },\n { value: 'ap-southeast-1', label: 'ap-southeast-1 (Singapore)' },\n { value: 'ap-southeast-2', label: 'ap-southeast-2 (Sydney)' },\n { value: 'ca-central-1', label: 'ca-central-1 (Canada)' },\n];\n\nexport const bedrockManifest: AdapterManifest = {\n vendor: 'bedrock',\n displayName: 'AWS Bedrock',\n authKinds: [\n {\n kind: 'bedrockApiKey',\n displayName: 'API Key',\n fields: [\n {\n name: 'apiKey',\n label: 'API Key',\n type: 'password',\n required: true,\n help: 'Bedrock API key (bearer token). Create one in the AWS console under Amazon Bedrock → API keys.',\n },\n {\n name: 'region',\n label: 'Region',\n type: 'select',\n required: true,\n default: 'us-east-1',\n options: BEDROCK_REGIONS,\n },\n ],\n },\n {\n kind: 'bedrockIam',\n displayName: 'IAM Credentials',\n fields: [\n {\n name: 'accessKeyId',\n label: 'Access Key ID',\n type: 'text',\n required: true,\n },\n {\n name: 'secretAccessKey',\n label: 'Secret Access Key',\n type: 'password',\n required: true,\n },\n {\n name: 'sessionToken',\n label: 'Session Token',\n type: 'password',\n required: false,\n help: 'Only required when using temporary credentials (e.g., STS).',\n },\n {\n name: 'region',\n label: 'Region',\n type: 'select',\n required: true,\n default: 'us-east-1',\n options: BEDROCK_REGIONS,\n },\n ],\n },\n ],\n knownModels: BEDROCK_KNOWN_MODELS,\n // The Bedrock runtime client does not expose a `/models` listing — model\n // enumeration lives in `@aws-sdk/client-bedrock` (control plane), which we\n // don't pull in. Return the curated set from the manifest.\n supportsModelListing: false,\n docsUrl: 'https://docs.aws.amazon.com/bedrock/latest/userguide/conversation-inference.html',\n};\n","import type {\n AdapterFactory,\n BedrockApiKeyAuth,\n BedrockIamAuth,\n} from '../../types.js';\nimport { BedrockAdapter } from './adapter.js';\nimport { bedrockManifest } from './manifest.js';\n\nexport const bedrockFactory: AdapterFactory<BedrockApiKeyAuth | BedrockIamAuth> = {\n vendor: bedrockManifest.vendor,\n manifest: bedrockManifest,\n create: () => new BedrockAdapter(),\n};\n","import { AzureOpenAI } from 'openai';\nimport type {\n AzureOpenAIApiKeyAuth,\n ClientOptions,\n LlmAdapter,\n LlmEvent,\n Message,\n ModelInfo,\n PromptRequest,\n ToolCallEvent,\n} from '../../types.js';\nimport {\n appendOpenAIAssistantToolCall,\n appendOpenAIToolResult,\n streamFromOpenAI,\n} from '../openai/_streaming.js';\nimport { makeMetadataExtractor } from '../_metadata.js';\nimport { azureOpenAIManifest } from './manifest.js';\n\n/**\n * Azure OpenAI response-header diagnostics.\n *\n * `x-ms-region` confirms which datacenter served (operators sometimes\n * provision multi-region deployments and want to verify routing).\n * `x-ms-deployment-name` confirms the deployment that served — useful\n * because Azure deployment names are arbitrary user strings and a\n * misconfigured credential could be pointed at a different deployment\n * than expected. `apim-request-id` is for support tickets;\n * `azureml-model-session` is the underlying model session id.\n */\nconst AZURE_OPENAI_METADATA_EXTRACTOR = makeMetadataExtractor([\n { header: 'x-ms-region', key: 'region' },\n { header: 'x-ms-deployment-name', key: 'deployment' },\n { header: 'apim-request-id', key: 'request_id' },\n { header: 'azureml-model-session', key: 'model_session' },\n { header: 'x-ratelimit-remaining-requests', key: 'requests_remaining', numeric: true },\n { header: 'x-ratelimit-remaining-tokens', key: 'tokens_remaining', numeric: true },\n]);\n\n/**\n * Adapter for Azure OpenAI Service.\n *\n * Azure speaks an OpenAI-compatible wire protocol for chat completions, so the\n * adapter reuses `streamFromOpenAI` / `appendOpenAI*` from the OpenAI adapter.\n * What differs is client construction:\n * - Auth is an `api-key` header, not `Authorization: Bearer`.\n * - The URL embeds the *deployment* name, not the model id:\n * `https://{endpoint}/openai/deployments/{deployment}/chat/completions?api-version={version}`\n * - The `model` field on the wire is ignored by Azure — the deployment in the\n * URL determines which model runs.\n *\n * The `AzureOpenAI` class exported from the `openai` SDK handles all three\n * quirks for us. It extends `OpenAI`, so passing it to `streamFromOpenAI()`\n * works without translation.\n */\nexport class AzureOpenAIAdapter implements LlmAdapter<AzureOpenAIApiKeyAuth> {\n readonly vendor = azureOpenAIManifest.vendor;\n readonly acceptedAuth = ['azureOpenAIApiKey'] as const;\n\n private client: AzureOpenAI | undefined;\n\n init(auth: AzureOpenAIApiKeyAuth, client?: ClientOptions): void {\n if (auth.kind !== 'azureOpenAIApiKey') {\n throw new Error(\n `AzureOpenAIAdapter: unsupported auth kind '${(auth as { kind: string }).kind}'`,\n );\n }\n if (!auth.apiKey) {\n throw new Error('AzureOpenAIAdapter: apiKey is required');\n }\n if (!auth.endpoint) {\n throw new Error('AzureOpenAIAdapter: endpoint is required');\n }\n if (!auth.deployment) {\n throw new Error('AzureOpenAIAdapter: deployment is required');\n }\n if (!auth.apiVersion) {\n throw new Error('AzureOpenAIAdapter: apiVersion is required');\n }\n\n this.client = new AzureOpenAI({\n apiKey: auth.apiKey,\n endpoint: auth.endpoint,\n apiVersion: auth.apiVersion,\n deployment: auth.deployment,\n ...(client?.timeout !== undefined ? { timeout: client.timeout } : {}),\n ...(client?.maxRetries !== undefined ? { maxRetries: client.maxRetries } : {}),\n });\n }\n\n stream(req: PromptRequest): AsyncIterable<LlmEvent> {\n // Azure deployment names are arbitrary user strings (e.g. `prod-gpt-4o`,\n // `my-assistant`, `gpt-5.4-mini`) — the model-id heuristic in\n // streamFromOpenAI can't see the underlying model, so pin the newer\n // parameter name. Microsoft's current Azure OpenAI backend accepts\n // `max_completion_tokens` for gpt-4o-family and requires it for\n // gpt-5-family / o-series reasoning models.\n return streamFromOpenAI(this.ensureClient(), req, {\n knownModels: azureOpenAIManifest.knownModels,\n tokensParam: 'max_completion_tokens',\n vendorMetadataExtractor: AZURE_OPENAI_METADATA_EXTRACTOR,\n });\n }\n\n appendAssistantToolCall(\n history: Message[],\n toolCalls: ReadonlyArray<ToolCallEvent>,\n assistantText?: string,\n ): Message[] {\n return appendOpenAIAssistantToolCall(history, toolCalls, assistantText);\n }\n\n appendToolResult(history: Message[], toolCallId: string, result: unknown): Message[] {\n return appendOpenAIToolResult(history, toolCallId, result);\n }\n\n async listAvailableModels(): Promise<ModelInfo[]> {\n // Azure's data-plane API doesn't expose a list-models endpoint; deployment\n // listing lives on the control plane (ARM) and requires AAD. Return the\n // manifest's curated set.\n return [...azureOpenAIManifest.knownModels];\n }\n\n async testCredential(): Promise<void> {\n // No cheap authenticated GET available on the data plane — `/models` on\n // Azure returns the account's deployments only if the key has the right\n // role, and is 404 on many configurations. A minimal chat-completions\n // call is the reliable probe: success proves the api-key authenticates\n // AND that the endpoint+deployment+api-version combination resolves.\n const client = this.ensureClient();\n await client.chat.completions.create({\n // Azure ignores `model` when a deployment is in the URL, but the SDK\n // still requires it as a parameter.\n model: 'probe',\n messages: [{ role: 'user', content: 'ping' }],\n // Use `max_completion_tokens` (not legacy `max_tokens`): gpt-5 family\n // and o-series reasoning models return 400 on the legacy parameter.\n // The newer name is a superset — also accepted by gpt-4o, gpt-4-turbo,\n // and gpt-3.5-turbo deployments — so it's the safe choice for a probe\n // that has to work regardless of the underlying deployment model.\n //\n // 256 (not 1): reasoning models consume reasoning tokens BEFORE\n // visible output, all counted against this cap. With 1 the model\n // can't produce any output and Azure returns\n // `400 Could not finish the message because max_tokens or model\n // output limit was reached`. 256 is comfortable headroom for\n // reasoning + a \"pong\"-sized reply on every model we ship in the\n // manifest, while still bounded so the probe can't run away on a\n // misconfigured deployment.\n max_completion_tokens: 256,\n stream: false,\n } as Parameters<typeof client.chat.completions.create>[0]);\n }\n\n async warmup(): Promise<void> {\n // No idempotent cheap endpoint on the data plane. No-op.\n }\n\n private ensureClient(): AzureOpenAI {\n if (!this.client) {\n throw new Error(\n 'AzureOpenAIAdapter: init() must be called before stream()/listAvailableModels()',\n );\n }\n return this.client;\n }\n}\n","import type { AdapterManifest, ModelInfo } from '../../types.js';\n\n/**\n * Known models that customers commonly deploy to Azure OpenAI Service.\n *\n * Unlike `api.openai.com`, Azure doesn't pick the model from the `model`\n * request field — the deployment name in the URL determines which model runs.\n * The manifest's model list is therefore keyed by the underlying *model* so\n * capability flags can be looked up by whichever model the user's deployment\n * points at. Common Azure deployment names mirror the model id (e.g. a\n * deployment called `gpt-4o` running `gpt-4o`), but customers may use arbitrary\n * names like `prod-chat` or `my-assistant` — that's fine; capability flags\n * default to something reasonable if the deployment name doesn't match.\n *\n * Azure's fine-tune deployments and private-preview model ids are out of scope.\n */\nconst AZURE_OPENAI_KNOWN_MODELS: ModelInfo[] = [\n {\n id: 'gpt-4o',\n displayName: 'GPT-4o (on Azure)',\n capabilities: {\n streaming: true,\n tools: true,\n vision: true,\n systemPrompt: true,\n maxContextTokens: 128_000,\n },\n },\n {\n id: 'gpt-4o-mini',\n displayName: 'GPT-4o mini (on Azure)',\n capabilities: {\n streaming: true,\n tools: true,\n vision: true,\n systemPrompt: true,\n maxContextTokens: 128_000,\n },\n },\n {\n id: 'gpt-4-turbo',\n displayName: 'GPT-4 Turbo (on Azure)',\n capabilities: {\n streaming: true,\n tools: true,\n vision: true,\n systemPrompt: true,\n maxContextTokens: 128_000,\n },\n },\n {\n // Azure spells it `gpt-35-turbo` (no dot). Keep their spelling for the id\n // so capability lookups against deployment names that echo the Azure id\n // hit.\n id: 'gpt-35-turbo',\n displayName: 'GPT-3.5 Turbo (on Azure)',\n capabilities: {\n streaming: true,\n tools: true,\n vision: false,\n systemPrompt: true,\n maxContextTokens: 16_385,\n },\n },\n {\n id: 'o1-preview',\n displayName: 'o1 preview — reasoning (on Azure)',\n capabilities: {\n streaming: false,\n tools: false,\n vision: false,\n systemPrompt: false,\n maxContextTokens: 128_000,\n },\n },\n {\n id: 'o1-mini',\n displayName: 'o1 mini — reasoning (on Azure)',\n capabilities: {\n streaming: false,\n tools: false,\n vision: false,\n systemPrompt: false,\n maxContextTokens: 128_000,\n },\n },\n];\n\nexport const azureOpenAIManifest: AdapterManifest = {\n vendor: 'azure-openai',\n displayName: 'Azure OpenAI',\n authKinds: [\n {\n kind: 'azureOpenAIApiKey',\n displayName: 'API Key',\n fields: [\n {\n name: 'apiKey',\n label: 'API Key',\n type: 'password',\n required: true,\n help:\n 'In Azure AI Foundry, open the deployment and copy the Key from ' +\n 'the Endpoint panel (eye icon to reveal). Same key is shown in ' +\n 'the Azure portal under your OpenAI resource → Keys and Endpoint.',\n },\n {\n name: 'endpoint',\n label: 'Endpoint',\n type: 'url',\n required: true,\n help:\n 'Resource hostname only — no path, no query string. Example: ' +\n 'https://my-resource.openai.azure.com. The Foundry deployment ' +\n 'page shows a Target URI like ' +\n 'https://my-resource.openai.azure.com/openai/responses?api-version=… ' +\n 'Strip everything from /openai/ onward and paste only the part ' +\n 'before it.',\n },\n {\n name: 'deployment',\n label: 'Deployment Name',\n type: 'text',\n required: true,\n help:\n 'The Name shown at the top of the deployment page in Azure AI ' +\n 'Foundry (also under Deployment info → Name). NOT the underlying ' +\n 'model id — deployments can be named anything you chose at create time.',\n },\n {\n name: 'apiVersion',\n label: 'API Version',\n type: 'text',\n required: true,\n default: '2025-03-01-preview',\n help:\n 'Data-plane api-version. Visible in Foundry as the ?api-version=… ' +\n 'query string in the Target URI, or the api_version=… line in the ' +\n 'Python sample. The default 2025-03-01-preview is the minimum that ' +\n 'works with gpt-5 / o-series deployments — Azure routes those ' +\n 'through the Responses API internally and rejects older versions.',\n },\n ],\n },\n ],\n knownModels: AZURE_OPENAI_KNOWN_MODELS,\n // Azure's list-deployments endpoint is on the control plane (ARM) and\n // requires AAD credentials the data-plane API key doesn't carry. Return\n // the curated set from the manifest.\n supportsModelListing: false,\n docsUrl: 'https://learn.microsoft.com/en-us/azure/ai-services/openai/reference',\n};\n","import type { AdapterFactory, AzureOpenAIApiKeyAuth } from '../../types.js';\nimport { AzureOpenAIAdapter } from './adapter.js';\nimport { azureOpenAIManifest } from './manifest.js';\n\nexport const azureOpenAIFactory: AdapterFactory<AzureOpenAIApiKeyAuth> = {\n vendor: azureOpenAIManifest.vendor,\n manifest: azureOpenAIManifest,\n create: () => new AzureOpenAIAdapter(),\n};\n","import type { AdapterManifest, ModelInfo } from '../../types.js';\n\n/**\n * Curated production-recommended Groq models. The live `/openai/v1/models`\n * endpoint returns the full catalog (which churns frequently); this list\n * seeds the admin-UI dropdown and capability flags.\n *\n * All entries here are tool-capable — Groq's catalog also includes\n * vision-only and safety-classifier models that we deliberately exclude\n * from the curated set because they don't make sense as the primary LLM\n * for a voice agent.\n */\nconst GROQ_KNOWN_MODELS: ModelInfo[] = [\n {\n id: 'llama-3.3-70b-versatile',\n displayName: 'Llama 3.3 70B Versatile (Groq)',\n capabilities: {\n streaming: true,\n tools: true,\n vision: false,\n systemPrompt: true,\n maxContextTokens: 128_000,\n },\n },\n {\n id: 'llama-3.1-8b-instant',\n displayName: 'Llama 3.1 8B Instant (Groq)',\n capabilities: {\n streaming: true,\n tools: true,\n vision: false,\n systemPrompt: true,\n maxContextTokens: 128_000,\n },\n },\n {\n id: 'gemma2-9b-it',\n displayName: 'Gemma 2 9B (Groq)',\n capabilities: {\n streaming: true,\n tools: true,\n vision: false,\n systemPrompt: true,\n maxContextTokens: 8_192,\n },\n },\n];\n\nexport const groqManifest: AdapterManifest = {\n vendor: 'groq',\n displayName: 'Groq',\n authKinds: [\n {\n kind: 'apiKey',\n displayName: 'API Key',\n fields: [\n {\n name: 'apiKey',\n label: 'API Key',\n type: 'password',\n required: true,\n help: 'Get an API key from https://console.groq.com/keys (sign in first if needed)',\n },\n {\n name: 'baseURL',\n label: 'Base URL',\n type: 'url',\n required: false,\n default: 'https://api.groq.com/openai/v1',\n help:\n 'Override only for proxies. Default points at Groq\\'s production endpoint.',\n },\n ],\n },\n ],\n knownModels: GROQ_KNOWN_MODELS,\n // Groq exposes /openai/v1/models with the same auth as chat completions.\n supportsModelListing: true,\n docsUrl: 'https://console.groq.com/docs/api-reference',\n};\n","import { OpenAIAdapter } from '../openai/adapter.js';\nimport { streamFromOpenAI } from '../openai/_streaming.js';\nimport type { ApiKeyAuth, ClientOptions, LlmEvent, PromptRequest } from '../../types.js';\nimport { makeMetadataExtractor } from '../_metadata.js';\nimport { groqManifest } from './manifest.js';\n\n/**\n * Groq response-header diagnostics. `x-groq-region` names the Groq\n * datacenter that served the request — useful for latency analysis.\n * `openai-processing-ms` is forwarded by Groq (they're OpenAI-wire-\n * compatible) and reports their server-side processing time, which\n * can be compared against wall-clock to spot infrastructure queueing\n * not counted in the model-server timer. Rate-limit headers help\n * operators spot when a workload is trending toward exhaustion\n * across turns within a call.\n */\nconst GROQ_METADATA_EXTRACTOR = makeMetadataExtractor([\n { header: 'x-request-id', key: 'request_id' },\n { header: 'x-groq-region', key: 'region' },\n { header: 'openai-processing-ms', key: 'processing_ms', numeric: true },\n { header: 'x-ratelimit-remaining-requests', key: 'requests_remaining', numeric: true },\n { header: 'x-ratelimit-remaining-tokens', key: 'tokens_remaining', numeric: true },\n]);\n\n/**\n * Adapter for Groq.\n *\n * Groq's chat-completions endpoint is OpenAI-wire-compatible — same request\n * shape, same streaming SSE, same tool-call format. The adapter is therefore\n * a thin subclass of `OpenAIAdapter` that defaults the `baseURL` to\n * `https://api.groq.com/openai/v1`. All wire translation, tool-call\n * accumulation, abort handling, and history round-tripping live in the\n * shared `streamFromOpenAI` helper.\n *\n * Why a separate class (vs. an inline alias like `DeepSeekAdapter` in\n * openai/factory.ts): keeps the manifest, README, and any future\n * Groq-specific quirks co-located in `src/adapters/groq/`. The DeepSeek\n * inline alias is a legacy shape; new vendors get their own directory.\n */\nexport class GroqAdapter extends OpenAIAdapter {\n override readonly vendor = groqManifest.vendor;\n\n override init(auth: ApiKeyAuth, client?: ClientOptions): void {\n super.init(\n {\n ...auth,\n baseURL: auth.baseURL ?? 'https://api.groq.com/openai/v1',\n },\n client,\n );\n }\n\n override stream(req: PromptRequest): AsyncIterable<LlmEvent> {\n // Override so we can pass Groq's own metadata extractor; otherwise\n // we'd inherit OpenAI's, which misses `x-groq-region`.\n return streamFromOpenAI(this.ensureClient(), req, {\n knownModels: groqManifest.knownModels,\n vendorMetadataExtractor: GROQ_METADATA_EXTRACTOR,\n // Groq caches automatically server-side and rejects/ignores undocumented\n // OpenAI params — do not forward prompt_cache_key.\n includeCacheKey: false,\n });\n }\n}\n","import type { AdapterFactory, ApiKeyAuth } from '../../types.js';\nimport { GroqAdapter } from './adapter.js';\nimport { groqManifest } from './manifest.js';\n\nexport const groqFactory: AdapterFactory<ApiKeyAuth> = {\n vendor: groqManifest.vendor,\n manifest: groqManifest,\n create: () => new GroqAdapter(),\n};\n","import type { AdapterManifest, ModelInfo } from '../../types.js';\n\n/**\n * Curated HuggingFace Inference Providers `knownModels`.\n *\n * Keyed by canonical HF model id (`<org>/<model>`). Customers can append a\n * `:provider-name` (`:fireworks-ai`, `:cerebras`, `:nebius`, etc.) or\n * `:fastest` suffix at request time to influence routing — those suffixed\n * variants are NOT enumerated here because the suffixed id is just a\n * routing hint, not a different model. The library's\n * `defaultCapabilitiesForUnknown` returns sensible defaults for any\n * suffixed id the heuristic doesn't recognize.\n *\n * The full live catalog is available via `listAvailableModels()` against\n * `/v1/models` — this list seeds the admin-UI dropdown with the most\n * common picks.\n */\nconst HF_KNOWN_MODELS: ModelInfo[] = [\n {\n id: 'meta-llama/Llama-3.3-70B-Instruct',\n displayName: 'Llama 3.3 70B Instruct (HF Providers)',\n capabilities: {\n streaming: true,\n tools: true,\n vision: false,\n systemPrompt: true,\n maxContextTokens: 128_000,\n },\n },\n {\n id: 'meta-llama/Llama-3.1-8B-Instruct',\n displayName: 'Llama 3.1 8B Instruct (HF Providers)',\n capabilities: {\n streaming: true,\n tools: true,\n vision: false,\n systemPrompt: true,\n maxContextTokens: 128_000,\n },\n },\n {\n id: 'Qwen/Qwen2.5-72B-Instruct',\n displayName: 'Qwen 2.5 72B Instruct (HF Providers)',\n capabilities: {\n streaming: true,\n tools: true,\n vision: false,\n systemPrompt: true,\n maxContextTokens: 128_000,\n },\n },\n {\n id: 'mistralai/Mistral-7B-Instruct-v0.3',\n displayName: 'Mistral 7B Instruct v0.3 (HF Providers)',\n capabilities: {\n streaming: true,\n tools: true,\n vision: false,\n systemPrompt: true,\n maxContextTokens: 32_000,\n },\n },\n {\n id: 'deepseek-ai/DeepSeek-V3',\n displayName: 'DeepSeek V3 (HF Providers)',\n capabilities: {\n streaming: true,\n tools: true,\n vision: false,\n systemPrompt: true,\n maxContextTokens: 64_000,\n },\n },\n];\n\nexport const huggingfaceManifest: AdapterManifest = {\n vendor: 'huggingface',\n displayName: 'HuggingFace Inference Providers',\n authKinds: [\n {\n kind: 'apiKey',\n displayName: 'API Key',\n fields: [\n {\n name: 'apiKey',\n label: 'HuggingFace Token',\n type: 'password',\n required: true,\n help:\n 'Get a token from https://huggingface.co/settings/tokens (Read scope is sufficient). ' +\n 'Inference Providers requires a credit balance — claim the free monthly tier or attach ' +\n 'a payment method at https://huggingface.co/billing.',\n },\n {\n name: 'baseURL',\n label: 'Base URL',\n type: 'url',\n required: false,\n default: 'https://router.huggingface.co/v1',\n help: 'Override only for proxies. Default is the HF Providers router endpoint.',\n },\n ],\n },\n ],\n knownModels: HF_KNOWN_MODELS,\n // The HF router exposes /v1/models with the same Bearer auth.\n supportsModelListing: true,\n docsUrl: 'https://huggingface.co/docs/inference-providers',\n};\n","import { OpenAIAdapter } from '../openai/adapter.js';\nimport { streamFromOpenAI } from '../openai/_streaming.js';\nimport type { ApiKeyAuth, ClientOptions, LlmEvent, PromptRequest } from '../../types.js';\nimport { makeMetadataExtractor } from '../_metadata.js';\nimport { huggingfaceManifest } from './manifest.js';\n\n/**\n * HuggingFace Inference Providers response-header diagnostics.\n *\n * `x-inference-provider` is the killer signal — names the actual\n * backend (Groq, Cerebras, Together, Fireworks, etc.) that served\n * the request. Useful for diagnosing latency anomalies and confirming\n * provider routing for `:fastest` / `:provider-name` model suffixes.\n */\nconst HUGGINGFACE_METADATA_EXTRACTOR = makeMetadataExtractor([\n { header: 'x-inference-provider', key: 'provider' },\n { header: 'x-request-id', key: 'request_id' },\n]);\n\n/**\n * Adapter for HuggingFace Inference Providers.\n *\n * HF Providers is a multi-provider broker: one HF token at\n * https://router.huggingface.co/v1 routes requests to whichever inference\n * shop hosts the requested model — Groq, Together, Fireworks, Cerebras,\n * Nebius, Hyperbolic, SambaNova, etc. The wire is OpenAI-compatible (chat\n * completions, streaming, tools, Bearer auth), so the adapter is a thin\n * subclass of `OpenAIAdapter` that defaults the `baseURL`.\n *\n * Model field syntax: customers pass canonical HF model ids\n * (`meta-llama/Llama-3.3-70B-Instruct`). They MAY append a routing\n * hint:\n * - `:fireworks-ai`, `:cerebras`, `:groq`, etc. — pin a specific provider\n * - `:fastest` — let HF route to the fastest available backend\n * Suffixes pass through to HF unchanged. The library's capability lookup\n * falls back to `defaultCapabilitiesForUnknown` for suffixed ids.\n */\nexport class HuggingfaceAdapter extends OpenAIAdapter {\n override readonly vendor = huggingfaceManifest.vendor;\n\n override init(auth: ApiKeyAuth, client?: ClientOptions): void {\n super.init(\n {\n ...auth,\n baseURL: auth.baseURL ?? 'https://router.huggingface.co/v1',\n },\n client,\n );\n }\n\n override stream(req: PromptRequest): AsyncIterable<LlmEvent> {\n return streamFromOpenAI(this.ensureClient(), req, {\n knownModels: huggingfaceManifest.knownModels,\n vendorMetadataExtractor: HUGGINGFACE_METADATA_EXTRACTOR,\n // The HF router fronts many third-party inference providers;\n // prompt_cache_key is unverified against them — do not forward.\n includeCacheKey: false,\n });\n }\n}\n","import type { AdapterFactory, ApiKeyAuth } from '../../types.js';\nimport { HuggingfaceAdapter } from './adapter.js';\nimport { huggingfaceManifest } from './manifest.js';\n\nexport const huggingfaceFactory: AdapterFactory<ApiKeyAuth> = {\n vendor: huggingfaceManifest.vendor,\n manifest: huggingfaceManifest,\n create: () => new HuggingfaceAdapter(),\n};\n","import type { AdapterManifest, ModelInfo } from '../../types.js';\n\n/**\n * Curated OpenRouter models for the admin-UI dropdown: fast, tool-capable\n * models that suit a voice agent. OpenRouter's live catalog (~450 models,\n * churning weekly) is returned by `listAvailableModels()` with capability\n * flags taken from its own `/models` metadata, so any model id works — this\n * list only seeds the dropdown.\n */\nconst OPENROUTER_KNOWN_MODELS: ModelInfo[] = [\n {\n id: 'anthropic/claude-haiku-5.5',\n displayName: 'Claude Haiku 5.5 (OpenRouter)',\n capabilities: {\n streaming: true,\n tools: true,\n vision: true,\n systemPrompt: true,\n maxContextTokens: 1_000_000,\n },\n },\n {\n id: 'anthropic/claude-sonnet-5.5',\n displayName: 'Claude Sonnet 5.5 (OpenRouter)',\n capabilities: {\n streaming: true,\n tools: true,\n vision: true,\n systemPrompt: true,\n maxContextTokens: 1_000_000,\n },\n },\n {\n id: 'openai/gpt-5.4-mini',\n displayName: 'GPT-5.4 Mini (OpenRouter)',\n capabilities: {\n streaming: true,\n tools: true,\n vision: true,\n systemPrompt: true,\n maxContextTokens: 400_000,\n },\n },\n {\n id: 'openai/gpt-4.1-mini',\n displayName: 'GPT-4.1 Mini (OpenRouter)',\n capabilities: {\n streaming: true,\n tools: true,\n vision: true,\n systemPrompt: true,\n maxContextTokens: 1_047_576,\n },\n },\n {\n id: 'google/gemini-3.5-flash',\n displayName: 'Gemini 3.5 Flash (OpenRouter)',\n capabilities: {\n streaming: true,\n tools: true,\n vision: true,\n systemPrompt: true,\n maxContextTokens: 1_048_576,\n },\n },\n {\n id: 'meta-llama/llama-3.3-70b-instruct',\n displayName: 'Llama 3.3 70B Instruct (OpenRouter)',\n capabilities: {\n streaming: true,\n tools: true,\n vision: false,\n systemPrompt: true,\n maxContextTokens: 131_072,\n },\n },\n];\n\nexport const openRouterManifest: AdapterManifest = {\n vendor: 'openrouter',\n displayName: 'OpenRouter',\n authKinds: [\n {\n kind: 'apiKey',\n displayName: 'API Key',\n fields: [\n {\n name: 'apiKey',\n label: 'API Key',\n type: 'password',\n required: true,\n help: 'Get an API key from https://openrouter.ai/settings/keys',\n },\n {\n name: 'baseURL',\n label: 'Base URL',\n type: 'url',\n required: false,\n default: 'https://openrouter.ai/api/v1',\n help: 'Override only for proxies. Default points at OpenRouter\\'s production endpoint.',\n },\n ],\n },\n ],\n knownModels: OPENROUTER_KNOWN_MODELS,\n // /models is public; the adapter enriches it with OpenRouter's own capability metadata.\n supportsModelListing: true,\n docsUrl: 'https://openrouter.ai/docs/api_reference/overview',\n};\n","import { OpenAIAdapter } from '../openai/adapter.js';\nimport { streamFromOpenAI } from '../openai/_streaming.js';\nimport type { ApiKeyAuth, ClientOptions, LlmEvent, ModelInfo, PromptRequest } from '../../types.js';\nimport { makeMetadataExtractor } from '../_metadata.js';\nimport { openRouterManifest } from './manifest.js';\n\n/**\n * OpenRouter response-header diagnostics. `x-generation-id` is the id\n * OpenRouter support asks for, and the key to `/api/v1/generation` for\n * per-request cost and upstream-provider stats.\n */\nconst OPENROUTER_METADATA_EXTRACTOR = makeMetadataExtractor([\n { header: 'x-generation-id', key: 'request_id' },\n]);\n\n/**\n * OpenRouter app attribution: credits this traffic to jambonz on\n * OpenRouter's public app rankings and model pages. No effect on routing,\n * pricing or rate limits. `HTTP-Referer` is the app's identity; the title\n * is its display name.\n */\nconst OPENROUTER_ATTRIBUTION_HEADERS = {\n 'HTTP-Referer': 'https://jambonz.org',\n 'X-OpenRouter-Title': 'jambonz',\n};\n\n/** The subset of OpenRouter's `/models` entry this adapter reads. */\ninterface OpenRouterModel {\n id: string;\n name?: string;\n context_length?: number;\n architecture?: { input_modalities?: string[]; output_modalities?: string[] };\n supported_parameters?: string[];\n}\n\n/**\n * Adapter for OpenRouter.\n *\n * OpenRouter's chat-completions endpoint is OpenAI-wire-compatible, so this\n * is a thin subclass of `OpenAIAdapter` that defaults the `baseURL` to\n * `https://openrouter.ai/api/v1`. Anthropic prompt caching on OpenRouter is\n * handled by the base class, which detects the openrouter.ai baseURL (so it\n * also works for OpenAI credentials pointed at OpenRouter).\n *\n * Every request carries jambonz's app-attribution headers.\n *\n * Two overrides exist because OpenRouter's `/models` is public:\n * - `testCredential()` probes the authenticated `/key` endpoint instead —\n * `/models` returns 200 for any key, bogus or not.\n * - `listAvailableModels()` uses the capability metadata `/models` carries\n * (tool support, vision, context length) rather than guessing by id.\n */\nexport class OpenRouterAdapter extends OpenAIAdapter {\n override readonly vendor = openRouterManifest.vendor;\n\n override init(auth: ApiKeyAuth, client?: ClientOptions): void {\n super.init(\n {\n ...auth,\n baseURL: auth.baseURL ?? 'https://openrouter.ai/api/v1',\n },\n client,\n );\n this.client = this.ensureClient().withOptions({\n defaultHeaders: OPENROUTER_ATTRIBUTION_HEADERS,\n });\n }\n\n override stream(req: PromptRequest): AsyncIterable<LlmEvent> {\n // Override so we can pass OpenRouter's own metadata extractor.\n return streamFromOpenAI(this.ensureClient(), req, {\n knownModels: this.knownModels(),\n vendorMetadataExtractor: OPENROUTER_METADATA_EXTRACTOR,\n // Verified accepted by OpenRouter (forwarded to OpenAI-family upstreams).\n includeCacheKey: true,\n openRouterAutoCache: this.isOpenRouter,\n });\n }\n\n override async listAvailableModels(): Promise<ModelInfo[]> {\n const result = await this.ensureClient().models.list();\n const out: ModelInfo[] = [];\n for (const m of result.data as unknown as OpenRouterModel[]) {\n // `:batch` variants are async-only; image-generation models emit no text.\n if (m.id.endsWith(':batch')) continue;\n const outputs = m.architecture?.output_modalities;\n if (outputs && !outputs.includes('text')) continue;\n const known = this.knownModels().find((k) => k.id === m.id);\n if (known) {\n out.push(known);\n continue;\n }\n out.push({\n id: m.id,\n ...(m.name ? { displayName: m.name } : {}),\n capabilities: {\n streaming: true,\n tools: m.supported_parameters?.includes('tools') ?? true,\n vision: m.architecture?.input_modalities?.includes('image') ?? false,\n systemPrompt: true,\n ...(m.context_length ? { maxContextTokens: m.context_length } : {}),\n },\n });\n }\n return out;\n }\n\n override async testCredential(): Promise<void> {\n // GET /key is authenticated (401 on a bad key) and free.\n await this.ensureClient().get('/key');\n }\n\n protected override knownModels(): ReadonlyArray<ModelInfo> {\n return openRouterManifest.knownModels;\n }\n}\n","import type { AdapterFactory, ApiKeyAuth } from '../../types.js';\nimport { OpenRouterAdapter } from './adapter.js';\nimport { openRouterManifest } from './manifest.js';\n\nexport const openRouterFactory: AdapterFactory<ApiKeyAuth> = {\n vendor: openRouterManifest.vendor,\n manifest: openRouterManifest,\n create: () => new OpenRouterAdapter(),\n};\n","import type { AdapterManifest } from '../types.js';\n\n/**\n * The harness vendor: a customer-run WebSocket endpoint that takes the agent's\n * \"think\" step (jambonz keeps telephony, STT, turn-taking and TTS).\n *\n * Credential-only: there is no adapter here, because feature-server speaks the\n * harness protocol itself. The manifest exists so api-server can validate and\n * store the credential and the portal can render its form. Stored as\n * `{url, api_key}`; feature-server reads exactly those two fields.\n */\nexport const harnessManifest: AdapterManifest = {\n vendor: 'harness',\n displayName: 'Harness',\n authKinds: [\n {\n // Only the form schema matters for a credential-only vendor; no\n // AuthSpec is ever built from it.\n kind: 'apiKey',\n displayName: 'API Key',\n fields: [\n {\n name: 'url',\n label: 'WebSocket URL',\n type: 'url',\n required: true,\n help:\n 'wss:// URL of your harness. ws:// is accepted only for a private or localhost address.',\n },\n {\n name: 'apiKey',\n label: 'API Key',\n type: 'password',\n required: true,\n help: 'Sent to the harness as \"Authorization: Bearer <key>\" when each call connects.',\n },\n ],\n },\n ],\n knownModels: [],\n supportsModelListing: false,\n credentialOnly: true,\n category: 'llm',\n};\n","import type { AdapterManifest } from '../types.js';\n\n/**\n * Dialogflow CES (Conversational Agents) for the dialogflow verb. Its own\n * credential, never a Google speech credential: a service account that works\n * for speech-to-text or text-to-speech need not have CES access, and the\n * other way round.\n *\n * Credential-only: feature-server runs the CES session itself. Stored as\n * `{service_key}` (the key JSON as a string); the dialogflow verb reads it\n * when its `credentials` is a reference `{vendor: 'dialogflow_ces', label}`.\n */\nexport const dialogflowCesManifest: AdapterManifest = {\n vendor: 'dialogflow_ces',\n displayName: 'Dialogflow CES',\n authKinds: [\n {\n kind: 'googleServiceAccount',\n displayName: 'Service Account JSON',\n fields: [\n {\n name: 'credentials',\n label: 'Service Account Key (JSON)',\n type: 'json-file',\n required: true,\n help: 'The key of a service account allowed to run your CES agents (Customer Engagement Suite).',\n },\n ],\n },\n ],\n knownModels: [],\n supportsModelListing: false,\n docsUrl: 'https://cloud.google.com/customer-engagement-ai/conversational-agents/ps',\n credentialOnly: true,\n category: 'hosted',\n};\n","import type { AdapterManifest } from '../types.js';\n\n/**\n * OpenAI Realtime for the llm verb (speech-to-speech). Its own credential,\n * separate from the `openai` language-model credential even though OpenAI\n * accepts the same kind of key for both: someone adds it on purpose, and may\n * use a different project or key for Realtime.\n *\n * Credential-only: feature-server runs the Realtime session itself. Stored as\n * `{api_key}`; the llm verb reads it when the verb names no `auth`.\n */\nexport const openaiS2sManifest: AdapterManifest = {\n vendor: 'openai_s2s',\n displayName: 'OpenAI Realtime',\n authKinds: [\n {\n kind: 'apiKey',\n displayName: 'API Key',\n fields: [\n {\n name: 'apiKey',\n label: 'API Key',\n type: 'password',\n required: true,\n help: 'An OpenAI API key with access to the Realtime API.',\n },\n ],\n },\n ],\n knownModels: [],\n supportsModelListing: false,\n docsUrl: 'https://platform.openai.com/docs/guides/realtime',\n credentialOnly: true,\n category: 's2s',\n};\n","/**\n * Central adapter registration.\n *\n * Each bundled vendor adapter is registered here at import time. When a new\n * vendor adapter is added under `src/adapters/<vendor>/`, add a single line\n * below to register its factory.\n *\n * The `_template` directory is intentionally NOT registered — it's a scaffold\n * for contributors to copy, not a live adapter.\n */\n\nimport { registerAdapter, registerCredentialVendor } from '../registry.js';\nimport {\n openAIFactory,\n deepseekFactory,\n basetenFactory,\n moonshotFactory,\n zaiFactory,\n xaiFactory,\n bedrockMantleFactory,\n} from './openai/index.js';\nimport { anthropicFactory } from './anthropic/index.js';\nimport { googleFactory } from './google/index.js';\nimport { vertexGeminiFactory } from './vertex-gemini/index.js';\nimport { vertexOpenAIFactory } from './vertex-openai/index.js';\nimport { bedrockFactory } from './bedrock/index.js';\nimport { azureOpenAIFactory } from './azure-openai/index.js';\nimport { groqFactory } from './groq/index.js';\nimport { huggingfaceFactory } from './huggingface/index.js';\nimport { openRouterFactory } from './openrouter/index.js';\nimport { harnessManifest } from '../vendors/harness.js';\nimport { dialogflowCesManifest } from '../vendors/dialogflow-ces.js';\nimport { openaiS2sManifest } from '../vendors/openai-s2s.js';\n\nregisterAdapter(openAIFactory);\nregisterAdapter(deepseekFactory);\nregisterAdapter(basetenFactory);\nregisterAdapter(moonshotFactory);\nregisterAdapter(zaiFactory);\nregisterAdapter(xaiFactory);\nregisterAdapter(bedrockMantleFactory);\nregisterAdapter(anthropicFactory);\nregisterAdapter(googleFactory);\nregisterAdapter(vertexGeminiFactory);\nregisterAdapter(vertexOpenAIFactory);\nregisterAdapter(bedrockFactory);\nregisterAdapter(azureOpenAIFactory);\nregisterAdapter(groqFactory);\nregisterAdapter(huggingfaceFactory);\nregisterAdapter(openRouterFactory);\n\n// Credential-only vendors: a manifest for credential storage and the portal\n// form, no adapter (see src/vendors/).\nregisterCredentialVendor(harnessManifest);\nregisterCredentialVendor(openaiS2sManifest);\nregisterCredentialVendor(dialogflowCesManifest);\n","import type {\n AuthSpec,\n AzureOpenAIApiKeyAuth,\n BedrockApiKeyAuth,\n BedrockIamAuth,\n GoogleApiKeyAuth,\n GoogleServiceAccountAuth,\n ServiceAccountJson,\n VertexServiceAccountAuth,\n} from './types.js';\n\n/**\n * The loose \"DB-shape\" input accepted by `normalizeAuth`.\n *\n * This is the shape produced by jambonz's api-server after decryption, and by\n * feature-server's `credential-mapper.js`. Snake-case is used to match the\n * legacy wire shape; the helper converts to the `AuthSpec` discriminated union.\n *\n * External callers that construct `AuthSpec` directly can skip this helper entirely.\n */\nexport interface RawCredential {\n api_key?: string | null;\n /** Either a JSON string or a parsed object. */\n service_key?: string | ServiceAccountJson | null;\n access_key_id?: string | null;\n secret_access_key?: string | null;\n session_token?: string | null;\n region?: string | null;\n api_url?: string | null;\n project_id?: string | null;\n location?: string | null;\n /** Azure OpenAI resource endpoint, e.g. `https://my-resource.openai.azure.com`. */\n endpoint?: string | null;\n /** Azure OpenAI deployment name (the user-created deployment, not the model id). */\n deployment?: string | null;\n /** Azure OpenAI data-plane api-version, e.g. `2025-03-01-preview`. */\n api_version?: string | null;\n}\n\n/**\n * Convert a vendor + raw credential into an `AuthSpec` discriminated union member.\n *\n * Supported vendors: openai, deepseek, baseten, moonshot, zai, xai, bedrock-mantle,\n * anthropic, google, vertex (alias for vertex-gemini + vertex-openai — both accept\n * the same auth shape), vertex-gemini, vertex-openai, bedrock, azure-openai, groq,\n * huggingface, openrouter.\n *\n * Throws with a clear message if the raw credential is missing required fields.\n */\nexport function normalizeAuth(vendor: string, raw: RawCredential): AuthSpec {\n switch (vendor) {\n case 'openai':\n case 'anthropic':\n case 'groq':\n case 'huggingface':\n case 'openrouter':\n case 'moonshot':\n case 'zai':\n case 'xai':\n case 'bedrock-mantle':\n // Standard ApiKeyAuth; these adapters default baseURL in init() if the\n // caller doesn't supply one (e.g. api.groq.com, router.huggingface.co, openrouter.ai/api/v1,\n // api.moonshot.ai/v1, api.z.ai/api/paas/v4, api.x.ai/v1). A user-supplied\n // api_url (e.g. Moonshot .cn, Z.ai's Coding-Plan endpoint, or a Bedrock\n // Mantle region / the /openai/v1 path xAI models require) is passed\n // through.\n return requireApiKey(vendor, raw);\n\n case 'deepseek':\n return {\n ...requireApiKey(vendor, raw),\n baseURL: raw.api_url ?? 'https://api.deepseek.com/v1',\n };\n\n case 'baseten':\n return {\n ...requireApiKey(vendor, raw),\n baseURL: raw.api_url ?? 'https://inference.baseten.co/v1',\n };\n\n case 'google':\n return normalizeGoogle(raw);\n\n case 'vertex':\n case 'vertex-gemini':\n case 'vertex-openai':\n return normalizeVertex(vendor, raw);\n\n case 'bedrock':\n return normalizeBedrock(raw);\n\n case 'azure-openai':\n return normalizeAzureOpenAI(raw);\n\n default:\n throw new Error(\n `normalizeAuth: unknown vendor '${vendor}'. ` +\n `If this is a custom adapter, construct the AuthSpec directly.`,\n );\n }\n}\n\nfunction requireApiKey(vendor: string, raw: RawCredential) {\n if (!raw.api_key) {\n throw new Error(`normalizeAuth: vendor '${vendor}' requires 'api_key'`);\n }\n const result: { kind: 'apiKey'; apiKey: string; baseURL?: string } = {\n kind: 'apiKey',\n apiKey: raw.api_key,\n };\n if (raw.api_url) {\n result.baseURL = raw.api_url;\n }\n return result;\n}\n\nfunction normalizeGoogle(raw: RawCredential): GoogleApiKeyAuth | GoogleServiceAccountAuth {\n if (raw.service_key) {\n return {\n kind: 'googleServiceAccount',\n credentials: parseServiceKey(raw.service_key),\n };\n }\n if (raw.api_key) {\n return { kind: 'googleApiKey', apiKey: raw.api_key };\n }\n throw new Error(`normalizeAuth: vendor 'google' requires either 'api_key' or 'service_key'`);\n}\n\nfunction normalizeVertex(vendor: string, raw: RawCredential): VertexServiceAccountAuth {\n if (!raw.service_key) {\n throw new Error(`normalizeAuth: vendor '${vendor}' requires 'service_key'`);\n }\n if (!raw.location) {\n throw new Error(`normalizeAuth: vendor '${vendor}' requires 'location'`);\n }\n const credentials = parseServiceKey(raw.service_key);\n const projectId = raw.project_id ?? credentials.project_id;\n if (!projectId) {\n throw new Error(\n `normalizeAuth: vendor '${vendor}' requires 'project_id' (not present ` +\n `in raw credential or service_key.project_id)`,\n );\n }\n return {\n kind: 'vertexServiceAccount',\n credentials,\n projectId,\n location: raw.location,\n };\n}\n\nfunction normalizeBedrock(raw: RawCredential): BedrockIamAuth | BedrockApiKeyAuth {\n if (!raw.region) {\n throw new Error(`normalizeAuth: vendor 'bedrock' requires 'region'`);\n }\n if (raw.access_key_id && raw.secret_access_key) {\n const result: BedrockIamAuth = {\n kind: 'bedrockIam',\n accessKeyId: raw.access_key_id,\n secretAccessKey: raw.secret_access_key,\n region: raw.region,\n };\n if (raw.session_token) {\n result.sessionToken = raw.session_token;\n }\n return result;\n }\n if (raw.api_key) {\n return {\n kind: 'bedrockApiKey',\n apiKey: raw.api_key,\n region: raw.region,\n };\n }\n throw new Error(\n `normalizeAuth: vendor 'bedrock' requires either (access_key_id + secret_access_key) or api_key`,\n );\n}\n\nfunction normalizeAzureOpenAI(raw: RawCredential): AzureOpenAIApiKeyAuth {\n if (!raw.api_key) {\n throw new Error(`normalizeAuth: vendor 'azure-openai' requires 'api_key'`);\n }\n if (!raw.endpoint) {\n throw new Error(`normalizeAuth: vendor 'azure-openai' requires 'endpoint'`);\n }\n if (!raw.deployment) {\n throw new Error(`normalizeAuth: vendor 'azure-openai' requires 'deployment'`);\n }\n if (!raw.api_version) {\n throw new Error(`normalizeAuth: vendor 'azure-openai' requires 'api_version'`);\n }\n return {\n kind: 'azureOpenAIApiKey',\n apiKey: raw.api_key,\n endpoint: raw.endpoint,\n deployment: raw.deployment,\n apiVersion: raw.api_version,\n };\n}\n\nfunction parseServiceKey(value: string | ServiceAccountJson): ServiceAccountJson {\n if (typeof value === 'string') {\n try {\n return JSON.parse(value) as ServiceAccountJson;\n } catch {\n throw new Error(`normalizeAuth: 'service_key' is not valid JSON`);\n }\n }\n return value;\n}\n","import type { RawCredential } from './normalize-auth.js';\nimport { getVendorManifest } from './registry.js';\nimport type { AuthKindSchema } from './types.js';\n\n/**\n * Given a vendor id and a raw snake_case credential blob, return the\n * `AuthKindSchema` from the vendor's manifest that matches the blob.\n *\n * Purpose: let credential-handling consumers (api-server's `encryptCredential`\n * in particular) validate and serialize the *right* set of fields for a\n * credential without carrying a per-vendor switch of their own. The\n * discriminator logic that distinguishes e.g. `bedrockApiKey` from\n * `bedrockIam` lives here, in the library, right next to `normalizeAuth`.\n *\n * Rules:\n * - Vendor with a single `authKind`: that kind is returned unconditionally.\n * - Bedrock: `access_key_id` + `secret_access_key` → `bedrockIam`; else `bedrockApiKey`.\n * - Google: `service_key` present → `googleServiceAccount`; `api_key` present → `googleApiKey`.\n *\n * Throws if the vendor is unknown or if no declared authKind matches the blob.\n */\nexport interface RawCredentialLoose extends RawCredential {\n [key: string]: unknown;\n}\n\nexport function pickAuthKind(vendor: string, raw: RawCredentialLoose): AuthKindSchema {\n const { authKinds } = getVendorManifest(vendor);\n\n if (authKinds.length === 1) {\n return authKinds[0]!;\n }\n\n switch (vendor) {\n case 'bedrock': {\n const iam = authKinds.find((k) => k.kind === 'bedrockIam');\n const apiKey = authKinds.find((k) => k.kind === 'bedrockApiKey');\n if (raw.access_key_id && raw.secret_access_key) {\n if (!iam) throw new Error(`pickAuthKind: bedrock manifest missing 'bedrockIam'`);\n return iam;\n }\n if (raw.api_key) {\n if (!apiKey) throw new Error(`pickAuthKind: bedrock manifest missing 'bedrockApiKey'`);\n return apiKey;\n }\n throw new Error(\n `pickAuthKind: bedrock credential missing both 'api_key' and ` +\n `('access_key_id' + 'secret_access_key')`,\n );\n }\n\n case 'google': {\n const svc = authKinds.find((k) => k.kind === 'googleServiceAccount');\n const apiKey = authKinds.find((k) => k.kind === 'googleApiKey');\n if (raw.service_key) {\n if (!svc) throw new Error(`pickAuthKind: google manifest missing 'googleServiceAccount'`);\n return svc;\n }\n if (raw.api_key) {\n if (!apiKey) throw new Error(`pickAuthKind: google manifest missing 'googleApiKey'`);\n return apiKey;\n }\n throw new Error(\n `pickAuthKind: google credential missing both 'api_key' and 'service_key'`,\n );\n }\n\n default:\n throw new Error(\n `pickAuthKind: vendor '${vendor}' declares ${authKinds.length} authKinds but ` +\n `has no discriminator rule. Add one in src/pick-auth-kind.ts.`,\n );\n }\n}\n"],"mappings":"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","names":["OpenAI","Anthropic","buildWireMessages","formatTools","isAbortError","formatTools","isAbortError","usage","mapFinishReason","import_genai","import_openai","OpenAI","buildWireMessages","formatTools","markLastMessageForCaching","isAbortError","mapStopReason","import_openai"]}