use anyhow::{Context, Result};
use async_trait::async_trait;
use std::time::Duration;
use crate::model_capabilities::Pricing;
pub mod modelsdev;
pub mod openrouter;
pub mod registry;
pub use modelsdev::{ModelsDevSource, parse_modelsdev};
pub use openrouter::{OpenRouterSource, parse_openrouter};
pub use registry::{ModelRegistry, ResolvedModel, ResolvedSource};
pub(crate) const MODELS_DEV_URL: &str = "https://models.dev/api.json";
pub(crate) const OPENROUTER_URL: &str = "https://openrouter.ai/api/v1/models";
const FEED_TIMEOUT_SECS: u64 = 30;
#[derive(Debug, Clone, PartialEq)]
pub struct CatalogEntry {
pub provider: String,
pub model_id: String,
pub context_window: Option<u32>,
pub max_output_tokens: Option<u32>,
pub pricing: Option<Pricing>,
pub supports_thinking: Option<bool>,
}
#[async_trait]
pub trait ModelCatalogSource: Send + Sync {
async fn fetch(&self) -> Result<Vec<CatalogEntry>>;
}
pub(crate) fn build_feed_client() -> Result<reqwest::Client> {
reqwest::Client::builder()
.connect_timeout(Duration::from_secs(FEED_TIMEOUT_SECS))
.timeout(Duration::from_secs(FEED_TIMEOUT_SECS))
.build()
.context("failed to build model-catalog feed HTTP client")
}