128 lines
4.0 KiB
Rust
128 lines
4.0 KiB
Rust
|
|
//! # Swarm Task Assignment Example
|
||
|
|
//!
|
||
|
|
//! Demonstrates how tasks are assigned to agents with load balancing.
|
||
|
|
//!
|
||
|
|
//! ## What This Example Shows
|
||
|
|
//! - Submitting tasks for swarm bidding
|
||
|
|
//! - Load-aware agent selection
|
||
|
|
//! - Task assignment with capability filtering
|
||
|
|
//! - Viewing assignment decisions
|
||
|
|
//!
|
||
|
|
//! ## Run
|
||
|
|
//! ```bash
|
||
|
|
//! cargo run --example 02-task-assignment -p vapora-swarm
|
||
|
|
//! ```
|
||
|
|
|
||
|
|
use vapora_swarm::{AgentProfile, SwarmCoordinator};
|
||
|
|
|
||
|
|
fn main() {
|
||
|
|
println!("=== Swarm Task Assignment Example ===\n");
|
||
|
|
|
||
|
|
// Step 1: Create coordinator and register agents
|
||
|
|
let coordinator = SwarmCoordinator::new();
|
||
|
|
|
||
|
|
let agents = vec![
|
||
|
|
AgentProfile {
|
||
|
|
id: "agent-1".to_string(),
|
||
|
|
roles: vec!["developer".to_string()],
|
||
|
|
capabilities: vec!["coding".to_string(), "testing".to_string()],
|
||
|
|
current_load: 0.20,
|
||
|
|
success_rate: 0.92,
|
||
|
|
availability: true,
|
||
|
|
},
|
||
|
|
AgentProfile {
|
||
|
|
id: "agent-2".to_string(),
|
||
|
|
roles: vec!["developer".to_string()],
|
||
|
|
capabilities: vec!["coding".to_string(), "documentation".to_string()],
|
||
|
|
current_load: 0.10,
|
||
|
|
success_rate: 0.85,
|
||
|
|
availability: true,
|
||
|
|
},
|
||
|
|
AgentProfile {
|
||
|
|
id: "agent-3".to_string(),
|
||
|
|
roles: vec!["reviewer".to_string()],
|
||
|
|
capabilities: vec!["code_review".to_string()],
|
||
|
|
current_load: 0.00,
|
||
|
|
success_rate: 0.98,
|
||
|
|
availability: true,
|
||
|
|
},
|
||
|
|
];
|
||
|
|
|
||
|
|
println!("Registering agents:");
|
||
|
|
for agent in &agents {
|
||
|
|
coordinator.register_agent(agent.clone()).ok();
|
||
|
|
println!(
|
||
|
|
" ✓ {} (load: {:.0}%, success: {:.0}%)",
|
||
|
|
agent.id,
|
||
|
|
agent.current_load * 100.0,
|
||
|
|
agent.success_rate * 100.0
|
||
|
|
);
|
||
|
|
}
|
||
|
|
|
||
|
|
// Step 2: Submit tasks for assignment
|
||
|
|
println!("\n=== Task Submissions ===\n");
|
||
|
|
|
||
|
|
let tasks = vec![
|
||
|
|
("task-001", "coding", vec!["coding".to_string()]),
|
||
|
|
("task-002", "code_review", vec!["code_review".to_string()]),
|
||
|
|
("task-003", "coding", vec!["coding".to_string()]),
|
||
|
|
(
|
||
|
|
"task-004",
|
||
|
|
"documentation",
|
||
|
|
vec!["documentation".to_string()],
|
||
|
|
),
|
||
|
|
];
|
||
|
|
|
||
|
|
for (task_id, description, required_capabilities) in &tasks {
|
||
|
|
println!("Task: {} ({})", task_id, description);
|
||
|
|
println!(" Required capabilities: {:?}", required_capabilities);
|
||
|
|
|
||
|
|
// In real scenario, this would call coordinator.submit_task_for_bidding
|
||
|
|
// For now, show the assignment logic
|
||
|
|
|
||
|
|
// Filter eligible agents
|
||
|
|
let eligible: Vec<_> = agents
|
||
|
|
.iter()
|
||
|
|
.filter(|a| {
|
||
|
|
required_capabilities
|
||
|
|
.iter()
|
||
|
|
.any(|cap| a.capabilities.contains(cap))
|
||
|
|
})
|
||
|
|
.collect();
|
||
|
|
|
||
|
|
println!(" Eligible agents: {}", eligible.len());
|
||
|
|
|
||
|
|
// Score agents
|
||
|
|
let mut scored: Vec<_> = eligible
|
||
|
|
.iter()
|
||
|
|
.map(|a| {
|
||
|
|
let score = a.success_rate / (1.0 + a.current_load);
|
||
|
|
(a, score)
|
||
|
|
})
|
||
|
|
.collect();
|
||
|
|
|
||
|
|
scored.sort_by(|a, b| b.1.partial_cmp(&a.1).unwrap_or(std::cmp::Ordering::Equal));
|
||
|
|
|
||
|
|
if let Some((best, score)) = scored.first() {
|
||
|
|
println!(" ✓ Assigned to: {} (score: {:.3})", best.id, score);
|
||
|
|
}
|
||
|
|
println!();
|
||
|
|
}
|
||
|
|
|
||
|
|
// Step 3: Show swarm statistics
|
||
|
|
println!("=== Swarm Statistics ===");
|
||
|
|
let stats = coordinator.get_swarm_stats();
|
||
|
|
println!("Total agents: {}", stats.total_agents);
|
||
|
|
println!("Available agents: {}", stats.available_agents);
|
||
|
|
println!("Average load: {:.2}%", stats.avg_load * 100.0);
|
||
|
|
println!("Active tasks: {}", stats.active_tasks);
|
||
|
|
|
||
|
|
// Step 4: Load distribution
|
||
|
|
println!("\n=== Load Distribution ===");
|
||
|
|
for agent in &agents {
|
||
|
|
let bar_length = (agent.current_load * 20.0) as usize;
|
||
|
|
let bar = "█".repeat(bar_length) + &"░".repeat(20 - bar_length);
|
||
|
|
println!(" {}: {} {:.0}%", agent.id, bar, agent.current_load * 100.0);
|
||
|
|
}
|
||
|
|
}
|