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,
90 task.title,
91 tag,
92 task.description,
93 task.id,
94 task.id
95 )
96}
97
98#[cfg(test)]
99mod tests {
100 use super::*;
101 use crate::models::task::Task;
102
103 #[test]
104 fn test_generate_prompt_basic() {
105 let task = Task::new(
106 "auth:1".to_string(),
107 "Implement login".to_string(),
108 "Add user authentication flow".to_string(),
109 );
110
111 let prompt = generate_prompt(&task, "auth");
112
113 assert!(prompt.contains("auth:1"));
114 assert!(prompt.contains("Implement login"));
115 assert!(prompt.contains("Tag: auth"));
116 assert!(prompt.contains("scud set-status auth:1 done"));
117 }
118
119 #[test]
120 fn test_generate_prompt_with_details() {
121 let mut task = Task::new(
122 "api:2".to_string(),
123 "Add endpoint".to_string(),
124 "Create REST endpoint".to_string(),
125 );
126 task.details = Some("Use Express.js router pattern".to_string());
127 task.test_strategy = Some("Unit test with Jest".to_string());
128
129 let prompt = generate_prompt(&task, "api");
130
131 assert!(prompt.contains("Technical Details:"));
132 assert!(prompt.contains("Express.js router"));
133 assert!(prompt.contains("Test Strategy:"));
134 assert!(prompt.contains("Unit test with Jest"));
135 }
136
137 #[test]
138 fn test_generate_minimal_prompt() {
139 let task = Task::new(
140 "fix:1".to_string(),
141 "Quick fix".to_string(),
142 "Fix typo".to_string(),
143 );
144
145 let prompt = generate_minimal_prompt(&task, "fix");
146
147 assert!(prompt.contains("fix:1"));
148 assert!(prompt.contains("Quick fix"));
149 assert!(!prompt.contains("Technical Details"));
150 }
151}