use agent_kernel::{Agent, AgentEvent, AgentRuntime, BoxFuture, Message, discuss};
use tokio::sync::mpsc;
use tokio_util::sync::CancellationToken;
struct MockRuntime;
impl AgentRuntime for MockRuntime {
fn respond<'a>(
&'a self,
agent: &'a Agent,
history: &'a [Message],
) -> BoxFuture<'a, anyhow::Result<String>> {
Box::pin(async move {
Ok(format!(
"[{}] I've seen {} messages. My take: this is interesting.",
agent.name,
history.len()
))
})
}
}
#[tokio::main]
async fn main() -> anyhow::Result<()> {
let runtime = MockRuntime;
let agents = vec![
Agent {
name: "alice".to_string(),
soul_md: "You are Alice, a systems architect. Be concise.".to_string(),
model: "anthropic/claude-sonnet-4-6".to_string(),
},
Agent {
name: "bob".to_string(),
soul_md: "You are Bob, a security engineer. Challenge assumptions.".to_string(),
model: "anthropic/claude-sonnet-4-6".to_string(),
},
];
let (tx, mut rx) = mpsc::channel::<AgentEvent>(64);
let cancel = CancellationToken::new();
let printer = tokio::spawn(async move {
while let Some(event) = rx.recv().await {
match &event {
AgentEvent::Progress { current_round, max_rounds } => {
println!("--- Round {current_round}/{max_rounds} ---");
}
AgentEvent::Round { round, agent_name, content } => {
println!(" [{round}] {agent_name}: {content}");
}
AgentEvent::Summary { content } => {
println!("\nSummary: {content}");
}
AgentEvent::Completed => {
println!("\nDiscussion completed.");
}
AgentEvent::Converged { reason } => {
println!("\nConverged: {reason}");
}
AgentEvent::Cancelled => {
println!("\nCancelled.");
}
AgentEvent::Evolved { agent, old_version, new_version } => {
println!("\n{agent} evolved: v{old_version} -> v{new_version}");
}
}
}
});
let summary = discuss(
&runtime,
&agents,
"What are the trade-offs between microservices and a monolith?",
3,
cancel,
tx,
)
.await?;
printer.await?;
println!("\nFinal summary returned by discuss(): {summary}");
Ok(())
}