helix/dna/mds/
generate.rs

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}