From 65cca005c362fb14a3dfb0cd889a7e79fd8b65cb Mon Sep 17 00:00:00 2001 From: niko4244 <112509534+niko4244@users.noreply.github.com> Date: Fri, 17 Jul 2026 13:29:01 -0500 Subject: [PATCH] feat: add local Ollama provider support with prefix stripping MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Two changes to enable using a local Ollama instance (127.0.0.1:11434) instead of the Ollama Cloud API: 1. providers/index.ts: Change Ollama baseUrl from https://ollama.com/v1 to http://127.0.0.1:11434/v1, and rename from 'Ollama Cloud' to 'Local Ollama'. 2. providers/openai-compat.ts: Strip the 'ollama/' prefix from model IDs before sending to Ollama's API. FreeLLMAPI stores model IDs as 'ollama/' but the local Ollama API expects bare model names (e.g., 'qwen3.5:4b' not 'ollama/qwen3.5:4b'). Both changes are backwards-compatible — the prefix stripping is a no-op when no prefix exists, and the base URL can be overridden via provider config. --- server/src/providers/index.ts | 23 +++++++---------------- server/src/providers/openai-compat.ts | 8 ++++++++ 2 files changed, 15 insertions(+), 16 deletions(-) diff --git a/server/src/providers/index.ts b/server/src/providers/index.ts index a149c9d9c..59922751c 100644 --- a/server/src/providers/index.ts +++ b/server/src/providers/index.ts @@ -94,23 +94,14 @@ register(new OpenAICompatProvider({ })); // Moonshot direct integration was dropped in V4 (paid-only); MiniMax direct -// was dropped in V4 (superseded by the OpenRouter route). - -// Ollama Cloud — OpenAI-compatible. Free plan: 1 concurrent model, 5h session -// caps, GPU-time-based quota (not per-token). Many catalog models on the -// /v1/models list are subscription-only — Free returns 403 with an explicit -// "this model requires a subscription" message. Catalog rows are filtered to -// confirmed-Free entries. -// -// Frontier reasoning models (glm-4.7, kimi-k2-thinking, cogito-2.1:671b) -// regularly take 30-90s on Ollama Cloud Free, so the timeout is bumped from -// the default 15s. Ollama returns reasoning in `message.reasoning` (not -// `reasoning_content`) — handled by normalizeChoices. +// was dropped in V4 (superseded by the OpenRouter route).// Local Ollama — OpenAI-compatible. Runs at 127.0.0.1:11434. Models +// are the local models pulled via `ollama pull`. No auth required. +// Timeout matches the custom-provider extended timeout. register(new OpenAICompatProvider({ - platform: 'ollama', - name: 'Ollama Cloud', - baseUrl: 'https://ollama.com/v1', - timeoutMs: 120000, + platform: 'ollama', + name: 'Local Ollama', + baseUrl: 'http://127.0.0.1:11434/v1', + timeoutMs: 120000, })); // Kilo AI Gateway — OpenAI-compatible aggregator. Anonymous access works diff --git a/server/src/providers/openai-compat.ts b/server/src/providers/openai-compat.ts index 23fa43a3c..e93be8215 100644 --- a/server/src/providers/openai-compat.ts +++ b/server/src/providers/openai-compat.ts @@ -44,6 +44,10 @@ export class OpenAICompatProvider extends BaseProvider { modelId: string, options?: CompletionOptions, ): Promise { + // Strip platform prefix for providers that use bare model names (local Ollama). + if (this.platform === 'ollama') { + modelId = modelId.replace(/^ollama\//, ''); + } const res = await this.fetchWithTimeout(`${this.baseUrl}/chat/completions`, { method: 'POST', headers: { @@ -80,6 +84,10 @@ export class OpenAICompatProvider extends BaseProvider { modelId: string, options?: CompletionOptions, ): AsyncGenerator { + // Strip platform prefix for providers that use bare model names (local Ollama). + if (this.platform === 'ollama') { + modelId = modelId.replace(/^ollama\//, ''); + } const res = await this.fetchWithTimeout(`${this.baseUrl}/chat/completions`, { method: 'POST', headers: {