ito_core/harness/
codex.rs1use super::streaming_cli::CliHarness;
2use super::types::{HarnessName, HarnessRunConfig};
3
4#[derive(Debug, Default)]
18pub struct CodexHarness;
19
20impl CliHarness for CodexHarness {
21 fn harness_name(&self) -> HarnessName {
22 HarnessName::Codex
23 }
24
25 fn binary(&self) -> &str {
26 "codex"
27 }
28
29 fn build_args(&self, config: &HarnessRunConfig) -> Vec<String> {
30 let mut args = vec!["exec".to_string()];
31 if let Some(model) = config.model.as_deref() {
32 args.push("--model".to_string());
33 args.push(model.to_string());
34 }
35 if config.allow_all {
36 args.push("--yolo".to_string());
37 }
38 args.push(config.prompt.clone());
39 args
40 }
41}
42
43#[cfg(test)]
44mod tests {
45 use super::*;
46 use std::collections::BTreeMap;
47
48 enum Allow {
49 All,
50 None,
51 }
52
53 fn config(allow: Allow, model: Option<&str>) -> HarnessRunConfig {
54 let allow_all = match allow {
55 Allow::All => true,
56 Allow::None => false,
57 };
58 HarnessRunConfig {
59 prompt: "do stuff".to_string(),
60 model: model.map(String::from),
61 cwd: std::env::temp_dir(),
62 env: BTreeMap::new(),
63 interactive: false,
64 allow_all,
65 inactivity_timeout: None,
66 }
67 }
68
69 #[test]
70 fn harness_name_is_codex() {
71 let harness = CodexHarness;
72 assert_eq!(harness.harness_name(), HarnessName::Codex);
73 }
74
75 #[test]
76 fn binary_is_codex() {
77 let harness = CodexHarness;
78 assert_eq!(harness.binary(), "codex");
79 }
80
81 #[test]
82 fn build_args_with_allow_all() {
83 let harness = CodexHarness;
84 let cfg = config(Allow::All, Some("o3"));
85 let args = harness.build_args(&cfg);
86 assert_eq!(args, vec!["exec", "--model", "o3", "--yolo", "do stuff"]);
87 }
88
89 #[test]
90 fn build_args_without_allow_all() {
91 let harness = CodexHarness;
92 let cfg = config(Allow::None, Some("o3"));
93 let args = harness.build_args(&cfg);
94 assert_eq!(args, vec!["exec", "--model", "o3", "do stuff"]);
95 }
96}