Skip to content

Default agent models to the provider's default, not hardcoded Claude Sonnet - #11

Merged
wparad merged 3 commits into
mainfrom
claude/gitzi-mobile-api-plan-hpgltd
Jul 20, 2026
Merged

Default agent models to the provider's default, not hardcoded Claude Sonnet#11
wparad merged 3 commits into
mainfrom
claude/gitzi-mobile-api-plan-hpgltd

Conversation

@wparad

@wparad wparad commented Jul 18, 2026

Copy link
Copy Markdown
Contributor

Problem

Every agent role resolved to a hardcoded Claude Sonnet model regardless of the configured provider. This came from two hardcodes:

  • AgentRole::default_agent_def (src/dispatcher/mod.rs) returned "claude-sonnet-4-20250514". This function was dead code — it had no callers anywhere in the repo.
  • config::default_model (src/config.rs) returned "claude-sonnet-4-6" as the serde/Default value for AgentDef::model, pinning any agent entry that omitted model to Sonnet and short-circuiting provider-based resolution. (Note: main has since made default_model empty on its own; the remaining gaps are the two items below.)

Change

The correct rule: each role defaults to the provider's own default model; if the provider has no default, fall back to qwen3-8b.

  • Removed the dead AgentRole::default_agent_def.
  • resolve_agent resolves the model through a single helper resolve_model: explicit model → the provider's default_model → terminal fallback qwen3-8b.
  • A provider whose default_model is an empty string still deliberately means "route to whatever model the provider has loaded" (e.g. LM Studio) and is preserved as empty; only a provider with no default (None), or no provider at all, falls through to qwen3-8b. qwen3-8b already exists as a provider default elsewhere in the codebase (setup.rs, bootstrap.rs).
  • Updated the resolve_agent property test to assert the new terminal fallback.

Also fixes CI (previously red on main)

main's CI has been red on tests/e2e_pipeline.rs::chat_with_mock_agent_returns_response ("response should not be empty") on its own tip and every recent run. Root cause: the main chat backend switched to streaming (turn_streaming sends stream: true and parses an SSE response), but the e2e mock server only ever returned a single non-streaming JSON body, so the streamed chat turn resolved to empty text. The mock now inspects the request's stream flag and responds in the matching shape — an SSE stream for streaming requests, the original JSON object for the non-streaming sub-agent calls.

Tests

Local run matches CI exactly and is fully green:

  • cargo fmt --check clean
  • cargo clippy --all-features -- -D warnings clean
  • cargo test --all-features → all suites pass (90 unit + every integration suite, including the previously-failing e2e_pipeline).

Context

Surfaced while designing the gitzi-api cloud backend, where model selection is per-tenant/per-provider and a universal Sonnet default is wrong.

🤖 Generated with Claude Code

https://claude.ai/code/session_018UFD2FvZXDBaMmaXJSSQQ5

@wparad
wparad force-pushed the claude/gitzi-mobile-api-plan-hpgltd branch 3 times, most recently from 8ffceb0 to 11b7e06 Compare July 18, 2026 07:03
claude added 2 commits July 20, 2026 13:12
main already made config::default_model empty, but two gaps remained:

- AgentRole::default_agent_def (dispatcher) still returned a hardcoded
  "claude-sonnet-4-20250514". It was dead code (no callers) — removed it.
- resolve_agent's terminal fallback was still empty (unwrap_or_default), so a
  role with no explicit model, no `main` fallback, and no provider default
  resolved to "".

resolve_agent now resolves the model through a single helper resolve_model:
explicit model -> the provider's `default_model` -> terminal fallback
`qwen3-8b`. A provider whose `default_model` is an empty string still
deliberately means "route to whatever the provider has loaded" (e.g. LM Studio
GUI) and is preserved as empty; only a provider with no default, or no provider
at all, falls through to qwen3-8b.

Updated the resolve_agent property test to assert the new terminal fallback.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018UFD2FvZXDBaMmaXJSSQQ5
The main chat backend switched to streaming (turn_streaming sends
`stream: true` and parses a Server-Sent Events response), but the e2e mock
server only ever returned a single non-streaming JSON body. The SSE parser
found no content chunks, so the main-agent chat turn resolved to empty text and
chat_with_mock_agent_returns_response failed with "response should not be
empty" — red on main's own tip and every recent CI run.

The mock now inspects the request's `stream` flag and responds in the matching
shape: an SSE stream (data: {delta}... / [DONE]) for streaming requests, and
the original single JSON object for the non-streaming sub-agent calls.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018UFD2FvZXDBaMmaXJSSQQ5
@wparad
wparad force-pushed the claude/gitzi-mobile-api-plan-hpgltd branch from d463df5 to 2e252b4 Compare July 20, 2026 13:17
CI's clippy step never ran on main because the cargo test step failed first
(the e2e mock test). With that test fixed, the clippy step now runs and flags
latent lints under the newer stable toolchain (1.97):

- src/daemon/mod.rs, src/model/task.rs, src/state/review.rs and several test
  files: redundant `&` in format! arguments (useless_borrows_in_formatting).
- src/main.rs: collapse an `and_then(|r| if ok { Some(r) } else { None })` into
  `filter(|r| r.status().is_success())`.
- tests: collapsible if / redundant closure.

Verified on the 1.97 toolchain: cargo fmt --check, cargo clippy --all-features
(and --all-targets) -- -D warnings, and cargo test --all-features all pass.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018UFD2FvZXDBaMmaXJSSQQ5
@wparad
wparad merged commit 98bc837 into main Jul 20, 2026
1 check passed
@wparad
wparad deleted the claude/gitzi-mobile-api-plan-hpgltd branch July 20, 2026 14:40
wparad added a commit that referenced this pull request Jul 25, 2026
Default agent models to the provider's default, not hardcoded Claude Sonnet
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.

2 participants