helios-engine 0.5.5

A powerful and flexible Rust framework for building LLM-powered agents with tool support, both locally and online
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
# AutoForest - Automatic Agent Orchestration

## Overview

AutoForest is an advanced feature in the Helios Engine that automatically orchestrates a forest of specialized agents to complete complex tasks. Instead of manually creating and configuring multiple agents, AutoForest intelligently:

- **Analyzes** the task to understand its complexity and requirements
- **Determines** the optimal number of agents needed
- **Generates** specialized system prompts for each agent
- **Coordinates** task execution across all agents
- **Aggregates** results into a comprehensive final response

> **Note**: While AutoForest plans for tool distribution among agents (as shown in the `AgentConfig.tool_indices` field), tools currently cannot be cloned and individually assigned to agents. All agents work without direct tool access, relying on LLM capabilities and specialized prompts that guide them to explain what tools would be needed and how they would use them.

## How It Works

### 1. Task Analysis & Planning

When you submit a task to AutoForest, it creates an orchestrator agent that analyzes the task and generates an `OrchestrationPlan`. This plan includes:

- **Number of agents**: How many specialized agents should be spawned (1-5)
- **Agent roles**: What each agent specializes in
- **System prompts**: Customized instructions for each agent's expertise
- **Tool assignments**: Planned tool distribution among agents (see Limitations)
- **Task breakdown**: Specific subtasks for each agent

### 2. Dynamic Agent Spawning

Based on the orchestration plan, AutoForest spawns specialized agents with:
- Unique configurations tailored to their role
- Specific system prompts guiding their behavior
- Customized instructions for their assigned subtask

### 3. Parallel Execution

Each agent works on their assigned subtask **in parallel** using Tokio's async/await, enabling efficient distributed task completion. All agents execute concurrently, significantly improving performance for complex tasks.

### 4. Result Aggregation

Results from all agents are collected and synthesized by the orchestrator into a cohesive final response.

## Architecture

### Core Components

#### `AutoForest`
The main orchestrator struct that manages the forest lifecycle:
```rust
pub struct AutoForest {
    config: Config,
    tools: Vec<Box<dyn Tool>>,
    spawned_agents: Vec<SpawnedAgent>,
    orchestration_plan: Option<OrchestrationPlan>,
    orchestrator_agent: Option<Agent>,
}
```

#### `AgentConfig`
Configuration for each spawned agent:
```rust
pub struct AgentConfig {
    pub name: String,                    // Agent name
    pub system_prompt: String,           // Specialized instructions
    pub tool_indices: Vec<usize>,        // Assigned tools
    pub role: String,                    // Agent's specialty/role
}
```

#### `OrchestrationPlan`
The strategic plan generated for a task:
```rust
pub struct OrchestrationPlan {
    pub task: String,                    // Original task
    pub num_agents: usize,               // Number of agents to spawn
    pub reasoning: String,               // Why this configuration was chosen
    pub agents: Vec<AgentConfig>,        // Configuration for each agent
    pub task_breakdown: HashMap<String, String>, // Subtasks per agent
}
```

#### `SpawnedAgent`
An agent spawned by the orchestrator:
```rust
pub struct SpawnedAgent {
    pub agent: Agent,                    // The agent instance
    pub config: AgentConfig,             // Its configuration
    pub result: Option<String>,          // Its result
}
```

## Usage Guide

### Basic Usage

```rust
use helios_engine::{AutoForest, Config, CalculatorTool, FileReadTool};

#[tokio::main]
async fn main() -> helios_engine::Result<()> {
    // Create configuration
    let config = Config::builder()
        .model("gpt-4")
        .api_key("your-api-key")
        .build();

    // Create AutoForest with available tools
    let mut auto_forest = AutoForest::new(config)
        .with_tools(vec![
            Box::new(CalculatorTool),
            Box::new(FileReadTool),
        ])
        .build()
        .await?;

    // Execute a complex task
    let task = "Analyze quarterly sales data and predict next quarter trends";
    let result = auto_forest.execute_task(task).await?;
    
    println!("Result:\n{}", result);
    Ok(())
}
```

### Accessing the Orchestration Plan

After executing a task, you can inspect how AutoForest organized the work:

```rust
let result = auto_forest.execute_task("Complex task").await?;

// Get the plan that was generated
if let Some(plan) = auto_forest.orchestration_plan() {
    println!("Number of agents spawned: {}", plan.num_agents);
    println!("Reasoning: {}", plan.reasoning);
    
    for agent_config in &plan.agents {
        println!("Agent: {} ({})", agent_config.name, agent_config.role);
    }
}
```

### Accessing Spawned Agents

You can also examine the agents that were created:

```rust
for spawned in auto_forest.spawned_agents() {
    println!("Agent: {}", spawned.config.name);
    println!("Role: {}", spawned.config.role);
    println!("Result: {:?}", spawned.result);
}
```

## Use Cases

### 1. Data Analysis
**Task**: "Analyze customer feedback data and identify pain points"

AutoForest might spawn:
- **Sentiment Analyzer**: Processes emotional tone
- **Pattern Recognizer**: Identifies recurring themes
- **Priority Ranker**: Orders issues by importance

### 2. Report Generation
**Task**: "Create a comprehensive market analysis report"

AutoForest might spawn:
- **Market Researcher**: Gathers market data
- **Analyst**: Interprets findings
- **Writer**: Synthesizes into coherent report

### 3. Problem Solving
**Task**: "Troubleshoot performance issues in our application"

AutoForest might spawn:
- **Log Analyzer**: Examines error logs
- **Performance Profiler**: Identifies bottlenecks
- **Solution Designer**: Proposes fixes

### 4. Content Generation
**Task**: "Create marketing copy for different audience segments"

AutoForest might spawn:
- **Copywriter-B2B**: Creates business-focused content
- **Copywriter-Consumer**: Creates consumer-focused content
- **Editor**: Reviews and harmonizes

## Advanced Features

### Planned Tool Assignment

The orchestrator plans for tool assignments among agents:

```rust
let auto_forest = AutoForest::new(config)
    .with_tools(vec![
        Box::new(CalculatorTool),        // Tool 0
        Box::new(FileReadTool),          // Tool 1
        Box::new(HttpRequestTool),       // Tool 2
        Box::new(TextProcessorTool),     // Tool 3
    ])
    .build()
    .await?;

// The orchestrator plans which tools go to which agents (see Limitations)
```

The `AgentConfig.tool_indices` field indicates planned tool assignments, though tools are not currently distributed to individual agents.

### Result Aggregation

For multi-agent tasks, AutoForest automatically:

1. Collects individual agent results
2. Uses the orchestrator to synthesize findings
3. Produces a unified final answer

```
## Task Execution Summary

**Task**: Analyze quarterly data

### Agent Results:

**Analyst**: Found 15% growth in Q3...
**Forecaster**: Predicting 12% growth in Q4...
**Reporter**: Key findings show...

### Synthesized Analysis:

Combining the analyses, we can conclude...
```

## Configuration

### Creating an AutoForest Instance

```rust
// Step 1: Create or load config
let config = Config::builder()
    .model("gpt-4")
    .temperature(0.7)
    .max_tokens(2048)
    .build();

// Step 2: Create AutoForest with tools
let auto_forest = AutoForest::new(config)
    .with_tools(vec![
        Box::new(CalculatorTool),
        Box::new(FileReadTool),
        // ... more tools
    ])
    .build()
    .await?;

// Step 3: Execute tasks
let result = auto_forest.execute_task("Your task here").await?;
```

## How the Orchestrator Makes Decisions

The orchestrator uses the following factors to decide:

1. **Task Complexity**: More complex tasks get more agents
2. **Tool Count**: More tools allow for specialization
3. **Subtask Identification**: Breaking down into discrete subtasks
4. **Role Specialization**: Assigning experts to specific domains

The orchestrator generates a JSON-based plan that includes:
- Agent count (1-5)
- Individual agent configurations
- Task breakdown
- Reasoning for decisions

## Best Practices

### 1. Provide Clear Task Descriptions

❌ **Poor**: "Analyze this"
✅ **Good**: "Analyze Q3 sales data to identify product categories with declining revenue and forecast Q4 trends"

### 2. Include Relevant Tools

Provide tools that are actually useful for the task:

```rust
// ✅ Good - tools align with task
.with_tools(vec![
    Box::new(CalculatorTool),
    Box::new(FileReadTool),
])

// ❌ Not ideal - irrelevant tools
.with_tools(vec![
    Box::new(HttpRequestTool),  // Not relevant for local analysis
])
```

### 3. Monitor Orchestration Plans

Check the generated plans to understand how AutoForest is organizing work:

```rust
if let Some(plan) = auto_forest.orchestration_plan() {
    println!("Orchestration reasoning: {}", plan.reasoning);
}
```

### 4. Start Simple, Scale Up

Begin with simpler tasks to understand how AutoForest works:

```rust
// Test with simpler task first
let simple_result = auto_forest.execute_task("Calculate 15 * 7 + 20").await?;

// Then try more complex tasks
let complex_result = auto_forest.execute_task("Complex analysis task").await?;
```

## Limitations & Considerations

### Current Limitations

1. **Tool Distribution**: While the orchestration plan includes tool assignments, tools currently cannot be cloned and individually assigned to agents. All agents work without direct tool access, relying on LLM capabilities and the task descriptions provided by the orchestrator.
   
2. **Tool Access Method**: To work around tool limitations, agents receive specialized prompts that guide them to explain what tools would be needed and how they would use them. This allows the orchestrator (or external systems) to delegate actual tool execution.

3. **Agent Count Cap**: Maximum 5 agents per orchestration (to avoid excessive parallelization overhead).

4. **No Inter-Agent Communication**: Agents work independently without direct messaging. Communication happens only through the task breakdown and final result aggregation.

### How Agents Get Tool Information

Even though tools aren't directly assigned, agents receive:
- A specialized system prompt tailored to their role
- Information about available tools through the task description
- Guidance on what they should focus on

This allows agents to be effective specialists even without direct tool access.

### Future Enhancements

- **Tool Cloning**: Enable dynamic tool assignment by making tools Clone or using Arc
-**Real-time Planning**: Adjust orchestration plan based on agent progress
-**Inter-Agent Communication**: Allow agents to collaborate directly
-**Performance Tracking**: Learn from historical agent performance
-**Hierarchical Orchestration**: Multi-level orchestrator networks

## Troubleshooting

### Issue: AutoForest doesn't spawn expected number of agents

**Solution**: Check your task description. Clear, detailed tasks result in better planning.

### Issue: Agents don't have access to needed functionality

**Solution**: Ensure required tools are included in the `with_tools()` call. Agents rely on LLM capabilities if tools aren't available.

### Issue: Results seem incomplete or fragmented

**Solution**: AutoForest should synthesize results automatically. Check the aggregated result section of the output.

## API Reference

### AutoForest Methods

```rust
impl AutoForest {
    // Create a builder
    pub fn new(config: Config) -> AutoForestBuilder

    // Get orchestration plan
    pub fn orchestration_plan(&self) -> Option<&OrchestrationPlan>

    // Get spawned agents
    pub fn spawned_agents(&self) -> &[SpawnedAgent]

    // Execute a task
    pub async fn execute_task(&mut self, task: &str) -> Result<String>
}
```

### AutoForestBuilder Methods

```rust
impl AutoForestBuilder {
    // Set tools
    pub fn with_tools(self, tools: Vec<Box<dyn Tool>>) -> Self

    // Build the orchestrator
    pub async fn build(self) -> Result<AutoForest>
}
```

## Examples

See `examples/auto_forest_demo.rs` for a complete working example.

## FAQ

**Q: How does AutoForest decide on the number of agents?**
A: The orchestrator analyzes task complexity, available tools, and identified subtasks to determine optimal agent count (1-5).

**Q: Can I force a specific number of agents?**
A: Currently, no. AutoForest makes intelligent decisions. You can inspect the plan and provide clearer task descriptions to influence the decision.

**Q: What if I only want one agent?**
A: If the orchestrator determines one agent is sufficient, it will spawn just one. This is common for simpler tasks.

**Q: Can agents communicate with each other?**
A: Currently, agents work independently. Results are aggregated by the orchestrator, but there's no real-time inter-agent messaging.

**Q: How does result aggregation work?**
A: For multiple agents, results are collected and the orchestrator synthesizes them into a cohesive final response.

## Conclusion

AutoForest brings intelligent orchestration to multi-agent systems, automatically handling the complexity of agent spawning, configuration, and coordination. It's ideal for complex tasks that benefit from specialized agents working in parallel.

For more information, see the examples and API documentation.