1use std::path::PathBuf;
2use std::fs;
3use anyhow::{Result, Context};
4
5pub fn generate_code(
6 template: String,
7 output: Option<PathBuf>,
8 name: Option<String>,
9 force: bool,
10 verbose: bool,
11) -> Result<()> {
12 if verbose {
13 println!("🔧 Generating code:");
14 println!(" Template: {}", template);
15 println!(
16 " Output: {}", output.as_ref().map(| p | p.display().to_string())
17 .unwrap_or_else(|| "current directory".to_string())
18 );
19 println!(" Name: {}", name.as_deref().unwrap_or("generated"));
20 }
21 let project_dir = find_project_root()?;
22 let output_path = output.unwrap_or_else(|| project_dir.join("src"));
23 fs::create_dir_all(&output_path).context("Failed to create output directory")?;
24 match template.as_str() {
25 "agent" => generate_agent_template(&output_path, name, force, verbose)?,
26 "workflow" => generate_workflow_template(&output_path, name, force, verbose)?,
27 "crew" => generate_crew_template(&output_path, name, force, verbose)?,
28 "context" => generate_context_template(&output_path, name, force, verbose)?,
29 "test" => generate_test_template(&output_path, name, force, verbose)?,
30 "benchmark" => generate_benchmark_template(&output_path, name, force, verbose)?,
31 _ => {
32 return Err(
33 anyhow::anyhow!(
34 "Unknown template '{}'. Available templates: agent, workflow, crew, context, test, benchmark",
35 template
36 ),
37 );
38 }
39 }
40 println!("✅ Generated {} template successfully!", template);
41 Ok(())
42}
43fn generate_agent_template(
44 output_path: &PathBuf,
45 name: Option<String>,
46 force: bool,
47 verbose: bool,
48) -> Result<()> {
49 let agent_name = name.unwrap_or_else(|| "MyAgent".to_string());
50 let filename = format!("{}.hlx", agent_name.to_lowercase());
51 let file_path = output_path.join(&filename);
52 if file_path.exists() && !force {
53 return Err(
54 anyhow::anyhow!(
55 "File '{}' already exists. Use --force to overwrite.", file_path
56 .display()
57 ),
58 );
59 }
60 let template = format!(
61 r#"// {} - AI Agent Configuration
62// Generated by HELIX Compiler
63
64agent {} {{
65 name: "{}"
66 description: "AI agent for {}"
67 model: "gpt-4"
68 temperature: 0.7
69 max_tokens: 2048
70
71 system_prompt: |
72 You are {}, a specialized AI agent.
73 Your role is to assist with {}.
74
75 Guidelines:
76 - Be helpful and accurate
77 - Provide clear explanations
78 - Ask clarifying questions when needed
79
80 capabilities: [
81 "reasoning"
82 "analysis"
83 "communication"
84 ]
85
86 tools: [
87 // Add tool configurations here
88 ]
89
90 constraints: [
91 "Always be truthful"
92 "Respect user privacy"
93 "Provide helpful responses"
94 ]
95
96 examples: [
97 {{
98 input: "Example input"
99 output: "Expected output"
100 }}
101 ]
102}}
103"#,
104 agent_name, agent_name, agent_name, agent_name.to_lowercase(), agent_name,
105 agent_name.to_lowercase()
106 );
107 fs::write(&file_path, template).context("Failed to write agent template")?;
108 if verbose {
109 println!(" Created: {}", file_path.display());
110 }
111 Ok(())
112}
113fn generate_workflow_template(
114 output_path: &PathBuf,
115 name: Option<String>,
116 force: bool,
117 verbose: bool,
118) -> Result<()> {
119 let workflow_name = name.unwrap_or_else(|| "MyWorkflow".to_string());
120 let filename = format!("{}.hlx", workflow_name.to_lowercase());
121 let file_path = output_path.join(&filename);
122 if file_path.exists() && !force {
123 return Err(
124 anyhow::anyhow!(
125 "File '{}' already exists. Use --force to overwrite.", file_path
126 .display()
127 ),
128 );
129 }
130 let template = format!(
131 r#"// {} - Workflow Configuration
132// Generated by HELIX Compiler
133
134workflow {} {{
135 name: "{}"
136 description: "Workflow for {}"
137
138 triggers: [
139 {{
140 type: "manual"
141 description: "Manual execution"
142 }}
143 ]
144
145 steps: [
146 {{
147 name: "step1"
148 agent: "MyAgent"
149 input: {{
150 prompt: "Process the input data"
151 }}
152 output: "processed_data"
153 }}
154 {{
155 name: "step2"
156 agent: "MyAgent"
157 input: {{
158 data: "{{processed_data}}"
159 prompt: "Analyze the processed data"
160 }}
161 output: "analysis_result"
162 }}
163 ]
164
165 error_handling: {{
166 retry_count: 3
167 retry_delay: 1000
168 fallback_action: "notify_admin"
169 }}
170
171 monitoring: {{
172 enabled: true
173 metrics: ["execution_time", "success_rate", "error_count"]
174 }}
175}}
176"#,
177 workflow_name, workflow_name, workflow_name, workflow_name.to_lowercase()
178 );
179 fs::write(&file_path, template).context("Failed to write workflow template")?;
180 if verbose {
181 println!(" Created: {}", file_path.display());
182 }
183 Ok(())
184}
185fn generate_crew_template(
186 output_path: &PathBuf,
187 name: Option<String>,
188 force: bool,
189 verbose: bool,
190) -> Result<()> {
191 let crew_name = name.unwrap_or_else(|| "MyCrew".to_string());
192 let filename = format!("{}.hlx", crew_name.to_lowercase());
193 let file_path = output_path.join(&filename);
194 if file_path.exists() && !force {
195 return Err(
196 anyhow::anyhow!(
197 "File '{}' already exists. Use --force to overwrite.", file_path
198 .display()
199 ),
200 );
201 }
202 let template = format!(
203 r#"// {} - Crew Configuration
204// Generated by HELIX Compiler
205
206crew {} {{
207 name: "{}"
208 description: "Crew for {}"
209
210 agents: [
211 {{
212 name: "Agent1"
213 role: "Primary Agent"
214 specialization: "main_task"
215 }}
216 {{
217 name: "Agent2"
218 role: "Support Agent"
219 specialization: "support_task"
220 }}
221 ]
222
223 collaboration: {{
224 mode: "sequential"
225 communication: "structured"
226 decision_making: "consensus"
227 }}
228
229 workflow: {{
230 name: "MyWorkflow"
231 steps: [
232 "Agent1 processes input"
233 "Agent2 reviews and validates"
234 "Both agents collaborate on final output"
235 ]
236 }}
237
238 performance: {{
239 target_accuracy: 0.95
240 max_execution_time: 30000
241 quality_threshold: 0.8
242 }}
243}}
244"#,
245 crew_name, crew_name, crew_name, crew_name.to_lowercase()
246 );
247 fs::write(&file_path, template).context("Failed to write crew template")?;
248 if verbose {
249 println!(" Created: {}", file_path.display());
250 }
251 Ok(())
252}
253fn generate_context_template(
254 output_path: &PathBuf,
255 name: Option<String>,
256 force: bool,
257 verbose: bool,
258) -> Result<()> {
259 let context_name = name.unwrap_or_else(|| "MyContext".to_string());
260 let filename = format!("{}.hlx", context_name.to_lowercase());
261 let file_path = output_path.join(&filename);
262 if file_path.exists() && !force {
263 return Err(
264 anyhow::anyhow!(
265 "File '{}' already exists. Use --force to overwrite.", file_path
266 .display()
267 ),
268 );
269 }
270 let template = format!(
271 r#"// {} - Context Configuration
272// Generated by HELIX Compiler
273
274context {} {{
275 name: "{}"
276 description: "Context for {}"
277
278 variables: {{
279 api_key: "{{env.API_KEY}}"
280 base_url: "https:
281 timeout: 30000
282 retry_count: 3
283 }}
284
285 resources: [
286 {{
287 name: "database"
288 type: "postgresql"
289 connection_string: "{{env.DATABASE_URL}}"
290 }}
291 {{
292 name: "cache"
293 type: "redis"
294 connection_string: "{{env.REDIS_URL}}"
295 }}
296 ]
297
298 environment: {{
299 development: {{
300 debug: true
301 log_level: "debug"
302 }}
303 production: {{
304 debug: false
305 log_level: "info"
306 }}
307 }}
308
309 security: {{
310 encryption: true
311 authentication: "bearer_token"
312 rate_limiting: {{
313 requests_per_minute: 100
314 burst_limit: 200
315 }}
316 }}
317}}
318"#,
319 context_name, context_name, context_name, context_name.to_lowercase()
320 );
321 fs::write(&file_path, template).context("Failed to write context template")?;
322 if verbose {
323 println!(" Created: {}", file_path.display());
324 }
325 Ok(())
326}
327fn generate_test_template(
328 output_path: &PathBuf,
329 name: Option<String>,
330 force: bool,
331 verbose: bool,
332) -> Result<()> {
333 let test_name = name.unwrap_or_else(|| "MyTest".to_string());
334 let filename = format!("test_{}.hlx", test_name.to_lowercase());
335 let file_path = output_path.join(&filename);
336 if file_path.exists() && !force {
337 return Err(
338 anyhow::anyhow!(
339 "File '{}' already exists. Use --force to overwrite.", file_path
340 .display()
341 ),
342 );
343 }
344 let template = format!(
345 r#"
346
347test {} {{
348 name: "{}"
349 description: "Test for {}"
350
351 setup: {{
352
353 mock_data: true
354 test_environment: "development"
355 }}
356
357 test_cases: [
358 {{
359 name: "basic_functionality"
360 input: {{
361 message: "Hello, world!"
362 }}
363 expected_output: {{
364 response: "Hello, world!"
365 status: "success"
366 }}
367 }}
368 {{
369 name: "error_handling"
370 input: {{
371 message: ""
372 }}
373 expected_output: {{
374 error: "Invalid input"
375 status: "error"
376 }}
377 }}
378 ]
379
380 assertions: [
381 "response.status == 'success'"
382 "response.time < 1000"
383 "response.accuracy > 0.9"
384 ]
385
386 cleanup: {{
387
388 remove_temp_files: true
389 reset_state: true
390 }}
391}}
392"#,
393 test_name, test_name, test_name
394 );
395 fs::write(&file_path, template).context("Failed to write test template")?;
396 if verbose {
397 println!(" Created: {}", file_path.display());
398 }
399 Ok(())
400}
401fn generate_benchmark_template(
402 output_path: &PathBuf,
403 name: Option<String>,
404 force: bool,
405 verbose: bool,
406) -> Result<()> {
407 let benchmark_name = name.unwrap_or_else(|| "MyBenchmark".to_string());
408 let filename = format!("bench_{}.hlx", benchmark_name.to_lowercase());
409 let file_path = output_path.join(&filename);
410 if file_path.exists() && !force {
411 return Err(
412 anyhow::anyhow!(
413 "File '{}' already exists. Use --force to overwrite.", file_path
414 .display()
415 ),
416 );
417 }
418 let template = format!(
419 r#"
420
421benchmark {} {{
422 name: "{}"
423 description: "Benchmark for {}"
424
425 configuration: {{
426 iterations: 1000
427 warmup_iterations: 100
428 timeout: 30000
429 parallel: false
430 }}
431
432 test_data: [
433 {{
434 name: "small_input"
435 size: "1KB"
436 data: "Small test data"
437 }}
438 {{
439 name: "medium_input"
440 size: "10KB"
441 data: "Medium test data with more content"
442 }}
443 {{
444 name: "large_input"
445 size: "100KB"
446 data: "Large test data with extensive content"
447 }}
448 ]
449
450 metrics: [
451 "execution_time"
452 "memory_usage"
453 "cpu_usage"
454 "throughput"
455 ]
456
457 thresholds: {{
458 max_execution_time: 1000
459 max_memory_usage: 50MB
460 min_throughput: 100
461 }}
462
463 reporting: {{
464 format: "json"
465 include_details: true
466 save_results: true
467 }}
468}}
469"#,
470 benchmark_name, benchmark_name, benchmark_name
471 );
472 fs::write(&file_path, template).context("Failed to write benchmark template")?;
473 if verbose {
474 println!(" Created: {}", file_path.display());
475 }
476 Ok(())
477}
478fn find_project_root() -> Result<PathBuf> {
479 let mut current_dir = std::env::current_dir()
480 .context("Failed to get current directory")?;
481 loop {
482 let manifest_path = current_dir.join("project.hlx");
483 if manifest_path.exists() {
484 return Ok(current_dir);
485 }
486 if let Some(parent) = current_dir.parent() {
487 current_dir = parent.to_path_buf();
488 } else {
489 break;
490 }
491 }
492 Err(anyhow::anyhow!("No HELIX project found. Run 'helix init' first."))
493}