Skip to main content

wagner/agent/
mod.rs

1mod claude;
2mod codex;
3mod droid;
4mod test;
5
6pub use claude::ClaudeCode;
7pub use codex::Codex;
8pub use droid::Droid;
9pub use test::TestAgent;
10
11use crate::error::{Result, WagnerError};
12use crate::model::Engine;
13use std::path::{Path, PathBuf};
14
15pub trait Agent: Send + Sync {
16    fn name(&self) -> &str;
17    fn engine(&self) -> Engine;
18    fn launch_command(&self, session_id: &str) -> String;
19    fn predict_jsonl_path(&self, session_id: &str, cwd: &Path) -> Option<PathBuf>;
20    fn resume_command(&self, session_id: &str) -> String;
21}
22
23#[derive(Debug, Clone)]
24pub enum AgentChoice {
25    Claude(ClaudeCode),
26    Codex(Codex),
27    Droid(Droid),
28}
29
30impl AgentChoice {
31    pub fn from_key(key: &str) -> Result<Self> {
32        match key {
33            "claude" | "claude-code" => Ok(Self::Claude(ClaudeCode::new())),
34            "codex" => Ok(Self::Codex(Codex::new())),
35            "droid" => Ok(Self::Droid(Droid::new())),
36            _ => Err(WagnerError::InvalidAgent(key.to_string())),
37        }
38    }
39}
40
41impl Agent for AgentChoice {
42    fn name(&self) -> &str {
43        match self {
44            Self::Claude(agent) => agent.name(),
45            Self::Codex(agent) => agent.name(),
46            Self::Droid(agent) => agent.name(),
47        }
48    }
49
50    fn engine(&self) -> Engine {
51        match self {
52            Self::Claude(agent) => agent.engine(),
53            Self::Codex(agent) => agent.engine(),
54            Self::Droid(agent) => agent.engine(),
55        }
56    }
57
58    fn launch_command(&self, session_id: &str) -> String {
59        match self {
60            Self::Claude(agent) => agent.launch_command(session_id),
61            Self::Codex(agent) => agent.launch_command(session_id),
62            Self::Droid(agent) => agent.launch_command(session_id),
63        }
64    }
65
66    fn predict_jsonl_path(&self, session_id: &str, cwd: &Path) -> Option<PathBuf> {
67        match self {
68            Self::Claude(agent) => agent.predict_jsonl_path(session_id, cwd),
69            Self::Codex(agent) => agent.predict_jsonl_path(session_id, cwd),
70            Self::Droid(agent) => agent.predict_jsonl_path(session_id, cwd),
71        }
72    }
73
74    fn resume_command(&self, session_id: &str) -> String {
75        match self {
76            Self::Claude(agent) => agent.resume_command(session_id),
77            Self::Codex(agent) => agent.resume_command(session_id),
78            Self::Droid(agent) => agent.resume_command(session_id),
79        }
80    }
81}