Skip to content

Commit 398bdb4

Browse files
author
kiran-garre
committed
refactor: Change to-do lists to use database over filesystem
Updates: - To-do lists now only use the database rather than the filesystem for managing past and unfinished tasks
1 parent 2a09ea9 commit 398bdb4

File tree

8 files changed

+118
-145
lines changed

8 files changed

+118
-145
lines changed

crates/chat-cli/src/cli/chat/cli/todos.rs

Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
use clap::Subcommand;
2-
use std::path::PathBuf;
32
use crate::{cli::chat::tools::todo::TodoState, os::Os};
43
use crossterm::{
54
execute,
@@ -14,28 +13,23 @@ use crate::cli::chat::{
1413

1514
use eyre::Result;
1615

17-
use crate::cli::chat::tools::todo::{
18-
build_path,
19-
TODO_STATE_FOLDER_PATH,
20-
};
21-
2216
use dialoguer::{
2317
FuzzySelect
2418
};
2519

2620
#[derive(Debug, PartialEq, Subcommand)]
2721
pub enum TodoSubcommand {
28-
// Task/prompt to generate TODO list for
2922
Show,
3023
ClearFinished,
3124
Select,
3225
}
3326

27+
/// Used for displaying completed and in-progress todo lists
3428
pub struct TodoDisplayEntry {
3529
pub num_completed: usize,
3630
pub num_tasks: usize,
3731
pub description: String,
38-
pub path: PathBuf,
32+
pub id: String,
3933
}
4034

4135
impl std::fmt::Display for TodoDisplayEntry {
@@ -60,7 +54,7 @@ impl TodoSubcommand {
6054
pub async fn execute(self, os: &mut Os, session: &mut ChatSession) -> Result<ChatState, ChatError> {
6155
match self {
6256
Self::Show => {
63-
match self.get_descriptions_and_statuses(os).await {
57+
match self.get_descriptions_and_statuses(os) {
6458
Ok(entries) => {
6559
if entries.len() == 0 {
6660
execute!(
@@ -88,7 +82,7 @@ impl TodoSubcommand {
8882
();
8983
},
9084
Self::Select => {
91-
match self.get_descriptions_and_statuses(os).await {
85+
match self.get_descriptions_and_statuses(os) {
9286
Ok(entries) => {
9387
if entries.len() == 0 {
9488
execute!(
@@ -110,7 +104,7 @@ impl TodoSubcommand {
110104
style::Print("⟳ Resuming: ".magenta()),
111105
style::Print(format!("{}\n", entries[index].description.clone())),
112106
)?;
113-
return session.resume_todo(os, entries[index].path.clone()).await;
107+
return session.resume_todo(os, &entries[index].id).await;
114108
}
115109
}
116110
}
@@ -125,23 +119,29 @@ impl TodoSubcommand {
125119
}
126120

127121
/// Convert all to-do list state files to displayable entries
128-
async fn get_descriptions_and_statuses(self, os: &Os) -> Result<Vec<TodoDisplayEntry>> {
122+
fn get_descriptions_and_statuses(self, os: &Os) -> Result<Vec<TodoDisplayEntry>> {
129123
let mut out = Vec::new();
130-
let mut entries = os.fs.read_dir(
131-
build_path(os, TODO_STATE_FOLDER_PATH, "")?
132-
).await?;
133-
134-
while let Some(entry) = entries.next_entry().await? {
135-
let contents = os.fs.read_to_string(entry.path()).await?;
136-
let temp_struct = match serde_json::from_str::<TodoState>(&contents) {
137-
Ok(state) => state,
138-
Err(_) => continue,
124+
let entries = os.database.get_all_todos()?;
125+
for (id, value) in entries.iter() {
126+
let temp_struct = match value.as_str() {
127+
Some(s) => { match serde_json::from_str::<TodoState>(s) {
128+
Ok(state) => state,
129+
Err(_) => continue,
130+
}},
131+
None => continue,
139132
};
140-
out.push( TodoDisplayEntry {
133+
// For some reason this doesn't work
134+
// Has to do with the Value::String wrapping in os.database.all_entries() rather than Value::from_str()
135+
// let temp_struct = match serde_json::from_value::<TodoState>(value.clone()) {
136+
// Ok(state) => state,
137+
// Err(_) => continue,
138+
// };
139+
140+
out.push(TodoDisplayEntry {
141141
num_completed: temp_struct.completed.iter().filter(|b| **b).count(),
142142
num_tasks: temp_struct.completed.len(),
143143
description: prewrap(&temp_struct.task_description),
144-
path: entry.path(),
144+
id: id.to_string(),
145145
});
146146
}
147147
Ok(out)

crates/chat-cli/src/cli/chat/conversation.rs

Lines changed: 13 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ use std::collections::{
44
VecDeque,
55
};
66
use std::io::Write;
7-
use std::path::PathBuf;
87
use std::sync::atomic::Ordering;
98

109
use crossterm::style::Color;
@@ -24,6 +23,7 @@ use tracing::{
2423

2524
use eyre::{
2625
Result,
26+
bail,
2727
};
2828

2929
use super::consts::{
@@ -847,17 +847,20 @@ impl ConversationState {
847847
}
848848
}
849849

850-
pub async fn create_todo_request(&self, os: &Os, path: PathBuf) -> Result<FigConversationState> {
851-
let contents = self.can_resume_todo(os, &path).await?;
850+
pub async fn create_todo_request(&self, os: &Os, id: &str) -> Result<FigConversationState> {
851+
let contents = match os.database.get_todo(id)? {
852+
Some(todo_list) => serde_json::to_string(&todo_list)?,
853+
None => bail!("No todo list with id {}", id)
854+
};
852855
let request = format!(
853-
"[SYSTEM NOTE: This is an automated request, not from the user]
854-
Read the TODO list contents below and understand the task description, completed tasks, and provided context.
855-
Call the `load` command of the todo_list tool with the given file path as an argument to display the TODO list to the user and officially resume execution of the TODO list tasks.
856-
You do not need to display the tasks to the user yourself. You can begin completing the tasks after calling the `load` command.
857-
TODO LIST CONTENTS: {}
858-
FILE PATH: {}",
856+
"[SYSTEM NOTE: This is an automated request, not from the user]\n
857+
Read the TODO list contents below and understand the task description, completed tasks, and provided context.\n
858+
Call the `load` command of the todo_list tool with the given ID as an argument to display the TODO list to the user and officially resume execution of the TODO list tasks.\n
859+
You do not need to display the tasks to the user yourself. You can begin completing the tasks after calling the `load` command.\n
860+
TODO LIST CONTENTS: {}\n
861+
ID: {}\n",
859862
contents,
860-
path.display()
863+
id
861864
);
862865

863866
let request_message = UserInputMessage {
@@ -874,13 +877,6 @@ impl ConversationState {
874877
history: None,
875878
})
876879
}
877-
878-
// For now, just check that file path is valid and deserializable
879-
pub async fn can_resume_todo(&self, os: &Os, path: &PathBuf) -> Result<String> {
880-
let contents = os.fs.read_to_string(path).await?;
881-
let _ = serde_json::from_str::<TodoState>(&contents)?;
882-
Ok(contents)
883-
}
884880
}
885881

886882
/// Represents a conversation state that can be converted into a [FigConversationState] (the type

crates/chat-cli/src/cli/chat/mod.rs

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,6 @@ use eyre::{
5555
bail,
5656
eyre,
5757
};
58-
use std::path::PathBuf;
5958

6059
use input_source::InputSource;
6160
use message::{
@@ -975,12 +974,12 @@ impl ChatSession {
975974
async fn resume_todo(
976975
&mut self,
977976
os: &mut Os,
978-
path: PathBuf,
977+
id: &str,
979978
) -> Result<ChatState, ChatError> {
980979

981980
let request_state = self
982981
.conversation
983-
.create_todo_request(os, path)
982+
.create_todo_request(os, id)
984983
.await;
985984

986985
match request_state {
@@ -1007,6 +1006,7 @@ impl ChatSession {
10071006

10081007
let response = os.client.send_message(conv_state).await?;
10091008

1009+
// Since this is an internal tool call, manually handle the tool requests from Q
10101010
let mut result = self.handle_response(os, response).await?;
10111011
loop {
10121012
match result {
@@ -1023,12 +1023,7 @@ impl ChatSession {
10231023
return Ok(other);
10241024
},
10251025
}
1026-
};
1027-
// Ok(ChatState::PromptUser {
1028-
// skip_printing_tools: true,
1029-
// })
1030-
1031-
1026+
};
10321027
}
10331028

10341029
/// Compacts the conversation history, replacing the history with a summary generated by the

0 commit comments

Comments
 (0)