/** * First-class local-LLM presets for Ollama, vLLM, and LM Studio. * * All three speak the OpenAI Chat Completions wire format at `/v1/chat/completions` * with SSE streaming, so the bulk of the work is a tuned `WireFormatConfig`. The * differences worth modeling: * * - Ollama: no auth at all (no `Authorization` header). Supports * `keep_alive` and `num_ctx` request fields. Historically omits `usage` * on the final chunk, so we synthesize a `message_stop` via * `finalizeStream` even when the upstream didn't emit one. * - vLLM: auth is optional (off by default). The server may close the * stream without a `data: [DONE]` sentinel — also handled via * `finalizeStream`. * - LM Studio: optional Bearer auth. Same stream shape as OpenAI, but * `max_tokens` is the accepted field (we always use it via the * `openai-compatible` family quirk). * * `createLocalLlmPreset` is the single source of truth — the three named * exports below are thin wrappers that pick the right defaults. */ import type { StopReason } from '@wrongstack/core/types'; export interface LocalLlmPresetOptions { /** Provider id used for logging and the registry (e.g. 'ollama'). */ id: string; /** Default base URL when the user doesn't override. */ defaultBaseUrl: string; /** * When true, the request is sent with no `Authorization` header. Use for * servers that reject any Authorization value (Ollama without auth). * When false/undefined, a `Bearer ` header is sent (any non-empty * key is fine for servers that have auth disabled). */ noAuth?: boolean | undefined; /** * Provider-specific request body extras. Keys here are merged into the * outgoing JSON body verbatim. Use for things like Ollama's `keep_alive` * or vLLM's `repetition_penalty`. Values that collide with canonical * fields (`model`, `messages`, `tools`, `stream`, `max_tokens`, …) are * dropped — canonical wins. */ bodyExtras?: Record | undefined; /** Default context window — surfaced via `capabilities.maxContext`. */ maxContext?: number | undefined; /** * Whether the model advertises vision input. Local vision models are * rare but Ollama supports them via multimodal tags; default false. */ vision?: boolean | undefined; } interface StreamingArgBuffer { chunks: string[]; length: number; } interface LocalLlmStreamToolState { id?: string | undefined; name?: string | undefined; argBuf: StreamingArgBuffer; emittedStart: boolean; emittedChunkIndex: number; } interface LocalLlmStreamState { model: string; started: boolean; textOpen: boolean; thinkingOpen: boolean; toolByIndex: Map; usage: { input: number; output: number; }; stopReason: StopReason; /** Tracks whether the upstream emitted a terminal `data: [DONE]` or `finish_reason`. */ endedNaturally: boolean; finalEmitted: boolean; } export declare function createLocalLlmPreset(opts: LocalLlmPresetOptions): import("../wire-format.js").WireFormatConfig; /** * Ollama — https://ollama.com * * Runs on `http://localhost:11434` by default and exposes an OpenAI-compatible * chat-completions endpoint at `/v1/chat/completions`. Ollama rejects any * `Authorization` header (it returns 400), so we send none. Ollama also * accepts the `keep_alive` body field (e.g. `"5m"`, `"-1"` for indefinite) * to control how long the model stays loaded in memory. */ export declare const ollamaWireFormat: import("../wire-format.js").WireFormatConfig; /** * vLLM — https://docs.vllm.ai * * Default server URL is `http://localhost:8000/v1`. Auth is disabled by * default in vLLM; if enabled, it expects a `Bearer ` header. vLLM * passes the legacy `max_tokens` parameter through correctly and supports * OpenAI-style tool calls. */ export declare const vllmWireFormat: import("../wire-format.js").WireFormatConfig; /** * LM Studio — https://lmstudio.ai * * Default server URL is `http://localhost:1234/v1`. LM Studio's local * server mirrors the OpenAI Chat Completions API exactly, with optional * Bearer auth. */ export declare const lmstudioWireFormat: import("../wire-format.js").WireFormatConfig; export {}; //# sourceMappingURL=local-llm.d.ts.map