Don't block thread creation when PromptStore fails to initialize

Richard Feldman created

NativeAgentServer::connect used prompt_store.await? which turned any
PromptStore initialization failure (permission denied, disk issues, etc.)
into a hard connection error, preventing all new native agent threads.

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 'last active thread not found in database'), then
verifies NewThread still produces a connected thread.

Change summary

crates/agent/src/native_agent_server.rs |  7 ++--
crates/agent_ui/src/agent_panel.rs      | 38 +++++++++++++++++++++++++++
2 files changed, 42 insertions(+), 3 deletions(-)

Detailed changes

crates/agent/src/native_agent_server.rs 🔗

@@ -10,6 +10,7 @@ use gpui::{App, Entity, Task};
 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};
 
@@ -47,11 +48,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);

crates/agent_ui/src/agent_panel.rs 🔗

@@ -6248,4 +6248,42 @@ mod tests {
             "the new worktree workspace should use the same agent (Codex) that was selected in the original panel",
         );
     }
+
+    /// 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"
+            );
+        });
+    }
 }