forest_of_agents/
forest_of_agents.rs

1//! # Forest of Agents Example
2//!
3//! This example demonstrates the Forest of Agents feature with STREAMING enabled by default.
4//! Watch as multiple agents collaborate in real-time, with their responses streaming
5//! token-by-token as they think and communicate.
6//!
7//! The Forest of Agents enables:
8//! - Inter-agent communication and messaging (with streaming responses)
9//! - Task delegation between agents
10//! - Shared context and memory
11//! - Collaborative task execution with real-time output
12//!
13//! Run this example with: `cargo run --example forest_of_agents`
14
15use helios_engine::{Agent, Config, ForestBuilder};
16use std::io::{self, Write};
17
18#[tokio::main]
19async fn main() -> helios_engine::Result<()> {
20    println!("🚀 Helios Engine - Forest of Agents Demo (with Real-Time Streaming)");
21    println!("====================================================================\n");
22    println!("💡 Note: All agent responses stream in real-time, token by token!\n");
23
24    // Load configuration
25    let config = Config::from_file("config.toml")?;
26
27    // Create a Forest of Agents with specialized agents
28    // Using the improved syntax to add multiple agents at once!
29    let mut forest = ForestBuilder::new()
30        .config(config)
31        .agents(vec![
32            // Coordinator agent - manages the team and delegates tasks
33            (
34                "coordinator".to_string(),
35                Agent::builder("coordinator")
36                    .system_prompt(
37                        "You are a project coordinator. For simple tasks that you can handle yourself, \
38                        complete them directly and provide a complete response. For complex tasks that \
39                        require specialized expertise, you can delegate using the 'delegate_task' tool \
40                        to agents like 'researcher', 'writer', 'editor', and 'qa'.\n\n\
41                        When you delegate a task, WAIT for the response and then synthesize the results. \
42                        Always provide a final, complete answer to the user's request."
43                    )
44                    .max_iterations(10)
45            ),
46            // Research agent - gathers and analyzes information
47            (
48                "researcher".to_string(),
49                Agent::builder("researcher")
50                    .system_prompt(
51                        "You are a research specialist who excels at gathering information, \
52                        analyzing data, and providing insights. You work closely with the coordinator \
53                        and writer to ensure all work is based on accurate information. Use \
54                        communication tools to share your findings and request clarification when needed."
55                    )
56                    .max_iterations(10)
57            ),
58            // Writer agent - creates content and documentation
59            (
60                "writer".to_string(),
61                Agent::builder("writer")
62                    .system_prompt(
63                        "You are a skilled writer who creates clear, well-structured content and \
64                        documentation. When you receive a task, complete it fully and provide the \
65                        final written content. You can use communication tools to request information \
66                        from the researcher if needed."
67                    )
68                    .max_iterations(10)
69            ),
70            // Editor agent - reviews and improves content
71            (
72                "editor".to_string(),
73                Agent::builder("editor")
74                    .system_prompt(
75                        "You are an editor who reviews content for quality, clarity, and consistency. \
76                        When you receive content to review, provide constructive feedback and an \
77                        improved version."
78                    )
79                    .max_iterations(10)
80            ),
81            // Quality Assurance agent - validates the final output
82            (
83                "qa".to_string(),
84                Agent::builder("qa")
85                    .system_prompt(
86                        "You are a quality assurance specialist who validates that all requirements \
87                        are met and the output is accurate and complete. When you receive content to \
88                        review, verify it meets all requirements and provide your assessment."
89                    )
90                    .max_iterations(10)
91            ),
92        ])
93        .max_iterations(15)
94        .build()
95        .await?;
96
97    println!("✅ Created Forest of Agents with 5 specialized agents:");
98    println!("  • 🎯 Coordinator: Manages projects and delegates tasks");
99    println!("  • 🔬 Researcher: Gathers and analyzes information");
100    println!("  • ✍️  Writer: Creates content and documentation");
101    println!("  • 📝 Editor: Reviews and improves content quality");
102    println!("  • ✅ QA: Validates requirements and final output");
103    println!();
104
105    // Demonstrate collaborative task execution with streaming
106    println!("🎯 TASK: Create a brief guide on sustainable gardening");
107    println!("{}", "=".repeat(70));
108    println!();
109
110    println!("🎬 Starting collaborative task execution...");
111    println!("   (Watch the responses stream in real-time!)\n");
112
113    // Simpler task for demonstration - DISABLED TOOLS FOR TESTING
114    let task = "Create a brief guide (2-3 paragraphs) on sustainable gardening. \
115                Include key benefits and one practical technique.";
116
117    println!("📋 Task Description:");
118    println!("   {}\n", task);
119
120    println!("{}", "─".repeat(70));
121    println!("🤖 COORDINATOR (streaming response):");
122    print!("   ");
123    io::stdout().flush()?;
124
125    let _result = forest
126        .execute_collaborative_task(
127            &"coordinator".to_string(),
128            task.to_string(),
129            vec![
130                "researcher".to_string(),
131                "writer".to_string(),
132                "editor".to_string(),
133                "qa".to_string(),
134            ],
135        )
136        .await?;
137
138    println!();
139    println!("{}", "─".repeat(70));
140    println!();
141    println!("✨ Collaborative task completed!");
142    println!();
143
144    // Demonstrate direct agent communication with streaming
145    println!("💬 Testing direct agent-to-agent communication with streaming:");
146    println!("{}", "─".repeat(70));
147    println!();
148
149    let mut forest_clone = forest;
150
151    // Test a simple chat to show streaming
152    println!("📤 Sending task to Writer agent...");
153    println!("🤖 WRITER (streaming response):");
154    print!("   ");
155    io::stdout().flush()?;
156
157    if let Some(writer) = forest_clone.get_agent_mut(&"writer".to_string()) {
158        let _response = writer
159            .chat("Write one short paragraph about composting.")
160            .await?;
161        println!();
162    }
163
164    println!();
165    println!("{}", "─".repeat(70));
166    println!();
167
168    // Send a direct message between agents
169    println!("📤 Coordinator → Researcher: Direct message");
170    forest_clone
171        .send_message(
172            &"coordinator".to_string(),
173            Some(&"researcher".to_string()),
174            "Great job on the research! The information was very helpful.".to_string(),
175        )
176        .await?;
177
178    forest_clone.process_messages().await?;
179
180    if let Some(researcher) = forest_clone.get_agent(&"researcher".to_string()) {
181        let messages = researcher.chat_session().messages.clone();
182        if let Some(last_msg) = messages.last() {
183            println!("📥 Researcher received: \"{}\"", last_msg.content);
184        }
185    }
186    println!();
187
188    // Demonstrate shared context
189    println!("🧠 Shared Context Demo:");
190    println!("{}", "─".repeat(70));
191    forest_clone
192        .set_shared_context(
193            "project_status".to_string(),
194            serde_json::json!({
195                "name": "Sustainable Gardening Guide",
196                "status": "completed",
197                "contributors": ["coordinator", "researcher", "writer"],
198                "completion_date": "2025-11-03"
199            }),
200        )
201        .await;
202
203    let context = forest_clone.get_shared_context().await;
204    if let Some(status) = context.get("project_status") {
205        println!("📊 Shared project status:");
206        println!("{}", serde_json::to_string_pretty(&status).unwrap());
207    }
208    println!();
209
210    println!("{}", "=".repeat(70));
211    println!("✅ Forest of Agents Demo Completed Successfully!");
212    println!("{}", "=".repeat(70));
213    println!();
214    println!("🎉 Key Features Demonstrated:");
215    println!("  ✓ Real-time streaming responses from all agents");
216    println!("  ✓ Multi-agent collaboration on tasks");
217    println!("  ✓ Inter-agent communication (direct messages)");
218    println!("  ✓ Task delegation and coordination");
219    println!("  ✓ Shared context and memory");
220    println!("  ✓ Specialized agent roles working together");
221    println!();
222    println!("💡 Notice how all responses streamed token-by-token in real-time!");
223    println!("   This provides immediate feedback and better user experience.");
224
225    Ok(())
226}