diff --git a/crates/goose/src/agents/subagent_execution_tool/tasks_manager.rs b/crates/goose/src/agents/subagent_execution_tool/tasks_manager.rs index b416518a9c..73051cff72 100644 --- a/crates/goose/src/agents/subagent_execution_tool/tasks_manager.rs +++ b/crates/goose/src/agents/subagent_execution_tool/tasks_manager.rs @@ -4,8 +4,6 @@ use std::sync::Arc; use tokio::sync::RwLock; use crate::agents::subagent_execution_tool::task_types::Task; -#[cfg(test)] -use crate::agents::subagent_execution_tool::task_types::TaskType; #[derive(Debug, Clone)] pub struct TasksManager { @@ -62,13 +60,13 @@ mod tests { fn create_test_task(id: &str, sub_recipe_name: &str) -> Task { Task { id: id.to_string(), - task_type: TaskType::SubRecipe, payload: json!({ - "sub_recipe": { - "name": sub_recipe_name, - "command_parameters": {}, - "recipe_path": "/test/path" - } + "recipe": { + "title": sub_recipe_name, + "instructions": "Test recipe" + }, + "return_last_only": false, + "sequential_when_repeated": false }), } } diff --git a/crates/goose/src/agents/subagent_execution_tool/utils/tests.rs b/crates/goose/src/agents/subagent_execution_tool/utils/tests.rs index 3e5c5cd291..0bf1465bce 100644 --- a/crates/goose/src/agents/subagent_execution_tool/utils/tests.rs +++ b/crates/goose/src/agents/subagent_execution_tool/utils/tests.rs @@ -1,4 +1,4 @@ -use crate::agents::subagent_execution_tool::task_types::{Task, TaskInfo, TaskStatus, TaskType}; +use crate::agents::subagent_execution_tool::task_types::{Task, TaskInfo, TaskStatus}; use crate::agents::subagent_execution_tool::utils::{ count_by_status, get_task_name, strip_ansi_codes, }; @@ -20,45 +20,43 @@ mod test_get_task_name { use super::*; #[test] - fn test_extracts_sub_recipe_name() { - let sub_recipe_task = Task { + fn test_extracts_recipe_title() { + let task = Task { id: "task_1".to_string(), - task_type: TaskType::SubRecipe, payload: json!({ - "sub_recipe": { - "name": "my_recipe", - "recipe_path": "/path/to/recipe" - } + "recipe": { + "title": "my_recipe", + "instructions": "do something" + }, + "sub_recipe_name": "my_recipe" }), }; - let task_info = create_task_info_with_defaults(sub_recipe_task, TaskStatus::Pending); + let task_info = create_task_info_with_defaults(task, TaskStatus::Pending); assert_eq!(get_task_name(&task_info), "my_recipe"); } #[test] - fn falls_back_to_task_id_for_inline_recipe() { - let inline_task = Task { + fn falls_back_to_task_id_for_recipe_without_title() { + let task = Task { id: "task_2".to_string(), - task_type: TaskType::InlineRecipe, payload: json!({"recipe": {"instructions": "do something"}}), }; - let task_info = create_task_info_with_defaults(inline_task, TaskStatus::Pending); + let task_info = create_task_info_with_defaults(task, TaskStatus::Pending); assert_eq!(get_task_name(&task_info), "task_2"); } #[test] - fn falls_back_to_task_id_when_sub_recipe_name_missing() { + fn falls_back_to_task_id_when_recipe_title_missing() { let malformed_task = Task { id: "task_3".to_string(), - task_type: TaskType::SubRecipe, payload: json!({ - "sub_recipe": { - "recipe_path": "/path/to/recipe" - // missing "name" field + "recipe": { + "instructions": "do something" + // missing "title" field } }), }; @@ -69,11 +67,10 @@ mod test_get_task_name { } #[test] - fn falls_back_to_task_id_when_sub_recipe_missing() { + fn falls_back_to_task_id_when_recipe_missing() { let malformed_task = Task { id: "task_4".to_string(), - task_type: TaskType::SubRecipe, - payload: json!({}), // missing "sub_recipe" field + payload: json!({}), // missing "recipe" field }; let task_info = create_task_info_with_defaults(malformed_task, TaskStatus::Pending); @@ -88,8 +85,12 @@ mod count_by_status { fn create_test_task(id: &str, status: TaskStatus) -> TaskInfo { let task = Task { id: id.to_string(), - task_type: TaskType::InlineRecipe, - payload: json!({}), + payload: json!({ + "recipe": { + "title": "Test Recipe", + "instructions": "Test" + } + }), }; create_task_info_with_defaults(task, status) } diff --git a/crates/goose/tests/task_types_tests.rs b/crates/goose/tests/task_types_tests.rs deleted file mode 100644 index 970d0286bd..0000000000 --- a/crates/goose/tests/task_types_tests.rs +++ /dev/null @@ -1,126 +0,0 @@ -use goose::agents::subagent_execution_tool::task_types::{Task, TaskType}; -use serde_json::json; - -#[test] -fn test_task_type_serialization() { - // Test that TaskType serializes to the expected string format - assert_eq!( - serde_json::to_string(&TaskType::InlineRecipe).unwrap(), - "\"inline_recipe\"" - ); - assert_eq!( - serde_json::to_string(&TaskType::SubRecipe).unwrap(), - "\"sub_recipe\"" - ); -} - -#[test] -fn test_task_type_deserialization() { - // Test that strings deserialize to the correct TaskType variants - assert_eq!( - serde_json::from_str::("\"inline_recipe\"").unwrap(), - TaskType::InlineRecipe - ); - assert_eq!( - serde_json::from_str::("\"sub_recipe\"").unwrap(), - TaskType::SubRecipe - ); -} - -#[test] -fn test_task_serialization_with_enum() { - let task = Task { - id: "test-id".to_string(), - task_type: TaskType::InlineRecipe, - payload: json!({"recipe": "test"}), - }; - - let serialized = serde_json::to_value(&task).unwrap(); - assert_eq!(serialized["id"], "test-id"); - assert_eq!(serialized["task_type"], "inline_recipe"); - assert_eq!(serialized["payload"]["recipe"], "test"); -} - -#[test] -fn test_task_deserialization_with_string() { - // Test backward compatibility - JSON with string task_type should deserialize - let json_str = r#"{ - "id": "test-id", - "task_type": "sub_recipe", - "payload": {"sub_recipe": {"name": "test"}} - }"#; - - let task: Task = serde_json::from_str(json_str).unwrap(); - assert_eq!(task.id, "test-id"); - assert_eq!(task.task_type, TaskType::SubRecipe); -} - -#[test] -fn test_task_type_display() { - assert_eq!(TaskType::InlineRecipe.to_string(), "inline_recipe"); - assert_eq!(TaskType::SubRecipe.to_string(), "sub_recipe"); -} - -#[test] -fn test_task_methods_with_sub_recipe() { - let task = Task { - id: "test-1".to_string(), - task_type: TaskType::SubRecipe, - payload: json!({ - "sub_recipe": { - "name": "test_recipe", - "recipe_path": "/path/to/recipe", - "command_parameters": {"key": "value"}, - "sequential_when_repeated": true - } - }), - }; - - assert!(task.get_sub_recipe().is_some()); - assert_eq!(task.get_sub_recipe_name(), Some("test_recipe")); - assert_eq!(task.get_sub_recipe_path(), Some("/path/to/recipe")); - assert!(task.get_command_parameters().is_some()); - assert!(task.get_sequential_when_repeated()); -} - -#[test] -fn test_task_methods_with_inline_recipe() { - let task = Task { - id: "test-3".to_string(), - task_type: TaskType::InlineRecipe, - payload: json!({ - "recipe": { - "instructions": "Test instructions" - }, - "return_last_only": true - }), - }; - - assert!(task.get_sub_recipe().is_none()); - assert!(task.get_sub_recipe_name().is_none()); - assert!(task.get_sub_recipe_path().is_none()); - assert!(task.get_command_parameters().is_none()); - assert!(!task.get_sequential_when_repeated()); -} - -#[test] -fn test_invalid_task_type_deserialization() { - // Test that invalid task_type strings fail to deserialize - let result = serde_json::from_str::("\"invalid_type\""); - assert!(result.is_err()); -} - -#[test] -fn test_task_with_missing_fields() { - let task = Task { - id: "test-4".to_string(), - task_type: TaskType::SubRecipe, - payload: json!({}), // Missing sub_recipe field - }; - - assert!(task.get_sub_recipe().is_none()); - assert!(task.get_sub_recipe_name().is_none()); - assert!(task.get_sub_recipe_path().is_none()); - assert!(task.get_command_parameters().is_none()); - assert!(!task.get_sequential_when_repeated()); -}