Skip to main content

combs_formats/
lib.rs

1//! # combs-formats
2//!
3//! File-format adapter layer. The runtime and model crates never touch file
4//! formats directly; they go through the [`ModelSource`] trait (the
5//! LiteRT-LM `ModelResources` equivalent). Phase 1 ships the
6//! [`safetensors`] adapter (HuggingFace `config.json` + `model.safetensors`,
7//! mmap-backed, zero-copy views). GGUF / ONNX / litertlm adapters plug in
8//! here later by implementing the same trait.
9
10mod gguf;
11mod metadata;
12mod safetensors;
13mod source;
14mod tokenizer;
15
16pub use gguf::GgufSource;
17pub use metadata::{ModelMetadata, VisionConfig};
18pub use safetensors::SafetensorsSource;
19pub use source::{ModelSource, SamplerConfig, TensorDtype, TensorReader};
20pub use tokenizer::TokenizerSpec;
21
22use std::path::Path;
23
24/// Opens any supported model path: a `.gguf` file, or a directory in the
25/// HuggingFace safetensors layout. This is the single entry point the CLI,
26/// FFI and server use — format detection lives here.
27pub fn open_model_source(path: impl AsRef<Path>) -> Result<Box<dyn ModelSource>> {
28    let path = path.as_ref();
29    if path.is_file() && path.extension().is_some_and(|e| e == "gguf") {
30        return Ok(Box::new(GgufSource::load(path)?));
31    }
32    if path.is_dir() {
33        return Ok(Box::new(SafetensorsSource::load(path)?));
34    }
35    Err(FormatError::MissingFile(path.display().to_string()))
36}
37
38/// Errors produced by format adapters.
39#[derive(Debug, thiserror::Error)]
40pub enum FormatError {
41    /// An I/O error while reading model files.
42    #[error("io error: {0}")]
43    Io(#[from] std::io::Error),
44
45    /// A JSON parse error (config.json, generation_config.json, …).
46    #[error("json error in {context}: {source}")]
47    Json {
48        /// Which file/section failed to parse.
49        context: String,
50        /// The underlying serde error.
51        source: serde_json::Error,
52    },
53
54    /// The safetensors container is malformed.
55    #[error("safetensors error: {0}")]
56    Safetensors(String),
57
58    /// A requested tensor does not exist in the source.
59    #[error("tensor not found: {0}")]
60    TensorNotFound(String),
61
62    /// A tensor has an unsupported dtype for this build.
63    #[error("unsupported dtype for tensor {tensor}: {dtype}")]
64    UnsupportedDtype {
65        /// Tensor name.
66        tensor: String,
67        /// Dtype string from the container.
68        dtype: String,
69    },
70
71    /// The model directory is missing a required file.
72    #[error("missing file: {0}")]
73    MissingFile(String),
74
75    /// The config is missing a required field.
76    #[error("missing config field: {0}")]
77    MissingField(String),
78}
79
80/// Convenient result alias for this crate.
81pub type Result<T> = std::result::Result<T, FormatError>;