Skip to main content

systemprompt_cli/commands/analytics/agents/
mod.rs

1mod list;
2mod show;
3mod stats;
4mod trends;
5
6use anyhow::Result;
7use clap::Subcommand;
8use schemars::JsonSchema;
9use serde::{Deserialize, Serialize};
10use systemprompt_runtime::DatabaseContext;
11
12use crate::shared::render_result;
13use crate::CliConfig;
14
15#[derive(Debug, Subcommand)]
16pub enum AgentsCommands {
17    #[command(about = "Aggregate agent statistics")]
18    Stats(stats::StatsArgs),
19
20    #[command(about = "List agents with metrics")]
21    List(list::ListArgs),
22
23    #[command(about = "Agent usage trends over time")]
24    Trends(trends::TrendsArgs),
25
26    #[command(about = "Deep dive into specific agent")]
27    Show(show::ShowArgs),
28}
29
30#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
31pub struct AgentStatsOutput {
32    pub period: String,
33    pub total_agents: i64,
34    pub total_tasks: i64,
35    pub completed_tasks: i64,
36    pub failed_tasks: i64,
37    pub success_rate: f64,
38    pub avg_execution_time_ms: i64,
39    pub total_ai_requests: i64,
40    pub total_cost_microdollars: i64,
41}
42
43#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
44pub struct AgentListRow {
45    pub agent_name: String,
46    pub task_count: i64,
47    pub success_rate: f64,
48    pub avg_execution_time_ms: i64,
49    pub total_cost_microdollars: i64,
50    pub last_active: String,
51}
52
53#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
54pub struct AgentListOutput {
55    pub agents: Vec<AgentListRow>,
56    pub total: i64,
57}
58
59#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
60pub struct AgentTrendPoint {
61    pub timestamp: String,
62    pub task_count: i64,
63    pub success_rate: f64,
64    pub avg_execution_time_ms: i64,
65}
66
67#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
68pub struct AgentTrendsOutput {
69    pub agent: Option<String>,
70    pub period: String,
71    pub group_by: String,
72    pub points: Vec<AgentTrendPoint>,
73}
74
75#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
76pub struct AgentShowOutput {
77    pub agent_name: String,
78    pub period: String,
79    pub summary: AgentStatsOutput,
80    pub status_breakdown: Vec<StatusBreakdownItem>,
81    pub top_errors: Vec<ErrorBreakdownItem>,
82    pub hourly_distribution: Vec<HourlyDistributionItem>,
83}
84
85#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
86pub struct StatusBreakdownItem {
87    pub status: String,
88    pub count: i64,
89    pub percentage: f64,
90}
91
92#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
93pub struct ErrorBreakdownItem {
94    pub error_type: String,
95    pub count: i64,
96}
97
98#[derive(Debug, Clone, Copy, Serialize, Deserialize, JsonSchema)]
99pub struct HourlyDistributionItem {
100    pub hour: i32,
101    pub count: i64,
102}
103
104pub async fn execute(command: AgentsCommands, config: &CliConfig) -> Result<()> {
105    match command {
106        AgentsCommands::Stats(args) => {
107            let result = stats::execute(args, config).await?;
108            render_result(&result);
109            Ok(())
110        },
111        AgentsCommands::List(args) => {
112            let result = list::execute(args, config).await?;
113            render_result(&result);
114            Ok(())
115        },
116        AgentsCommands::Trends(args) => {
117            let result = trends::execute(args, config).await?;
118            render_result(&result);
119            Ok(())
120        },
121        AgentsCommands::Show(args) => {
122            let result = show::execute(args, config).await?;
123            render_result(&result);
124            Ok(())
125        },
126    }
127}
128
129pub async fn execute_with_pool(
130    command: AgentsCommands,
131    db_ctx: &DatabaseContext,
132    config: &CliConfig,
133) -> Result<()> {
134    match command {
135        AgentsCommands::Stats(args) => {
136            let result = stats::execute_with_pool(args, db_ctx, config).await?;
137            render_result(&result);
138            Ok(())
139        },
140        AgentsCommands::List(args) => {
141            let result = list::execute_with_pool(args, db_ctx, config).await?;
142            render_result(&result);
143            Ok(())
144        },
145        AgentsCommands::Trends(args) => {
146            let result = trends::execute_with_pool(args, db_ctx, config).await?;
147            render_result(&result);
148            Ok(())
149        },
150        AgentsCommands::Show(args) => {
151            let result = show::execute_with_pool(args, db_ctx, config).await?;
152            render_result(&result);
153            Ok(())
154        },
155    }
156}