From 23decdeebf15439bdac2284313dac0048b805a4c Mon Sep 17 00:00:00 2001 From: Zhiwei Liang Date: Thu, 4 Jun 2026 12:03:35 -0400 Subject: [PATCH] Refresh OpenRouter models after setting API key (#58551) Self-Review Checklist: - [x] I've reviewed my own diff for quality, security, and reliability - [x] Unsafe blocks (if any) have justifying comments - [ ] The content is consistent with the [UI/UX checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist) - [ ] Tests cover the new/changed behavior - [x] Performance impact has been considered and is acceptable ## Summary Adding an OpenRouter API key did not populate the model list until the app was restarted. `set_api_key` stored the credential but never triggered a model fetch, so until re-authentication happened (on restart or a settings change) the picker showed only the user-configured `settings.available_models`, not the models returned by the OpenRouter API. This makes `set_api_key` refresh the models right after the key is stored, mirroring how `authenticate` already does it. ## Changes - `set_api_key` awaits the credential store and then calls `restart_fetch_models_task`, so the API model list loads immediately after a key is entered (and is cleared when the key is removed). - `fetch_models` now maps `list_models` errors via `LanguageModelCompletionError::from`, preserving the real OpenRouter error message instead of wrapping it in a generic `Other(...)`. Release Notes: - Fixed OpenRouter models not appearing until restart after adding an API key Signed-off-by: Zhiwei Liang --- .../src/provider/open_router.rs | 20 ++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/crates/language_models/src/provider/open_router.rs b/crates/language_models/src/provider/open_router.rs index ef434eed85..c414ccacee 100644 --- a/crates/language_models/src/provider/open_router.rs +++ b/crates/language_models/src/provider/open_router.rs @@ -59,13 +59,20 @@ impl State { fn set_api_key(&mut self, api_key: Option, cx: &mut Context) -> Task> { let credentials_provider = self.credentials_provider.clone(); let api_url = OpenRouterLanguageModelProvider::api_url(cx); - self.api_key_state.store( + let task = self.api_key_state.store( api_url, api_key, |this| &mut this.api_key_state, credentials_provider, cx, - ) + ); + + cx.spawn(async move |this, cx| { + let result = task.await?; + this.update(cx, |this, cx| this.restart_fetch_models_task(cx)) + .ok(); + Ok(result) + }) } fn authenticate(&mut self, cx: &mut Context) -> Task> { @@ -103,12 +110,7 @@ impl State { cx.spawn(async move |this, cx| { let models = list_models(http_client.as_ref(), &api_url, &api_key, &extra_headers) .await - .map_err(|e| { - LanguageModelCompletionError::Other(anyhow::anyhow!( - "OpenRouter error: {:?}", - e - )) - })?; + .map_err(LanguageModelCompletionError::from)?; this.update(cx, |this, cx| { this.available_models = models; @@ -125,7 +127,7 @@ impl State { let task = self.fetch_models(cx); self.fetch_models_task.replace(task); } else { - self.available_models = Vec::new(); + self.available_models.clear(); } } }