use ai_lib_rust::protocol::ProtocolLoader;
use std::path::PathBuf;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let protocol_dir = std::env::var("AI_PROTOCOL_DIR")
.or_else(|_| std::env::var("AI_PROTOCOL_PATH"))
.unwrap_or_else(|_| {
let candidates = vec![
"ai-protocol",
"../ai-protocol",
"../../ai-protocol",
"d:\\ai-protocol",
];
for candidate in candidates {
let path = PathBuf::from(candidate).join("v1").join("providers");
if path.exists() {
return candidate.to_string();
}
}
panic!("AI_PROTOCOL_DIR not set and no protocol directory found");
});
println!("Using protocol directory: {}", protocol_dir);
std::env::set_var("AI_PROTOCOL_DIR", &protocol_dir);
let loader = ProtocolLoader::new().with_base_path(&protocol_dir);
let providers = vec!["openai", "anthropic", "gemini", "deepseek", "groq", "qwen"];
let mut errors = Vec::new();
println!("\n=== Validating Provider Manifests ===");
for provider in &providers {
print!("Validating {}... ", provider);
match loader.load_provider(provider).await {
Ok(_) => println!("✅"),
Err(e) => {
println!("❌");
errors.push(format!(" {}: {}", provider, e));
}
}
}
println!("\n=== Validating Model Registries ===");
let models_dir = PathBuf::from(&protocol_dir).join("v1").join("models");
if models_dir.exists() {
let model_files = std::fs::read_dir(&models_dir)?
.filter_map(|e| e.ok())
.filter(|e| {
e.path()
.extension()
.map(|ext| ext == "yaml" || ext == "yml" || ext == "json")
.unwrap_or(false)
})
.collect::<Vec<_>>();
for entry in model_files {
let file_name = entry.file_name();
let file_name_str = file_name.to_string_lossy();
print!("Validating model registry {}... ", file_name_str);
match std::fs::read_to_string(entry.path()) {
Ok(content) => {
let is_json = entry.path().extension().is_some_and(|e| e == "json");
let result = if is_json {
serde_json::from_str::<serde_json::Value>(&content)
.map_err(|e| e.to_string())
} else {
serde_yaml::from_str::<serde_json::Value>(&content)
.map_err(|e| e.to_string())
};
match result {
Ok(_) => println!("✅"),
Err(e) => {
println!("❌");
errors.push(format!(
" {}: Invalid {}: {}",
file_name_str,
if is_json { "JSON" } else { "YAML" },
e
));
}
}
}
Err(e) => {
println!("❌");
errors.push(format!(" {}: Read error: {}", file_name_str, e));
}
}
}
} else {
println!("Models directory not found, skipping model validation");
}
println!("\n=== Summary ===");
if errors.is_empty() {
println!("✅ All protocol files are valid!");
Ok(())
} else {
println!("❌ Found {} validation error(s):\n", errors.len());
for err in &errors {
println!("{}", err);
}
std::process::exit(1);
}
}