Add user picked model to be used as a default for open router provider when generating comments and thread summary (#47475)

zapp88 created

Closes #37525

By default, thread summary uses default_fast_model (if set), otherwise
default_model, which resolves to openrouter/auto for openrouter
provider. This may cause the summary to be generated by a different
model than the one used by the agent, potentially leading — in cases
such as Claude Opus 4.5 — to summary costs exceeding main agent
execution costs.
The current logic in registry.rs prioritizes default_fast_model over
default_model, which overrides the user-selected model (assigned only to
default_model). Setting default_fast_model = None for the OpenRouter
provider preserves the fallback to openrouter/auto when no model is
chosen, while respecting the user's explicit model selection when one is
provided.

```rust
    pub fn set_default_model(&mut self, model: Option<ConfiguredModel>, cx: &mut Context<Self>) {
        match (self.default_model.as_ref(), model.as_ref()) {
            (Some(old), Some(new)) if old.is_same_as(new) => {}
            (None, None) => {}
            _ => cx.emit(Event::DefaultModelChanged),
        }
        self.default_fast_model = maybe!({
            let provider = &model.as_ref()?.provider;
            let fast_model = provider.default_fast_model(cx)?;
            Some(ConfiguredModel {
                provider: provider.clone(),
                model: fast_model,
            })
        }); // This sets default fast model (in our case openrouter/auto)
        self.default_model = model;  //This sets default_model to user selected model
    }
```

And latter on :
```rust
    pub fn thread_summary_model(&self) -> Option<ConfiguredModel> {
        #[cfg(debug_assertions)]
        if std::env::var("ZED_SIMULATE_NO_LLM_PROVIDER").is_ok() {
            return None;
        }

        self.thread_summary_model
            .clone()
            .or_else(|| self.default_fast_model.clone()) // We pick fast_model over default model here
            .or_else(|| self.default_model.clone())
    }
```
Which results in user choice being ignored.

Proposed behavior:

Use the model explicitly selected by the user in Zed agent
configuration.
If no model is specified, fall back to the configured default.

The resolution is to set in :  provider/open_router.rs
```rust
fn default_fast_model(&self, _cx: &App) -> Option<Arc<dyn LanguageModel>> {
     None
}
```
This will have a consequence of default_fast_model not being provided
and falling back to user choice - but once the fast model is set via for
example a configuration property - the default_fast_model is picked over
default_model

Release Notes:

- open_router: Use user's default model when comments and thread summary

Change summary

crates/language_models/src/provider/open_router.rs | 2 +-
crates/open_router/src/open_router.rs              | 6 +-----
2 files changed, 2 insertions(+), 6 deletions(-)

Detailed changes

crates/language_models/src/provider/open_router.rs 🔗

@@ -189,7 +189,7 @@ impl LanguageModelProvider for OpenRouterLanguageModelProvider {
     }
 
     fn default_fast_model(&self, _cx: &App) -> Option<Arc<dyn LanguageModel>> {
-        Some(self.create_language_model(open_router::Model::default_fast()))
+        None
     }
 
     fn provided_models(&self, cx: &App) -> Vec<Arc<dyn LanguageModel>> {

crates/open_router/src/open_router.rs 🔗

@@ -82,7 +82,7 @@ pub struct Model {
 }
 
 impl Model {
-    pub fn default_fast() -> Self {
+    pub fn default() -> Self {
         Self::new(
             "openrouter/auto",
             Some("Auto Router"),
@@ -94,10 +94,6 @@ impl Model {
         )
     }
 
-    pub fn default() -> Self {
-        Self::default_fast()
-    }
-
     pub fn new(
         name: &str,
         display_name: Option<&str>,