use std::sync::Arc;
use anyhow::Result;
use async_trait::async_trait;
use futures::stream::BoxStream;
use brainwires_agents::brainwires_core::{
ChatOptions, ChatResponse, Message, Provider, StreamChunk, Task, Tool, ToolContext, ToolResult,
ToolUse, Usage,
};
use brainwires_agents::brainwires_tool_system::ToolExecutor;
use brainwires_agents::{
AgentMessage, AgentPool, CommunicationHub, FileLockManager, LockType, TaskAgentConfig,
};
struct MockProvider;
#[async_trait]
impl Provider for MockProvider {
fn name(&self) -> &str {
"mock"
}
async fn chat(
&self,
_messages: &[Message],
_tools: Option<&[Tool]>,
_options: &ChatOptions,
) -> Result<ChatResponse> {
Ok(ChatResponse {
message: Message::assistant("Done"),
finish_reason: Some("stop".to_string()),
usage: Usage::default(),
})
}
fn stream_chat<'a>(
&'a self,
_messages: &'a [Message],
_tools: Option<&'a [Tool]>,
_options: &'a ChatOptions,
) -> BoxStream<'a, Result<StreamChunk>> {
Box::pin(futures::stream::empty())
}
}
struct NoOpExecutor;
#[async_trait]
impl ToolExecutor for NoOpExecutor {
async fn execute(&self, tu: &ToolUse, _ctx: &ToolContext) -> Result<ToolResult> {
Ok(ToolResult::success(tu.id.clone(), "ok".to_string()))
}
fn available_tools(&self) -> Vec<Tool> {
vec![]
}
}
#[tokio::main]
async fn main() -> Result<()> {
tracing_subscriber::fmt::init();
let hub = Arc::new(CommunicationHub::new());
let lock_manager = Arc::new(FileLockManager::new());
println!("=== Agent Pool Demo ===\n");
let pool = AgentPool::new(
5,
Arc::new(MockProvider),
Arc::new(NoOpExecutor),
Arc::clone(&hub),
Arc::clone(&lock_manager),
"/tmp/demo-project",
);
let make_config = || {
let mut cfg = TaskAgentConfig::default();
cfg.validation_config = None;
Some(cfg)
};
let id1 = pool
.spawn_agent(
Task::new("task-1", "Implement authentication module"),
make_config(),
)
.await?;
println!("Spawned agent: {id1}");
let id2 = pool
.spawn_agent(
Task::new("task-2", "Add unit tests for parser"),
make_config(),
)
.await?;
println!("Spawned agent: {id2}");
let id3 = pool
.spawn_agent(
Task::new("task-3", "Refactor error handling"),
make_config(),
)
.await?;
println!("Spawned agent: {id3}");
let stats = pool.stats().await;
println!("\nPool stats:");
println!(" Max agents: {}", stats.max_agents);
println!(" Total agents: {}", stats.total_agents);
println!(" Running: {}", stats.running);
println!(" Completed: {}", stats.completed);
let active = pool.list_active().await;
println!("\nActive agents:");
for (id, status) in &active {
println!(" {}: {}", &id[..20.min(id.len())], status);
}
println!("\nAwaiting all agent completions...");
let results = pool.await_all().await;
for (id, result) in &results {
match result {
Ok(r) => println!(
" {} => success={}, iterations={}, summary={}",
&id[..20.min(id.len())],
r.success,
r.iterations,
&r.summary[..50.min(r.summary.len())]
),
Err(e) => println!(" {} => error: {}", &id[..20.min(id.len())], e),
}
}
println!("\n=== File Lock Coordination ===");
{
let read1 = lock_manager
.acquire_lock("demo-agent-1", "src/lib.rs", LockType::Read)
.await?;
let read2 = lock_manager
.acquire_lock("demo-agent-2", "src/lib.rs", LockType::Read)
.await?;
println!("Two agents reading src/lib.rs concurrently - OK");
lock_manager
.release_lock("demo-agent-1", "src/lib.rs", LockType::Read)
.await?;
lock_manager
.release_lock("demo-agent-2", "src/lib.rs", LockType::Read)
.await?;
std::mem::forget(read1);
std::mem::forget(read2);
}
{
let _write = lock_manager
.acquire_lock("demo-agent-1", "src/lib.rs", LockType::Write)
.await?;
println!("One agent has exclusive write access to src/lib.rs - OK");
}
println!("\n=== Communication Hub ===");
hub.register_agent("listener-1".to_string()).await?;
hub.register_agent("listener-2".to_string()).await?;
hub.broadcast(
"orchestrator".to_string(),
AgentMessage::StatusUpdate {
agent_id: "orchestrator".to_string(),
status: "planning".to_string(),
details: Some("Starting cycle 1".to_string()),
},
)
.await?;
for listener in &["listener-1", "listener-2"] {
match hub.receive_message(listener).await {
Some(env) => println!(" {listener} received: {:?}", env.message),
None => println!(" {listener}: no messages"),
}
}
println!("\nAgent pool demo complete.");
Ok(())
}