diff --git a/Cargo.lock b/Cargo.lock index a4b12223e5..cdabeb26ec 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -109,6 +109,7 @@ dependencies = [ "isahc", "language", "menu", + "regex", "schemars", "search", "serde", diff --git a/crates/ai/Cargo.toml b/crates/ai/Cargo.toml index 7f8954bb21..76aaf41017 100644 --- a/crates/ai/Cargo.toml +++ b/crates/ai/Cargo.toml @@ -25,6 +25,7 @@ anyhow.workspace = true chrono = "0.4" futures.workspace = true isahc.workspace = true +regex.workspace = true schemars.workspace = true serde.workspace = true serde_json.workspace = true diff --git a/crates/ai/src/ai.rs b/crates/ai/src/ai.rs index f6bcb670ad..a676737d87 100644 --- a/crates/ai/src/ai.rs +++ b/crates/ai/src/ai.rs @@ -1,10 +1,21 @@ pub mod assistant; mod assistant_settings; +use anyhow::Result; pub use assistant::AssistantPanel; +use chrono::{DateTime, Local}; +use fs::Fs; +use futures::StreamExt; use gpui::AppContext; +use regex::Regex; use serde::{Deserialize, Serialize}; -use std::fmt::{self, Display}; +use std::{ + fmt::{self, Display}, + path::PathBuf, + sync::Arc, + time::SystemTime, +}; +use util::paths::CONVERSATIONS_DIR; // Data types for chat completion requests #[derive(Debug, Serialize)] @@ -21,6 +32,42 @@ struct SavedConversation { messages: Vec, } +impl SavedConversation { + pub async fn list(fs: Arc) -> Result> { + let mut paths = fs.read_dir(&CONVERSATIONS_DIR).await?; + + let mut conversations = Vec::::new(); + while let Some(path) = paths.next().await { + let path = path?; + + let pattern = r" - \d+.zed.json$"; + let re = Regex::new(pattern).unwrap(); + + let metadata = fs.metadata(&path).await?; + if let Some((file_name, metadata)) = path + .file_name() + .and_then(|name| name.to_str()) + .zip(metadata) + { + let title = re.replace(file_name, ""); + conversations.push(SavedConversationMetadata { + title: title.into_owned(), + path, + mtime: metadata.mtime, + }); + } + } + + Ok(conversations) + } +} + +struct SavedConversationMetadata { + title: String, + path: PathBuf, + mtime: SystemTime, +} + #[derive(Serialize, Deserialize, Debug, Eq, PartialEq)] struct RequestMessage { role: Role,