Skip to main content

ralph_workflow/diagnostics/
agents.rs

1//! Agent diagnostics and availability testing.
2
3use crate::agents::AgentRegistry;
4use itertools::Itertools;
5
6/// Agent diagnostics.
7#[derive(Debug)]
8pub struct AgentDiagnostics {
9    pub total_agents: usize,
10    pub available_agents: usize,
11    pub unavailable_agents: usize,
12    pub agent_status: Vec<AgentStatus>,
13}
14
15/// Individual agent status.
16#[derive(Debug)]
17pub struct AgentStatus {
18    pub name: String,
19    pub display_name: String,
20    pub available: bool,
21    pub json_parser: String,
22    pub command: String,
23}
24
25impl AgentDiagnostics {
26    /// Test agent availability.
27    #[must_use]
28    pub fn test(registry: &AgentRegistry) -> Self {
29        let all_agents = registry.list();
30
31        // Build agent status entries using iterator pipeline - functional style
32        let agent_status: Vec<AgentStatus> = all_agents
33            .iter()
34            .map(|(name, cfg)| {
35                let available = registry.is_agent_available(name);
36                AgentStatus {
37                    name: name.to_string(),
38                    display_name: registry.display_name(name),
39                    available,
40                    json_parser: format!("{:?}", cfg.json_parser),
41                    command: cfg
42                        .cmd
43                        .split_whitespace()
44                        .next()
45                        .unwrap_or(&cfg.cmd)
46                        .to_string(),
47                }
48            })
49            .collect();
50
51        // Calculate counts using iterator - functional style
52        let available_count = agent_status
53            .iter()
54            .filter(|status| status.available)
55            .count();
56
57        let total_agents = all_agents.len();
58        let unavailable_agents = total_agents - available_count;
59
60        // Sort by name for consistent output using functional pipeline
61        let agent_status = agent_status
62            .into_iter()
63            .sorted_by(|a, b| a.name.cmp(&b.name))
64            .collect();
65
66        Self {
67            total_agents,
68            available_agents: available_count,
69            unavailable_agents,
70            agent_status,
71        }
72    }
73}