use nemo_flow::plugin::ConfigPolicy;
use serde::{Deserialize, Serialize};
use serde_json::{Map, Value as Json};
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AdaptiveConfig {
#[serde(default = "default_adaptive_config_version")]
pub version: u32,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub agent_id: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub state: Option<StateConfig>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub telemetry: Option<TelemetryComponentConfig>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub adaptive_hints: Option<AdaptiveHintsComponentConfig>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub tool_parallelism: Option<ToolParallelismComponentConfig>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub acg: Option<AcgComponentConfig>,
#[serde(default)]
pub policy: ConfigPolicy,
}
impl Default for AdaptiveConfig {
fn default() -> Self {
Self {
version: default_adaptive_config_version(),
agent_id: None,
state: None,
telemetry: None,
adaptive_hints: None,
tool_parallelism: None,
acg: None,
policy: ConfigPolicy::default(),
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct StateConfig {
pub backend: BackendSpec,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct BackendSpec {
pub kind: String,
#[serde(default)]
pub config: Map<String, Json>,
}
impl BackendSpec {
pub fn in_memory() -> Self {
Self {
kind: "in_memory".to_string(),
config: Map::new(),
}
}
#[cfg(feature = "redis-backend")]
pub fn redis(url: impl Into<String>, key_prefix: impl Into<String>) -> Self {
let mut config = Map::new();
config.insert("url".to_string(), Json::String(url.into()));
config.insert("key_prefix".to_string(), Json::String(key_prefix.into()));
Self {
kind: "redis".to_string(),
config,
}
}
}
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
pub struct TelemetryComponentConfig {
#[serde(default, skip_serializing_if = "Option::is_none")]
pub subscriber_name: Option<String>,
#[serde(default)]
pub learners: Vec<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AdaptiveHintsComponentConfig {
#[serde(default = "default_priority")]
pub priority: i32,
#[serde(default)]
pub break_chain: bool,
#[serde(default = "default_true")]
pub inject_header: bool,
#[serde(default = "default_adaptive_hints_path")]
pub inject_body_path: String,
}
impl Default for AdaptiveHintsComponentConfig {
fn default() -> Self {
Self {
priority: default_priority(),
break_chain: false,
inject_header: true,
inject_body_path: default_adaptive_hints_path(),
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ToolParallelismComponentConfig {
#[serde(default = "default_priority")]
pub priority: i32,
#[serde(default = "default_tool_parallelism_mode")]
pub mode: String,
}
impl Default for ToolParallelismComponentConfig {
fn default() -> Self {
Self {
priority: default_priority(),
mode: default_tool_parallelism_mode(),
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AcgComponentConfig {
#[serde(default = "default_acg_provider")]
pub provider: String,
#[serde(default = "default_acg_observation_window")]
pub observation_window: usize,
#[serde(default = "default_acg_priority")]
pub priority: i32,
#[serde(default)]
pub stability_thresholds: crate::acg::stability::StabilityThresholds,
}
impl Default for AcgComponentConfig {
fn default() -> Self {
Self {
provider: default_acg_provider(),
observation_window: default_acg_observation_window(),
priority: default_acg_priority(),
stability_thresholds: crate::acg::stability::StabilityThresholds::default(),
}
}
}
fn default_adaptive_config_version() -> u32 {
1
}
fn default_priority() -> i32 {
100
}
fn default_true() -> bool {
true
}
fn default_adaptive_hints_path() -> String {
"nvext.agent_hints".to_string()
}
fn default_tool_parallelism_mode() -> String {
"observe_only".to_string()
}
fn default_acg_provider() -> String {
"passthrough".to_string()
}
fn default_acg_observation_window() -> usize {
100
}
fn default_acg_priority() -> i32 {
50
}
#[cfg(test)]
#[path = "../tests/unit/config_tests.rs"]
mod tests;