/** * OpenAI-Compatible Bearer Adapter * * A hosted OpenAI-compatible chat-completions adapter for any provider that * speaks the `${baseURL}/chat/completions` wire format with an optional * `Authorization: Bearer ` header. This is the shared substrate for * Fireworks, Kimi (via Fireworks), Together, and the self-hosted Fleet serving * tier — all of which are OpenAI-compatible Bearer endpoints. * * Why a separate adapter from `openrouter.ts` / `xai.ts`? * - Those adapters depend on the optional `openai` SDK and add provider * attribution headers. This adapter is SDK-free (raw fetch) and carries no * provider-specific headers — it's the lowest-common-denominator path so a * caller can point it at ANY OpenAI-compatible endpoint (cloud or * self-hosted vLLM/TGI/SGLang box) with just `{ baseURL, apiKey?, model }`. * - It implements native streaming (`streamCompletion`) by parsing the * OpenAI chat-completions SSE stream, INCLUDING fragmented * `tool_calls.function.arguments` accumulation across deltas — the exact * parsing logic that previously lived in * `services/llm-service/src/services/InferenceRouter.ts` (`parseOpenAIStream`). * Lifting it here lets the service dogfood the package instead of * hand-rolling the parser. * * The public stream shape is the package's `LLMStreamChunk` discriminated * union (text_delta / tool_use_start / tool_use_input_delta / tool_use_end / * message_stop). Service-side callers that need the legacy * `StreamEvent {type,payload}` wire contract shim `LLMStreamChunk` → that shape * at their boundary; the package itself never speaks `StreamEvent`. * * @version 1.0.0 */ import { BaseLLMAdapter } from '../base-adapter'; import type { Capabilities, LLMCompletionRequest, LLMCompletionResponse, LLMStreamChunk, LLMProviderConfig } from '../types'; /** * Config for a generic hosted OpenAI-compatible Bearer endpoint. * * `apiKey` is optional — a self-hosted box launched without `--api-key` * answers unauthenticated, so we omit the `Authorization` header when no key * is present (matches the Fleet serving tier's dev/unauthenticated mode). */ export type OpenAICompatibleAdapterConfig = Omit & { /** Bearer token for the endpoint. Omit / empty => no Authorization header. */ apiKey?: string; /** Default model id sent in the request body. */ model?: string; }; /** * Capability manifest — generic OpenAI-compatible endpoint. Capabilities are * per-endpoint/per-model not per-provider; this is the conservative manifest * for the wire protocol itself. Tool-calling is declared `true` because the * adapter parses fragmented `tool_calls` deltas — but whether the BACKING * model honors tools is model-dependent. * * Exported as a constant so the capability-aware router can read it without * instantiating the adapter — single source of truth per W.GOLD.006. */ export declare const OPENAI_COMPATIBLE_CAPABILITIES: Capabilities; export declare class OpenAICompatibleAdapter extends BaseLLMAdapter { readonly name: "openrouter"; readonly models: readonly string[]; readonly defaultHoloScriptModel: string; readonly capabilities: Capabilities; private readonly endpointBaseURL; private readonly bearerKey; constructor(config?: OpenAICompatibleAdapterConfig); protected getDefaultModel(): string; private buildHeaders; private mapFinishReason; private ollamaNumCtx; complete(request: LLMCompletionRequest, model?: string): Promise; private mapToolToOpenAI; streamCompletion(request: LLMCompletionRequest, model?: string): AsyncIterable; /** * Health check — probe the OpenAI-compatible endpoint's /v1/models-style * surface cheaply rather than a full chat round-trip. Tries the parent of * the chat-completions path (`${baseURL}/models`), falling back to a HEAD on * the base. Local boxes expose /v1/models; cloud endpoints usually do too. */ healthCheck(): Promise<{ ok: boolean; latencyMs: number; error?: string; }>; }