use std::path::PathBuf;
use anyhow::Result;
pub const DEFAULT_REPO: &str = "PulpBio/LuMamba";
pub const CHECKPOINTS: &[&str] = &[
"LuMamba_LeJEPA_reconstruction_128slices.safetensors",
"LuMamba_LeJEPA_reconstruction_300slices.safetensors",
"LuMamba_LeJEPAOnly_128slices.safetensors",
"LuMamba_ReconstructionOnly.safetensors",
];
pub fn resolve(spec: &str) -> Result<PathBuf> {
if let Some(rest) = spec.strip_prefix("hf://") {
let mut it = rest.splitn(3, '/');
match (it.next(), it.next(), it.next()) {
(Some(owner), Some(repo), Some(file))
if !owner.is_empty() && !repo.is_empty() && !file.is_empty() =>
{
fetch(&format!("{owner}/{repo}"), file)
}
_ => anyhow::bail!(
"bad HF spec '{spec}', expected hf://<owner>/<repo>/<file.safetensors>"
),
}
} else {
Ok(PathBuf::from(spec))
}
}
#[cfg(feature = "hf-download")]
pub fn download(repo: &str, file: &str) -> Result<PathBuf> {
use hf_hub::api::sync::Api;
let api = Api::new()?;
Ok(api.model(repo.to_string()).get(file)?)
}
#[cfg(feature = "hf-download")]
fn fetch(repo: &str, file: &str) -> Result<PathBuf> {
eprintln!("Fetching {repo} / {file} from HuggingFace …");
download(repo, file)
}
#[cfg(not(feature = "hf-download"))]
fn fetch(repo: &str, file: &str) -> Result<PathBuf> {
anyhow::bail!(
"hf:// weights ({repo}/{file}) require building with `--features hf-download`"
)
}