Sync the online models.dev catalog into a compact ModelCatalog with
ETag caching, zstd compression, and offline fallback. ~3000 models in ~24 KiB.
If you run coding agents against many providers, you want to have fresh data. models.dev is one such source of data.
This crate downloads from models.dev, keeps only the fields we need, and
builds a reloaded_code_core::models::ModelCatalog.
- Read cache header (if present) and get the old ETag.
- Send request to models.dev with
If-None-Matchwhen ETag exists. - If server returns
304 Not Modified, load catalog from cache. - If server returns
200 OK, parse JSON, map it into catalog sources, write fresh cache, then build catalog. - If network fails, try cached data as fallback; if no valid cache exists, return an error.
use reloaded_code_models_dev::{CatalogLoadSource, ModelsDevCatalog};
#[cfg(feature = "tokio")]
async fn load_catalog() -> Result<(), Box<dyn std::error::Error>> {
let result = ModelsDevCatalog::load().await?;
match result.source {
CatalogLoadSource::Downloaded => {
println!("Downloaded fresh catalog data.")
}
CatalogLoadSource::NotModifiedCache => {
println!("Cache is already up to date.")
}
CatalogLoadSource::FallbackCache => {
println!("Network unavailable, using cached catalog data.")
}
}
if let Some(entry) = result.catalog.lookup("openai", "gpt-4") {
println!("provider api url: {}", entry.0.api_url);
println!("max input tokens: {}", entry.1.max_input);
}
Ok(())
}use reloaded_code_models_dev::{CatalogLoadSource, ModelsDevCatalog};
#[cfg(feature = "blocking")]
fn load_catalog() -> Result<(), Box<dyn std::error::Error>> {
let result = ModelsDevCatalog::load()?;
match result.source {
CatalogLoadSource::Downloaded => {
println!("Downloaded fresh catalog data.")
}
CatalogLoadSource::NotModifiedCache => {
println!("Cache is already up to date.")
}
CatalogLoadSource::FallbackCache => {
println!("Network unavailable, using cached catalog data.")
}
}
if let Some(entry) = result.catalog.lookup("openai", "gpt-4") {
println!("provider api url: {}", entry.0.api_url);
println!("max input tokens: {}", entry.1.max_input);
}
Ok(())
}use reloaded_code_models_dev::ModelsDevCatalog;
use std::path::PathBuf;
#[cfg(feature = "tokio")]
async fn load_catalog() -> Result<(), Box<dyn std::error::Error>> {
let cache_path = PathBuf::from("/tmp/models-dev.cache");
let _result = ModelsDevCatalog::load_at(&cache_path).await?;
Ok(())
}
#[cfg(feature = "blocking")]
fn load_catalog() -> Result<(), Box<dyn std::error::Error>> {
let cache_path = PathBuf::from("/tmp/models-dev.cache");
let _result = ModelsDevCatalog::load_at(&cache_path)?;
Ok(())
}use reloaded_code_models_dev::shared_cache_path;
fn print_cache_path() -> Result<(), Box<dyn std::error::Error>> {
let path = shared_cache_path()?;
println!("{}", path.display());
Ok(())
}By default, cache is stored in the platform cache directory:
- Linux:
~/.cache/reloaded-code/models.dev.catalog.v1.cache - macOS:
~/Library/Caches/reloaded-code/models.dev.catalog.v1.cache - Windows:
%LOCALAPPDATA%\reloaded-code\models.dev.catalog.v1.cache
Set RELOADED_CODE_MODELS_DEV_CACHE_PATH to override this path.
Current ballpark from a recent models.dev/api.json snapshot:
- Size: about
1.31 MiBJSON ->109 KiBserialized payload ->23.7 KiBcompressed cache - Compression: about
10.1 mswith current zstd level17 - Decompression: about
0.057 ms(57 us) in--release - Cache load into
ModelCatalog: about0.31 ms(read + decompress + decode + build)
Measured on a single core of a Ryzen 9950X3D; these are rough guidance numbers and will drift as the upstream catalog changes.
tokio(default): async runtime support.blocking: synchronous runtime support.
Exactly one runtime mode must be enabled.
Apache-2.0