Skip to main content

max / everycycle

3.1 KB · 102 lines History Blame Raw
1 //! Model identifiers, prompt shape, sampling.
2 //!
3 //! Deliberately small: the daemon's model registry is canonical;
4 //! clients refer to models by name and don't carry weights over the
5 //! wire. The format is chosen by the operator at load time, not by
6 //! the client.
7
8 /// Reference to a model the daemon has (or can) load.
9 #[derive(Clone, Debug, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize)]
10 pub struct ModelRef {
11 /// Operator-chosen name. Stable across reloads of the same
12 /// weights.
13 pub name: String,
14 /// Optional revision tag — lets a client pin a specific weights
15 /// version if the operator has multiple. `None` means "whatever
16 /// is current."
17 pub revision: Option<String>,
18 }
19
20 /// Prompt input to an inference request.
21 ///
22 /// Token IDs are not on the wire at this layer — clients send text
23 /// or chat-message structure; the daemon owns the tokenizer for the
24 /// referenced model. Sending pre-tokenized input would couple
25 /// clients to the daemon's tokenizer choice, which is exactly the
26 /// kind of coupling the v1 freeze is meant to prevent.
27 #[derive(Clone, Debug, serde::Serialize, serde::Deserialize)]
28 pub enum PromptSpec {
29 /// Single text completion.
30 Text(String),
31 /// Chat-style message list. The daemon applies the model's
32 /// chat template.
33 Chat(Vec<ChatMessage>),
34 }
35
36 /// One message in a chat-style prompt.
37 #[derive(Clone, Debug, serde::Serialize, serde::Deserialize)]
38 pub struct ChatMessage {
39 pub role: ChatRole,
40 pub content: String,
41 }
42
43 /// Conversation role. Mirrors the OpenAI-style triad — the J1 shim
44 /// translates one-to-one without information loss.
45 #[derive(Clone, Copy, Debug, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
46 pub enum ChatRole {
47 System,
48 User,
49 Assistant,
50 }
51
52 /// Sampling parameters. Conservative defaults; the daemon may
53 /// further constrain values it can't honor for the selected model.
54 #[derive(Clone, Debug, serde::Serialize, serde::Deserialize)]
55 pub struct SamplingParams {
56 pub max_tokens: u32,
57 pub temperature: f32,
58 pub top_p: f32,
59 /// Stop strings. Generation halts on the first match.
60 pub stop: Vec<String>,
61 /// Seed for reproducible sampling. `None` means daemon-chosen.
62 pub seed: Option<u64>,
63 }
64
65 impl Default for SamplingParams {
66 fn default() -> Self {
67 Self {
68 max_tokens: 512,
69 temperature: 0.7,
70 top_p: 0.95,
71 stop: Vec::new(),
72 seed: None,
73 }
74 }
75 }
76
77 /// Scheduling priority class. The supervisor's fair-share policy
78 /// uses these to weight admission and preemption between
79 /// concurrent clients (Thread C, A2).
80 #[derive(
81 Clone,
82 Copy,
83 Debug,
84 Default,
85 PartialEq,
86 Eq,
87 PartialOrd,
88 Ord,
89 serde::Serialize,
90 serde::Deserialize,
91 )]
92 pub enum Priority {
93 /// Background work; preemptible. Batch jobs, embeddings runs.
94 Background,
95 /// Default. Interactive but not latency-critical.
96 #[default]
97 Normal,
98 /// Latency-critical interactive sessions. Preempts background
99 /// work but not other interactive sessions.
100 Interactive,
101 }
102