feat(generate): fall back to Ollama automatically when no API key configured#17
Conversation
…configured When no provider is explicitly set (via --provider or config) and no API key is found, probe Ollama at localhost:11434. If reachable, switch to local mode and print an info line to stderr. If not reachable, include an Ollama hint in the error message. forerunner doctor surfaces the effective mode: "local mode" when Ollama is the active or auto-detected provider; hint about Ollama when no config and no API key are present. Tests: +13 (187 total, 1 skipped). Covers is_available(), CLI fallback paths, explicit-provider/config-provider non-fallback, model preservation, and all three doctor local-mode scenarios. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
📝 WalkthroughWalkthroughThis PR implements automatic fallback to local Ollama generation when API keys are unavailable. It adds an Ollama availability probe, updates CLI and diagnostic checks to conditionally use local mode, and includes comprehensive test coverage for fallback scenarios. ChangesOllama local-mode fallback
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
✨ Simplify code
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/codeforerunner/cli.py`:
- Around line 114-116: The current logic treats cfg.provider as an explicit user
choice even when the config file contains defaults; fix explicit_provider by
checking whether the provider key was actually present in the loaded config
(e.g., use a presence check on the config object or its raw dict rather than
truthiness of cfg.provider) and only treat it as explicit if the key exists;
apply the same presence-based check to the other provider-selection spots noted
around lines 136-147 (where provider/model are derived), and add a regression
test that writes a config file without a provider key, ensures no API key is
set, sets ollama_available=True, runs the CLI selection path, and asserts the
selected provider is "ollama".
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 3d604a85-c799-4cb8-b729-170b1f4ff24c
📒 Files selected for processing (7)
src/codeforerunner/cli.pysrc/codeforerunner/doctor.pysrc/codeforerunner/providers/__init__.pysrc/codeforerunner/providers/ollama.pytests/test_cli.pytests/test_doctor.pytests/test_providers.py
| explicit_provider = args.provider or (cfg.provider if cfg else None) | ||
| provider_name = explicit_provider or "anthropic" | ||
| model = args.model or (cfg.model if cfg else None) |
There was a problem hiding this comment.
explicit_provider incorrectly treats default config as user-explicit provider.
Line 114 currently marks cfg.provider as explicit even when it comes from defaults, so fallback is skipped whenever forerunner.config.yaml exists without a provider: key. That breaks the intended “no explicit provider → auto-fallback to Ollama” flow.
💡 Proposed fix
- from codeforerunner.config import load_from_repo
+ from codeforerunner.config import CONFIG_FILENAME, load_from_repo
@@
- explicit_provider = args.provider or (cfg.provider if cfg else None)
- provider_name = explicit_provider or "anthropic"
+ cfg_path = repo_root / CONFIG_FILENAME
+ config_provider_is_explicit = False
+ if cfg_path.is_file():
+ config_provider_is_explicit = any(
+ line.split("#", 1)[0].strip().startswith("provider:")
+ for line in cfg_path.read_text(encoding="utf-8").splitlines()
+ )
+
+ explicit_provider = args.provider or (
+ cfg.provider if (cfg and config_provider_is_explicit) else None
+ )
+ provider_name = args.provider or (cfg.provider if cfg else "anthropic")Also add a regression test for: config file exists without provider:, no API key, ollama_available=True ⇒ fallback occurs.
Also applies to: 136-147
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/codeforerunner/cli.py` around lines 114 - 116, The current logic treats
cfg.provider as an explicit user choice even when the config file contains
defaults; fix explicit_provider by checking whether the provider key was
actually present in the loaded config (e.g., use a presence check on the config
object or its raw dict rather than truthiness of cfg.provider) and only treat it
as explicit if the key exists; apply the same presence-based check to the other
provider-selection spots noted around lines 136-147 (where provider/model are
derived), and add a regression test that writes a config file without a provider
key, ensures no API key is set, sets ollama_available=True, runs the CLI
selection path, and asserts the selected provider is "ollama".
Summary
OllamaProvider.is_available()— lightweightGET /api/tagsprobe (2s timeout) to detect a running Ollama instanceforerunner generateauto-switches to Ollama when no provider is explicitly configured and no API key is present; printsinfo: no API key; falling back to Ollama (local mode)to stderr. An explicit--providerflag orprovider:in config suppresses the fallback.hint: start Ollama for keyless local generationlineforerunner doctorsurfaces the effective mode:[ok] local modewhen Ollama is configured or auto-detected; Ollama hint when no config and no key are presentTest plan
pytest tests/— 187 passed, 1 skippedtest_ollama_is_available_*(4 tests) — probe logic, env override, explicit host, package exporttest_generate_falls_back_to_ollama_*(5 tests) — fallback fires, explicit provider blocks fallback, config provider blocks fallback, Ollama hint in error, model flag preserved through fallbacktest_provider_api_key_local_mode_*/test_provider_api_key_hint_*(3 tests) — doctor local-mode message paths🤖 Generated with Claude Code
Summary by CodeRabbit