tycode_core/spawn/
complete_task.rs1use crate::chat::events::{ToolRequest as ToolRequestEvent, ToolRequestType};
4use crate::tools::r#trait::{ToolCallHandle, ToolCategory, ToolExecutor, ToolOutput, ToolRequest};
5use crate::tools::ToolName;
6use anyhow::Result;
7use serde::{Deserialize, Serialize};
8use serde_json::{json, Value};
9
10#[derive(Debug, Serialize, Deserialize)]
11struct CompleteTaskParams {
12 result: String,
13 success: bool,
14}
15
16pub struct CompleteTask;
17
18impl CompleteTask {
19 pub fn tool_name() -> ToolName {
20 ToolName::new("complete_task")
21 }
22
23 pub fn standalone() -> Self {
25 Self
26 }
27}
28
29struct CompleteTaskHandle {
30 success: bool,
31 result: String,
32 tool_use_id: String,
33}
34
35#[async_trait::async_trait(?Send)]
36impl ToolCallHandle for CompleteTaskHandle {
37 fn tool_request(&self) -> ToolRequestEvent {
38 ToolRequestEvent {
39 tool_call_id: self.tool_use_id.clone(),
40 tool_name: "complete_task".to_string(),
41 tool_type: ToolRequestType::Other {
42 args: json!({
43 "success": self.success,
44 "result": self.result,
45 }),
46 },
47 }
48 }
49
50 async fn execute(self: Box<Self>) -> ToolOutput {
51 ToolOutput::PopAgent {
52 success: self.success,
53 result: self.result,
54 }
55 }
56}
57
58#[async_trait::async_trait(?Send)]
59impl ToolExecutor for CompleteTask {
60 fn name(&self) -> String {
61 "complete_task".to_string()
62 }
63
64 fn description(&self) -> String {
65 "Signal task completion (success or failure) and return control to parent agent. \
66 FAIL a task when: \
67 • Required resources/files don't exist \
68 • The task requirements are unclear or contradictory \
69 • You encounter errors you cannot resolve \
70 • The requested change would break existing functionality \
71 • You lack necessary permissions or access \
72 SUCCEED when: \
73 • All requested changes are implemented \
74 • The task objectives are met \
75 NOTE: Sub-agents must use this with failure instead of spawning more agents when stuck. \
76 Parent agents have more context to handle failures properly."
77 .to_string()
78 }
79
80 fn input_schema(&self) -> Value {
81 json!({
82 "type": "object",
83 "required": ["result", "success"],
84 "properties": {
85 "result": {
86 "type": "string",
87 "description": "Result of the task - summary of what was accomplished, failure details, code outline, or any other output"
88 },
89 "success": {
90 "type": "boolean",
91 "description": "Whether the task completed successfully"
92 }
93 }
94 })
95 }
96
97 fn category(&self) -> ToolCategory {
98 ToolCategory::Meta
99 }
100
101 async fn process(&self, request: &ToolRequest) -> Result<Box<dyn ToolCallHandle>> {
102 let params: CompleteTaskParams = serde_json::from_value(request.arguments.clone())?;
103
104 Ok(Box::new(CompleteTaskHandle {
105 success: params.success,
106 result: params.result,
107 tool_use_id: request.tool_use_id.clone(),
108 }))
109 }
110}