fix(claude-code): pass configured model to the spawned CLI (#2881) - #7
fix(claude-code): pass configured model to the spawned CLI (#2881)#7chethanuk wants to merge 2 commits into
Conversation
…ectorize-io#2881) Red test: both call() and call_with_tools() must place self.model on the ClaudeAgentOptions handed to the Claude Agent SDK, since that field is what the SDK transport turns into the CLI --model flag. Currently the model is dropped, so the spawned claude CLI runs its own default while metrics report self.model.
…-io#2881) ClaudeCodeLLM.call() and call_with_tools() built ClaudeAgentOptions without model=, so the model resolved by config (global, per-scope, or the provider default) was stored on self.model and reported in metrics/traces but never reached the spawned `claude` CLI — it silently ran its own default model. ClaudeAgentOptions.model is the only field the SDK transport turns into the CLI's --model flag; add model=self.model at both option sites (unconditional, the transport already skips a falsy model). Move the claude-code provider default from the dated claude-sonnet-4-5-20250929 to the undated alias claude-sonnet-4-5 (one of the ids the Claude Agent SDK documents as a model example, and the "full name" form the CLI accepts). The dated id was previously inert; now that it becomes a real --model argument, an undated form avoids breaking provider-only setups such as the shipped docker-compose claude-code profile. Aligned across config.py, llmProviders.json, and the configuration docs; skills/ references regenerated. Add the model field to the _FakeOptions stand-ins in the two existing claude-code test modules so they keep constructing options once model= is passed.
|
Caution The consumer version of Gemini Code Assist on GitHub has been sunset. All code review activity has officially ceased. |
🤖 CodeAnt AI — Review Status
|
Thanks for using CodeAnt! 🎉We're free for open-source projects. if you're enjoying it, help us grow by sharing. Share on X · |
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (9)
📝 WalkthroughWalkthroughThe Claude Code provider now passes its configured model explicitly to the Claude Agent SDK for regular and tool-enabled calls. Default model references and documentation use ChangesClaude Code model selection
Estimated code review effort: 2 (Simple) | ~10 minutes Suggested labels: Suggested reviewers: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
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 |
Fixes the behaviour reported in vectorize-io#2881.
Problem
With
HINDSIGHT_API_*_LLM_PROVIDER=claude-code, the model resolved from config — global (HINDSIGHT_API_LLM_MODEL), per-scope (..._RETAIN_/_REFLECT_/_CONSOLIDATION_LLM_MODEL), or the provider default — was accepted, stored on the provider asself.model, and reported in metrics/traces, but the spawnedclaudeCLI ignored it and ran its own default model. Cost/latency attribution was wrong and per-scope model tuning silently did nothing.Root cause
ClaudeCodeLLM.call()andClaudeCodeLLM.call_with_tools()inhindsight-api-slim/hindsight_api/engine/providers/claude_code_llm.pybuiltClaudeAgentOptions(...)withoutmodel=.ClaudeAgentOptions.modelis the only field the Claude Agent SDK transport turns into the CLI's--modelflag, so the configured model never reached the subprocess.Fix
model=self.modelat bothClaudeAgentOptionssites (unconditional — the SDK transport already skips a falsy model).claude-codeprovider default from the datedclaude-sonnet-4-5-20250929to the undated aliasclaude-sonnet-4-5(an id the Claude Agent SDK documents as amodelexample and the "full name" form the CLI accepts). The dated id was previously inert; now that it becomes a real--modelargument, the undated form avoids breaking provider-only setups such as the shipped docker-composeclaude-codeprofile. Aligned acrossconfig.py,hindsight-docs/src/data/llmProviders.json, and the configuration docs;skills/references regenerated.modelfield to the_FakeOptionsstand-ins in the two existing claude-code test modules so they keep constructing options oncemodel=is passed.Test evidence
New parametrized regression test
tests/test_claude_code_llm_model.pymocks the SDK and asserts the configured model lands onClaudeAgentOptionsfor bothcallandcall_with_tools(rows:claude-haiku-4-5,sonnet,claude-sonnet-4-5). It fails 6/6 before the fix (AssertionError: assert None == '<model>') and passes after.ruff check .— All checks passedruff format --check(touched files) — already formattedty check(provider + config) — All checks passed./scripts/generate-docs-skill.sh— regeneratedskills/in sync (no diff)Note:
./scripts/hooks/lint.shESLint step could not run in the QA environment (@eslint/jsnot installed — control-planenode_modulesabsent). This branch changes zero JS/TS files, so ESLint has nothing of this change to check.Refs vectorize-io#2881