ralph/contracts/config/
phase.rs1use crate::contracts::model::{Model, ReasoningEffort};
10use crate::contracts::runner::Runner;
11use schemars::JsonSchema;
12use serde::{Deserialize, Serialize};
13
14#[derive(Debug, Clone, Default, Serialize, Deserialize, JsonSchema, PartialEq)]
20#[serde(default, deny_unknown_fields)]
21pub struct PhaseOverrideConfig {
22 #[serde(skip_serializing_if = "Option::is_none")]
24 pub runner: Option<Runner>,
25
26 #[serde(skip_serializing_if = "Option::is_none")]
28 pub model: Option<Model>,
29
30 #[serde(skip_serializing_if = "Option::is_none")]
32 pub reasoning_effort: Option<ReasoningEffort>,
33}
34
35impl PhaseOverrideConfig {
36 pub fn merge_from(&mut self, other: Self) {
38 if other.runner.is_some() {
39 self.runner = other.runner;
40 }
41 if other.model.is_some() {
42 self.model = other.model;
43 }
44 if other.reasoning_effort.is_some() {
45 self.reasoning_effort = other.reasoning_effort;
46 }
47 }
48}
49
50#[derive(Debug, Clone, Default, Serialize, Deserialize, JsonSchema, PartialEq)]
60#[serde(default, deny_unknown_fields)]
61pub struct PhaseOverrides {
62 #[serde(skip_serializing_if = "Option::is_none")]
64 pub phase1: Option<PhaseOverrideConfig>,
65
66 #[serde(skip_serializing_if = "Option::is_none")]
68 pub phase2: Option<PhaseOverrideConfig>,
69
70 #[serde(skip_serializing_if = "Option::is_none")]
72 pub phase3: Option<PhaseOverrideConfig>,
73}
74
75impl PhaseOverrides {
76 pub fn merge_from(&mut self, other: Self) {
79 match (&mut self.phase1, other.phase1) {
81 (Some(existing), Some(new)) => existing.merge_from(new),
82 (None, Some(new)) => self.phase1 = Some(new),
83 _ => {}
84 }
85
86 match (&mut self.phase2, other.phase2) {
88 (Some(existing), Some(new)) => existing.merge_from(new),
89 (None, Some(new)) => self.phase2 = Some(new),
90 _ => {}
91 }
92
93 match (&mut self.phase3, other.phase3) {
95 (Some(existing), Some(new)) => existing.merge_from(new),
96 (None, Some(new)) => self.phase3 = Some(new),
97 _ => {}
98 }
99 }
100}