# Forest of Agents - Feature Updates
## Summary
Successfully updated the Forest of Agents feature to support:
1. **Streaming by default** for `Agent.chat()` and `forest.execute_collaborative_task()`
2. **Unlimited number of agents** (clarified and demonstrated with 5 agents in the example)
## Changes Made
### 1. Agent.chat() Now Uses Streaming by Default
**File: `src/agent.rs`**
- Modified `Agent.chat()` to use streaming by default
- Added new method `execute_with_tools_streaming()` that implements streaming
- Tokens are printed to stdout in real-time as they're generated
- Provides immediate feedback to users
**Key Features:**
- First iteration uses streaming for immediate response visibility
- Subsequent iterations (for tool calls) use non-streaming for efficiency
- Automatic stdout flushing for smooth output
- Maintains full backward compatibility
### 2. Forest Collaborative Tasks Use Streaming
**File: `src/forest.rs`**
- `execute_collaborative_task()` now benefits from streaming through `Agent.chat()`
- Added agent identification labels (e.g., `[coordinator] Starting task...`)
- Added `[agent_name] Responding...` labels before each agent's turn
- Better visibility into the collaboration process
**Benefits:**
- See which agent is currently active
- Watch the collaboration unfold in real-time
- Better debugging and monitoring of agent interactions
### 3. Multiple Agents Support Demonstrated
**File: `examples/forest_of_agents.rs`**
Updated the example to showcase **5 specialized agents**:
- **Coordinator**: Manages projects and delegates tasks
- **Researcher**: Gathers and analyzes information
- **Writer**: Creates content and documentation
- **Editor**: Reviews and improves content quality (NEW)
- **QA**: Validates requirements and final output (NEW)
**Important Note:** The Forest of Agents never had a hard limit of 2 agents. The architecture has always supported unlimited agents. This update demonstrates that capability more clearly.
## Usage Examples
### Creating a Forest with Multiple Agents
```rust
use helios_engine::{Agent, Config, ForestBuilder};
let config = Config::from_file("config.toml")?;
let mut forest = ForestBuilder::new()
.config(config)
.agent("coordinator".to_string(), Agent::builder("coordinator")
.system_prompt("You are a project coordinator..."))
.agent("researcher".to_string(), Agent::builder("researcher")
.system_prompt("You are a research specialist..."))
.agent("writer".to_string(), Agent::builder("writer")
.system_prompt("You are a skilled writer..."))
.agent("editor".to_string(), Agent::builder("editor")
.system_prompt("You are an editor..."))
.agent("qa".to_string(), Agent::builder("qa")
.system_prompt("You are a QA specialist..."))
// Add as many agents as you need!
.max_iterations(10)
.build()
.await?;
```
### Running a Collaborative Task
```rust
let result = forest
.execute_collaborative_task(
&"coordinator".to_string(),
"Create a comprehensive guide on sustainable gardening".to_string(),
vec![
"researcher".to_string(),
"writer".to_string(),
"editor".to_string(),
"qa".to_string(),
],
)
.await?;
println!("Final Result:\n{}", result);
```
## Streaming Output Example
When running collaborative tasks, you'll see output like:
```
[coordinator] Starting task...
I'll break down this task and delegate to the team. Let me start by...
[streaming tokens appear in real-time...]
[researcher] Responding...
Based on my research, I've found the following key points...
[streaming tokens appear in real-time...]
[writer] Responding...
I'll now draft the content based on the research findings...
[streaming tokens appear in real-time...]
```
## Testing
All tests pass successfully:
- ✅ 10 Forest of Agents tests
- ✅ 9 Agent tests
- ✅ Code compiles without errors
- ✅ Backward compatibility maintained
Run the example:
```bash
cargo run --example forest_of_agents
```
## Technical Details
### Streaming Implementation
The streaming is implemented at the `Agent` level:
1. `Agent.chat()` calls `execute_with_tools_streaming()`
2. First iteration uses `LLMClient.chat_stream()` with a callback
3. Callback prints each token chunk and flushes stdout
4. Tool call iterations use regular non-streaming for reliability
5. Full response is returned after streaming completes
### Architecture
```
ForestBuilder
└─> ForestOfAgents
├─> Agent 1 (chat with streaming)
├─> Agent 2 (chat with streaming)
├─> Agent 3 (chat with streaming)
├─> Agent N (unlimited agents supported)
└─> SharedContext & MessageQueue
```
## Backward Compatibility
✅ **Fully Backward Compatible**
- Existing `Agent.chat()` calls work with streaming
- `send_message()` method still available
- All existing APIs unchanged
- Tool execution remains functional
## Performance Considerations
- **Streaming overhead**: Minimal - only affects output display
- **Memory usage**: Unchanged - same chat session management
- **Network**: No additional requests - streaming uses same LLM connection
- **Tool calls**: Non-streaming iterations for stability
## Latest Enhancement: Coordinator-Based Planning System
### New in v0.4.1: Structured Task Planning and Shared Memory
The Forest of Agents now includes a sophisticated coordinator-based planning system:
**New Features:**
- **TaskPlan**: Structured plans with task breakdown and dependencies
- **Shared Task Memory**: All agents can read/write to shared memory
- **create_plan tool**: Coordinator creates detailed task plans
- **update_task_memory tool**: Agents save results for others to use
- **Task Dependencies**: Ensure proper execution order
- **Progress Tracking**: Real-time monitoring of task completion
**How It Works:**
1. Coordinator analyzes the task and creates a structured plan
2. Tasks are executed in dependency order
3. Each agent updates shared memory with their results
4. Other agents can see and build upon previous work
5. Coordinator synthesizes final comprehensive result
**Example:**
```rust
let mut forest = ForestBuilder::new()
.config(config)
.agent("coordinator".to_string(), Agent::builder("coordinator")...)
.agent("researcher".to_string(), Agent::builder("researcher")...)
.agent("writer".to_string(), Agent::builder("writer")...)
.build()
.await?;
let result = forest
.execute_collaborative_task(
&"coordinator".to_string(),
"Create a comprehensive guide on renewable energy".to_string(),
vec!["researcher".to_string(), "writer".to_string()],
)
.await?;
```
**Documentation:**
- See `docs/FOREST_COORDINATOR_PLANNING.md` for complete guide
- Run `cargo run --example forest_with_coordinator` for demo
## Future Enhancements
Potential improvements:
- [ ] Option to disable streaming per agent
- [ ] Configurable streaming behavior (env var or config)
- [ ] Colored output for different agents
- [ ] Stream tool execution results
- [ ] Progress indicators for long tasks
- [ ] Log streaming output to files
- [ ] Parallel task execution for independent tasks
- [ ] Task retry logic for failed tasks
- [ ] Dynamic replanning based on results
- [ ] Visualization of task execution flow
## Files Modified
1. `src/agent.rs` - Added streaming to chat() method
2. `src/forest.rs` - Added agent labels to collaborative tasks
3. `examples/forest_of_agents.rs` - Updated to demonstrate 5 agents
## Conclusion
The Forest of Agents feature now provides:
✅ Real-time streaming output by default
✅ Support for unlimited agents (no restrictions)
✅ Better visibility into agent collaboration
✅ Improved user experience with immediate feedback
✅ Full backward compatibility