scud/commands/spawn/
agent.rs1use crate::models::task::Task;
6
7pub fn generate_prompt(task: &Task, tag: &str) -> String {
9 let mut prompt = format!(
10 r#"You are working on SCUD task {id}: {title}
11
12Tag: {tag}
13Complexity: {complexity}
14Priority: {priority:?}
15
16Description:
17{description}
18"#,
19 id = task.id,
20 title = task.title,
21 tag = tag,
22 complexity = task.complexity,
23 priority = task.priority,
24 description = task.description,
25 );
26
27 if let Some(ref details) = task.details {
29 prompt.push_str(&format!(
30 r#"
31Technical Details:
32{}
33"#,
34 details
35 ));
36 }
37
38 if let Some(ref test_strategy) = task.test_strategy {
40 prompt.push_str(&format!(
41 r#"
42Test Strategy:
43{}
44"#,
45 test_strategy
46 ));
47 }
48
49 if !task.dependencies.is_empty() {
51 prompt.push_str(&format!(
52 r#"
53Dependencies (should be done):
54{}
55"#,
56 task.dependencies.join(", ")
57 ));
58 }
59
60 prompt.push_str(&format!(
62 r#"
63Instructions:
641. First, explore the codebase to understand the context for this task
652. Implement the task following project conventions and patterns
663. Write tests if applicable based on the test strategy
674. When complete, run: scud set-status {} done
685. If blocked by issues, run: scud set-status {} blocked
69
70Begin by understanding what needs to be done and exploring relevant code.
71"#,
72 task.id, task.id
73 ));
74
75 prompt
76}
77
78pub fn generate_minimal_prompt(task: &Task, tag: &str) -> String {
80 format!(
81 r#"SCUD Task {}: {}
82
83Tag: {}
84Description: {}
85
86When done: scud set-status {} done
87If blocked: scud set-status {} blocked
88"#,
89 task.id, task.title, tag, task.description, task.id, task.id
90 )
91}
92
93#[cfg(test)]
94mod tests {
95 use super::*;
96 use crate::models::task::Task;
97
98 #[test]
99 fn test_generate_prompt_basic() {
100 let task = Task::new(
101 "auth:1".to_string(),
102 "Implement login".to_string(),
103 "Add user authentication flow".to_string(),
104 );
105
106 let prompt = generate_prompt(&task, "auth");
107
108 assert!(prompt.contains("auth:1"));
109 assert!(prompt.contains("Implement login"));
110 assert!(prompt.contains("Tag: auth"));
111 assert!(prompt.contains("scud set-status auth:1 done"));
112 }
113
114 #[test]
115 fn test_generate_prompt_with_details() {
116 let mut task = Task::new(
117 "api:2".to_string(),
118 "Add endpoint".to_string(),
119 "Create REST endpoint".to_string(),
120 );
121 task.details = Some("Use Express.js router pattern".to_string());
122 task.test_strategy = Some("Unit test with Jest".to_string());
123
124 let prompt = generate_prompt(&task, "api");
125
126 assert!(prompt.contains("Technical Details:"));
127 assert!(prompt.contains("Express.js router"));
128 assert!(prompt.contains("Test Strategy:"));
129 assert!(prompt.contains("Unit test with Jest"));
130 }
131
132 #[test]
133 fn test_generate_minimal_prompt() {
134 let task = Task::new(
135 "fix:1".to_string(),
136 "Quick fix".to_string(),
137 "Fix typo".to_string(),
138 );
139
140 let prompt = generate_minimal_prompt(&task, "fix");
141
142 assert!(prompt.contains("fix:1"));
143 assert!(prompt.contains("Quick fix"));
144 assert!(!prompt.contains("Technical Details"));
145 }
146}