use crate::config::{
Capabilities, Constraints, MessageFormat, Pricing, RateLimits, VerificationStatus,
};
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
pub struct RegistryExport {
pub services: Vec<ServiceExport>,
pub families: Vec<String>,
pub models: Vec<ModelExport>,
pub stats: RegistryStats,
}
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
pub struct RegistryStats {
pub service_count: usize,
pub family_count: usize,
pub model_count: usize,
pub verified_count: usize,
pub unverified_count: usize,
}
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
pub struct ServiceExport {
pub name: String,
pub base_url: String,
pub message_format: MessageFormat,
pub rate_limits: Option<RateLimitsExport>,
pub model_count: usize,
}
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
pub struct RateLimitsExport {
pub requests_per_minute: Option<u32>,
pub tokens_per_minute: Option<u32>,
pub concurrent_requests: Option<u32>,
}
impl From<&RateLimits> for RateLimitsExport {
fn from(rl: &RateLimits) -> Self {
Self {
requests_per_minute: rl.requests_per_minute,
tokens_per_minute: rl.tokens_per_minute,
concurrent_requests: rl.concurrent_requests,
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
pub struct ModelExport {
pub id: String,
pub family: String,
pub name: String,
pub service: String,
pub version: Option<String>,
pub variant: Option<String>,
pub lab: Option<String>,
pub status: VerificationStatus,
pub capabilities: Capabilities,
pub pricing: Pricing,
pub constraints: Constraints,
pub use_cases: Vec<String>,
}
impl From<&crate::config::ModelConfig> for ModelExport {
fn from(cfg: &crate::config::ModelConfig) -> Self {
Self {
id: cfg.model.id.clone(),
family: cfg.model.family.clone(),
name: cfg.model.name.clone(),
service: cfg.model.service.clone(),
version: cfg.model.version.clone(),
variant: cfg.model.variant.clone(),
lab: cfg.model.lab.clone(),
status: cfg.model.status.clone(),
capabilities: cfg.capabilities.clone(),
pricing: cfg.pricing.clone(),
constraints: cfg.constraints.clone(),
use_cases: cfg.use_cases.clone(),
}
}
}
impl RegistryExport {
pub fn verified_only(&self) -> Self {
self.clone().into_verified_only()
}
pub fn into_verified_only(self) -> Self {
let models: Vec<ModelExport> = self
.models
.into_iter()
.filter(|m| m.status == VerificationStatus::Verified)
.collect();
let verified_count = models.len();
Self {
services: self.services,
families: self.families,
models,
stats: RegistryStats {
service_count: self.stats.service_count,
family_count: self.stats.family_count,
model_count: verified_count,
verified_count,
unverified_count: 0,
},
}
}
pub fn filter_by_family(&self, family: &str) -> Self {
self.clone().into_filter_by_family(family)
}
pub fn into_filter_by_family(self, family: &str) -> Self {
let models: Vec<ModelExport> = self
.models
.into_iter()
.filter(|m| m.family == family)
.collect();
let verified_count = models
.iter()
.filter(|m| m.status == VerificationStatus::Verified)
.count();
let model_count = models.len();
Self {
services: self.services,
families: vec![family.to_string()],
models,
stats: RegistryStats {
service_count: self.stats.service_count,
family_count: 1,
model_count,
verified_count,
unverified_count: model_count - verified_count,
},
}
}
pub fn filter_by_service(&self, service: &str) -> Self {
self.clone().into_filter_by_service(service)
}
pub fn into_filter_by_service(self, service: &str) -> Self {
let models: Vec<ModelExport> = self
.models
.into_iter()
.filter(|m| m.service == service)
.collect();
let mut families: Vec<&str> = models.iter().map(|m| m.family.as_str()).collect();
families.sort_unstable();
families.dedup();
let families: Vec<String> = families.into_iter().map(String::from).collect();
let verified_count = models
.iter()
.filter(|m| m.status == VerificationStatus::Verified)
.count();
let family_count = families.len();
let model_count = models.len();
Self {
services: self
.services
.into_iter()
.filter(|s| s.name == service)
.collect(),
families,
models,
stats: RegistryStats {
service_count: 1,
family_count,
model_count,
verified_count,
unverified_count: model_count - verified_count,
},
}
}
}