Dedupe `PromptBuilder` construction (#23496)

Marshall Bowers created

This PR dedupes the construction of the `PromptBuilder`.

Previously this was constructed by both `assistant` and `assistant2`,
but now we construct it outside and pass it in.

Release Notes:

- N/A

Change summary

crates/assistant/src/assistant.rs    | 19 +++----------------
crates/assistant2/src/assistant.rs   | 20 +++++++-------------
crates/prompt_library/src/prompts.rs | 15 ++++++++++++++-
crates/zed/src/main.rs               |  8 +++++---
crates/zed/src/zed.rs                |  9 +++++++--
5 files changed, 36 insertions(+), 35 deletions(-)

Detailed changes

crates/assistant/src/assistant.rs 🔗

@@ -19,11 +19,10 @@ use gpui::{actions, AppContext, Global, UpdateGlobal};
 use language_model::{
     LanguageModelId, LanguageModelProviderId, LanguageModelRegistry, LanguageModelResponseMessage,
 };
-use prompt_library::{PromptBuilder, PromptLoadingParams};
+use prompt_library::PromptBuilder;
 use semantic_index::{CloudEmbeddingProvider, SemanticDb};
 use serde::Deserialize;
 use settings::{Settings, SettingsStore};
-use util::ResultExt;
 
 pub use crate::assistant_panel::{AssistantPanel, AssistantPanelEvent};
 pub(crate) use crate::inline_assistant::*;
@@ -93,9 +92,9 @@ impl Assistant {
 pub fn init(
     fs: Arc<dyn Fs>,
     client: Arc<Client>,
-    stdout_is_a_pty: bool,
+    prompt_builder: Arc<PromptBuilder>,
     cx: &mut AppContext,
-) -> Arc<PromptBuilder> {
+) {
     cx.set_global(Assistant::default());
     AssistantSettings::register(cx);
     SlashCommandSettings::register(cx);
@@ -135,16 +134,6 @@ pub fn init(
     assistant_panel::init(cx);
     context_server::init(cx);
 
-    let prompt_builder = PromptBuilder::new(Some(PromptLoadingParams {
-        fs: fs.clone(),
-        repo_path: stdout_is_a_pty
-            .then(|| std::env::current_dir().log_err())
-            .flatten(),
-        cx,
-    }))
-    .log_err()
-    .map(Arc::new)
-    .unwrap_or_else(|| Arc::new(PromptBuilder::new(None).unwrap()));
     register_slash_commands(Some(prompt_builder.clone()), cx);
     inline_assistant::init(
         fs.clone(),
@@ -175,8 +164,6 @@ pub fn init(
         });
     })
     .detach();
-
-    prompt_builder
 }
 
 fn init_language_model_settings(cx: &mut AppContext) {

crates/assistant2/src/assistant.rs 🔗

@@ -25,9 +25,8 @@ use command_palette_hooks::CommandPaletteFilter;
 use feature_flags::{Assistant2FeatureFlag, FeatureFlagAppExt};
 use fs::Fs;
 use gpui::{actions, AppContext};
-use prompt_library::{PromptBuilder, PromptLoadingParams};
+use prompt_library::PromptBuilder;
 use settings::Settings as _;
-use util::ResultExt;
 
 pub use crate::assistant_panel::{AssistantPanel, ConcreteAssistantPanelDelegate};
 pub use crate::inline_assistant::InlineAssistant;
@@ -60,20 +59,15 @@ actions!(
 const NAMESPACE: &str = "assistant2";
 
 /// Initializes the `assistant2` crate.
-pub fn init(fs: Arc<dyn Fs>, client: Arc<Client>, stdout_is_a_pty: bool, cx: &mut AppContext) {
+pub fn init(
+    fs: Arc<dyn Fs>,
+    client: Arc<Client>,
+    prompt_builder: Arc<PromptBuilder>,
+    cx: &mut AppContext,
+) {
     AssistantSettings::register(cx);
     assistant_panel::init(cx);
 
-    let prompt_builder = PromptBuilder::new(Some(PromptLoadingParams {
-        fs: fs.clone(),
-        repo_path: stdout_is_a_pty
-            .then(|| std::env::current_dir().log_err())
-            .flatten(),
-        cx,
-    }))
-    .log_err()
-    .map(Arc::new)
-    .unwrap_or_else(|| Arc::new(PromptBuilder::new(None).unwrap()));
     inline_assistant::init(
         fs.clone(),
         prompt_builder.clone(),

crates/prompt_library/src/prompts.rs 🔗

@@ -2,7 +2,7 @@ use anyhow::Result;
 use assets::Assets;
 use fs::Fs;
 use futures::StreamExt;
-use gpui::AssetSource;
+use gpui::{AppContext, AssetSource};
 use handlebars::{Handlebars, RenderError};
 use language::{BufferSnapshot, LanguageName, Point};
 use parking_lot::Mutex;
@@ -56,6 +56,19 @@ pub struct PromptBuilder {
 }
 
 impl PromptBuilder {
+    pub fn load(fs: Arc<dyn Fs>, stdout_is_a_pty: bool, cx: &mut AppContext) -> Arc<Self> {
+        Self::new(Some(PromptLoadingParams {
+            fs: fs.clone(),
+            repo_path: stdout_is_a_pty
+                .then(|| std::env::current_dir().log_err())
+                .flatten(),
+            cx,
+        }))
+        .log_err()
+        .map(Arc::new)
+        .unwrap_or_else(|| Arc::new(Self::new(None).unwrap()))
+    }
+
     pub fn new(loading_params: Option<PromptLoadingParams>) -> Result<Self> {
         let mut handlebars = Handlebars::new();
         Self::register_built_in_templates(&mut handlebars)?;

crates/zed/src/main.rs 🔗

@@ -25,6 +25,7 @@ use gpui::{
 use http_client::{read_proxy_from_env, Uri};
 use language::LanguageRegistry;
 use log::LevelFilter;
+use prompt_library::PromptBuilder;
 use reqwest_client::ReqwestClient;
 
 use assets::Assets;
@@ -443,16 +444,17 @@ fn main() {
             app_state.user_store.clone(),
             cx,
         );
-        let prompt_builder = assistant::init(
+        let prompt_builder = PromptBuilder::load(app_state.fs.clone(), stdout_is_a_pty(), cx);
+        assistant::init(
             app_state.fs.clone(),
             app_state.client.clone(),
-            stdout_is_a_pty(),
+            prompt_builder.clone(),
             cx,
         );
         assistant2::init(
             app_state.fs.clone(),
             app_state.client.clone(),
-            stdout_is_a_pty(),
+            prompt_builder.clone(),
             cx,
         );
         assistant_tools::init(cx);

crates/zed/src/zed.rs 🔗

@@ -3833,8 +3833,13 @@ mod tests {
                 app_state.fs.clone(),
                 cx,
             );
-            let prompt_builder =
-                assistant::init(app_state.fs.clone(), app_state.client.clone(), false, cx);
+            let prompt_builder = PromptBuilder::load(app_state.fs.clone(), false, cx);
+            assistant::init(
+                app_state.fs.clone(),
+                app_state.client.clone(),
+                prompt_builder.clone(),
+                cx,
+            );
             repl::init(app_state.fs.clone(), cx);
             repl::notebook::init(cx);
             tasks_ui::init(cx);