SharedContext

Struct SharedContext 

Source
pub struct SharedContext {
    pub data: HashMap<String, Value>,
    pub message_history: Vec<ForestMessage>,
    pub metadata: HashMap<String, String>,
}
Expand description

Shared context that can be accessed by all agents in the forest.

Fields§

§data: HashMap<String, Value>

Key-value store for shared data.

§message_history: Vec<ForestMessage>

Message history between agents.

§metadata: HashMap<String, String>

Global metadata.

Implementations§

Source§

impl SharedContext

Source

pub fn new() -> Self

Creates a new empty shared context.

Examples found in repository?
examples/send_message_tool_demo.rs (line 53)
19async fn main() -> helios_engine::Result<()> {
20    println!("📨 Helios Engine - SendMessageTool Demo");
21    println!("=======================================\n");
22
23    // Load configuration
24    let config = Config::from_file("config.toml")?;
25    println!("✓ Loaded configuration from config.toml");
26
27    // Create a simple forest with two agents
28    let mut forest = ForestBuilder::new()
29        .config(config)
30        .agent(
31            "alice".to_string(),
32            Agent::builder("alice")
33                .system_prompt("You are Alice, a helpful communication assistant."),
34        )
35        .agent(
36            "bob".to_string(),
37            Agent::builder("bob")
38                .system_prompt("You are Bob, a friendly colleague who responds to messages."),
39        )
40        .max_iterations(3)
41        .build()
42        .await?;
43
44    println!("✓ Created Forest with 2 agents: Alice and Bob");
45    println!();
46
47    // Demonstrate SendMessageTool direct messaging
48    println!("📤 Testing SendMessageTool - Direct Message:");
49    println!("---------------------------------------------");
50
51    // Create the tool for Alice
52    let message_queue = Arc::new(RwLock::new(Vec::new()));
53    let shared_context = Arc::new(RwLock::new(helios_engine::SharedContext::new()));
54
55    let send_tool = SendMessageTool::new(
56        "alice".to_string(),
57        Arc::clone(&message_queue),
58        Arc::clone(&shared_context),
59    );
60
61    // Test 1: Send a direct message from Alice to Bob
62    println!("1. Alice sends a direct message to Bob...");
63
64    let direct_message_args = serde_json::json!({
65        "to": "bob",
66        "message": "Hi Bob! How are you doing today?"
67    });
68
69    let result = send_tool.execute(direct_message_args).await?;
70    println!("   Tool result: {}", result.output);
71    println!("   Success: {}", result.success);
72
73    // Check the message queue
74    {
75        let queue = message_queue.read().await;
76        println!("   Messages in queue: {}", queue.len());
77        if let Some(msg) = queue.first() {
78            println!("   Message details:");
79            println!("     From: {}", msg.from);
80            println!("     To: {:?}", msg.to);
81            println!("     Content: {}", msg.content);
82        }
83    }
84
85    // Check shared context
86    {
87        let context = shared_context.read().await;
88        let messages = context.get_recent_messages(10);
89        println!("   Messages in shared context: {}", messages.len());
90    }
91
92    println!();
93
94    // Test 2: Send a broadcast message
95    println!("2. Alice broadcasts a message to everyone...");
96
97    let broadcast_message_args = serde_json::json!({
98        "message": "Hello everyone! This is a broadcast message from Alice."
99    });
100
101    let result2 = send_tool.execute(broadcast_message_args).await?;
102    println!("   Tool result: {}", result2.output);
103    println!("   Success: {}", result2.success);
104
105    // Check the message queue after broadcast
106    {
107        let queue = message_queue.read().await;
108        println!("   Messages in queue: {}", queue.len());
109        if let Some(msg) = queue.last() {
110            println!("   Latest message details:");
111            println!("     From: {}", msg.from);
112            println!("     To: {:?}", msg.to);
113            println!("     Content: {}", msg.content);
114        }
115    }
116
117    println!();
118
119    // Demonstrate integration with Forest messaging system
120    println!("🌲 Testing Forest Integration:");
121    println!("------------------------------");
122
123    // Clear our test queues and use the forest's messaging system
124    {
125        let mut queue = message_queue.write().await;
126        queue.clear();
127    }
128
129    println!("3. Using Forest's messaging system...");
130
131    // Send message through the forest
132    forest
133        .send_message(
134            &"alice".to_string(),
135            Some(&"bob".to_string()),
136            "Hello Bob via Forest messaging!".to_string(),
137        )
138        .await?;
139
140    // Process messages
141    forest.process_messages().await?;
142
143    // Check if Bob received the message
144    if let Some(bob) = forest.get_agent(&"bob".to_string()) {
145        let messages = bob.chat_session().messages.clone();
146        println!("   Bob's message count: {}", messages.len());
147        if let Some(last_msg) = messages.last() {
148            println!("   Bob received: {}", last_msg.content);
149        }
150    }
151
152    println!();
153
154    // Test broadcast through forest
155    println!("4. Forest broadcast message...");
156
157    forest
158        .send_message(
159            &"alice".to_string(),
160            None, // Broadcast
161            "Forest broadcast: Meeting at 3 PM!".to_string(),
162        )
163        .await?;
164
165    forest.process_messages().await?;
166
167    // Check all agents received the broadcast
168    for agent_id in ["alice", "bob"] {
169        if let Some(agent) = forest.get_agent(&agent_id.to_string()) {
170            let messages = agent.chat_session().messages.clone();
171            if let Some(last_msg) = messages.last() {
172                if last_msg.content.contains("broadcast") || last_msg.content.contains("Meeting") {
173                    println!("   {} received broadcast: {}", agent_id, last_msg.content);
174                }
175            }
176        }
177    }
178
179    println!();
180    println!("✅ SendMessageTool demo completed successfully!");
181    println!();
182    println!("Key features tested:");
183    println!("  • Direct messaging between agents");
184    println!("  • Broadcast messaging to all agents");
185    println!("  • Message queue management");
186    println!("  • Shared context integration");
187    println!("  • Forest messaging system integration");
188
189    Ok(())
190}
Source

pub fn set(&mut self, key: String, value: Value)

Sets a value in the shared context.

Source

pub fn get(&self, key: &str) -> Option<&Value>

Gets a value from the shared context.

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

pub fn remove(&mut self, key: &str) -> Option<Value>

Removes a value from the shared context.

Source

pub fn add_message(&mut self, message: ForestMessage)

Adds a message to the history.

Source

pub fn get_recent_messages(&self, limit: usize) -> &[ForestMessage]

Gets recent messages (last N messages).

Examples found in repository?
examples/send_message_tool_demo.rs (line 88)
19async fn main() -> helios_engine::Result<()> {
20    println!("📨 Helios Engine - SendMessageTool Demo");
21    println!("=======================================\n");
22
23    // Load configuration
24    let config = Config::from_file("config.toml")?;
25    println!("✓ Loaded configuration from config.toml");
26
27    // Create a simple forest with two agents
28    let mut forest = ForestBuilder::new()
29        .config(config)
30        .agent(
31            "alice".to_string(),
32            Agent::builder("alice")
33                .system_prompt("You are Alice, a helpful communication assistant."),
34        )
35        .agent(
36            "bob".to_string(),
37            Agent::builder("bob")
38                .system_prompt("You are Bob, a friendly colleague who responds to messages."),
39        )
40        .max_iterations(3)
41        .build()
42        .await?;
43
44    println!("✓ Created Forest with 2 agents: Alice and Bob");
45    println!();
46
47    // Demonstrate SendMessageTool direct messaging
48    println!("📤 Testing SendMessageTool - Direct Message:");
49    println!("---------------------------------------------");
50
51    // Create the tool for Alice
52    let message_queue = Arc::new(RwLock::new(Vec::new()));
53    let shared_context = Arc::new(RwLock::new(helios_engine::SharedContext::new()));
54
55    let send_tool = SendMessageTool::new(
56        "alice".to_string(),
57        Arc::clone(&message_queue),
58        Arc::clone(&shared_context),
59    );
60
61    // Test 1: Send a direct message from Alice to Bob
62    println!("1. Alice sends a direct message to Bob...");
63
64    let direct_message_args = serde_json::json!({
65        "to": "bob",
66        "message": "Hi Bob! How are you doing today?"
67    });
68
69    let result = send_tool.execute(direct_message_args).await?;
70    println!("   Tool result: {}", result.output);
71    println!("   Success: {}", result.success);
72
73    // Check the message queue
74    {
75        let queue = message_queue.read().await;
76        println!("   Messages in queue: {}", queue.len());
77        if let Some(msg) = queue.first() {
78            println!("   Message details:");
79            println!("     From: {}", msg.from);
80            println!("     To: {:?}", msg.to);
81            println!("     Content: {}", msg.content);
82        }
83    }
84
85    // Check shared context
86    {
87        let context = shared_context.read().await;
88        let messages = context.get_recent_messages(10);
89        println!("   Messages in shared context: {}", messages.len());
90    }
91
92    println!();
93
94    // Test 2: Send a broadcast message
95    println!("2. Alice broadcasts a message to everyone...");
96
97    let broadcast_message_args = serde_json::json!({
98        "message": "Hello everyone! This is a broadcast message from Alice."
99    });
100
101    let result2 = send_tool.execute(broadcast_message_args).await?;
102    println!("   Tool result: {}", result2.output);
103    println!("   Success: {}", result2.success);
104
105    // Check the message queue after broadcast
106    {
107        let queue = message_queue.read().await;
108        println!("   Messages in queue: {}", queue.len());
109        if let Some(msg) = queue.last() {
110            println!("   Latest message details:");
111            println!("     From: {}", msg.from);
112            println!("     To: {:?}", msg.to);
113            println!("     Content: {}", msg.content);
114        }
115    }
116
117    println!();
118
119    // Demonstrate integration with Forest messaging system
120    println!("🌲 Testing Forest Integration:");
121    println!("------------------------------");
122
123    // Clear our test queues and use the forest's messaging system
124    {
125        let mut queue = message_queue.write().await;
126        queue.clear();
127    }
128
129    println!("3. Using Forest's messaging system...");
130
131    // Send message through the forest
132    forest
133        .send_message(
134            &"alice".to_string(),
135            Some(&"bob".to_string()),
136            "Hello Bob via Forest messaging!".to_string(),
137        )
138        .await?;
139
140    // Process messages
141    forest.process_messages().await?;
142
143    // Check if Bob received the message
144    if let Some(bob) = forest.get_agent(&"bob".to_string()) {
145        let messages = bob.chat_session().messages.clone();
146        println!("   Bob's message count: {}", messages.len());
147        if let Some(last_msg) = messages.last() {
148            println!("   Bob received: {}", last_msg.content);
149        }
150    }
151
152    println!();
153
154    // Test broadcast through forest
155    println!("4. Forest broadcast message...");
156
157    forest
158        .send_message(
159            &"alice".to_string(),
160            None, // Broadcast
161            "Forest broadcast: Meeting at 3 PM!".to_string(),
162        )
163        .await?;
164
165    forest.process_messages().await?;
166
167    // Check all agents received the broadcast
168    for agent_id in ["alice", "bob"] {
169        if let Some(agent) = forest.get_agent(&agent_id.to_string()) {
170            let messages = agent.chat_session().messages.clone();
171            if let Some(last_msg) = messages.last() {
172                if last_msg.content.contains("broadcast") || last_msg.content.contains("Meeting") {
173                    println!("   {} received broadcast: {}", agent_id, last_msg.content);
174                }
175            }
176        }
177    }
178
179    println!();
180    println!("✅ SendMessageTool demo completed successfully!");
181    println!();
182    println!("Key features tested:");
183    println!("  • Direct messaging between agents");
184    println!("  • Broadcast messaging to all agents");
185    println!("  • Message queue management");
186    println!("  • Shared context integration");
187    println!("  • Forest messaging system integration");
188
189    Ok(())
190}

Trait Implementations§

Source§

impl Clone for SharedContext

Source§

fn clone(&self) -> SharedContext

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for SharedContext

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Default for SharedContext

Source§

fn default() -> Self

Returns the “default value” for a type. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> FromRef<T> for T
where T: Clone,

Source§

fn from_ref(input: &T) -> T

Converts to this type from a reference to the input type.
Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> PolicyExt for T
where T: ?Sized,

Source§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow only if self and other return Action::Follow. Read more
Source§

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow if either self or other returns Action::Follow. Read more
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more