fix(desktop): surface model requests the harness rejected - #4519
Open
mikececco wants to merge 1 commit into
Open
fix(desktop): surface model requests the harness rejected#4519mikececco wants to merge 1 commit into
mikececco wants to merge 1 commit into
Conversation
When a requested model has no byte-exact match in the harness catalog,
buzz-acp warns and starts the session on the agent's own default instead.
The only signal reaching desktop was `modelOverridden`, which is false
both when a request was rejected AND when no model was requested at all,
so the ModelPicker kept displaying the rejected pick as though it had
taken effect. A wrong model was indistinguishable from a right one, with
nothing surfaced anywhere.
The harness now reports `requestedModel` and `modelApplied` alongside
`modelOverridden` in `session_config_captured`. The config surface derives
`unappliedModelRequest` from that pair, and the ModelPicker renders
"<model> not applied" when the live session is not honouring the pick.
Both fields are purely additive; existing `model_overridden` consumers are
untouched. Harnesses that predate the pair omit both, and a missing
`requestedModel` keeps those sessions out of the warning rather than
mislabelling them.
Two mechanical extractions are included because
`desktop/scripts/check-file-sizes.mjs` forbids *any* growth in files
already past the 1000-line cap, and both files this fix must touch were
over it:
- `commands/agent_config.rs` (1112) — ACP session-payload parsing moved
verbatim to `config_bridge/session_payload.rs`, beside the types it
produces. Now 989.
- `shared/api/types.ts` (1032) — config-bridge types moved verbatim to
`shared/api/configBridge.ts` and re-exported. Now 956.
Both moves are code-identical with no behaviour change.
Refs block#2692, block#4004, block#2265
Co-Authored-By: Claude <noreply@anthropic.com>
Signed-off-by: Mike Cecconello <mikececco2000@gmail.com>
This was referenced Aug 3, 2026
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.
Problem
When a requested model has no byte-exact match in the harness catalog,
buzz-acpwarns and starts the session on the agent's own default:The only signal that reached Desktop was
modelOverridden. That flag isfalsein two different situations:
reader.rscollapses both (if !model_overridden { … }), so the ModelPicker keptshowing the rejected pick as though it had taken effect. A wrong model was
indistinguishable from a right one, with nothing surfaced anywhere.
That matches the reports in #2692 ("picker persists but nothing applies it at
spawn", 3 independent repros), #4004 (
composer-2.5[fast=false]runs asfast=true), and #2265 (silent fallback when the default model needs credits).Change
The harness now reports two additional fields in
session_config_captured:requestedModelnullwhen nothing wasmodelAppliedThe config surface derives
unappliedModelRequestfrom the pair, and theModelPicker renders
<model> not applied(with a tooltip naming the fallback)when the live session is not honouring the pick.
Both fields are purely additive —
model_overriddenand all its existingconsumers are untouched. Harnesses predating the pair omit both, and a missing
requestedModelkeeps those sessions out of the warning rather thanmislabelling them.
Why this PR also moves two blocks of code
desktop/scripts/check-file-sizes.mjsforbids any growth in files alreadypast the 1000-line cap, and both files this fix has to touch were over it. Per
the repo's own guidance ("split the file — never bump the limit"), each got one
mechanical extraction:
commands/agent_config.rsconfig_bridge/session_payload.rs(ACP payload parsing, beside the types it produces)shared/api/types.tsshared/api/configBridge.ts(config-bridge types, re-exported)Both moves are code-identical — no behaviour change. Reviewing them as pure
moves should be quick; happy to split them into a separate prep PR if you'd
rather land them independently.
Tests
Three regression tests in
config_bridge/reader_tests.rspin the distinctionthat was missing — including the case that makes this non-trivial: a session
running the harness default because nothing was requested must stay silent,
even though
model_appliedisfalsethere too.Green locally:
just desktop-check— pass (size ratchet included)just desktop-test— 3923 pass, 0 failjust desktop-tauri-test— 2109 pass, 0 failjust desktop-tauri-clippy— cleancargo test -p buzz-acp— 668 pass, 0 failUI note
The visible change is a single conditional label in
ModelPicker.tsx, using thesame
text-2xs text-warningtreatment as the existing "restart to apply"indicator next to it. I haven't attached a screenshot because the e2e mock
bridge doesn't populate
unappliedModelRequest— I'd need to seedbuildMockConfigSurfaceto stage the state. Glad to add that plus a capturedscreenshot if you'd like it before review.
Refs #2692, #4004, #2265