use std::path::{Path, PathBuf};
use anyhow::Result;
pub use crate::gguf_resolve::{
GgufTensorNameResolver, LlamaFamilyGgufResolver, PassThroughGgufResolver,
PrefixStripGgufResolver, Qwen35NativeGgufResolver, register_gguf_tensor_resolver,
};
pub use crate::gguf_support::{
ResolveWeightsOptions, gguf_split_siblings, gguf_validate_arch, list_gguf_files_in_dir,
load_gguf_file, resolve_weights_file, resolve_weights_file_with_options,
};
pub use crate::weight_loader::{GgufLoader, WeightLoader};
pub use crate::weight_map::{WeightDrainPolicy, WeightMap};
pub use crate::weight_registry::{
LoadWeightsOptions, LoadedWeights, RegisteredFormat, WeightFormatRegistration,
format_for_extension, list_registered_formats, load_weight_map_resolved, load_weights_resolved,
open_weight_loader, register_weight_format,
};
pub type LoadOpts<'a> = LoadWeightsOptions<'a>;
pub type ResolveOpts<'a> = ResolveWeightsOptions<'a>;
pub fn default_resolve_opts<'a>() -> ResolveWeightsOptions<'a> {
ResolveWeightsOptions::default()
.prefer_substring(crate::gguf_support::DEFAULT_GGUF_PREFER_SUBSTR)
}
pub fn pick(path: impl AsRef<Path>, resolve: &ResolveWeightsOptions<'_>) -> Result<PathBuf> {
resolve_weights_file_with_options(path.as_ref(), resolve)
}
pub fn pick_default(path: impl AsRef<Path>) -> Result<PathBuf> {
pick(path, &default_resolve_opts())
}
pub fn load_weight_map(path: impl AsRef<Path>, gguf_arches: &[&str]) -> Result<WeightMap> {
let path = path.as_ref();
let file = pick_default(path)?;
if file.extension().and_then(|s| s.to_str()) == Some("gguf") {
gguf_validate_arch(&file, gguf_arches)?;
}
WeightMap::from_resolved_path(path)
}
pub fn init() {
crate::gguf_resolve::ensure_builtin_resolvers();
}
impl WeightFormatRegistration {
pub const fn new(
id: &'static str,
extensions: &'static [&'static str],
open: crate::weight_registry::WeightLoaderFactory,
) -> Self {
Self {
id,
extensions,
open,
}
}
pub fn register(self) {
register_weight_format(self);
}
}
pub fn open(path: impl AsRef<Path>) -> Result<LoadedWeights> {
open_with(LoadOpts::loader(), path)
}
pub fn open_with(opts: LoadOpts<'_>, path: impl AsRef<Path>) -> Result<LoadedWeights> {
load_weights_resolved(path.as_ref(), opts)
}
pub fn open_map(path: impl AsRef<Path>) -> Result<(PathBuf, WeightMap)> {
open_map_with(LoadOpts::map(), path)
}
pub fn open_map_with(opts: LoadOpts<'_>, path: impl AsRef<Path>) -> Result<(PathBuf, WeightMap)> {
load_weight_map_resolved(path.as_ref(), opts)
}
pub fn gguf_dir_guide(dir: &Path) -> Result<GgufDirGuide> {
let files = list_gguf_files_in_dir(dir)?;
let mut lines = Vec::new();
if files.is_empty() {
lines.push(format!("No .gguf files in {dir:?}"));
return Ok(GgufDirGuide { files, lines });
}
lines.push(format!("{} .gguf file(s) in {dir:?}:", files.len()));
for (i, p) in files.iter().enumerate() {
let name = p.file_name().and_then(|s| s.to_str()).unwrap_or("?");
lines.push(format!(" [{i}] {name}"));
}
if files.len() > 1 {
lines.push(String::new());
lines.push("Pick one:".into());
lines.push(format!(" pass exact path: {:?}", files[0]));
lines.push(" Rust: LoadOpts::map().prefer_q4_k_m()".into());
lines.push(" Rust: LoadOpts::map().gguf_index(0)".into());
lines.push(" CLI: rlx-inspect dir/ --prefer Q4_K_M".into());
}
Ok(GgufDirGuide { files, lines })
}
#[derive(Debug, Clone)]
pub struct GgufDirGuide {
pub files: Vec<PathBuf>,
pub lines: Vec<String>,
}
impl GgufDirGuide {
pub fn print(&self) {
for line in &self.lines {
println!("{line}");
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn load_opts_format_only() {
assert!(LoadOpts::map().into_map);
assert!(!LoadOpts::loader().into_map);
}
}