use crate::models::registry::ModelRegistry; use anyhow::Result; use tracing::info; const MODELS_DEV_URL: &str = "https://models.dev/api.json"; pub async fn fetch_registry() -> Result { info!("Fetching model registry from {}", MODELS_DEV_URL); let client = reqwest::Client::builder() .timeout(std::time::Duration::from_secs(10)) .build()?; let response = client.get(MODELS_DEV_URL).send().await?; if !response.status().is_success() { return Err(anyhow::anyhow!("Failed to fetch registry: HTTP {}", response.status())); } let registry: ModelRegistry = response.json().await?; info!("Successfully loaded model registry"); Ok(registry) } /// Heuristic: decide whether a model should be routed to OpenAI Responses API /// instead of the legacy chat/completions endpoint. /// /// Currently this uses simple patterns (codex, gpt-5 series) and also checks /// the loaded registry metadata name for the substring "codex" as a hint. pub fn model_prefers_responses(registry: &ModelRegistry, model: &str) -> bool { let model_lc = model.to_lowercase(); if model_lc.contains("codex") { return true; } if model_lc.starts_with("gpt-5") || model_lc.contains("gpt-5.") { return true; } if let Some(meta) = registry.find_model(model) { if meta.name.to_lowercase().contains("codex") { return true; } } false }