Skip to main content

ironflow_engine/config/
agent.rs

1//! Agent step configuration -- re-exports [`AgentConfig`] from `ironflow-core`.
2//!
3//! [`AgentStepConfig`] is a type alias for [`AgentConfig`], keeping backward
4//! compatibility while eliminating the duplicated config struct.
5
6pub use ironflow_core::provider::AgentConfig;
7
8/// Backward-compatible alias for [`AgentConfig`].
9///
10/// # Examples
11///
12/// ```
13/// use ironflow_engine::config::AgentStepConfig;
14///
15/// let config = AgentStepConfig::new("Review this code for security issues")
16///     .model("haiku")
17///     .max_budget_usd(0.10);
18/// ```
19pub type AgentStepConfig = AgentConfig;
20
21#[cfg(test)]
22mod tests {
23    use super::*;
24    use schemars::JsonSchema;
25
26    #[test]
27    fn builder() {
28        let config = AgentStepConfig::new("Review code")
29            .system_prompt("You are a code reviewer")
30            .model("haiku")
31            .max_budget_usd(0.50)
32            .max_turns(5)
33            .allow_tool("read")
34            .working_dir("/repo")
35            .permission_mode(ironflow_core::operations::agent::PermissionMode::Auto);
36
37        assert_eq!(config.prompt, "Review code");
38        assert_eq!(config.system_prompt.unwrap(), "You are a code reviewer");
39        assert_eq!(config.model, "haiku");
40        assert_eq!(config.allowed_tools, vec!["read"]);
41        assert!(config.json_schema.is_none());
42    }
43
44    #[test]
45    fn output_sets_schema_from_type() {
46        #[derive(serde::Deserialize, JsonSchema)]
47        #[allow(dead_code)]
48        struct Labels {
49            labels: Vec<String>,
50        }
51
52        let config = AgentStepConfig::new("Classify").output::<Labels>();
53
54        let schema = config.json_schema.expect("schema should be set");
55        assert!(schema.contains("labels"));
56    }
57
58    #[test]
59    fn output_schema_raw_sets_string() {
60        let raw = r#"{"type":"object"}"#;
61        let config = AgentStepConfig::new("Rate").output_schema_raw(raw);
62
63        assert_eq!(config.json_schema.as_deref(), Some(raw));
64    }
65
66    #[test]
67    fn output_overrides_previous_schema() {
68        #[derive(serde::Deserialize, JsonSchema)]
69        #[allow(dead_code)]
70        struct First {
71            a: String,
72        }
73
74        #[derive(serde::Deserialize, JsonSchema)]
75        #[allow(dead_code)]
76        struct Second {
77            b: i32,
78        }
79
80        let config = AgentStepConfig::new("Test")
81            .output::<First>()
82            .output::<Second>();
83
84        let schema = config.json_schema.expect("schema should be set");
85        assert!(!schema.contains("\"a\""));
86        assert!(schema.contains("\"b\""));
87    }
88
89    #[test]
90    fn output_schema_raw_overrides_typed_schema() {
91        #[derive(serde::Deserialize, JsonSchema)]
92        #[allow(dead_code)]
93        struct Typed {
94            field: String,
95        }
96
97        let raw = r#"{"type":"string"}"#;
98        let config = AgentStepConfig::new("Test")
99            .output::<Typed>()
100            .output_schema_raw(raw);
101
102        assert_eq!(config.json_schema.as_deref(), Some(raw));
103    }
104
105    #[test]
106    fn default_output_schema_is_none() {
107        let config = AgentStepConfig::new("Hello");
108        assert!(config.json_schema.is_none());
109    }
110
111    #[test]
112    fn serde_roundtrip_with_defaults() {
113        let json = r#"{"prompt":"hello"}"#;
114        let config: AgentConfig = serde_json::from_str(json).unwrap();
115        assert_eq!(config.prompt, "hello");
116        assert_eq!(config.model, "sonnet");
117        assert!(!config.verbose);
118    }
119
120    #[test]
121    fn serde_permission_mode_case_insensitive() {
122        let json = r#"{"prompt":"test","permission_mode":"auto"}"#;
123        let config: AgentConfig = serde_json::from_str(json).unwrap();
124        assert!(matches!(
125            config.permission_mode,
126            ironflow_core::operations::agent::PermissionMode::Auto
127        ));
128    }
129
130    #[test]
131    fn serde_output_schema_alias() {
132        let json = r#"{"prompt":"test","output_schema":"{\"type\":\"object\"}"}"#;
133        let config: AgentConfig = serde_json::from_str(json).unwrap();
134        assert_eq!(config.json_schema.as_deref(), Some(r#"{"type":"object"}"#));
135    }
136}