offline_intelligence/model_management/
mod.rs1pub mod registry;
11pub mod downloader;
12pub mod storage;
13pub mod recommendation;
14pub mod progress;
15pub mod hf_access;
16
17pub use registry::{ModelRegistry, ModelInfo, ModelPricing, ModelStatus};
18pub use downloader::{ModelDownloader, DownloadSource};
19pub use storage::{ModelStorage, StorageLocation};
20pub use recommendation::ModelRecommender;
21pub use progress::{DownloadProgress, ProgressTracker};
22pub use hf_access::{check_hf_gated_access, HfAccessStatus};
23
24use anyhow::Result;
25use std::sync::Arc;
26use tokio::sync::RwLock;
27
28use crate::config::Config;
29
30pub struct ModelManager {
32 pub registry: Arc<RwLock<ModelRegistry>>,
33 pub downloader: Arc<ModelDownloader>,
34 pub storage: Arc<ModelStorage>,
35 pub recommender: Arc<ModelRecommender>,
36}
37
38impl ModelManager {
39 pub fn new() -> Result<Self> {
40 let storage = Arc::new(ModelStorage::new()?);
41 let registry = Arc::new(RwLock::new(ModelRegistry::new(storage.clone())?));
42 let downloader = Arc::new(ModelDownloader::new(storage.clone()));
43 let recommender = Arc::new(ModelRecommender::new());
44
45 Ok(Self {
46 registry,
47 downloader,
48 storage,
49 recommender,
50 })
51 }
52
53 pub async fn initialize(&self, cfg: &Config) -> Result<()> {
55 self.registry.write().await.scan_storage().await?;
57
58 self.refresh_catalogs(cfg).await?;
60
61 let hardware = ModelRecommender::detect_hardware_profile(cfg);
65 {
66 let mut registry = self.registry.write().await;
67 let recommender = &*self.recommender;
68 registry.update_compatibility_scores(recommender, &hardware);
69 let _ = registry.save_registry().await;
71 }
72
73 Ok(())
74 }
75
76 pub async fn refresh_catalogs(&self, cfg: &Config) -> Result<()> {
78 let env_key = std::env::var("OPENROUTER_API_KEY").ok();
79 let api_key = if !cfg.openrouter_api_key.is_empty() && !cfg.openrouter_api_key.trim().is_empty() {
80 Some(cfg.openrouter_api_key.as_str())
81 } else if let Some(ref env_value) = env_key {
82 Some(env_value.as_str())
83 } else {
84 None
85 };
86
87 let mut registry = self.registry.write().await;
89 if let Some(key) = api_key {
90 if let Err(e) = registry.refresh_openrouter_catalog_from_api(key).await {
91 tracing::warn!("Failed to refresh OpenRouter catalog: {}", e);
92 }
94 } else {
95 registry.populate_default_openrouter_models().await;
97 }
98
99 if let Err(e) = registry.save_registry().await {
100 tracing::error!("Failed to save model registry after OpenRouter refresh: {}", e);
101 }
102
103 if let Err(e) = registry.refresh_huggingface_catalog_from_api(500).await {
106 tracing::warn!("Failed to refresh Hugging Face catalog: {}", e);
107 }
108 if let Err(e) = registry.save_registry().await {
109 tracing::error!("Failed to save model registry after HuggingFace refresh: {}", e);
110 }
111
112 Ok(())
113 }
114}