import type { AIProvider, JsonObject, Message, ProviderEvent, ProviderRequest, Usage } from "../contracts.js"; import { type CredentialValueSource } from "../credentials.js"; export interface OpenAICompatibleProviderOptions { readonly id?: string; readonly baseUrl: string; readonly apiKey?: CredentialValueSource; readonly fetch?: typeof fetch; /** Override chat-completions URL (default `${baseUrl}/chat/completions`). */ readonly chatCompletionsUrl?: string | ((request: ProviderRequest) => string); /** Default `bearer`. Azure resource keys use `api-key`; host-signed fetches may use `none`. */ readonly authStyle?: "bearer" | "api-key" | "none"; /** Extra provider-specific body fields (thinking/reasoning/cache); merged over the base body. */ readonly buildBodyExtra?: (request: ProviderRequest) => JsonObject | undefined; /** Transform messages before serialization (e.g. cache-control markers). Defaults to `request.messages`. */ readonly mapMessages?: (request: ProviderRequest) => readonly Message[]; /** Custom message serializer (e.g. Z.AI `reasoning_content` replay). Defaults to assert + `serializeOpenAIChatMessage`. */ readonly serializeMessage?: (message: Message, request: ProviderRequest) => JsonObject; /** Custom usage mapping (e.g. OpenRouter cost fields). Defaults to `mapOpenAIChatUsage`. */ readonly mapUsage?: (usage: unknown) => Usage | undefined; /** Extra request headers (merged over caller headers; provider auth/content-type still win). */ readonly extraHeaders?: (request: ProviderRequest) => Record; /** Final body transform applied last (token limits, compat stripping). Wins over everything. */ readonly transformBody?: (body: JsonObject, request: ProviderRequest) => JsonObject; /** Require `[DONE]` and a `finish_reason` before emitting `done`; truncated streams yield an error. `done` then carries the final usage. Default `true` (fail-closed); set `false` explicitly to accept streams that end without completion evidence. */ readonly strictCompletion?: boolean; /** Emit the final stream usage on the `done` event (without strict completion checks). */ readonly doneUsage?: boolean; /** Prefix for HTTP error messages (default `OpenAI-compatible request failed`). */ readonly requestFailedPrefix?: string; /** Custom HTTP error mapping (e.g. NeuralWatt retry classification). Receives the response and redacted body text. */ readonly mapHttpError?: (response: Response, bodyText: string, secrets: readonly (string | undefined)[]) => Error; /** Handle SSE comment lines in the stream (e.g. NeuralWatt energy/cost telemetry). */ readonly onComment?: (text: string) => ProviderEvent | undefined; } export interface OpenAIChatEventsOptions { readonly signal?: AbortSignal; /** Require `[DONE]` and a `finish_reason`; `done` then carries the final usage. Default `true` (fail-closed); set `false` explicitly to accept streams that end without completion evidence. */ readonly strictCompletion?: boolean; /** Emit the final stream usage on the `done` event. */ readonly doneUsage?: boolean; readonly mapUsage?: (usage: unknown) => Usage | undefined; /** Handle an SSE comment line (text after `:`), e.g. NeuralWatt `: energy` / `: cost` telemetry. Returned events are yielded in stream order before the data of the same SSE event. */ readonly onComment?: (text: string) => ProviderEvent | undefined; } /** * Shared OpenAI Chat Completions SSE stream loop: maps `data:` frames to Prism * `ProviderEvent` values (text/thinking deltas, tool-call fragments, usage, done/error). */ export declare function openAIChatEvents(body: ReadableStream, options?: OpenAIChatEventsOptions): AsyncIterable; export declare function createOpenAICompatibleProvider(options: OpenAICompatibleProviderOptions): AIProvider; /** Subset of factory options that shape the request body. */ export type OpenAIChatBodyOptions = Pick; /** Base Chat Completions request body builder, exported for provider packages keeping public body helpers. */ export declare function buildOpenAIChatBody(request: ProviderRequest, options?: OpenAIChatBodyOptions): JsonObject;