mod claude_code;
mod codex;
use serde_json::Value;
use crate::config::AgentProfileSchema;
use super::response::AgentEvent;
pub(super) use claude_code::ClaudeCodeAdapter;
pub(super) use codex::CodexAdapter;
#[derive(Debug, Clone)]
pub struct AgentCommand {
pub program: String,
pub args: Vec<String>,
pub stdin: AgentStdin,
}
#[allow(dead_code)]
#[derive(Debug, Clone)]
pub enum AgentStdin {
None,
Inherit,
Pipe(String),
}
pub trait AgentAdapter: Send + Sync {
fn build_command(&self, profile: &AgentProfileSchema, prompt: String) -> AgentCommand;
fn map_event(&self, value: Value) -> Vec<AgentEvent>;
}
fn build_extra_args(map: &serde_yaml::Mapping) -> Vec<String> {
map
.iter()
.flat_map(|(k, v)| {
let k = k.as_str()?;
let kv = match v {
serde_yaml::Value::String(s) => Some((k, s.clone())),
serde_yaml::Value::Number(n) => Some((k, n.to_string())),
serde_yaml::Value::Bool(true) => return Some(vec![k.to_string()]),
serde_yaml::Value::Bool(false) => return Some(Vec::new()),
serde_yaml::Value::Sequence(seq) => Some((
k,
seq
.iter()
.filter_map(|item| item.as_str().map(|s| s.to_string()))
.collect::<Vec<String>>()
.join(","),
)),
_ => return None,
};
if let Some((k, v)) = kv {
Some(vec![k.to_string(), v])
} else {
None
}
})
.flatten()
.collect()
}