Skip to main content

kernel/records/
identifiers.rs

1//! The vocabulary types that identify a model and its runtime.
2//!
3//! `Modality`, `Capability`, `SourceKind`, and `RuntimeId` are open string sets
4//! (new values can appear without a code change), modeled as string newtypes with
5//! constructors for the well-known values. The remaining enums are closed.
6
7macro_rules! string_id {
8    (
9        $(#[$meta:meta])*
10        $name:ident { $( $ctor:ident => $value:literal ),* $(,)? }
11    ) => {
12        $(#[$meta])*
13        #[derive(
14            Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord,
15            serde::Serialize, serde::Deserialize,
16        )]
17        #[serde(transparent)]
18        pub struct $name(String);
19
20        impl $name {
21            $(
22                #[doc = concat!("The well-known `", $value, "` value.")]
23                pub fn $ctor() -> Self {
24                    Self(String::from($value))
25                }
26            )*
27
28            /// The underlying string value.
29            pub fn as_str(&self) -> &str {
30                &self.0
31            }
32        }
33
34        impl AsRef<str> for $name {
35            fn as_ref(&self) -> &str {
36                &self.0
37            }
38        }
39
40        impl From<&str> for $name {
41            fn from(value: &str) -> Self {
42                Self(value.to_owned())
43            }
44        }
45
46        impl From<String> for $name {
47            fn from(value: String) -> Self {
48                Self(value)
49            }
50        }
51
52        impl From<$name> for String {
53            fn from(value: $name) -> Self {
54                value.0
55            }
56        }
57
58        impl std::fmt::Display for $name {
59            fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
60                formatter.write_str(&self.0)
61            }
62        }
63    };
64}
65
66string_id! {
67    /// A model's primary output modality.
68    Modality {
69        unknown => "unknown",
70        text => "text",
71        image => "image",
72        speech => "speech",
73        audio => "audio",
74        video => "video",
75        vision => "vision",
76        embedding => "embedding",
77    }
78}
79
80string_id! {
81    /// Something a model can be asked to do.
82    Capability {
83        chat => "chat",
84        complete => "complete",
85        embed => "embed",
86        see => "see",
87        image => "image",
88        speak => "speak",
89        transcribe => "transcribe",
90        tools => "tools",
91        judge => "judge",
92    }
93}
94
95string_id! {
96    /// Where a model was found or installed from.
97    SourceKind {
98        ollama => "ollama",
99        huggingface_cache => "huggingface-cache",
100        lm_studio => "lm-studio",
101        builtin => "builtin",
102        endpoint => "endpoint",
103        file => "file",
104        folder => "folder",
105    }
106}
107
108string_id! {
109    /// The identifier of a runtime adapter that can execute a model.
110    RuntimeId {
111        llama_cpp => "llama-cpp",
112        whisper_cpp => "whisper-cpp",
113        ollama => "ollama",
114        mlx_swift => "mlx-swift",
115        apple_foundation => "apple-foundation",
116        openai_endpoint => "generic:openai-server",
117        mflux => "python:mflux",
118        diffusers => "python:diffusers",
119        mlx_lm => "python:mlx-lm",
120        mlx_audio => "python:mlx-audio",
121        mlx_vlm => "python:mlx-vlm",
122        embeddings => "python:embeddings",
123        comfy_ui => "comfyui",
124        a1111 => "a1111",
125    }
126}
127
128/// How a runtime delivers a model's output.
129#[derive(
130    Debug, Clone, Copy, PartialEq, Eq, Hash, Default, serde::Serialize, serde::Deserialize,
131)]
132#[serde(rename_all = "lowercase")]
133pub enum ExecutionMode {
134    /// Tokens stream back incrementally.
135    Stream,
136    /// A long-running job produces an artifact.
137    Job,
138    /// A single synchronous request/response.
139    #[default]
140    Sync,
141}
142
143impl ExecutionMode {
144    /// The stable string form, the same one serde writes.
145    pub fn as_str(&self) -> &'static str {
146        match self {
147            ExecutionMode::Stream => "stream",
148            ExecutionMode::Job => "job",
149            ExecutionMode::Sync => "sync",
150        }
151    }
152}
153
154/// How much support a model needs before it can run.
155#[derive(
156    Debug, Clone, Copy, PartialEq, Eq, Hash, Default, serde::Serialize, serde::Deserialize,
157)]
158#[serde(rename_all = "kebab-case")]
159pub enum RunTier {
160    /// Runs directly, no extra runtime to install.
161    Native,
162    /// Runs via a managed sidecar the app provisions.
163    Managed,
164    /// Runs on a remote endpoint.
165    Remote,
166    /// Needs a runtime recipe that is not yet available.
167    #[default]
168    RecipeNeeded,
169}
170
171/// The lifecycle state of a model record.
172#[derive(
173    Debug, Clone, Copy, PartialEq, Eq, Hash, Default, serde::Serialize, serde::Deserialize,
174)]
175#[serde(rename_all = "lowercase")]
176pub enum ModelState {
177    /// Resolved to a runtime and present on disk.
178    Ready,
179    /// Not yet resolved to a runtime.
180    #[default]
181    Unresolved,
182    /// Known but its weights are no longer on disk.
183    Missing,
184}
185
186impl ModelState {
187    /// The stable string form, the same one serde writes.
188    pub fn as_str(&self) -> &'static str {
189        match self {
190            ModelState::Ready => "ready",
191            ModelState::Unresolved => "unresolved",
192            ModelState::Missing => "missing",
193        }
194    }
195}
196
197/// The bid preference numbers runtime adapters use to compete for a model. Lower
198/// wins. This is the single global ordering; adapters must not mint their own.
199pub struct BidPreference;
200
201impl BidPreference {
202    /// llama.cpp GGUF text runtime.
203    pub const LLAMA_CPP: i64 = 10;
204    /// whisper.cpp transcription runtime.
205    pub const WHISPER_CPP: i64 = 10;
206    /// OpenAI-compatible remote endpoint.
207    pub const ENDPOINT: i64 = 10;
208    /// mlx-vlm vision-language sidecar.
209    pub const MLX_VLM: i64 = 14;
210    /// in-process MLX-Swift text runtime.
211    pub const MLX_SWIFT: i64 = 15;
212    /// Apple Foundation Models.
213    pub const APPLE_FOUNDATION: i64 = 15;
214    /// Ollama daemon.
215    pub const OLLAMA: i64 = 20;
216    /// mflux FLUX image runtime.
217    pub const MFLUX: i64 = 25;
218    /// diffusers image runtime.
219    pub const DIFFUSERS: i64 = 26;
220    /// ComfyUI daemon.
221    pub const COMFY_UI: i64 = 27;
222    /// Automatic1111 daemon.
223    pub const A1111: i64 = 28;
224    /// mlx-audio speech runtime.
225    pub const MLX_AUDIO: i64 = 30;
226    /// embeddings sidecar.
227    pub const EMBEDDINGS: i64 = 32;
228    /// mlx-lm text sidecar.
229    pub const MLX_LM: i64 = 40;
230    /// Manifest-declared runtime (lowest priority).
231    pub const MANIFEST: i64 = 100;
232}