use serde::{Deserialize, Serialize};
use crate::records::{Capability, ExecutionMode, Modality};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[serde(rename_all = "kebab-case")]
pub enum ModelFormat {
Gguf,
GgmlBin,
Safetensors,
MlxSafetensors,
Diffusers,
OllamaStore,
Builtin,
Endpoint,
Unknown,
}
#[derive(Debug, Clone, PartialEq)]
pub struct GgufArchitectureProfile {
pub modality: Modality,
pub capabilities: Vec<Capability>,
pub execution: ExecutionMode,
}
#[derive(Debug, Clone, PartialEq)]
pub struct GgufFacts {
pub architecture: Option<String>,
pub context_length: Option<i64>,
pub has_chat_template: bool,
pub quantization: Option<String>,
}
pub fn gguf_architecture_profile(architecture: &str) -> Option<GgufArchitectureProfile> {
let profile = |modality, capabilities, execution| GgufArchitectureProfile {
modality,
capabilities,
execution,
};
let embedding = || {
Some(profile(
Modality::embedding(),
vec![Capability::embed()],
ExecutionMode::Stream,
))
};
let sees = || {
Some(profile(
Modality::text(),
vec![
Capability::chat(),
Capability::complete(),
Capability::see(),
],
ExecutionMode::Stream,
))
};
let component = |modality| Some(profile(modality, vec![], ExecutionMode::Sync));
match architecture {
"whisper" => Some(profile(
Modality::audio(),
vec![Capability::transcribe()],
ExecutionMode::Stream,
)),
"qwen2vl" | "qwen3vl" | "qwen3vlmoe" | "mllama" | "cogvlm" | "hunyuan-vl" => sees(),
"bert" | "nomic-bert" | "nomic-bert-moe" | "jina-bert-v2" | "jina-bert-v3" | "neo-bert"
| "modern-bert" | "eurobert" | "gemma-embedding" | "llama-embed" | "t5encoder" => {
embedding()
}
"clip" => component(Modality::vision()),
"wavtokenizer-dec" => component(Modality::audio()),
_ => None,
}
}
pub fn ollama_chat_profile() -> GgufArchitectureProfile {
GgufArchitectureProfile {
modality: Modality::text(),
capabilities: vec![Capability::chat(), Capability::complete()],
execution: ExecutionMode::Stream,
}
}
pub fn ollama_vision_profile() -> GgufArchitectureProfile {
GgufArchitectureProfile {
modality: Modality::text(),
capabilities: vec![
Capability::chat(),
Capability::complete(),
Capability::see(),
],
execution: ExecutionMode::Stream,
}
}
pub fn ollama_profile(has_projector: bool, architecture: Option<&str>) -> GgufArchitectureProfile {
if has_projector {
return ollama_vision_profile();
}
architecture
.and_then(gguf_architecture_profile)
.unwrap_or_else(ollama_chat_profile)
}