[TEST] feature/ollama-llm-provider — add Ollama as a second LLM backend behind askLLM#37
Merged
Conversation
There was a problem hiding this comment.
Pull request overview
This PR adds Ollama as an optional second LLM backend behind the existing askLLM API, controlled via a new config switch, while keeping the caller-facing askLLM signature and result shape unchanged.
Changes:
- Introduces
llm_provider(openrouterdefault |ollama) plusollama_urlandollama_modelconfig keys, with CLI setters for each. - Splits
@bb/llmprovider logic intoopenrouter.tsand newollama.ts, and refactorsclient.tsinto a provider dispatcher. - Updates cache keying to include provider, and short-circuits cost estimation to
$0when the active provider is Ollama.
Reviewed changes
Copilot reviewed 12 out of 12 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| packages/types/src/config.ts | Adds new Config enum keys for provider + Ollama settings. |
| packages/config/src/schema.ts | Adds Zod schema + types for llm_provider / ollama_* keys and CLI hints. |
| packages/config/src/index.ts | Re-exports LLM_PROVIDERS and LlmProvider type. |
| packages/config/context.md | Documents new config keys and provider selection. |
| packages/cli/src/keyMap.ts | Adds bytebell set llm-provider, ollama-url, ollama-model setters with validation. |
| packages/llm/src/client.ts | Dispatches askLLM to OpenRouter vs Ollama; includes provider in cache key input. |
| packages/llm/src/openrouter.ts | Extracts OpenRouter HTTP implementation and chain resolution. |
| packages/llm/src/ollama.ts | Implements Ollama /api/chat call and token-count mapping. |
| packages/llm/src/cache.ts | Includes provider in cache key derivation to avoid cross-provider collisions. |
| packages/llm/src/pricing.ts | Returns $0 estimate when active provider is Ollama. |
| packages/llm/context.md | Updates package contract/docs for multi-provider behavior and caching changes. |
| CLAUDE.md | Updates “Rule of LLM Provider” / outbound-call wording to include Ollama. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
33
to
+38
| log_level: z.enum(LOG_LEVELS).default("info"), | ||
| log_retention_days: z.number().int().positive().default(14), | ||
| llm_cache_enabled: z.boolean().default(true), | ||
| llm_provider: z.enum(LLM_PROVIDERS).default("openrouter"), | ||
| ollama_url: z.string().default("http://localhost:11434"), | ||
| ollama_model: z.string().default(""), |
Comment on lines
+168
to
+171
| - Per-usage-record provider persistence — Ollama `$0` cost is keyed | ||
| off the _current_ `Config.LlmProvider`. Historical OpenRouter rows | ||
| still price correctly because their model IDs resolve in | ||
| OpenRouter's pricing map regardless of the current provider. |
Comment on lines
110
to
111
| 1. Add a new `Config` enum entry in `src/schema.ts`. | ||
| 2. Add the field to `configSchema` with a `.default(...)`. |
Comment on lines
+29
to
32
| const provider = getConfigValue(Config.LlmProvider); | ||
| const timeoutMs = opts.timeoutMs ?? DEFAULT_TIMEOUT_MS; | ||
| const chain = provider === "ollama" ? resolveOllamaChain(opts) : resolveOpenRouterChain(opts); | ||
|
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What changed
Config.LlmProviderswitch (openrouterdefault |ollama) with three new config keys:llm_provider,ollama_url(defaulthttp://localhost:11434),ollama_model(free-form, no default — user picks any model they've pulled).bytebell set llm-provider <openrouter|ollama>bytebell set ollama-url <url>bytebell set ollama-model <model>@bb/llmby provider:packages/llm/src/openrouter.ts— extracted the existing OpenRouter HTTP path verbatim (chain resolution +/api/v1/chat/completionscall).packages/llm/src/ollama.ts— new, POSTs to${ollama_url}/api/chatwith{ model, messages, stream: false }, mapsprompt_eval_count/eval_counttoinputTokens/outputTokens.packages/llm/src/client.ts— now a thin dispatcher (143 → 64 lines): resolve chain → cache check → call right provider → record decision. PublicaskLLMsignature and return shape unchanged.packages/llm/src/cache.tsnow includesprovider, so the same prompt+model run through different backends caches separately.estimateCostUsdinpackages/llm/src/pricing.tsshort-circuits to$0when the current provider is Ollama. Historical OpenRouter rows still price correctly via OpenRouter's pricing map.packages/llm/context.md,packages/config/context.md, andCLAUDE.md(Rule of LLM Provider widens from "OpenRouter only" to "OpenRouter or local Ollama. No direct vendor SDKs.").Why
Users running on bounded local hardware or working offline want to bypass OpenRouter and hit a local Ollama daemon. The previous "OpenRouter only" rule was a v0 simplification; lifting it to "OpenRouter or local Ollama" keeps the no-vendor-SDK invariant intact (we still only speak HTTP — no
openai/anthropicpackages) while removing the cloud dependency for users who already have models pulled locally.Decisions captured in /Users/deadbytes/.claude/plans/currenbtly-our-askllm-only-toasty-starlight.md:
askLLMcallers (ingest-github/analyze.ts,ingest-github/bigFile.ts) untouched.ollama_modelis free-form on purpose — any locally-pulled model works (llama3.2:latest,qwen2.5-coder:7b, custom Modelfile names). We don't validate against an allowlist.$0keyed off current provider, not persisted per usage record — keeps the change small.How to test
OpenRouter path unchanged (regression check):
bytebell index <small-repo>.bytebell statsreports non-zero cost and logs showopenrouter.ai.Switch to Ollama: