Skip to content

Commit c72e594

Browse files
authored
acp: Fix model selector sometimes showing no models (#36995)
Release Notes: - N/A
1 parent b4d4294 commit c72e594

File tree

1 file changed

+50
-1
lines changed

1 file changed

+50
-1
lines changed

crates/agent2/src/agent.rs

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,16 +61,19 @@ pub struct LanguageModels {
6161
model_list: acp_thread::AgentModelList,
6262
refresh_models_rx: watch::Receiver<()>,
6363
refresh_models_tx: watch::Sender<()>,
64+
_authenticate_all_providers_task: Task<()>,
6465
}
6566

6667
impl LanguageModels {
67-
fn new(cx: &App) -> Self {
68+
fn new(cx: &mut App) -> Self {
6869
let (refresh_models_tx, refresh_models_rx) = watch::channel(());
70+
6971
let mut this = Self {
7072
models: HashMap::default(),
7173
model_list: acp_thread::AgentModelList::Grouped(IndexMap::default()),
7274
refresh_models_rx,
7375
refresh_models_tx,
76+
_authenticate_all_providers_task: Self::authenticate_all_language_model_providers(cx),
7477
};
7578
this.refresh_list(cx);
7679
this
@@ -150,6 +153,52 @@ impl LanguageModels {
150153
fn model_id(model: &Arc<dyn LanguageModel>) -> acp_thread::AgentModelId {
151154
acp_thread::AgentModelId(format!("{}/{}", model.provider_id().0, model.id().0).into())
152155
}
156+
157+
fn authenticate_all_language_model_providers(cx: &mut App) -> Task<()> {
158+
let authenticate_all_providers = LanguageModelRegistry::global(cx)
159+
.read(cx)
160+
.providers()
161+
.iter()
162+
.map(|provider| (provider.id(), provider.name(), provider.authenticate(cx)))
163+
.collect::<Vec<_>>();
164+
165+
cx.background_spawn(async move {
166+
for (provider_id, provider_name, authenticate_task) in authenticate_all_providers {
167+
if let Err(err) = authenticate_task.await {
168+
if matches!(err, language_model::AuthenticateError::CredentialsNotFound) {
169+
// Since we're authenticating these providers in the
170+
// background for the purposes of populating the
171+
// language selector, we don't care about providers
172+
// where the credentials are not found.
173+
} else {
174+
// Some providers have noisy failure states that we
175+
// don't want to spam the logs with every time the
176+
// language model selector is initialized.
177+
//
178+
// Ideally these should have more clear failure modes
179+
// that we know are safe to ignore here, like what we do
180+
// with `CredentialsNotFound` above.
181+
match provider_id.0.as_ref() {
182+
"lmstudio" | "ollama" => {
183+
// LM Studio and Ollama both make fetch requests to the local APIs to determine if they are "authenticated".
184+
//
185+
// These fail noisily, so we don't log them.
186+
}
187+
"copilot_chat" => {
188+
// Copilot Chat returns an error if Copilot is not enabled, so we don't log those errors.
189+
}
190+
_ => {
191+
log::error!(
192+
"Failed to authenticate provider: {}: {err}",
193+
provider_name.0
194+
);
195+
}
196+
}
197+
}
198+
}
199+
}
200+
})
201+
}
153202
}
154203

155204
pub struct NativeAgent {

0 commit comments

Comments
 (0)