Scan conversations dir on assistant panel open and on changes
Co-Authored-By: Julia Risley <julia@zed.dev>
This commit is contained in:
parent
230b4d237e
commit
bd7f8e8b38
2 changed files with 41 additions and 11 deletions
|
@ -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,
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue