Merge commit 'd803bfe2b1fe7f5e219e50ac20d6801a0a58ac75' as 'vendor/ruvector'
This commit is contained in:
114
vendor/ruvector/examples/edge/src/bin/agent.rs
vendored
Normal file
114
vendor/ruvector/examples/edge/src/bin/agent.rs
vendored
Normal file
@@ -0,0 +1,114 @@
|
||||
//! Edge Agent Binary
|
||||
//!
|
||||
//! Run a single swarm agent that can connect to a coordinator.
|
||||
|
||||
use clap::Parser;
|
||||
use ruvector_edge::prelude::*;
|
||||
use ruvector_edge::Transport;
|
||||
use std::time::Duration;
|
||||
use tokio::signal;
|
||||
use tokio::time::interval;
|
||||
|
||||
#[derive(Parser, Debug)]
|
||||
#[command(name = "edge-agent")]
|
||||
#[command(about = "RuVector Edge Swarm Agent")]
|
||||
struct Args {
|
||||
/// Agent ID (auto-generated if not provided)
|
||||
#[arg(short, long)]
|
||||
id: Option<String>,
|
||||
|
||||
/// Agent role: coordinator, worker, scout, specialist
|
||||
#[arg(short, long, default_value = "worker")]
|
||||
role: String,
|
||||
|
||||
/// Coordinator URL to connect to
|
||||
#[arg(short, long)]
|
||||
coordinator: Option<String>,
|
||||
|
||||
/// Transport type: websocket, shared-memory
|
||||
#[arg(short, long, default_value = "shared-memory")]
|
||||
transport: String,
|
||||
|
||||
/// Sync interval in milliseconds
|
||||
#[arg(long, default_value = "1000")]
|
||||
sync_interval: u64,
|
||||
|
||||
/// Enable verbose logging
|
||||
#[arg(short, long)]
|
||||
verbose: bool,
|
||||
}
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() -> Result<()> {
|
||||
let args = Args::parse();
|
||||
|
||||
// Initialize tracing
|
||||
let level = if args.verbose { "debug" } else { "info" };
|
||||
tracing_subscriber::fmt()
|
||||
.with_env_filter(level)
|
||||
.init();
|
||||
|
||||
// Parse role
|
||||
let role = match args.role.to_lowercase().as_str() {
|
||||
"coordinator" => AgentRole::Coordinator,
|
||||
"scout" => AgentRole::Scout,
|
||||
"specialist" => AgentRole::Specialist,
|
||||
_ => AgentRole::Worker,
|
||||
};
|
||||
|
||||
// Parse transport
|
||||
let transport = match args.transport.to_lowercase().as_str() {
|
||||
"websocket" | "ws" => Transport::WebSocket,
|
||||
_ => Transport::SharedMemory,
|
||||
};
|
||||
|
||||
// Create config
|
||||
let mut config = SwarmConfig::default()
|
||||
.with_role(role)
|
||||
.with_transport(transport);
|
||||
|
||||
if let Some(id) = args.id {
|
||||
config = config.with_agent_id(id);
|
||||
}
|
||||
|
||||
if let Some(url) = &args.coordinator {
|
||||
config = config.with_coordinator(url);
|
||||
}
|
||||
|
||||
config.sync_interval_ms = args.sync_interval;
|
||||
|
||||
// Create agent
|
||||
let mut agent = SwarmAgent::new(config).await?;
|
||||
tracing::info!("Agent created: {} ({:?})", agent.id(), agent.role());
|
||||
|
||||
// Connect if coordinator URL provided
|
||||
if let Some(ref url) = args.coordinator {
|
||||
tracing::info!("Connecting to coordinator: {}", url);
|
||||
agent.join_swarm(url).await?;
|
||||
agent.start_sync_loop().await;
|
||||
} else if matches!(role, AgentRole::Coordinator) {
|
||||
tracing::info!("Running as standalone coordinator");
|
||||
}
|
||||
|
||||
// Print status periodically
|
||||
let agent_id = agent.id().to_string();
|
||||
let stats_interval = Duration::from_secs(10);
|
||||
|
||||
tokio::spawn(async move {
|
||||
let mut ticker = interval(stats_interval);
|
||||
loop {
|
||||
ticker.tick().await;
|
||||
tracing::info!("Agent {} heartbeat", agent_id);
|
||||
}
|
||||
});
|
||||
|
||||
// Wait for shutdown signal
|
||||
tracing::info!("Agent running. Press Ctrl+C to stop.");
|
||||
|
||||
signal::ctrl_c().await.expect("Failed to listen for Ctrl+C");
|
||||
|
||||
tracing::info!("Shutting down...");
|
||||
agent.leave_swarm().await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
93
vendor/ruvector/examples/edge/src/bin/coordinator.rs
vendored
Normal file
93
vendor/ruvector/examples/edge/src/bin/coordinator.rs
vendored
Normal file
@@ -0,0 +1,93 @@
|
||||
//! Edge Coordinator Binary
|
||||
//!
|
||||
//! Run a swarm coordinator that manages connected agents.
|
||||
|
||||
use clap::Parser;
|
||||
use ruvector_edge::prelude::*;
|
||||
use ruvector_edge::Transport;
|
||||
use std::time::Duration;
|
||||
use tokio::signal;
|
||||
use tokio::time::interval;
|
||||
|
||||
#[derive(Parser, Debug)]
|
||||
#[command(name = "edge-coordinator")]
|
||||
#[command(about = "RuVector Edge Swarm Coordinator")]
|
||||
struct Args {
|
||||
/// Coordinator ID
|
||||
#[arg(short, long, default_value = "coordinator-001")]
|
||||
id: String,
|
||||
|
||||
/// Listen address for WebSocket connections
|
||||
#[arg(short, long, default_value = "0.0.0.0:8080")]
|
||||
listen: String,
|
||||
|
||||
/// Transport type: websocket, shared-memory
|
||||
#[arg(short, long, default_value = "shared-memory")]
|
||||
transport: String,
|
||||
|
||||
/// Maximum connected agents
|
||||
#[arg(long, default_value = "100")]
|
||||
max_agents: usize,
|
||||
|
||||
/// Enable verbose logging
|
||||
#[arg(short, long)]
|
||||
verbose: bool,
|
||||
}
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() -> Result<()> {
|
||||
let args = Args::parse();
|
||||
|
||||
// Initialize tracing
|
||||
let level = if args.verbose { "debug" } else { "info" };
|
||||
tracing_subscriber::fmt()
|
||||
.with_env_filter(level)
|
||||
.init();
|
||||
|
||||
// Parse transport
|
||||
let transport = match args.transport.to_lowercase().as_str() {
|
||||
"websocket" | "ws" => Transport::WebSocket,
|
||||
_ => Transport::SharedMemory,
|
||||
};
|
||||
|
||||
// Create config
|
||||
let config = SwarmConfig::default()
|
||||
.with_agent_id(&args.id)
|
||||
.with_role(AgentRole::Coordinator)
|
||||
.with_transport(transport);
|
||||
|
||||
// Create coordinator agent
|
||||
let agent = SwarmAgent::new(config).await?;
|
||||
|
||||
println!("🎯 RuVector Edge Coordinator");
|
||||
println!(" ID: {}", agent.id());
|
||||
println!(" Transport: {:?}", transport);
|
||||
println!(" Max Agents: {}", args.max_agents);
|
||||
println!();
|
||||
|
||||
// Start sync loop for coordinator duties
|
||||
agent.start_sync_loop().await;
|
||||
|
||||
// Status reporting
|
||||
let stats_interval = Duration::from_secs(5);
|
||||
tokio::spawn({
|
||||
let agent_id = agent.id().to_string();
|
||||
async move {
|
||||
let mut ticker = interval(stats_interval);
|
||||
loop {
|
||||
ticker.tick().await;
|
||||
// In real implementation, would report actual peer stats
|
||||
tracing::info!("Coordinator {} status: healthy", agent_id);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
println!("✅ Coordinator running. Press Ctrl+C to stop.\n");
|
||||
|
||||
// Wait for shutdown
|
||||
signal::ctrl_c().await.expect("Failed to listen for Ctrl+C");
|
||||
|
||||
println!("\n👋 Coordinator shutting down...");
|
||||
|
||||
Ok(())
|
||||
}
|
||||
127
vendor/ruvector/examples/edge/src/bin/demo.rs
vendored
Normal file
127
vendor/ruvector/examples/edge/src/bin/demo.rs
vendored
Normal file
@@ -0,0 +1,127 @@
|
||||
//! Edge Swarm Demo
|
||||
//!
|
||||
//! Demonstrates distributed learning across multiple agents.
|
||||
|
||||
use ruvector_edge::prelude::*;
|
||||
use ruvector_edge::Transport;
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() -> Result<()> {
|
||||
// Initialize tracing
|
||||
tracing_subscriber::fmt()
|
||||
.with_env_filter("info")
|
||||
.init();
|
||||
|
||||
println!("🚀 RuVector Edge Swarm Demo\n");
|
||||
|
||||
// Create coordinator agent
|
||||
let coordinator_config = SwarmConfig::default()
|
||||
.with_agent_id("coordinator-001")
|
||||
.with_role(AgentRole::Coordinator)
|
||||
.with_transport(Transport::SharedMemory);
|
||||
|
||||
let coordinator = SwarmAgent::new(coordinator_config).await?;
|
||||
println!("✅ Coordinator created: {}", coordinator.id());
|
||||
|
||||
// Create worker agents
|
||||
let mut workers = Vec::new();
|
||||
for i in 1..=3 {
|
||||
let config = SwarmConfig::default()
|
||||
.with_agent_id(format!("worker-{:03}", i))
|
||||
.with_role(AgentRole::Worker)
|
||||
.with_transport(Transport::SharedMemory);
|
||||
|
||||
let worker = SwarmAgent::new(config).await?;
|
||||
println!("✅ Worker created: {}", worker.id());
|
||||
workers.push(worker);
|
||||
}
|
||||
|
||||
println!("\n📚 Simulating distributed learning...\n");
|
||||
|
||||
// Simulate learning across agents
|
||||
let learning_scenarios = vec![
|
||||
("edit_ts", "typescript-developer", 0.9),
|
||||
("edit_rs", "rust-developer", 0.95),
|
||||
("edit_py", "python-developer", 0.85),
|
||||
("test_run", "test-engineer", 0.8),
|
||||
("review_pr", "reviewer", 0.88),
|
||||
];
|
||||
|
||||
for (i, worker) in workers.iter().enumerate() {
|
||||
// Each worker learns from different scenarios
|
||||
for (j, (state, action, reward)) in learning_scenarios.iter().enumerate() {
|
||||
// Distribute scenarios across workers
|
||||
if j % 3 == i {
|
||||
worker.learn(state, action, *reward).await;
|
||||
println!(
|
||||
" {} learned: {} → {} (reward: {:.2})",
|
||||
worker.id(),
|
||||
state,
|
||||
action,
|
||||
reward
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
println!("\n🔄 Syncing patterns across swarm...\n");
|
||||
|
||||
// Simulate pattern sync (in real implementation, this goes over network)
|
||||
for worker in &workers {
|
||||
let state = worker.get_best_action("edit_ts", &["coder".to_string(), "typescript-developer".to_string()]).await;
|
||||
if let Some((action, confidence)) = state {
|
||||
println!(
|
||||
" {} best action for edit_ts: {} (confidence: {:.1}%)",
|
||||
worker.id(),
|
||||
action,
|
||||
confidence * 100.0
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
println!("\n💾 Storing vectors in shared memory...\n");
|
||||
|
||||
// Store some vector memories
|
||||
let embeddings = vec![
|
||||
("Authentication flow implementation", vec![0.1, 0.2, 0.8, 0.3]),
|
||||
("Database connection pooling", vec![0.4, 0.1, 0.2, 0.9]),
|
||||
("API rate limiting logic", vec![0.3, 0.7, 0.1, 0.4]),
|
||||
];
|
||||
|
||||
for (content, embedding) in embeddings {
|
||||
let id = coordinator.store_memory(content, embedding).await?;
|
||||
println!(" Stored: {} (id: {})", content, &id[..8]);
|
||||
}
|
||||
|
||||
// Search for similar vectors
|
||||
let query = vec![0.1, 0.2, 0.7, 0.4];
|
||||
let results = coordinator.search_memory(&query, 2).await;
|
||||
|
||||
println!("\n🔍 Vector search results:");
|
||||
for (content, score) in results {
|
||||
println!(" - {} (score: {:.3})", content, score);
|
||||
}
|
||||
|
||||
println!("\n📊 Swarm Statistics:\n");
|
||||
|
||||
// Print stats for each agent
|
||||
let stats = coordinator.get_stats().await;
|
||||
println!(
|
||||
" Coordinator: {} patterns, {} memories",
|
||||
stats.total_patterns, stats.total_memories
|
||||
);
|
||||
|
||||
for worker in &workers {
|
||||
let stats = worker.get_stats().await;
|
||||
println!(
|
||||
" {}: {} patterns, confidence: {:.1}%",
|
||||
worker.id(),
|
||||
stats.total_patterns,
|
||||
stats.avg_confidence * 100.0
|
||||
);
|
||||
}
|
||||
|
||||
println!("\n✨ Demo complete!\n");
|
||||
|
||||
Ok(())
|
||||
}
|
||||
Reference in New Issue
Block a user