use super::ApiState;
use anyhow::{anyhow, Result};
use std::sync::Arc;
use uuid::Uuid;
pub async fn get_production_model_version(state: &ApiState) -> Result<Uuid> {
let models = state.models.read().await;
if models.is_empty() {
return Err(anyhow!("No models available"));
}
let mut best_model: Option<(Uuid, f64)> = None;
for (uuid, model) in models.iter() {
if !model.is_trained() {
continue; }
let stats = model.get_stats();
let mut score = 0.0;
if stats.is_trained {
score += 100.0;
}
score += (stats.num_entities as f64).ln() * 10.0;
score += (stats.num_relations as f64).ln() * 10.0;
if let Some(last_training) = &stats.last_training_time {
let days_since_training = (chrono::Utc::now() - *last_training).num_days();
if days_since_training <= 30 {
score += 20.0; }
}
if let Some((_, best_score)) = best_model {
if score > best_score {
best_model = Some((*uuid, score));
}
} else {
best_model = Some((*uuid, score));
}
}
if let Some((uuid, _)) = best_model {
Ok(uuid)
} else {
let (uuid, _) = models.iter().next().expect("models should not be empty");
Ok(*uuid)
}
}
pub fn validate_api_key(api_key: &str, state: &ApiState) -> bool {
if !state.config.auth.require_api_key {
return true;
}
if state.config.auth.api_keys.contains(&api_key.to_string()) {
return true;
}
false
}
pub fn calculate_cache_hit_rate(hits: usize, total: usize) -> f64 {
if total == 0 {
0.0
} else {
(hits as f64 / total as f64) * 100.0
}
}
pub async fn get_production_model<T>(
_registry: &T,
) -> Result<Arc<dyn crate::EmbeddingModel + Send + Sync>> {
Err(anyhow!("get_production_model not yet implemented"))
}