Don't block thread creation when PromptStore fails to initialize (#52333)

NativeAgentServer::connect used `prompt_store.await?` which turned any
PromptStore initialization failure (permission denied, disk issues,
etc.) into a hard connection error, putting the ConversationView into
LoadError state and preventing all new native agent threads from being
created.

Changed to `.log_err()` so the error is logged at ERROR level but thread
creation proceeds with `prompt_store: None`. `NativeAgent::new` already
accepts `Option<Entity<PromptStore>>` and handles `None` gracefully —
user custom prompts won't load but threads still work.

Added a regression test that serializes a stale thread ID, loads the
panel (triggering the "last active thread not found in database"
warning), then dispatches NewThread through the real NativeAgentServer
path and verifies it produces a connected thread.

Release Notes:

- Agent panel now handles filesystem errors more gracefully
This commit is contained in:
Richard Feldman authored and GitHub committed 2026-04-24 12:32:28 +00:00
1 parent 03064b953f
commit 4a15e201ba
2 files changed
+42 -3

No files matched your search

+4 -3
View File
@@ -11,6 +11,7 @@ use language_model::{LanguageModelId, LanguageModelProviderId, LanguageModelRegi
use project::{AgentId, Project};
use prompt_store::PromptStore;
use settings::{LanguageModelSelection, Settings as _, update_settings_file};
use util::ResultExt as _;
use crate::{NativeAgent, NativeAgentConnection, ThreadStore, templates::Templates};
@@ -48,11 +49,11 @@ impl AgentServer for NativeAgentServer {
cx.spawn(async move |cx| {
log::debug!("Creating templates for native agent");
let templates = Templates::new();
let prompt_store = prompt_store.await?;
let prompt_store = prompt_store.await.log_err();
log::debug!("Creating native agent entity");
let agent = cx
.update(|cx| NativeAgent::new(thread_store, templates, Some(prompt_store), fs, cx));
let agent =
cx.update(|cx| NativeAgent::new(thread_store, templates, prompt_store, fs, cx));
// Create the connection wrapper
let connection = NativeAgentConnection(agent);
+38
View File
@@ -7123,4 +7123,42 @@ mod tests {
);
});
}
/// Regression test: NewThread must produce a connected thread even when
/// the PromptStore fails to initialize (e.g. LMDB permission error).
/// Before the fix, `NativeAgentServer::connect` propagated the
/// PromptStore error with `?`, which put every new ConversationView
/// into LoadError and made it impossible to start any native-agent
/// thread.
#[gpui::test]
async fn test_new_thread_with_prompt_store_error(cx: &mut TestAppContext) {
let (panel, mut cx) = setup_panel(cx).await;
// NativeAgentServer::connect needs a global Fs.
let fs = FakeFs::new(cx.executor());
cx.update(|_, cx| {
<dyn fs::Fs>::set_global(fs.clone(), cx);
});
cx.run_until_parked();
// Dispatch NewThread, which goes through the real NativeAgentServer
// path. In tests the PromptStore LMDB open fails with
// "Permission denied"; the fix (.log_err() instead of ?) lets
// the connection succeed anyway.
panel.update_in(&mut cx, |panel, window, cx| {
panel.new_thread(&NewThread, window, cx);
});
cx.run_until_parked();
panel.read_with(&cx, |panel, cx| {
assert!(
panel.active_conversation_view().is_some(),
"panel should have a conversation view after NewThread"
);
assert!(
panel.active_agent_thread(cx).is_some(),
"panel should have an active, connected agent thread"
);
});
}
}