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 <zhiwei.liang@zliang.me>
This commit is contained in:
Zhiwei Liang authored and GitHub committed 2026-06-04 16:03:35 +00:00
1 parent 3d700c5042
commit 23decdeebf
1 file changed
+11 -9
@@ -59,13 +59,20 @@ impl State {
fn set_api_key(&mut self, api_key: Option<String>, cx: &mut Context<Self>) -> Task<Result<()>> {
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<Self>) -> Task<Result<(), AuthenticateError>> {
@@ -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();
}
}
}