Skip to main content

synth_ai_core/data/
enums.rs

1//! Core enumeration types for the Synth SDK.
2//!
3//! These enums match the Python SDK's `synth_ai/data/enums.py`.
4
5use serde::{Deserialize, Serialize};
6
7/// Type of optimization/training job.
8#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
9#[serde(rename_all = "snake_case")]
10pub enum JobType {
11    PromptLearning,
12    Sft,
13    Rl,
14    Gspo,
15    Eval,
16    ResearchAgent,
17}
18
19impl Default for JobType {
20    fn default() -> Self {
21        Self::PromptLearning
22    }
23}
24
25/// Status of a job.
26#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
27#[serde(rename_all = "snake_case")]
28pub enum JobStatus {
29    Pending,
30    Queued,
31    Running,
32    Succeeded,
33    Failed,
34    Cancelled,
35}
36
37impl JobStatus {
38    /// Returns true if the job is in a terminal state.
39    pub fn is_terminal(&self) -> bool {
40        matches!(self, Self::Succeeded | Self::Failed | Self::Cancelled)
41    }
42
43    /// Returns true if the job completed successfully.
44    pub fn is_success(&self) -> bool {
45        matches!(self, Self::Succeeded)
46    }
47}
48
49impl Default for JobStatus {
50    fn default() -> Self {
51        Self::Pending
52    }
53}
54
55/// LLM provider name.
56#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
57#[serde(rename_all = "snake_case")]
58pub enum ProviderName {
59    Openai,
60    Groq,
61    Google,
62    Anthropic,
63    Together,
64    Fireworks,
65    Bedrock,
66    Azure,
67}
68
69impl Default for ProviderName {
70    fn default() -> Self {
71        Self::Openai
72    }
73}
74
75/// Inference mode for model calls.
76#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
77#[serde(rename_all = "snake_case")]
78pub enum InferenceMode {
79    Standard,
80    Batched,
81    Streaming,
82}
83
84impl Default for InferenceMode {
85    fn default() -> Self {
86        Self::Standard
87    }
88}
89
90/// Source of reward signal.
91#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
92#[serde(rename_all = "snake_case")]
93pub enum RewardSource {
94    TaskApp,
95    Verifier,
96    Fused,
97    Environment,
98    Runner,
99    Evaluator,
100    Human,
101}
102
103impl Default for RewardSource {
104    fn default() -> Self {
105        Self::TaskApp
106    }
107}
108
109/// Type of reward signal.
110#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
111#[serde(rename_all = "snake_case")]
112pub enum RewardType {
113    Shaped,
114    Sparse,
115    Penalty,
116    Evaluator,
117    Human,
118    Achievement,
119    AchievementDelta,
120    UniqueAchievementDelta,
121}
122
123impl Default for RewardType {
124    fn default() -> Self {
125        Self::Sparse
126    }
127}
128
129/// Scope of reward (event-level or outcome-level).
130#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
131#[serde(rename_all = "snake_case")]
132pub enum RewardScope {
133    Event,
134    Outcome,
135}
136
137impl Default for RewardScope {
138    fn default() -> Self {
139        Self::Outcome
140    }
141}
142
143/// Key identifying an objective metric.
144#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
145#[serde(rename_all = "snake_case")]
146pub enum ObjectiveKey {
147    Reward,
148    LatencyMs,
149    CostUsd,
150    TokensTotal,
151    TurnsCount,
152}
153
154impl Default for ObjectiveKey {
155    fn default() -> Self {
156        Self::Reward
157    }
158}
159
160/// Direction for objective optimization.
161#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
162#[serde(rename_all = "snake_case")]
163pub enum ObjectiveDirection {
164    Maximize,
165    Minimize,
166}
167
168impl Default for ObjectiveDirection {
169    fn default() -> Self {
170        Self::Maximize
171    }
172}
173
174/// Output mode for LLM responses.
175#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
176#[serde(rename_all = "snake_case")]
177pub enum OutputMode {
178    ToolCalls,
179    Text,
180    Structured,
181}
182
183impl Default for OutputMode {
184    fn default() -> Self {
185        Self::Text
186    }
187}
188
189/// Success/failure status for rollout execution.
190#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
191#[serde(rename_all = "snake_case")]
192pub enum SuccessStatus {
193    Success,
194    Timeout,
195    NetworkError,
196    ApplyFailed,
197    RuntimeError,
198    Failure,
199}
200
201impl SuccessStatus {
202    /// Returns true if the status indicates success.
203    pub fn is_success(&self) -> bool {
204        matches!(self, Self::Success)
205    }
206}
207
208impl Default for SuccessStatus {
209    fn default() -> Self {
210        Self::Success
211    }
212}
213
214/// Type of graph in graph optimization.
215#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
216#[serde(rename_all = "snake_case")]
217pub enum GraphType {
218    Sequential,
219    Parallel,
220    Conditional,
221    Loop,
222}
223
224impl Default for GraphType {
225    fn default() -> Self {
226        Self::Sequential
227    }
228}
229
230/// Optimization mode for learning jobs.
231#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
232#[serde(rename_all = "snake_case")]
233pub enum OptimizationMode {
234    Online,
235    Offline,
236    Hybrid,
237}
238
239impl Default for OptimizationMode {
240    fn default() -> Self {
241        Self::Online
242    }
243}
244
245/// Verifier evaluation mode.
246#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
247#[serde(rename_all = "snake_case")]
248pub enum VerifierMode {
249    Binary,
250    Rubric,
251    Criteria,
252    Custom,
253}
254
255impl Default for VerifierMode {
256    fn default() -> Self {
257        Self::Binary
258    }
259}
260
261/// Training type for SFT/RL jobs.
262#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
263#[serde(rename_all = "snake_case")]
264pub enum TrainingType {
265    Sft,
266    Rl,
267    Dpo,
268    Ppo,
269    Grpo,
270}
271
272impl Default for TrainingType {
273    fn default() -> Self {
274        Self::Sft
275    }
276}
277
278/// Adaptive curriculum difficulty level.
279#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
280#[serde(rename_all = "snake_case")]
281pub enum AdaptiveCurriculumLevel {
282    Easy,
283    Medium,
284    Hard,
285    Expert,
286}
287
288impl Default for AdaptiveCurriculumLevel {
289    fn default() -> Self {
290        Self::Medium
291    }
292}
293
294/// Adaptive batch sizing level.
295#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
296#[serde(rename_all = "snake_case")]
297pub enum AdaptiveBatchLevel {
298    Small,
299    Medium,
300    Large,
301    Auto,
302}
303
304impl Default for AdaptiveBatchLevel {
305    fn default() -> Self {
306        Self::Auto
307    }
308}
309
310#[cfg(test)]
311mod tests {
312    use super::*;
313
314    #[test]
315    fn test_job_status_terminal() {
316        assert!(!JobStatus::Pending.is_terminal());
317        assert!(!JobStatus::Running.is_terminal());
318        assert!(JobStatus::Succeeded.is_terminal());
319        assert!(JobStatus::Failed.is_terminal());
320        assert!(JobStatus::Cancelled.is_terminal());
321    }
322
323    #[test]
324    fn test_serde_roundtrip() {
325        let status = JobStatus::Running;
326        let json = serde_json::to_string(&status).unwrap();
327        assert_eq!(json, "\"running\"");
328
329        let parsed: JobStatus = serde_json::from_str(&json).unwrap();
330        assert_eq!(parsed, status);
331    }
332
333    #[test]
334    fn test_success_status() {
335        assert!(SuccessStatus::Success.is_success());
336        assert!(!SuccessStatus::Failure.is_success());
337        assert!(!SuccessStatus::Timeout.is_success());
338    }
339}