//! Model identifiers, prompt shape, sampling. //! //! Deliberately small: the daemon's model registry is canonical; //! clients refer to models by name and don't carry weights over the //! wire. The format is chosen by the operator at load time, not by //! the client. /// Reference to a model the daemon has (or can) load. #[derive(Clone, Debug, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize)] pub struct ModelRef { /// Operator-chosen name. Stable across reloads of the same /// weights. pub name: String, /// Optional revision tag — lets a client pin a specific weights /// version if the operator has multiple. `None` means "whatever /// is current." pub revision: Option, } /// Prompt input to an inference request. /// /// Token IDs are not on the wire at this layer — clients send text /// or chat-message structure; the daemon owns the tokenizer for the /// referenced model. Sending pre-tokenized input would couple /// clients to the daemon's tokenizer choice, which is exactly the /// kind of coupling the v1 freeze is meant to prevent. #[derive(Clone, Debug, serde::Serialize, serde::Deserialize)] pub enum PromptSpec { /// Single text completion. Text(String), /// Chat-style message list. The daemon applies the model's /// chat template. Chat(Vec), } /// One message in a chat-style prompt. #[derive(Clone, Debug, serde::Serialize, serde::Deserialize)] pub struct ChatMessage { pub role: ChatRole, pub content: String, } /// Conversation role. Mirrors the OpenAI-style triad — the J1 shim /// translates one-to-one without information loss. #[derive(Clone, Copy, Debug, PartialEq, Eq, serde::Serialize, serde::Deserialize)] pub enum ChatRole { System, User, Assistant, } /// Sampling parameters. Conservative defaults; the daemon may /// further constrain values it can't honor for the selected model. #[derive(Clone, Debug, serde::Serialize, serde::Deserialize)] pub struct SamplingParams { pub max_tokens: u32, pub temperature: f32, pub top_p: f32, /// Stop strings. Generation halts on the first match. pub stop: Vec, /// Seed for reproducible sampling. `None` means daemon-chosen. pub seed: Option, } impl Default for SamplingParams { fn default() -> Self { Self { max_tokens: 512, temperature: 0.7, top_p: 0.95, stop: Vec::new(), seed: None, } } } /// Scheduling priority class. The supervisor's fair-share policy /// uses these to weight admission and preemption between /// concurrent clients (Thread C, A2). #[derive( Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, serde::Serialize, serde::Deserialize, )] pub enum Priority { /// Background work; preemptible. Batch jobs, embeddings runs. Background, /// Default. Interactive but not latency-critical. #[default] Normal, /// Latency-critical interactive sessions. Preempts background /// work but not other interactive sessions. Interactive, }