/** * @aparte/provider-openai-compat — ONE adapter for every OpenAI-compatible * chat-completions endpoint. * * The OpenAI `/chat/completions` wire format is the de-facto industry standard: * OpenAI, Mistral, OpenRouter, Z.ai, Groq, Together, LM Studio, Ollama (`/v1`) * and many more all speak it. This package is the single, zero-dependency * format adapter for that family — vendors differ only by DATA (base URL, auth * header, branding), which you pass as config (or pick from `presets`). * * It replaces the per-vendor `@aparte/provider-{openai,mistral,zai,openrouter, * lmstudio,ollama}` packages, whose adapter bodies were byte-identical copies * (drift even produced real bugs: LM Studio dropped `max_tokens`, Z.ai dropped * `seed` — both fixed here by construction, there is only one body now). * * Model lists are CONSUMER data: pass `models` statically, or rely on the * generic `GET {baseURL}/models` fetcher (part of the compat standard). For * vendors outside this family (Anthropic, Gemini, …) use the AI-SDK bridge * provider instead — this package deliberately covers ONE format. */ import type { AparteAIProvider, AparteAIModel, AparteAIProviderConfigSchema, AparteStreamEvent, AparteFormatAdapter } from '@aparte/core'; /** Config for one OpenAI-compatible endpoint. Everything but `id`/`baseURL` is branding/data. */ export interface OpenAICompatProviderOptions { /** Provider id used across aparté (key resolution, model picker, events). */ id: string; /** Endpoint base, e.g. `https://api.openai.com/v1` or `http://localhost:11434/v1`. */ baseURL: string; /** Display name (defaults to `id`). */ name?: string; /** Brand icon (SVG string / data URI / icon-provider key). */ icon?: string; /** Brand color. */ color?: string; /** Short tag line. */ description?: string; /** Where the user gets a key. */ helpUrl?: string; /** Whether the vendor offers free models. */ hasFreeModels?: boolean; /** * Local server (LM Studio, Ollama…): key optional, and the generic * `/models` fetch runs even without a key. */ isLocal?: boolean; /** Static model list (consumer data). Defaults to `[]` — use `fetchModels`. */ models?: AparteAIModel[]; /** * Extra headers sent on every request (chat + model fetch), e.g. * OpenRouter's attribution headers `HTTP-Referer` / `X-Title`. */ extraHeaders?: Record; /** Override the default apiKey+endpoint settings schema. */ configSchema?: AparteAIProviderConfigSchema; } /** * What {@link createOpenAICompatProvider} hands back: a provider whose whole * format-adapter surface is guaranteed present. * * `AparteAIProvider` declares that surface optional — correct in general, since a * provider may own its I/O through `chat()` instead — and `AparteFormatAdapter` keeps * `authHeaders` / `parseText` optional because some vendors authenticate by query * string or never answer non-streaming. THIS factory always supplies all of them, so * saying so here is the difference between a caller writing * `provider.buildRequest(req)` and a caller sprinkling `!` or writing a check that * cannot fail. Useful to annotate with when you drive the adapter yourself (your own * `fetch`, your own `AbortSignal`) from a server or an Electron main process. */ export type OpenAICompatProvider = AparteAIProvider & AparteFormatAdapter & Required>; /** * Build an `AparteAIProvider` (full format-adapter surface) for one * OpenAI-compatible endpoint. Register it like any provider: * * ```ts * import { createOpenAICompatProvider, presets } from '@aparte/provider-openai-compat'; * aparteGlobalConfig.registerAIProvider(createOpenAICompatProvider(presets.OPENROUTER)); * // or any compat endpoint, no preset needed: * aparteGlobalConfig.registerAIProvider(createOpenAICompatProvider({ id: 'groq', baseURL: 'https://api.groq.com/openai/v1' })); * ``` * * Returns {@link OpenAICompatProvider}: the full format-adapter surface, non-optional. */ export declare function createOpenAICompatProvider(opts: OpenAICompatProviderOptions): OpenAICompatProvider; /** * OpenAI-compatible SSE stream parser — this package's own copy of core's * `parseOpenAIStream` (the parser follows the format adapter; core keeps only * the aparté-native NDJSON parser). * * Handles: * - `delta.content` → text event * - `delta.reasoning_content` → thinking event (Qwen3, DeepSeek R1, …) * - `delta.tool_calls` → accumulate → tool_use on finish_reason='tool_calls' * - usage-only chunk + [DONE] → done{usage} */ export declare function parseOpenAICompatStream(stream: ReadableStream): ReadableStream; export * from './presets.js'; export type { AparteAIProvider, AparteAIModel } from '@aparte/core'; //# sourceMappingURL=index.d.ts.map