Code Examples

Real-world examples of using VEX.

Basic Agent

use vex_core::{Agent, AgentConfig};
use vex_llm::MockProvider;

#[tokio::main]
async fn main() {
    let agent = Agent::new(AgentConfig {
        name: "Assistant".to_string(),
        role: "You are a helpful assistant".to_string(),
        max_depth: 3,
        spawn_shadow: false,
    });

    let llm = MockProvider::smart();
    let response = llm.ask("What is Rust?").await.unwrap();
    println!("{}", response);
}

Agent with Shadow Verification

use vex_core::{Agent, AgentConfig};
use vex_adversarial::{ShadowAgent, ShadowConfig};
use vex_llm::DeepSeekProvider;

#[tokio::main]
async fn main() {
    // Create Blue agent
    let agent = Agent::new(AgentConfig {
        name: "Researcher".to_string(),
        role: "You research topics thoroughly".to_string(),
        max_depth: 3,
        spawn_shadow: true,
    });

    // Create Red shadow
    let shadow = ShadowAgent::new(&agent, ShadowConfig {
        intensity: 0.7,
        fact_check: true,
        logic_check: true,
    });

    // Get response from LLM
    let llm = DeepSeekProvider::new(std::env::var("DEEPSEEK_API_KEY").unwrap());
    let response = llm.ask("Is water wet?").await.unwrap();

    // Verify with shadow
    let issues = shadow.detect_issues(&response);
    if issues.is_empty() {
        println!("Verified: {}", response);
    } else {
        println!("Issues found: {:?}", issues);
    }
}

Merkle Tree Verification

use vex_core::{MerkleTree, Hash, ContextPacket};

fn main() {
    // Create context packets
    let ctx1 = ContextPacket::new("First message");
    let ctx2 = ContextPacket::new("Second message");
    let ctx3 = ContextPacket::new("Third message");

    // Build Merkle tree
    let leaves = vec![
        ("ctx1".to_string(), ctx1.hash.clone()),
        ("ctx2".to_string(), ctx2.hash.clone()),
        ("ctx3".to_string(), ctx3.hash.clone()),
    ];
    let tree = MerkleTree::from_leaves(leaves);

    // Get root for verification
    let root = tree.root_hash().unwrap();
    println!("Merkle Root: {}", root);

    // Verify membership
    assert!(tree.contains(&ctx1.hash));
}

Episodic Memory with Decay

use vex_temporal::{EpisodicMemory, Episode, HorizonConfig, TimeHorizon};

fn main() {
    let mut memory = EpisodicMemory::new(HorizonConfig {
        horizon: TimeHorizon::MediumTerm,
        max_entries: 50,
        ..Default::default()
    });

    // Add memories with importance
    memory.remember("User's name is Alice", 0.9);
    memory.remember("User likes Rust", 0.7);
    memory.remember("User asked about weather", 0.3);

    // Pin critical memories
    memory.add(Episode::pinned("API key configured"));

    // Get summary for LLM context
    let summary = memory.summarize();
    println!("Context: {}", summary);
}

Consensus Voting

use vex_adversarial::{Consensus, ConsensusProtocol, Vote};

fn main() {
    let mut consensus = Consensus::new(ConsensusProtocol::SuperMajority);

    // Agents vote
    consensus.add_vote(Vote::new("agent1", true, 0.9));
    consensus.add_vote(Vote::new("agent2", true, 0.8));
    consensus.add_vote(Vote::new("agent3", false, 0.6));

    // Evaluate
    consensus.evaluate();

    println!("Reached: {}", consensus.reached);
    println!("Decision: {}", consensus.decision);
    println!("Confidence: {:.2}", consensus.confidence);
}

HTTP API Server

use vex_api::{VexServer, ServerConfig};

#[tokio::main]
async fn main() {
    let config = ServerConfig {
        host: "0.0.0.0".to_string(),
        port: 3000,
        jwt_secret: std::env::var("VEX_JWT_SECRET").unwrap(),
        ..Default::default()
    };

    let server = VexServer::new(config).await.unwrap();
    server.run().await.unwrap();
}

Rate-Limited LLM Provider

use vex_llm::{DeepSeekProvider, RateLimiter, RateLimitConfig, RateLimitedProvider};

#[tokio::main]
async fn main() {
    let provider = DeepSeekProvider::new(api_key);
    let limiter = RateLimiter::new(RateLimitConfig {
        requests_per_second: 10,
        burst_size: 20,
    });

    let limited = RateLimitedProvider::new(provider, limiter);
    
    // This will respect rate limits
    let response = limited.ask("Hello!").await.unwrap();
}