acp: Fix stale ACP reasoning-effort options when model switch keeps same config IDs (#50246)

## Problem
Zed's ACP config-options UI was only rebuilding selectors when the set
of config option IDs changed.

For many model switches, the IDs stay the same (`mode`, `model`,
`reasoning_effort`) while the valid values for `reasoning_effort` change
by model. As a result, the picker could show stale values (for example,
missing `xhigh` on `gpt-5.3-codex`, or showing extra `xhigh` after
switching away).

This is especially problematic for providers like Copilot that expose
multiple agents/models with different reasoning-level capabilities.

## Fix
Rebuild ACP config-option selectors on every `config_option_update`, not
only when config IDs change.

This refreshes cached picker entries whenever model-specific option
values change, even if option IDs are unchanged.

## User Impact
- Reasoning-effort picker now reflects the selected model immediately on
Claude <-> GPT transitions.
- Prevents stale or invalid effort choices in ACP sessions.

## Validation
- Manual validation: switch across models with different
reasoning-effort sets and confirm picker updates immediately.
- Local `cargo check -p agent_ui` remains blocked by unrelated
pre-existing `livekit-protocol` compile errors in this checkout.

## Files Changed
- `crates/agent_ui/src/acp/config_options.rs`

Release Notes:

- acp: Fix for config selectors not always being refreshed

---------

Co-authored-by: Ben Brandt <benjamin.j.brandt@gmail.com>
This commit is contained in:
Nikhil Pandey 2026-02-26 17:03:46 -05:00 committed by GitHub
parent da2bed1930
commit cbbcb1e101
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -49,7 +49,7 @@ impl ConfigOptionsView {
if let Some(mut rx) = rx {
while let Ok(()) = rx.recv().await {
this.update_in(cx, |this, window, cx| {
this.refresh_selectors_if_needed(window, cx);
this.rebuild_selectors(window, cx);
cx.notify();
})
.log_err();
@ -184,15 +184,10 @@ impl ConfigOptionsView {
.collect()
}
fn refresh_selectors_if_needed(&mut self, window: &mut Window, cx: &mut Context<Self>) {
let current_ids = Self::config_option_ids(&self.config_options);
if current_ids != self.config_option_ids {
self.config_option_ids = current_ids;
self.rebuild_selectors(window, cx);
}
}
fn rebuild_selectors(&mut self, window: &mut Window, cx: &mut Context<Self>) {
// Config option updates can mutate option values for existing IDs (for example,
// reasoning levels after a model switch). Rebuild to refresh cached picker entries.
self.config_option_ids = Self::config_option_ids(&self.config_options);
self.selectors = Self::build_selectors(
&self.config_options,
&self.agent_server,