use reputation_core::{Calculator, CalculatorPreset, BatchOptions};
use reputation_types::AgentDataBuilder;
use std::sync::{Arc, Mutex};
fn main() -> Result<(), Box<dyn std::error::Error>> {
println!("=== KnowThat Reputation Engine - Phase 2 Complete Guide ===\n");
println!("1. BUILDER PATTERN CONFIGURATION");
println!("--------------------------------");
demonstrate_builder_pattern()?;
println!("\n2. ENHANCED SCORE STRUCTURE");
println!("---------------------------");
demonstrate_enhanced_scores()?;
println!("\n3. BATCH PROCESSING");
println!("-------------------");
demonstrate_batch_processing()?;
println!("\n4. UTILITY METHODS");
println!("------------------");
demonstrate_utility_methods()?;
println!("\n5. COMPLETE INTEGRATION EXAMPLE");
println!("-------------------------------");
demonstrate_integration()?;
Ok(())
}
fn demonstrate_builder_pattern() -> Result<(), Box<dyn std::error::Error>> {
let default_calc = Calculator::default();
println!("Default calculator: k={}", default_calc.confidence_k());
let custom_calc = Calculator::builder()
.confidence_k(25.0)
.prior_base(55.0)
.prior_max(85.0)
.build()?;
println!("Custom calculator: k={}, base={}, max={}",
custom_calc.confidence_k(),
custom_calc.prior_base(),
custom_calc.prior_max()
);
let conservative = Calculator::builder()
.preset(CalculatorPreset::Conservative)
.build()?;
println!("Conservative preset: k={}", conservative.confidence_k());
let testing = Calculator::builder()
.preset(CalculatorPreset::Testing)
.prior_base(60.0) .build()?;
println!("Testing preset with override: k={}, base={}",
testing.confidence_k(),
testing.prior_base()
);
Ok(())
}
fn demonstrate_enhanced_scores() -> Result<(), Box<dyn std::error::Error>> {
let calc = Calculator::default();
let new_agent = AgentDataBuilder::new("did:example:new")
.with_reviews(2, 4.5)
.total_interactions(2)
.build()?;
let established_agent = AgentDataBuilder::new("did:example:established")
.with_reviews(100, 4.2)
.total_interactions(150)
.mcp_level(2)
.identity_verified(true)
.security_audit_passed(true)
.build()?;
for (name, agent) in [("New Agent", &new_agent), ("Established Agent", &established_agent)] {
let score = calc.calculate(agent)?;
println!("\n{}:", name);
println!(" Score: {:.1}", score.score);
println!(" Confidence: {:.1}% ({:?})", score.confidence * 100.0, score.level);
println!(" Is Provisional: {}", score.is_provisional);
println!(" Data Points: {}", score.data_points);
println!(" Components:");
println!(" Prior Score: {:.1}", score.components.prior_score);
println!(" Empirical Score: {:.1}", score.components.empirical_score);
if agent.mcp_level.is_some() {
let breakdown = &score.components.prior_breakdown;
println!(" Prior Breakdown:");
println!(" Base: {:.1}", breakdown.base_score);
println!(" MCP Bonus: {:.1}", breakdown.mcp_bonus);
println!(" Identity Bonus: {:.1}", breakdown.identity_bonus);
println!(" Security Audit Bonus: {:.1}", breakdown.security_audit_bonus);
println!(" Total: {:.1}", breakdown.total);
}
}
Ok(())
}
fn demonstrate_batch_processing() -> Result<(), Box<dyn std::error::Error>> {
let calc = Calculator::default();
let agents: Vec<_> = (0..20)
.map(|i| {
let mut builder = AgentDataBuilder::new(&format!("did:example:batch{}", i))
.total_interactions(i * 10);
if i > 0 {
builder = builder.with_reviews(i * 5, 3.5 + (i as f64 * 0.05));
}
if i % 3 == 0 {
builder = builder.mcp_level(1);
}
builder.build().unwrap()
})
.collect();
println!("Simple batch processing:");
let start = std::time::Instant::now();
let results = calc.calculate_batch(&agents);
let duration = start.elapsed();
let successful = results.iter().filter(|r| r.is_ok()).count();
println!(" Processed {} agents in {:?}", agents.len(), duration);
println!(" Successful: {}", successful);
println!("\nBatch with progress tracking:");
let progress_log = Arc::new(Mutex::new(Vec::new()));
let progress_clone = Arc::clone(&progress_log);
let options = BatchOptions {
chunk_size: Some(5),
fail_fast: false,
progress_callback: Some(Box::new(move |completed, total| {
progress_clone.lock().unwrap().push((completed, total));
print!(".");
std::io::Write::flush(&mut std::io::stdout()).unwrap();
})),
};
let _start = std::time::Instant::now();
let batch_result = calc.calculate_batch_with_options(&agents, options);
println!();
println!(" Total duration: {:?}", batch_result.total_duration);
println!(" Successful: {}", batch_result.successful_count);
println!(" Failed: {}", batch_result.failed_count);
println!(" Progress updates: {}", progress_log.lock().unwrap().len());
println!("\n Sample results:");
for (i, calc) in batch_result.calculations.iter().take(3).enumerate() {
if let Ok(score) = &calc.result {
println!(" Agent {}: score={:.1}, confidence={:.1}%, time={:?}",
i, score.score, score.confidence * 100.0, calc.duration);
}
}
Ok(())
}
fn demonstrate_utility_methods() -> Result<(), Box<dyn std::error::Error>> {
let calc = Calculator::default();
let agent = AgentDataBuilder::new("did:example:utility")
.with_reviews(30, 4.0)
.total_interactions(40)
.mcp_level(1)
.identity_verified(true)
.build()?;
println!("Score Explanation:");
let explanation = calc.explain_score(&agent)?;
println!("{}", explanation.explanation);
println!("\nConfidence Planning:");
let current_conf = calc.confidence_after_interactions(40, 0);
println!(" Current confidence: {:.1}%", current_conf * 100.0);
for target in [0.7, 0.8, 0.9] {
let needed = calc.interactions_for_confidence(40, target)?;
println!(" Need {} more interactions for {:.0}% confidence",
needed, target * 100.0);
}
println!("\nScore Predictions:");
let scenarios = vec![
(20, 5.0, "20 five-star reviews"),
(20, 3.0, "20 three-star reviews"),
(50, 4.0, "50 four-star reviews"),
];
for (count, rating, desc) in scenarios {
let prediction = calc.predict_score_change(&agent, count, rating)?;
println!(" {}: {:+.1} points (→ {:.1})",
desc, prediction.score_change, prediction.predicted_score);
}
println!("\nAgent Comparison:");
let competitor = AgentDataBuilder::new("did:example:competitor")
.with_reviews(100, 3.8)
.total_interactions(150)
.build()?;
let comparison = calc.compare_agents(&agent, &competitor)?;
println!(" Agent A: score={:.1}, confidence={:.1}%",
comparison.score_a, comparison.confidence_a * 100.0);
println!(" Agent B: score={:.1}, confidence={:.1}%",
comparison.score_b, comparison.confidence_b * 100.0);
println!(" Higher score: {}",
if comparison.higher_score_agent.contains("utility") { "Agent A" } else { "Agent B" });
println!(" More reliable: {}",
if comparison.more_reliable_agent.contains("utility") { "Agent A" } else { "Agent B" });
Ok(())
}
fn demonstrate_integration() -> Result<(), Box<dyn std::error::Error>> {
println!("Simulating a reputation analysis workflow...\n");
let calc = Calculator::builder()
.preset(CalculatorPreset::Default)
.build()?;
let agents = vec![
AgentDataBuilder::new("did:example:alice")
.with_reviews(50, 4.5)
.total_interactions(60)
.mcp_level(2)
.identity_verified(true)
.build()?,
AgentDataBuilder::new("did:example:bob")
.with_reviews(20, 4.8)
.total_interactions(25)
.mcp_level(1)
.build()?,
AgentDataBuilder::new("did:example:charlie")
.with_reviews(200, 3.9)
.total_interactions(300)
.security_audit_passed(true)
.build()?,
];
let batch_result = calc.calculate_batch_with_options(&agents, BatchOptions::default());
let mut best_score = 0.0;
let mut best_agent = None;
for (agent, calc_result) in agents.iter().zip(batch_result.calculations.iter()) {
if let Ok(score) = &calc_result.result {
if score.score > best_score {
best_score = score.score;
best_agent = Some(agent);
}
}
}
if let Some(best) = best_agent {
println!("Best agent: {} with score {:.1}", best.did, best_score);
let explanation = calc.explain_score(best)?;
println!("\nDetailed Analysis:");
println!("{}", explanation.explanation);
println!("\nRecommendations:");
let current_conf = calc.confidence_after_interactions(best.total_interactions, 0);
if current_conf < 0.9 {
let needed = calc.interactions_for_confidence(best.total_interactions, 0.9)?;
println!("- Gain {} more interactions to reach 90% confidence", needed);
}
let prediction = calc.predict_score_change(best, 50, 4.5)?;
println!("- Maintaining 4.5★ for 50 reviews would {:+.1} points",
prediction.score_change);
}
Ok(())
}