Scan conversations dir on assistant panel open and on changes

Co-Authored-By: Julia Risley <julia@zed.dev>
This commit is contained in:
Nathan Sobo 2023-06-20 16:19:43 -06:00
parent 230b4d237e
commit bd7f8e8b38
2 changed files with 41 additions and 11 deletions

View file

@ -3,7 +3,6 @@ mod assistant_settings;
use anyhow::Result; use anyhow::Result;
pub use assistant::AssistantPanel; pub use assistant::AssistantPanel;
use chrono::{DateTime, Local};
use fs::Fs; use fs::Fs;
use futures::StreamExt; use futures::StreamExt;
use gpui::AppContext; use gpui::AppContext;
@ -32,10 +31,17 @@ struct SavedConversation {
messages: Vec<RequestMessage>, messages: Vec<RequestMessage>,
} }
impl SavedConversation { struct SavedConversationMetadata {
pub async fn list(fs: Arc<dyn Fs>) -> Result<Vec<SavedConversationMetadata>> { title: String,
let mut paths = fs.read_dir(&CONVERSATIONS_DIR).await?; path: PathBuf,
mtime: SystemTime,
}
impl SavedConversationMetadata {
pub async fn list(fs: Arc<dyn Fs>) -> Result<Vec<Self>> {
fs.create_dir(&CONVERSATIONS_DIR).await?;
let mut paths = fs.read_dir(&CONVERSATIONS_DIR).await?;
let mut conversations = Vec::<SavedConversationMetadata>::new(); let mut conversations = Vec::<SavedConversationMetadata>::new();
while let Some(path) = paths.next().await { while let Some(path) = paths.next().await {
let path = path?; let path = path?;
@ -50,7 +56,7 @@ impl SavedConversation {
.zip(metadata) .zip(metadata)
{ {
let title = re.replace(file_name, ""); let title = re.replace(file_name, "");
conversations.push(SavedConversationMetadata { conversations.push(Self {
title: title.into_owned(), title: title.into_owned(),
path, path,
mtime: metadata.mtime, mtime: metadata.mtime,
@ -62,12 +68,6 @@ impl SavedConversation {
} }
} }
struct SavedConversationMetadata {
title: String,
path: PathBuf,
mtime: SystemTime,
}
#[derive(Serialize, Deserialize, Debug, Eq, PartialEq)] #[derive(Serialize, Deserialize, Debug, Eq, PartialEq)]
struct RequestMessage { struct RequestMessage {
role: Role, role: Role,

View file

@ -1,6 +1,7 @@
use crate::{ use crate::{
assistant_settings::{AssistantDockPosition, AssistantSettings}, assistant_settings::{AssistantDockPosition, AssistantSettings},
OpenAIRequest, OpenAIResponseStreamEvent, RequestMessage, Role, SavedConversation, OpenAIRequest, OpenAIResponseStreamEvent, RequestMessage, Role, SavedConversation,
SavedConversationMetadata,
}; };
use anyhow::{anyhow, Result}; use anyhow::{anyhow, Result};
use chrono::{DateTime, Local}; use chrono::{DateTime, Local};
@ -105,6 +106,8 @@ pub struct AssistantPanel {
languages: Arc<LanguageRegistry>, languages: Arc<LanguageRegistry>,
fs: Arc<dyn Fs>, fs: Arc<dyn Fs>,
subscriptions: Vec<Subscription>, subscriptions: Vec<Subscription>,
saved_conversations: Vec<SavedConversationMetadata>,
_watch_saved_conversations: Task<Result<()>>,
} }
impl AssistantPanel { impl AssistantPanel {
@ -113,6 +116,12 @@ impl AssistantPanel {
cx: AsyncAppContext, cx: AsyncAppContext,
) -> Task<Result<ViewHandle<Self>>> { ) -> Task<Result<ViewHandle<Self>>> {
cx.spawn(|mut cx| async move { 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. // TODO: deserialize state.
workspace.update(&mut cx, |workspace, cx| { workspace.update(&mut cx, |workspace, cx| {
cx.add_view::<Self, _>(|cx| { cx.add_view::<Self, _>(|cx| {
@ -171,6 +180,25 @@ impl AssistantPanel {
pane 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 { let mut this = Self {
pane, pane,
api_key: Rc::new(RefCell::new(None)), api_key: Rc::new(RefCell::new(None)),
@ -181,6 +209,8 @@ impl AssistantPanel {
width: None, width: None,
height: None, height: None,
subscriptions: Default::default(), subscriptions: Default::default(),
saved_conversations,
_watch_saved_conversations,
}; };
let mut old_dock_position = this.position(cx); let mut old_dock_position = this.position(cx);