From d3af6b26ee35e3317f032c017fdb986be3ee3e1b Mon Sep 17 00:00:00 2001 From: dkudos Date: Sat, 1 Nov 2025 17:10:19 -0500 Subject: [PATCH 1/4] adding the auto-detection of ollama local with a variable for baseURL --- packages/opencode/src/provider/provider.ts | 79 +++++++++++++++++++++ packages/web/src/content/docs/providers.mdx | 71 +++++++++++++++--- 2 files changed, 139 insertions(+), 11 deletions(-) diff --git a/packages/opencode/src/provider/provider.ts b/packages/opencode/src/provider/provider.ts index 730ba3963ad..11d2da39757 100644 --- a/packages/opencode/src/provider/provider.ts +++ b/packages/opencode/src/provider/provider.ts @@ -227,6 +227,71 @@ export namespace Provider { }, } }, + ollama: async (provider) => { + const envUrl = process.env["OLLAMA_BASE_URL"] + const url = await (async () => { + if (envUrl) { + log.info("ollama auto-detected via OLLAMA_BASE_URL", { baseURL: envUrl }) + return envUrl + } + + for (const base of ["http://localhost:11434", "http://127.0.0.1:11434"]) { + const ok = await fetch(`${base}/api/tags`, { + signal: AbortSignal.timeout(1000), + }) + .then((r) => r.ok) + .catch(() => false) + + if (ok) { + log.info("ollama auto-detected at", { baseURL: base }) + return base + } + } + return null + })() + + if (!url) { + log.debug("ollama not detected") + return { autoload: false } + } + + type TagsResponse = { models?: Array<{ name: string; model: string }> } + const data = await fetch(`${url}/api/tags`, { + signal: AbortSignal.timeout(3000), + }) + .then((r) => (r.ok ? r.json() : null)) + .catch(() => null) as TagsResponse | null + + const models = data?.models || [] + if (models.length === 0 && Object.keys(provider?.models || {}).length === 0) { + log.debug("ollama not detected or no models available") + return { autoload: false } + } + + for (const model of models) { + if (provider?.models?.[model.name]) continue + if (!provider) continue + if (!provider.models) provider.models = {} + + provider.models[model.name] = { + id: model.name, + name: model.name, + release_date: new Date().toISOString().split("T")[0], + attachment: false, + reasoning: false, + temperature: true, + tool_call: true, + cost: { input: 0, output: 0, cache_read: 0, cache_write: 0 }, + limit: { context: 0, output: 0 }, + modalities: { input: ["text"], output: ["text"] }, + options: {}, + } + } + + const baseURL = url.endsWith("/v1") ? url : `${url}/v1` + log.info("ollama auto-loaded with models", { count: models.length }) + return { autoload: true, options: { baseURL } } + }, } const state = Instance.state(async () => { @@ -343,6 +408,20 @@ export namespace Provider { database[providerID] = parsed } + // Ensure Ollama provider exists in database for auto-detection + if (!database["ollama"]) { + database["ollama"] = { + id: "ollama", + name: "Ollama (local)", + npm: "@ai-sdk/openai-compatible", + env: [], + models: {}, + } + } + if (database["ollama"] && !database["ollama"].npm) { + database["ollama"].npm = "@ai-sdk/openai-compatible" + } + const disabled = await Config.get().then((cfg) => new Set(cfg.disabled_providers ?? [])) // load env for (const [providerID, provider] of Object.entries(database)) { diff --git a/packages/web/src/content/docs/providers.mdx b/packages/web/src/content/docs/providers.mdx index 41e6308f716..516141df4db 100644 --- a/packages/web/src/content/docs/providers.mdx +++ b/packages/web/src/content/docs/providers.mdx @@ -559,9 +559,55 @@ To use Kimi K2 from Moonshot AI: ### Ollama -You can configure opencode to use local models through Ollama. +OpenCode provides zero-configuration support for Ollama, automatically detecting your server and discovering all installed models. -```json title="opencode.json" "ollama" {5, 6, 8, 10-14} +:::tip +**Zero Configuration Required!** Just have Ollama running and OpenCode will automatically discover your server and all installed models. +::: + +#### Quick Start (Zero Config!) + +1. **Start Ollama** (if not already running): + ```bash + ollama serve + ``` + +2. **Run OpenCode** - it will automatically detect Ollama and discover all models: + ```bash + opencode + ``` + +That's it! All your Ollama models will appear in the model list automatically. + +#### Auto-detection + +OpenCode will automatically detect the Ollama server URL in the following priority: + +1. **Environment variable**: If you set `OLLAMA_BASE_URL`, OpenCode will use that URL. + ```bash + OLLAMA_BASE_URL=http://192.168.2.26:11434 opencode + ``` + + Or add it to your bash profile: + ```bash title="~/.bash_profile" + export OLLAMA_BASE_URL=http://192.168.2.26:11434 + ``` + +2. **Default URLs**: If `OLLAMA_BASE_URL` is not set, OpenCode will automatically try: + - `http://localhost:11434` + - `http://127.0.0.1:11434` + +3. **Model Discovery**: OpenCode automatically fetches and loads all models from `/api/tags` + +:::note +All models installed in your Ollama instance will be automatically discovered and loaded. Custom configuration is optional and only needed if you want to override display names or other settings. +::: + +#### Optional Manual Configuration + +If you want to customize model names or specify a custom server URL, you can configure Ollama in `opencode.json`: + +```json title="opencode.json" { "$schema": "https://opencode.ai/config.json", "provider": { @@ -569,11 +615,14 @@ You can configure opencode to use local models through Ollama. "npm": "@ai-sdk/openai-compatible", "name": "Ollama (local)", "options": { - "baseURL": "http://localhost:11434/v1" + "baseURL": "http://custom-server:11434/v1" }, "models": { - "llama2": { - "name": "Llama 2" + "llama3.2:latest": { + "name": "Llama 3.2" + }, + "qwen2.5-coder:7b": { + "name": "Qwen 2.5 Coder 7B" } } } @@ -581,13 +630,13 @@ You can configure opencode to use local models through Ollama. } ``` -In this example: +**Configuration options:** -- `ollama` is the custom provider ID. This can be any string you want. -- `npm` specifies the package to use for this provider. Here, `@ai-sdk/openai-compatible` is used for any OpenAI-compatible API. -- `name` is the display name for the provider in the UI. -- `options.baseURL` is the endpoint for the local server. -- `models` is a map of model IDs to their configurations. The model name will be displayed in the model selection list. +- `ollama` - provider ID (defaults to "ollama") +- `npm` - AI SDK package (defaults to `@ai-sdk/openai-compatible`) +- `name` - display name in UI (defaults to "Ollama (local)") +- `options.baseURL` - server endpoint (auto-detected if not specified) +- `models` - custom model configurations (auto-discovered if not specified) :::tip If tool calls aren't working, try increasing `num_ctx` in Ollama. Start around 16k - 32k. From 0ffb048299469ec3bdc857c4ae9ffbf266e5b9dc Mon Sep 17 00:00:00 2001 From: GitHub Action Date: Mon, 10 Nov 2025 19:56:33 +0000 Subject: [PATCH 2/4] chore: format code --- packages/opencode/src/provider/provider.ts | 4 ++-- packages/web/src/content/docs/providers.mdx | 3 +++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/packages/opencode/src/provider/provider.ts b/packages/opencode/src/provider/provider.ts index bf53b7d1b31..75a351b059c 100644 --- a/packages/opencode/src/provider/provider.ts +++ b/packages/opencode/src/provider/provider.ts @@ -237,11 +237,11 @@ export namespace Provider { } type TagsResponse = { models?: Array<{ name: string; model: string }> } - const data = await fetch(`${url}/api/tags`, { + const data = (await fetch(`${url}/api/tags`, { signal: AbortSignal.timeout(3000), }) .then((r) => (r.ok ? r.json() : null)) - .catch(() => null) as TagsResponse | null + .catch(() => null)) as TagsResponse | null const models = data?.models || [] if (models.length === 0 && Object.keys(provider?.models || {}).length === 0) { diff --git a/packages/web/src/content/docs/providers.mdx b/packages/web/src/content/docs/providers.mdx index 04cdbaad84e..6d940dc0d35 100644 --- a/packages/web/src/content/docs/providers.mdx +++ b/packages/web/src/content/docs/providers.mdx @@ -607,6 +607,7 @@ OpenCode provides zero-configuration support for Ollama, automatically detecting #### Quick Start (Zero Config!) 1. **Start Ollama** (if not already running): + ```bash ollama serve ``` @@ -623,11 +624,13 @@ That's it! All your Ollama models will appear in the model list automatically. OpenCode will automatically detect the Ollama server URL in the following priority: 1. **Environment variable**: If you set `OLLAMA_BASE_URL`, OpenCode will use that URL. + ```bash OLLAMA_BASE_URL=http://192.168.2.26:11434 opencode ``` Or add it to your bash profile: + ```bash title="~/.bash_profile" export OLLAMA_BASE_URL=http://192.168.2.26:11434 ``` From 169e3963781653ae30481fd2b4bbb653396addd7 Mon Sep 17 00:00:00 2001 From: GitHub Action Date: Sun, 30 Nov 2025 02:51:00 +0000 Subject: [PATCH 3/4] chore: format code --- packages/plugin/package.json | 2 +- packages/sdk/js/package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/plugin/package.json b/packages/plugin/package.json index 409056da177..6a9f7c4b525 100644 --- a/packages/plugin/package.json +++ b/packages/plugin/package.json @@ -24,4 +24,4 @@ "typescript": "catalog:", "@typescript/native-preview": "catalog:" } -} \ No newline at end of file +} diff --git a/packages/sdk/js/package.json b/packages/sdk/js/package.json index bbc122db21a..18096746c5f 100644 --- a/packages/sdk/js/package.json +++ b/packages/sdk/js/package.json @@ -26,4 +26,4 @@ "publishConfig": { "directory": "dist" } -} \ No newline at end of file +} From 8968005779d1702ac9bceb644d9eb404e3208a55 Mon Sep 17 00:00:00 2001 From: Github Action Date: Sun, 30 Nov 2025 02:51:58 +0000 Subject: [PATCH 4/4] Update Nix flake.lock and hashes --- flake.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/flake.lock b/flake.lock index f35c345f0ba..211be53aa99 100644 --- a/flake.lock +++ b/flake.lock @@ -2,11 +2,11 @@ "nodes": { "nixpkgs": { "locked": { - "lastModified": 1764384123, - "narHash": "sha256-UoliURDJFaOolycBZYrjzd9Cc66zULEyHqGFH3QHEq0=", + "lastModified": 1764445028, + "narHash": "sha256-ik6H/0Zl+qHYDKTXFPpzuVHSZE+uvVz2XQuQd1IVXzo=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "59b6c96beacc898566c9be1052ae806f3835f87d", + "rev": "a09378c0108815dbf3961a0e085936f4146ec415", "type": "github" }, "original": {