ai-agent-sdk 0.5.0

Idiomatic agent sdk inspired by the claude code source leak
Documentation
//! Task management tools.
//!
//! Provides tools for creating, listing, updating, and getting tasks.

use crate::types::*;

/// TaskCreate tool - create a new task
pub struct TaskCreateTool;

impl TaskCreateTool {
    pub fn new() -> Self {
        Self
    }

    pub fn input_schema(&self) -> ToolInputSchema {
        ToolInputSchema {
            schema_type: "object".to_string(),
            properties: serde_json::json!({
                "subject": {
                    "type": "string",
                    "description": "A brief title for the task"
                },
                "description": {
                    "type": "string",
                    "description": "What needs to be done"
                },
                "activeForm": {
                    "type": "string",
                    "description": "Present continuous form shown in spinner when in_progress"
                }
            }),
            required: Some(vec!["subject".to_string(), "description".to_string()]),
        }
    }

    pub async fn execute(&self, input: serde_json::Value, _context: &ToolContext) -> Result<ToolResult, crate::error::AgentError> {
        let subject = input["subject"].as_str().unwrap_or("");
        let description = input["description"].as_str().unwrap_or("");
        let active_form = input["activeForm"].as_str().unwrap_or(subject);

        let response = format!(
            "Task created: {}\nDescription: {}\nActive form: {}",
            subject, description, active_form
        );

        Ok(ToolResult {
            result_type: "text".to_string(),
            tool_use_id: "task_create".to_string(),
            content: response,
            is_error: Some(false),
        })
    }
}

impl Default for TaskCreateTool {
    fn default() -> Self {
        Self::new()
    }
}

/// TaskList tool - list all tasks
pub struct TaskListTool;

impl TaskListTool {
    pub fn new() -> Self {
        Self
    }

    pub fn input_schema(&self) -> ToolInputSchema {
        ToolInputSchema {
            schema_type: "object".to_string(),
            properties: serde_json::json!({}),
            required: None,
        }
    }

    pub async fn execute(&self, _input: serde_json::Value, _context: &ToolContext) -> Result<ToolResult, crate::error::AgentError> {
        let response = "Tasks:\n- (none)".to_string();

        Ok(ToolResult {
            result_type: "text".to_string(),
            tool_use_id: "task_list".to_string(),
            content: response,
            is_error: Some(false),
        })
    }
}

impl Default for TaskListTool {
    fn default() -> Self {
        Self::new()
    }
}

/// TaskUpdate tool - update a task
pub struct TaskUpdateTool;

impl TaskUpdateTool {
    pub fn new() -> Self {
        Self
    }

    pub fn input_schema(&self) -> ToolInputSchema {
        ToolInputSchema {
            schema_type: "object".to_string(),
            properties: serde_json::json!({
                "taskId": {
                    "type": "string",
                    "description": "The ID of the task to update"
                },
                "subject": {
                    "type": "string",
                    "description": "New subject for the task"
                },
                "description": {
                    "type": "string",
                    "description": "New description for the task"
                },
                "status": {
                    "type": "string",
                    "enum": ["pending", "in_progress", "completed", "deleted"],
                    "description": "New status for the task"
                },
                "activeForm": {
                    "type": "string",
                    "description": "New active form"
                }
            }),
            required: Some(vec!["taskId".to_string()]),
        }
    }

    pub async fn execute(&self, input: serde_json::Value, _context: &ToolContext) -> Result<ToolResult, crate::error::AgentError> {
        let task_id = input["taskId"].as_str().unwrap_or("");
        let status = input["status"].as_str().unwrap_or("pending");

        let response = format!(
            "Task {} updated:\n- Status: {}",
            task_id, status
        );

        Ok(ToolResult {
            result_type: "text".to_string(),
            tool_use_id: "task_update".to_string(),
            content: response,
            is_error: Some(false),
        })
    }
}

impl Default for TaskUpdateTool {
    fn default() -> Self {
        Self::new()
    }
}

/// TaskGet tool - get a specific task
pub struct TaskGetTool;

impl TaskGetTool {
    pub fn new() -> Self {
        Self
    }

    pub fn input_schema(&self) -> ToolInputSchema {
        ToolInputSchema {
            schema_type: "object".to_string(),
            properties: serde_json::json!({
                "taskId": {
                    "type": "string",
                    "description": "The ID of the task to retrieve"
                }
            }),
            required: Some(vec!["taskId".to_string()]),
        }
    }

    pub async fn execute(&self, input: serde_json::Value, _context: &ToolContext) -> Result<ToolResult, crate::error::AgentError> {
        let task_id = input["taskId"].as_str().unwrap_or("");

        let response = format!(
            "Task ID: {}\nStatus: pending\nSubject: (placeholder)\nDescription: (placeholder)",
            task_id
        );

        Ok(ToolResult {
            result_type: "text".to_string(),
            tool_use_id: "task_get".to_string(),
            content: response,
            is_error: Some(false),
        })
    }
}

impl Default for TaskGetTool {
    fn default() -> Self {
        Self::new()
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_task_create_schema() {
        let tool = TaskCreateTool::new();
        let schema = tool.input_schema();
        assert_eq!(schema.schema_type, "object");
        assert!(schema.properties.get("subject").is_some());
        assert!(schema.properties.get("description").is_some());
    }

    #[test]
    fn test_task_list_schema() {
        let tool = TaskListTool::new();
        let schema = tool.input_schema();
        assert_eq!(schema.schema_type, "object");
    }

    #[test]
    fn test_task_update_schema() {
        let tool = TaskUpdateTool::new();
        let schema = tool.input_schema();
        assert!(schema.properties.get("taskId").is_some());
        assert!(schema.properties.get("status").is_some());
    }

    #[test]
    fn test_task_get_schema() {
        let tool = TaskGetTool::new();
        let schema = tool.input_schema();
        assert!(schema.properties.get("taskId").is_some());
    }
}