use crate::services::ModelService;
use anyhow::Result;
use serde::Deserialize;
use std::path::PathBuf;
#[derive(Deserialize, Default)]
struct NodeModelConfig {
model: Option<ModelInfo>,
}
#[derive(Deserialize)]
struct ModelInfo {
name: Option<String>,
}
#[derive(Deserialize)]
struct EnvironmentNodeConfig {
dev: Option<NodeModelConfig>,
production: Option<NodeModelConfig>,
}
fn parse_node_config(content: &str) -> Option<NodeModelConfig> {
let profile = std::env::var("MECHA10_ENVIRONMENT").unwrap_or_else(|_| "dev".to_string());
if let Ok(env_config) = serde_json::from_str::<EnvironmentNodeConfig>(content) {
let config = match profile.as_str() {
"production" | "prod" => env_config.production,
_ => env_config.dev,
};
return config;
}
serde_json::from_str(content).ok()
}
pub(super) async fn ensure_node_models_available(node_names: &[String]) -> Result<()> {
let model_service = match ModelService::with_models_dir("models".into()) {
Ok(service) => service,
Err(e) => {
eprintln!("⚠️ Warning: Could not initialize model service: {}", e);
return Ok(());
}
};
for node_name in node_names {
let short_name = node_name.strip_prefix("@mecha10/").unwrap_or(node_name);
let config_paths = crate::paths::config::node_config_candidates(short_name);
for config_path in &config_paths {
let path = PathBuf::from(config_path);
if !path.exists() {
continue;
}
let content = match std::fs::read_to_string(&path) {
Ok(c) => c,
Err(_) => continue,
};
let config = match parse_node_config(&content) {
Some(c) => c,
None => continue,
};
if let Some(model_info) = config.model {
if let Some(model_name) = model_info.name {
let model_path = PathBuf::from(format!("models/{}/model.onnx", model_name));
if !model_path.exists() {
println!("📦 Downloading model '{}' for node '{}'...", model_name, node_name);
match model_service.pull(&model_name, None).await {
Ok(_) => println!("✅ Model '{}' ready", model_name),
Err(e) => {
eprintln!("⚠️ Warning: Failed to download model '{}': {}", model_name, e);
eprintln!(" You can manually download with: mecha10 model pull {}", model_name);
}
}
}
}
}
break; }
}
Ok(())
}