Skip to content

feat(llm): split LLM config into per-pipeline sections#575

Merged
cpcloud merged 2 commits intomainfrom
worktree-merry-doodling-stroustrup
Mar 4, 2026
Merged

feat(llm): split LLM config into per-pipeline sections#575
cpcloud merged 2 commits intomainfrom
worktree-merry-doodling-stroustrup

Conversation

@cpcloud
Copy link
Copy Markdown
Collaborator

@cpcloud cpcloud commented Mar 2, 2026

Summary

  • Add [llm.chat] and [llm.extraction] TOML sub-sections so each pipeline can use its own LLM provider, model, API key, base URL, timeout, and thinking level
  • Base [llm] section serves as the default; non-empty override fields take precedence per-pipeline
  • Deprecate [extraction].model and [extraction].thinking in favor of [llm.extraction].model / [llm.extraction].thinking with migration + warnings

Test plan

  • Set up a config with [llm] only (no sub-sections) and verify both chat and extraction work as before
  • Set up [llm.extraction] pointing to a different cloud provider (e.g. Anthropic) while [llm] uses Ollama; verify extraction uses the cloud model and chat uses Ollama
  • Set the deprecated [extraction].model key and verify the deprecation warning appears on startup
  • Run micasa config llm.extraction.model and micasa config llm.chat.provider to verify new config keys are accessible

closes #569

🤖 Generated with Claude Code

@codecov
Copy link
Copy Markdown

codecov Bot commented Mar 2, 2026

Codecov Report

❌ Patch coverage is 78.70370% with 46 lines in your changes missing coverage. Please review.
✅ Project coverage is 76.18%. Comparing base (5a1aec5) to head (b0b5555).
⚠️ Report is 2 commits behind head on main.

Files with missing lines Patch % Lines
internal/app/model.go 62.50% 16 Missing and 2 partials ⚠️
cmd/micasa/main.go 0.00% 17 Missing ⚠️
internal/config/config.go 95.89% 4 Missing and 2 partials ⚠️
internal/app/types.go 0.00% 5 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #575      +/-   ##
==========================================
+ Coverage   75.90%   76.18%   +0.28%     
==========================================
  Files          63       63              
  Lines       18469    18638     +169     
==========================================
+ Hits        14018    14200     +182     
+ Misses       3784     3763      -21     
- Partials      667      675       +8     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@cpcloud cpcloud force-pushed the worktree-merry-doodling-stroustrup branch from 9d36f78 to 8b7de15 Compare March 3, 2026 10:41
cpcloud and others added 2 commits March 3, 2026 18:52
Add [llm.chat] and [llm.extraction] TOML sub-sections so each pipeline
can have its own provider, base_url, model, api_key, timeout, and
thinking level. The base [llm] section serves as the default; non-empty
override fields take precedence.

- LLMChatOverride / LLMExtractionOverride types with per-pipeline env
  vars (MICASA_LLM_CHAT_*, MICASA_LLM_EXTRACTION_*)
- ResolvedLLM type and ChatConfig() / ExtractionConfig() merge methods
- Auto-detect provider when override has its own connection settings
- Per-pipeline validation for provider, thinking, timeout
- Deprecation migration: extraction.model -> llm.extraction.model,
  extraction.thinking -> llm.extraction.thinking (TOML + env vars)
- extractionLLMClient() creates an independent client when extraction
  has its own provider, falls back to chat client otherwise
- 25+ new config tests covering merging, overrides, deprecation

closes #569

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Exercise the per-pipeline LLM config through the extraction overlay UI
using sendExtractionKey keypresses rather than internal API calls:

- Model picker shows extraction-specific model (not chat model)
- Model picker falls back to chat model when no extraction model set
- Model selection with independent provider rebuilds client correctly
- Extraction client is independent when extraction has its own provider
- Extraction client falls back to chat config for missing fields
- extractionLLMClient() returns nil when no config exists

closes #569
@cpcloud cpcloud force-pushed the worktree-merry-doodling-stroustrup branch from 8b7de15 to b0b5555 Compare March 3, 2026 23:57
@cpcloud cpcloud merged commit 8d03b74 into main Mar 4, 2026
17 checks passed
@cpcloud cpcloud deleted the worktree-merry-doodling-stroustrup branch March 4, 2026 00:05
cpcloud added a commit that referenced this pull request Mar 19, 2026
## Summary

- Add `[llm.chat]` and `[llm.extraction]` TOML sub-sections so each
pipeline can use its own LLM provider, model, API key, base URL,
timeout, and thinking level
- Base `[llm]` section serves as the default; non-empty override fields
take precedence per-pipeline
- Deprecate `[extraction].model` and `[extraction].thinking` in favor of
`[llm.extraction].model` / `[llm.extraction].thinking` with migration +
warnings

## Test plan

- [ ] Set up a config with `[llm]` only (no sub-sections) and verify
both chat and extraction work as before
- [ ] Set up `[llm.extraction]` pointing to a different cloud provider
(e.g. Anthropic) while `[llm]` uses Ollama; verify extraction uses the
cloud model and chat uses Ollama
- [ ] Set the deprecated `[extraction].model` key and verify the
deprecation warning appears on startup
- [ ] Run `micasa config llm.extraction.model` and `micasa config
llm.chat.provider` to verify new config keys are accessible

closes #569

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat(extract): allow extraction pipeline to use cloud LLM providers

1 participant