feat(daemon): Ollama backend wiring — settings + selector + UI (v0.1.1)#68
Merged
Conversation
…ootstrap wiring TDD red-pass for v0.1.1 Ollama daemon wiring (Track 1, item 1 per AGENT_OPERATIONS.md). Tests reference symbols that don't yet exist; CI will fail at compile, which IS the red. The green commit follows. selector.rs: - BackendKind::Ollama (new variant) + as_str() = "Ollama" - DEFAULT_OLLAMA_BASE_URL = "http://127.0.0.1:11434" - make_backend_for_kind(kind, inference_url, ollama_url, ollama_model) — settings-driven constructor; existing make_backend(base_url) preserved - existing detect / make_backend tests updated for the third variant (auto-detect still never picks Ollama — opt-in only) settings.rs: - Backend enum (Auto/LlamaCpp/Vllm/Ollama), serde lowercase - new fields: backend (default Auto), ollama_base_url, ollama_model - forward-compat: legacy settings.toml without `backend` parses to Auto - TOML round-trip for every Backend variant bootstrap.rs: - build_app_state honors Settings.backend: · Auto → existing platform detect (LlamaCpp/Vllm only) · Ollama → Ollama backend wired through (the headline assertion) · Explicit LlamaCpp/Vllm → that backend regardless of platform - Ollama with unset URL/model falls back to daemon defaults API server passes the configured model through implicitly: AppState.backend is Arc<dyn InferenceBackend>; the Ollama adapter already takes (base_url, model) in its constructor, so wiring it via bootstrap is the only change needed at the API layer. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Minimal implementation to turn the RED commit green. The Ollama adapter already exists (crates/ocm-inference/src/ollama.rs); this commit makes it constructible from settings. selector.rs: - BackendKind::Ollama variant; as_str() = "Ollama" (matches Ollama::name) - DEFAULT_OLLAMA_BASE_URL = "http://127.0.0.1:11434" (Ollama daemon default) - make_backend_for_kind(kind, inference_url, ollama_url, ollama_model): settings-driven constructor; keeps make_backend(base_url) for back-compat - detect_backend_kind never returns Ollama (opt-in only — auto-detect picks between backends OCM can supervise itself) settings.rs: - Backend enum (Auto/LlamaCpp/Vllm/Ollama), serde lowercase, default Auto - new fields: backend, ollama_base_url, ollama_model - all new fields #[serde(default)] for forward-compat with old settings.toml bootstrap.rs: - resolve_backend_kind(Settings.backend) → BackendKind (Auto delegates to detect_backend_kind; explicit selections override) - build_app_state resolves Ollama URL/model to constants when unset and calls make_backend_for_kind — Ollama backend now flows through to AppState.backend, satisfying the "API server passes the configured model through" requirement (AppState.backend: Arc<dyn InferenceBackend> is the abstraction boundary) Frontend type + UI changes follow in the next commit (no Rust impact). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…impls) CI's `clippy -D warnings` rejected the manual `impl Default for Backend`. Switch to the derive-with-#[default] form (same observable behavior: Backend::default() = Backend::Auto). Tests unchanged. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Mirrors the new Settings fields on the Rust side (crates/ocm-daemon/src/
settings.rs): backend, ollama_base_url, ollama_model.
settings.ts:
- Backend type ('auto' | 'llamacpp' | 'vllm' | 'ollama'), matches Rust serde
- Three new fields on the Settings interface
settings/+page.svelte:
- backend <select> with humanized labels (auto/llama.cpp/vLLM/Ollama)
- Ollama URL input (placeholder shows the daemon default 11434)
- Ollama model input (placeholder shows the existing DEFAULT_MODEL = llama3)
- Fields shown unconditionally; matches existing pattern (one form, all rows)
Verified locally: npm run check (258 files, 0 errors) + npm run build (3.80s).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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.
Summary
Track 1, item 1 from
docs/AGENT_OPERATIONS.md— Ollama daemon wiring. v0.1.1 ships on this.backend = "ollama"is now a first-class configured choice end-to-end: settings (TOML + Tauri commands) → selector → API server → settings UI.The Ollama adapter itself (
crates/ocm-inference/src/ollama.rs, NDJSON over:11434) already existed and was bench-verified; this PR makes it constructible from settings rather than dead code.What changed
Rust (
crates/)ocm-daemon::settings—Backendenum (auto/llamacpp/vllm/ollama, serde lowercase, defaultAuto) + 3 new fields:backend,ollama_base_url,ollama_model. All new fields#[serde(default)]so a v0.1.0settings.tomlwithout these keys still parses (legacy-load test included).ocm-inference::selector—BackendKind::Ollamavariant;DEFAULT_OLLAMA_BASE_URL = "http://127.0.0.1:11434"; newmake_backend_for_kind(kind, inference_url, ollama_url, ollama_model)settings-driven constructor. Existingmake_backend(base_url)preserved for back-compat. Auto-detect (detect_backend_kind) never returns Ollama — Ollama is opt-in (bridges to an external daemon; not something OCM auto-supervises).ocm-daemon::bootstrap—build_app_stateresolvesSettings.backend(Auto → existing detect; explicit → that kind), falls back toDEFAULT_OLLAMA_BASE_URL/ollama::DEFAULT_MODELwhen URL/model unset, and callsmake_backend_for_kind. The Ollama backend now flows through toAppState.backend, which is the abstraction the OpenAI-compat API server consumes — "API passes the configured model through" is satisfied at the bootstrap layer (noopenai.rschange needed).Tauri commands (
get_settings/save_settings) need no change: they round-trip the wholeSettingsstruct, so the new fields flow through automatically.Frontend (
frontend/)settings.ts—Backendtype + 3 new fields on theSettingsinterface (mirror of Rust).settings/+page.svelte—<select>for backend (humanized labels: auto/llama.cpp/vLLM/Ollama) + two<input>s for Ollama URL and Ollama model. Placeholders show the daemon's native defaults (127.0.0.1:11434,llama3).TDD
Followed the test-first discipline adapted for "CI is my compiler" (no local Rust toolchain on this machine).
42004cctest(ollama): REDcb61171feat(ollama): GREENclippy::derivable_impls— a lint, not a logic failure)6963c3ffix(settings)#[derive(Default)]+#[default]instead of manual impld8b126cfeat(frontend)The RED-then-GREEN audit trail is intentional — it proves each new test actually tested something that didn't exist, then turned green from the minimal impl.
New test coverage
selector.rs(+4 tests):as_str()lockstep withOllama::name(); default URL constant;make_backend_for_kindproduces the expected backendname()for all three kinds.settings.rs(+5 tests):Backend::default() == Auto; lowercase TOML serde; full Ollama round-trip; forward-compat legacy-load (settings.toml withoutbackendkey still parses toAuto); all-variants TOML round-trip.bootstrap.rs(+4 tests): the headline assertion —Settings.backend = Ollama⇒AppState.backend.name() == "Ollama"; Ollama with no URL/model still constructs (defaults fill in); explicit LlamaCpp / Vllm override platform detect.Test plan
cargo clippy --workspace --all-targets -- -D warnings— green on ubuntu/macOS/windows (run 27379270693)cargo test --workspace— green on ubuntu/macOS/windows (run 27379270693; counts per crate visible in log)npm run check— 258 files, 0 errors, 0 warnings (local, then CI run 27379313091)npm run build— clean static build in 3.80s (local)cargo tauri dev, pick Ollama in the new selector, point at a runningollama serve, send a chat. Not run here (no local Rust toolchain; per AGENT_OPERATIONS verification doctrine, CI is the compiler).Out of scope (deferred per AGENT_OPERATIONS Track 1)
supervisor.rsis still#[allow(dead_code)]. Will land in a separate PR.🤖 Generated with Claude Code