nemo_flow_adaptive/
config.rs1use nemo_flow::plugin::ConfigPolicy;
7use serde::{Deserialize, Serialize};
8use serde_json::{Map, Value as Json};
9
10#[derive(Debug, Clone, Serialize, Deserialize)]
12pub struct AdaptiveConfig {
13 #[serde(default = "default_adaptive_config_version")]
15 pub version: u32,
16 #[serde(default, skip_serializing_if = "Option::is_none")]
18 pub agent_id: Option<String>,
19 #[serde(default, skip_serializing_if = "Option::is_none")]
21 pub state: Option<StateConfig>,
22 #[serde(default, skip_serializing_if = "Option::is_none")]
24 pub telemetry: Option<TelemetryComponentConfig>,
25 #[serde(default, skip_serializing_if = "Option::is_none")]
27 pub adaptive_hints: Option<AdaptiveHintsComponentConfig>,
28 #[serde(default, skip_serializing_if = "Option::is_none")]
30 pub tool_parallelism: Option<ToolParallelismComponentConfig>,
31 #[serde(default, skip_serializing_if = "Option::is_none")]
33 pub acg: Option<AcgComponentConfig>,
34 #[serde(default)]
36 pub policy: ConfigPolicy,
37}
38
39impl Default for AdaptiveConfig {
40 fn default() -> Self {
41 Self {
42 version: default_adaptive_config_version(),
43 agent_id: None,
44 state: None,
45 telemetry: None,
46 adaptive_hints: None,
47 tool_parallelism: None,
48 acg: None,
49 policy: ConfigPolicy::default(),
50 }
51 }
52}
53
54#[derive(Debug, Clone, Serialize, Deserialize)]
56pub struct StateConfig {
57 pub backend: BackendSpec,
59}
60
61#[derive(Debug, Clone, Serialize, Deserialize)]
63pub struct BackendSpec {
64 pub kind: String,
66 #[serde(default)]
68 pub config: Map<String, Json>,
69}
70
71impl BackendSpec {
72 pub fn in_memory() -> Self {
74 Self {
75 kind: "in_memory".to_string(),
76 config: Map::new(),
77 }
78 }
79
80 #[cfg(feature = "redis-backend")]
81 pub fn redis(url: impl Into<String>, key_prefix: impl Into<String>) -> Self {
83 let mut config = Map::new();
84 config.insert("url".to_string(), Json::String(url.into()));
85 config.insert("key_prefix".to_string(), Json::String(key_prefix.into()));
86 Self {
87 kind: "redis".to_string(),
88 config,
89 }
90 }
91}
92
93#[derive(Debug, Clone, Default, Serialize, Deserialize)]
95pub struct TelemetryComponentConfig {
96 #[serde(default, skip_serializing_if = "Option::is_none")]
98 pub subscriber_name: Option<String>,
99 #[serde(default)]
101 pub learners: Vec<String>,
102}
103
104#[derive(Debug, Clone, Serialize, Deserialize)]
106pub struct AdaptiveHintsComponentConfig {
107 #[serde(default = "default_priority")]
109 pub priority: i32,
110 #[serde(default)]
112 pub break_chain: bool,
113 #[serde(default = "default_true")]
115 pub inject_header: bool,
116 #[serde(default = "default_adaptive_hints_path")]
118 pub inject_body_path: String,
119}
120
121impl Default for AdaptiveHintsComponentConfig {
122 fn default() -> Self {
123 Self {
124 priority: default_priority(),
125 break_chain: false,
126 inject_header: true,
127 inject_body_path: default_adaptive_hints_path(),
128 }
129 }
130}
131
132#[derive(Debug, Clone, Serialize, Deserialize)]
134pub struct ToolParallelismComponentConfig {
135 #[serde(default = "default_priority")]
137 pub priority: i32,
138 #[serde(default = "default_tool_parallelism_mode")]
140 pub mode: String,
141}
142
143impl Default for ToolParallelismComponentConfig {
144 fn default() -> Self {
145 Self {
146 priority: default_priority(),
147 mode: default_tool_parallelism_mode(),
148 }
149 }
150}
151
152#[derive(Debug, Clone, Serialize, Deserialize)]
154pub struct AcgComponentConfig {
155 #[serde(default = "default_acg_provider")]
157 pub provider: String,
158 #[serde(default = "default_acg_observation_window")]
160 pub observation_window: usize,
161 #[serde(default = "default_acg_priority")]
163 pub priority: i32,
164 #[serde(default)]
166 pub stability_thresholds: crate::acg::stability::StabilityThresholds,
167}
168
169impl Default for AcgComponentConfig {
170 fn default() -> Self {
171 Self {
172 provider: default_acg_provider(),
173 observation_window: default_acg_observation_window(),
174 priority: default_acg_priority(),
175 stability_thresholds: crate::acg::stability::StabilityThresholds::default(),
176 }
177 }
178}
179
180fn default_adaptive_config_version() -> u32 {
181 1
182}
183
184fn default_priority() -> i32 {
185 100
186}
187
188fn default_true() -> bool {
189 true
190}
191
192fn default_adaptive_hints_path() -> String {
193 "nvext.agent_hints".to_string()
194}
195
196fn default_tool_parallelism_mode() -> String {
197 "observe_only".to_string()
198}
199
200fn default_acg_provider() -> String {
201 "passthrough".to_string()
202}
203
204fn default_acg_observation_window() -> usize {
205 100
206}
207
208fn default_acg_priority() -> i32 {
209 50
210}
211
212#[cfg(test)]
213#[path = "../tests/unit/config_tests.rs"]
214mod tests;