use std::time::{Duration, Instant};
use anyhow::Result;
use brainwires_agents::contract_net::{
BidEvaluationStrategy, ContractNetManager, TaskAnnouncement, TaskBid, TaskRequirements,
};
#[tokio::main]
async fn main() -> Result<()> {
println!("=== Contract-Net Bidding Protocol ===\n");
let requirements = TaskRequirements::new()
.with_capabilities(vec!["rust".to_string(), "testing".to_string()])
.with_complexity(5)
.with_priority(3);
let announcement = TaskAnnouncement::new(
"task-refactor",
"Refactor error handling module with full test coverage",
"orchestrator",
Instant::now() + Duration::from_secs(30),
)
.with_requirements(requirements);
println!("Task announced: {}", announcement.description);
println!(
" Requirements: {:?}, complexity={}",
announcement.requirements.capabilities, announcement.requirements.complexity
);
println!(" Bidding open: {}\n", announcement.is_bidding_open());
let bid_alpha = TaskBid::new("agent-alpha", "task-refactor")
.with_capability_score(0.95) .with_load(0.6) .with_duration(Duration::from_secs(300));
let bid_beta = TaskBid::new("agent-beta", "task-refactor")
.with_capability_score(0.70) .with_load(0.1) .with_duration(Duration::from_secs(180));
let bid_gamma = TaskBid::new("agent-gamma", "task-refactor")
.with_capability_score(0.85) .with_load(0.3) .with_duration(Duration::from_secs(240));
let bids = [&bid_alpha, &bid_beta, &bid_gamma];
println!("--- Bid Scores (default weights) ---");
for bid in &bids {
println!(
" {}: score={:.3} (capability={:.2}, load={:.2}, duration={}s)",
bid.agent_id,
bid.score(),
bid.capability_score,
bid.current_load,
bid.estimated_duration.as_secs(),
);
}
println!();
let strategies: Vec<(&str, BidEvaluationStrategy)> = vec![
("HighestScore", BidEvaluationStrategy::HighestScore),
(
"FastestCompletion",
BidEvaluationStrategy::FastestCompletion,
),
("LoadBalancing", BidEvaluationStrategy::LoadBalancing),
("BestCapability", BidEvaluationStrategy::BestCapability),
];
println!("--- Winners by Strategy ---");
for (label, strategy) in strategies {
let manager = ContractNetManager::with_strategy(strategy);
let task_id = manager
.announce_task(TaskAnnouncement::new(
"",
"Refactor error handling",
"orchestrator",
Instant::now() + Duration::from_secs(30),
))
.await;
for bid in &bids {
let new_bid = TaskBid::new(&bid.agent_id, &task_id)
.with_capability_score(bid.capability_score)
.with_load(bid.current_load)
.with_duration(bid.estimated_duration);
manager
.receive_bid(new_bid)
.await
.map_err(|e| anyhow::anyhow!(e))?;
}
let winner = manager.award_task(&task_id).await;
println!(
" {:<20} => winner: {}",
label,
winner.unwrap_or_else(|| "none".into())
);
}
println!();
println!("--- Full Lifecycle Demo ---");
let manager = ContractNetManager::new();
let task_id = manager
.announce_task(TaskAnnouncement::new(
"lifecycle-task",
"Build auth module",
"orchestrator",
Instant::now() + Duration::from_secs(30),
))
.await;
manager
.receive_bid(
TaskBid::new("agent-alpha", &task_id)
.with_capability_score(0.9)
.with_load(0.2),
)
.await
.map_err(|e| anyhow::anyhow!(e))?;
let winner = manager.award_task(&task_id).await.unwrap();
println!(" Awarded to: {winner}");
manager
.accept_award(&task_id, &winner)
.await
.map_err(|e| anyhow::anyhow!(e))?;
let status = manager.get_task_status(&task_id).await;
println!(" Status after accept: {:?}", status);
manager
.complete_task(&task_id, &winner, true, Some("Auth module ready".into()))
.await
.map_err(|e| anyhow::anyhow!(e))?;
let status = manager.get_task_status(&task_id).await;
println!(" Status after complete: {:?}", status);
println!("\nContract-Net demo complete.");
Ok(())
}