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