Fix CC todo tool parsing (#35721)
It looks like the TODO tool call no longer requires a priority. Release Notes: - N/A
This commit is contained in:
parent
22fa41e9c0
commit
69dc870828
2 changed files with 73 additions and 24 deletions
|
@ -764,6 +764,8 @@ enum PermissionMode {
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
pub(crate) mod tests {
|
pub(crate) mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
use crate::e2e_tests;
|
||||||
|
use gpui::TestAppContext;
|
||||||
use serde_json::json;
|
use serde_json::json;
|
||||||
|
|
||||||
crate::common_e2e_tests!(ClaudeCode, allow_option_id = "allow");
|
crate::common_e2e_tests!(ClaudeCode, allow_option_id = "allow");
|
||||||
|
@ -776,6 +778,68 @@ pub(crate) mod tests {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[gpui::test]
|
||||||
|
#[cfg_attr(not(feature = "e2e"), ignore)]
|
||||||
|
async fn test_todo_plan(cx: &mut TestAppContext) {
|
||||||
|
let fs = e2e_tests::init_test(cx).await;
|
||||||
|
let project = Project::test(fs, [], cx).await;
|
||||||
|
let thread =
|
||||||
|
e2e_tests::new_test_thread(ClaudeCode, project.clone(), "/private/tmp", cx).await;
|
||||||
|
|
||||||
|
thread
|
||||||
|
.update(cx, |thread, cx| {
|
||||||
|
thread.send_raw(
|
||||||
|
"Create a todo plan for initializing a new React app. I'll follow it myself, do not execute on it.",
|
||||||
|
cx,
|
||||||
|
)
|
||||||
|
})
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let mut entries_len = 0;
|
||||||
|
|
||||||
|
thread.read_with(cx, |thread, _| {
|
||||||
|
entries_len = thread.plan().entries.len();
|
||||||
|
assert!(thread.plan().entries.len() > 0, "Empty plan");
|
||||||
|
});
|
||||||
|
|
||||||
|
thread
|
||||||
|
.update(cx, |thread, cx| {
|
||||||
|
thread.send_raw(
|
||||||
|
"Mark the first entry status as in progress without acting on it.",
|
||||||
|
cx,
|
||||||
|
)
|
||||||
|
})
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
thread.read_with(cx, |thread, _| {
|
||||||
|
assert!(matches!(
|
||||||
|
thread.plan().entries[0].status,
|
||||||
|
acp::PlanEntryStatus::InProgress
|
||||||
|
));
|
||||||
|
assert_eq!(thread.plan().entries.len(), entries_len);
|
||||||
|
});
|
||||||
|
|
||||||
|
thread
|
||||||
|
.update(cx, |thread, cx| {
|
||||||
|
thread.send_raw(
|
||||||
|
"Now mark the first entry as completed without acting on it.",
|
||||||
|
cx,
|
||||||
|
)
|
||||||
|
})
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
thread.read_with(cx, |thread, _| {
|
||||||
|
assert!(matches!(
|
||||||
|
thread.plan().entries[0].status,
|
||||||
|
acp::PlanEntryStatus::Completed
|
||||||
|
));
|
||||||
|
assert_eq!(thread.plan().entries.len(), entries_len);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_deserialize_content_untagged_text() {
|
fn test_deserialize_content_untagged_text() {
|
||||||
let json = json!("Hello, world!");
|
let json = json!("Hello, world!");
|
||||||
|
|
|
@ -143,25 +143,6 @@ impl ClaudeTool {
|
||||||
Self::Grep(Some(params)) => vec![format!("`{params}`").into()],
|
Self::Grep(Some(params)) => vec![format!("`{params}`").into()],
|
||||||
Self::WebFetch(Some(params)) => vec![params.prompt.clone().into()],
|
Self::WebFetch(Some(params)) => vec![params.prompt.clone().into()],
|
||||||
Self::WebSearch(Some(params)) => vec![params.to_string().into()],
|
Self::WebSearch(Some(params)) => vec![params.to_string().into()],
|
||||||
Self::TodoWrite(Some(params)) => vec![
|
|
||||||
params
|
|
||||||
.todos
|
|
||||||
.iter()
|
|
||||||
.map(|todo| {
|
|
||||||
format!(
|
|
||||||
"- {} {}: {}",
|
|
||||||
match todo.status {
|
|
||||||
TodoStatus::Completed => "✅",
|
|
||||||
TodoStatus::InProgress => "🚧",
|
|
||||||
TodoStatus::Pending => "⬜",
|
|
||||||
},
|
|
||||||
todo.priority,
|
|
||||||
todo.content
|
|
||||||
)
|
|
||||||
})
|
|
||||||
.join("\n")
|
|
||||||
.into(),
|
|
||||||
],
|
|
||||||
Self::ExitPlanMode(Some(params)) => vec![params.plan.clone().into()],
|
Self::ExitPlanMode(Some(params)) => vec![params.plan.clone().into()],
|
||||||
Self::Edit(Some(params)) => vec![acp::ToolCallContent::Diff {
|
Self::Edit(Some(params)) => vec![acp::ToolCallContent::Diff {
|
||||||
diff: acp::Diff {
|
diff: acp::Diff {
|
||||||
|
@ -193,6 +174,10 @@ impl ClaudeTool {
|
||||||
})
|
})
|
||||||
.unwrap_or_default()
|
.unwrap_or_default()
|
||||||
}
|
}
|
||||||
|
Self::TodoWrite(Some(_)) => {
|
||||||
|
// These are mapped to plan updates later
|
||||||
|
vec![]
|
||||||
|
}
|
||||||
Self::Task(None)
|
Self::Task(None)
|
||||||
| Self::NotebookRead(None)
|
| Self::NotebookRead(None)
|
||||||
| Self::NotebookEdit(None)
|
| Self::NotebookEdit(None)
|
||||||
|
@ -488,10 +473,11 @@ impl std::fmt::Display for GrepToolParams {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Deserialize, Serialize, JsonSchema, strum::Display, Debug)]
|
#[derive(Default, Deserialize, Serialize, JsonSchema, strum::Display, Debug)]
|
||||||
#[serde(rename_all = "snake_case")]
|
#[serde(rename_all = "snake_case")]
|
||||||
pub enum TodoPriority {
|
pub enum TodoPriority {
|
||||||
High,
|
High,
|
||||||
|
#[default]
|
||||||
Medium,
|
Medium,
|
||||||
Low,
|
Low,
|
||||||
}
|
}
|
||||||
|
@ -526,14 +512,13 @@ impl Into<acp::PlanEntryStatus> for TodoStatus {
|
||||||
|
|
||||||
#[derive(Deserialize, Serialize, JsonSchema, Debug)]
|
#[derive(Deserialize, Serialize, JsonSchema, Debug)]
|
||||||
pub struct Todo {
|
pub struct Todo {
|
||||||
/// Unique identifier
|
|
||||||
pub id: String,
|
|
||||||
/// Task description
|
/// Task description
|
||||||
pub content: String,
|
pub content: String,
|
||||||
/// Priority level of the todo
|
|
||||||
pub priority: TodoPriority,
|
|
||||||
/// Current status of the todo
|
/// Current status of the todo
|
||||||
pub status: TodoStatus,
|
pub status: TodoStatus,
|
||||||
|
/// Priority level of the todo
|
||||||
|
#[serde(default)]
|
||||||
|
pub priority: TodoPriority,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Into<acp::PlanEntry> for Todo {
|
impl Into<acp::PlanEntry> for Todo {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue