Merge commit 'd803bfe2b1fe7f5e219e50ac20d6801a0a58ac75' as 'vendor/ruvector'

This commit is contained in:
ruv
2026-02-28 14:39:40 -05:00
7854 changed files with 3522914 additions and 0 deletions

View 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(())
}

View 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(())
}

View 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(())
}