From bd7f8e8b3810689c7bfc470133e4771c798b3164 Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Tue, 20 Jun 2023 16:19:43 -0600 Subject: [PATCH] Scan conversations dir on assistant panel open and on changes Co-Authored-By: Julia Risley --- crates/ai/src/ai.rs | 22 +++++++++++----------- crates/ai/src/assistant.rs | 30 ++++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+), 11 deletions(-) diff --git a/crates/ai/src/ai.rs b/crates/ai/src/ai.rs index a676737d87..728648a293 100644 --- a/crates/ai/src/ai.rs +++ b/crates/ai/src/ai.rs @@ -3,7 +3,6 @@ mod assistant_settings; use anyhow::Result; pub use assistant::AssistantPanel; -use chrono::{DateTime, Local}; use fs::Fs; use futures::StreamExt; use gpui::AppContext; @@ -32,10 +31,17 @@ struct SavedConversation { messages: Vec, } -impl SavedConversation { - pub async fn list(fs: Arc) -> Result> { - let mut paths = fs.read_dir(&CONVERSATIONS_DIR).await?; +struct SavedConversationMetadata { + title: String, + path: PathBuf, + mtime: SystemTime, +} +impl SavedConversationMetadata { + pub async fn list(fs: Arc) -> Result> { + fs.create_dir(&CONVERSATIONS_DIR).await?; + + let mut paths = fs.read_dir(&CONVERSATIONS_DIR).await?; let mut conversations = Vec::::new(); while let Some(path) = paths.next().await { let path = path?; @@ -50,7 +56,7 @@ impl SavedConversation { .zip(metadata) { let title = re.replace(file_name, ""); - conversations.push(SavedConversationMetadata { + conversations.push(Self { title: title.into_owned(), path, mtime: metadata.mtime, @@ -62,12 +68,6 @@ impl SavedConversation { } } -struct SavedConversationMetadata { - title: String, - path: PathBuf, - mtime: SystemTime, -} - #[derive(Serialize, Deserialize, Debug, Eq, PartialEq)] struct RequestMessage { role: Role, diff --git a/crates/ai/src/assistant.rs b/crates/ai/src/assistant.rs index b7b0335a70..f7929006c6 100644 --- a/crates/ai/src/assistant.rs +++ b/crates/ai/src/assistant.rs @@ -1,6 +1,7 @@ use crate::{ assistant_settings::{AssistantDockPosition, AssistantSettings}, OpenAIRequest, OpenAIResponseStreamEvent, RequestMessage, Role, SavedConversation, + SavedConversationMetadata, }; use anyhow::{anyhow, Result}; use chrono::{DateTime, Local}; @@ -105,6 +106,8 @@ pub struct AssistantPanel { languages: Arc, fs: Arc, subscriptions: Vec, + saved_conversations: Vec, + _watch_saved_conversations: Task>, } impl AssistantPanel { @@ -113,6 +116,12 @@ impl AssistantPanel { cx: AsyncAppContext, ) -> Task>> { cx.spawn(|mut cx| async move { + let fs = workspace.read_with(&cx, |workspace, _| workspace.app_state().fs.clone())?; + let saved_conversations = SavedConversationMetadata::list(fs.clone()) + .await + .log_err() + .unwrap_or_default(); + // TODO: deserialize state. workspace.update(&mut cx, |workspace, cx| { cx.add_view::(|cx| { @@ -171,6 +180,25 @@ impl AssistantPanel { pane }); + const CONVERSATION_WATCH_DURATION: Duration = Duration::from_millis(100); + let _watch_saved_conversations = cx.spawn(move |this, mut cx| async move { + let mut events = fs + .watch(&CONVERSATIONS_DIR, CONVERSATION_WATCH_DURATION) + .await; + while events.next().await.is_some() { + let saved_conversations = SavedConversationMetadata::list(fs.clone()) + .await + .log_err() + .unwrap_or_default(); + this.update(&mut cx, |this, _| { + this.saved_conversations = saved_conversations + }) + .ok(); + } + + anyhow::Ok(()) + }); + let mut this = Self { pane, api_key: Rc::new(RefCell::new(None)), @@ -181,6 +209,8 @@ impl AssistantPanel { width: None, height: None, subscriptions: Default::default(), + saved_conversations, + _watch_saved_conversations, }; let mut old_dock_position = this.position(cx);