prime-radiant 0.1.0

Universal coherence engine using sheaf Laplacian mathematics for AI safety, hallucination detection, and structural consistency verification in LLMs and distributed systems
//! LLM Response Validation Example
//!
//! This example demonstrates how to use Prime-Radiant's sheaf coherence
//! to validate LLM responses against their context.
//!
//! The validator:
//! 1. Converts context and response embeddings into sheaf graph nodes
//! 2. Adds edges with semantic consistency constraints
//! 3. Computes coherence energy
//! 4. Produces a validation result with witness record for audit
//!
//! Run with: `cargo run --example llm_validation --features ruvllm`

#[cfg(feature = "ruvllm")]
use prime_radiant::ruvllm_integration::{
    EdgeWeights, SheafCoherenceValidator, ValidationContext, ValidatorConfig,
};

#[cfg(feature = "ruvllm")]
fn main() {
    println!("=== Prime-Radiant: LLM Validation Example ===\n");

    // Example 1: Coherent response (passes validation)
    println!("--- Example 1: Coherent LLM Response ---");
    run_coherent_validation();

    println!();

    // Example 2: Incoherent response (fails validation)
    println!("--- Example 2: Incoherent LLM Response ---");
    run_incoherent_validation();

    println!();

    // Example 3: Validation with supporting evidence
    println!("--- Example 3: Validation with Supporting Evidence ---");
    run_validation_with_support();

    println!();

    // Example 4: Demonstrate witness generation
    println!("--- Example 4: Witness Generation for Audit Trail ---");
    run_witness_example();
}

#[cfg(not(feature = "ruvllm"))]
fn main() {
    println!("This example requires the 'ruvllm' feature.");
    println!("Run with: cargo run --example llm_validation --features ruvllm");
}

#[cfg(feature = "ruvllm")]
fn run_coherent_validation() {
    // Create a validator with default configuration
    let mut validator = SheafCoherenceValidator::with_defaults();

    // Create context and response embeddings
    // In practice, these would come from an embedding model
    // Here we simulate a coherent scenario: response is very similar to context

    let context_embedding = create_embedding(64, 1.0, 0.5);
    let response_embedding = create_embedding(64, 1.0, 0.5); // Same as context

    let ctx = ValidationContext::new()
        .with_context_embedding(context_embedding)
        .with_response_embedding(response_embedding)
        .with_scope("general")
        .with_metadata("model", "example-llm")
        .with_metadata("prompt_type", "factual_qa");

    // Validate the response
    match validator.validate(&ctx) {
        Ok(result) => {
            println!("Validation Context:");
            println!("  Embedding dimension: {}", ctx.embedding_dim());
            println!("  Scope: {}", ctx.scope);
            println!();
            println!("Validation Result:");
            println!("  Allowed: {}", result.allowed);
            println!("  Energy: {:.6}", result.energy);
            println!("  Reason: {}", result.reason.as_deref().unwrap_or("N/A"));
            println!();
            println!("Witness:");
            println!("  ID: {}", result.witness.id);
            println!("  Energy at validation: {:.6}", result.witness.energy);
            println!("  Decision allowed: {}", result.witness.decision.allowed);
            println!(
                "  Integrity verified: {}",
                result.witness.verify_integrity()
            );

            if result.allowed {
                println!();
                println!("  -> Response passed coherence validation!");
            }
        }
        Err(e) => {
            println!("Validation failed: {}", e);
        }
    }
}

#[cfg(feature = "ruvllm")]
fn run_incoherent_validation() {
    // Configure a strict validator
    let config = ValidatorConfig {
        default_dim: 64,
        reflex_threshold: 0.01, // Very strict - low energy required
        retrieval_threshold: 0.05,
        heavy_threshold: 0.1,
        include_supporting: false,
        create_cross_support_edges: false,
    };

    let mut validator = SheafCoherenceValidator::with_defaults().with_config(config);

    // Create DIFFERENT embeddings to simulate incoherent response
    // This could represent:
    // - A hallucinated response not supported by context
    // - An off-topic response
    // - Factually inconsistent information

    let context_embedding = create_embedding(64, 1.0, 0.0); // Context about topic A
    let response_embedding = create_embedding(64, -1.0, 0.5); // Response about opposite topic

    let ctx = ValidationContext::new()
        .with_context_embedding(context_embedding)
        .with_response_embedding(response_embedding)
        .with_scope("strict")
        .with_edge_weights(EdgeWeights::strict()) // Use strict weights
        .with_metadata("model", "example-llm")
        .with_metadata("risk_level", "high");

    match validator.validate(&ctx) {
        Ok(result) => {
            println!("Validation Context:");
            println!("  Embedding dimension: {}", ctx.embedding_dim());
            println!("  Edge weights: Strict mode");
            println!();
            println!("Validation Result:");
            println!("  Allowed: {}", result.allowed);
            println!("  Energy: {:.6}", result.energy);
            println!("  Reason: {}", result.reason.as_deref().unwrap_or("N/A"));
            println!();

            if !result.allowed {
                println!("  -> Response REJECTED due to high incoherence!");
                println!("     The response embedding differs significantly from context.");
                println!("     In a real system, this might indicate:");
                println!("     - Hallucination (making up facts)");
                println!("     - Off-topic response");
                println!("     - Contradiction with given context");
            }
        }
        Err(e) => {
            println!("Validation failed: {}", e);
        }
    }
}

#[cfg(feature = "ruvllm")]
fn run_validation_with_support() {
    // Configure validator to include supporting embeddings
    let config = ValidatorConfig {
        default_dim: 64,
        reflex_threshold: 0.3,
        retrieval_threshold: 0.6,
        heavy_threshold: 0.9,
        include_supporting: true,         // Enable supporting evidence
        create_cross_support_edges: true, // Create edges between support docs
    };

    let mut validator = SheafCoherenceValidator::with_defaults().with_config(config);

    // Create embeddings: context, response, and retrieved support documents
    let context_embedding = create_embedding(64, 0.8, 0.3);
    let response_embedding = create_embedding(64, 0.75, 0.35); // Similar to context

    // Supporting documents (e.g., from RAG retrieval)
    let support_1 = create_embedding(64, 0.85, 0.28); // Close to context
    let support_2 = create_embedding(64, 0.78, 0.32); // Also close

    let ctx = ValidationContext::new()
        .with_context_embedding(context_embedding)
        .with_response_embedding(response_embedding)
        .with_supporting_embedding(support_1)
        .with_supporting_embedding(support_2)
        .with_scope("rag_qa")
        .with_metadata("retriever", "dense_passage")
        .with_metadata("num_docs", "2");

    match validator.validate(&ctx) {
        Ok(result) => {
            println!("Validation with Supporting Evidence:");
            println!("  Context embedding: 64 dimensions");
            println!("  Response embedding: 64 dimensions");
            println!("  Supporting documents: 2");
            println!();
            println!("Sheaf Graph Structure:");
            println!("  - Context node connected to Response");
            println!("  - Context node connected to each Support doc");
            println!("  - Response node connected to each Support doc");
            println!("  - Support docs connected to each other (cross-edges enabled)");
            println!();
            println!("Validation Result:");
            println!("  Allowed: {}", result.allowed);
            println!("  Energy: {:.6}", result.energy);
            println!();

            // Show edge breakdown
            if !result.edge_breakdown.is_empty() {
                println!("Edge Energy Breakdown:");
                for (edge_type, energy) in &result.edge_breakdown {
                    println!("  {}: {:.6}", edge_type, energy);
                }
            }
        }
        Err(e) => {
            println!("Validation failed: {}", e);
        }
    }
}

#[cfg(feature = "ruvllm")]
fn run_witness_example() {
    let mut validator = SheafCoherenceValidator::with_defaults();

    let context_embedding = create_embedding(64, 1.0, 0.0);
    let response_embedding = create_embedding(64, 0.9, 0.1);

    let ctx = ValidationContext::new()
        .with_context_embedding(context_embedding)
        .with_response_embedding(response_embedding)
        .with_scope("audit_example")
        .with_metadata("user_id", "user_12345")
        .with_metadata("session_id", "sess_abc");

    match validator.validate(&ctx) {
        Ok(result) => {
            println!("Witness Record for Audit Trail:");
            println!("================================");
            println!();
            println!("Witness ID: {}", result.witness.id);
            println!("Timestamp: {:?}", result.witness.timestamp);
            println!();
            println!("Content Hashes (for integrity verification):");
            println!("  Context hash: {}", result.witness.context_hash);
            println!("  Response hash: {}", result.witness.response_hash);
            println!("  Fingerprint: {}", result.witness.fingerprint);
            println!();
            println!("Decision Details:");
            println!("  Scope: {}", result.witness.scope);
            println!("  Allowed: {}", result.witness.decision.allowed);
            println!(
                "  Compute lane: {} (0=Reflex, 1=Retrieval, 2=Heavy, 3=Human)",
                result.witness.decision.lane
            );
            println!("  Confidence: {:.4}", result.witness.decision.confidence);
            println!("  Energy: {:.6}", result.witness.energy);
            println!();
            println!("Integrity Verification:");
            println!("  Hash matches: {}", result.witness.verify_integrity());
            println!();
            println!("Request Correlation:");
            println!("  Request ID: {}", result.request_id);
            println!();
            println!("This witness record provides:");
            println!("  - Cryptographic proof of the validation decision");
            println!("  - Content hashes for tamper detection");
            println!("  - Correlation ID for request tracing");
            println!("  - Energy metrics for monitoring");
        }
        Err(e) => {
            println!("Validation failed: {}", e);
        }
    }
}

/// Helper function to create a test embedding
/// base_value and variation control the embedding pattern
#[cfg(feature = "ruvllm")]
fn create_embedding(dim: usize, base_value: f32, variation: f32) -> Vec<f32> {
    (0..dim)
        .map(|i| {
            let angle = (i as f32) * std::f32::consts::PI / (dim as f32);
            base_value * angle.cos() + variation * angle.sin()
        })
        .collect()
}