ralph_workflow/agents/mod.rs
1//! Agent Abstraction Module
2//!
3//! Provides a pluggable agent system for different AI coding assistants
4//! (Claude, Codex, OpenCode, Goose, Cline, CCS, etc.)
5//!
6//! # Key Types
7//!
8//! - [`AgentRegistry`] - Registry for looking up and managing agent configurations
9//! - [`AgentConfig`] - Configuration for a single agent (command, flags, parser type)
10//! - [`AgentErrorKind`] - Error classification for fault-tolerant execution
11//! - [`JsonParserType`] - Parser selection for agent NDJSON output (Claude, Codex, Gemini, OpenCode, Generic)
12//!
13//! For detailed compatibility information, see
14//! [`docs/agent-compatibility.md`](https://codeberg.org/mistlight/RalphWithReviewer/src/branch/main/docs/agent-compatibility.md).
15//!
16//! ## Module Structure
17//!
18//! - `ccs` - CCS (Claude Code Switch) alias resolution
19//! - `config` - Agent configuration types and TOML parsing
20//! - `error` - Error classification for fault-tolerant execution
21//! - `fallback` - Fallback chain configuration for agent switching
22//! - `parser` - JSON parser type definitions
23//! - `providers` - `OpenCode` provider types and authentication
24//! - `registry` - Agent registry for agent lookup and management
25//!
26//! ## Configuration
27//!
28//! Agents can be configured via (in order of increasing priority):
29//! 1. Built-in defaults (claude, codex, opencode, ccs, aider, goose, cline, continue, amazon-q, gemini)
30//! 2. Unified config file (`~/.config/ralph-workflow.toml`)
31//! 3. Environment variables (`RALPH_DEVELOPER_CMD`, `RALPH_REVIEWER_CMD`)
32//! 4. Programmatic registration via `AgentRegistry::register()`
33//!
34//! ## CCS (Claude Code Switch) Support
35//!
36//! CCS aliases can be defined in the unified config and used with `ccs/alias` syntax:
37//! ```toml
38//! [ccs_aliases]
39//! work = "ccs work"
40//! personal = "ccs personal"
41//! gemini = "ccs gemini"
42//!
43//! [agent_chain]
44//! developer = ["ccs/work", "claude"]
45//! ```
46//!
47//! ## Agent Switching / Fallback
48//!
49//! Configure fallback agents for automatic switching when primary agent fails:
50//! ```toml
51//! [agent_chain]
52//! developer = ["claude", "codex", "goose"]
53//! reviewer = ["codex", "claude"]
54//! max_retries = 3
55//! retry_delay_ms = 1000
56//! ```
57//!
58//! ## Example TOML Configuration
59//!
60//! ```toml
61//! [agents.myagent]
62//! cmd = "my-ai-tool run"
63//! output_flag = "--json-stream"
64//! yolo_flag = "--auto-fix"
65//! verbose_flag = "--verbose"
66//! can_commit = true
67//! json_parser = "claude" # Use Claude's JSON parser
68//! ```
69
70#[cfg(any(test, feature = "test-utils"))]
71pub mod ccs;
72#[cfg(not(any(test, feature = "test-utils")))]
73mod ccs;
74mod ccs_env;
75mod config;
76mod error;
77pub mod fallback;
78pub mod opencode_api;
79mod opencode_resolver;
80mod parser;
81mod providers;
82mod registry;
83mod retry_timer;
84pub mod validation;
85
86// Re-export public types for crate-level access
87pub use ccs::is_ccs_ref;
88pub use config::{
89 AgentConfig, AgentConfigBuilder, AgentsConfigFile, ConfigInitResult, ConfigSource,
90};
91pub use error::{contains_glm_model, is_glm_like_agent, AgentErrorKind};
92pub use fallback::AgentRole;
93pub use parser::JsonParserType;
94pub use providers::{
95 auth_failure_advice, strip_model_flag_prefix, validate_model_flag, OpenCodeProviderType,
96};
97pub use registry::AgentRegistry;
98pub use retry_timer::RetryTimerProvider;
99
100#[cfg(test)]
101mod tests {
102 use super::fallback::FallbackConfig;
103 use super::*;
104
105 #[test]
106 fn test_module_exports() {
107 // Verify all expected types are accessible through the module
108 let _ = AgentRegistry::new().unwrap();
109 let _ = FallbackConfig::default();
110 let _ = AgentErrorKind::Permanent;
111 let _ = AgentRole::Developer;
112 let _ = JsonParserType::Claude;
113 let _ = OpenCodeProviderType::OpenCodeZen;
114 }
115}