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::CliConfig;
13
14#[derive(Debug, Subcommand)]
15pub enum AgentsCommands {
16    #[command(about = "Aggregate agent statistics")]
17    Stats(stats::StatsArgs),
18
19    #[command(about = "List agents with metrics")]
20    List(list::ListArgs),
21
22    #[command(about = "Agent usage trends over time")]
23    Trends(trends::TrendsArgs),
24
25    #[command(about = "Deep dive into specific agent")]
26    Show(show::ShowArgs),
27}
28
29#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
30pub struct AgentStatsOutput {
31    pub period: String,
32    pub total_agents: i64,
33    pub total_tasks: i64,
34    pub completed_tasks: i64,
35    pub failed_tasks: i64,
36    pub success_rate: f64,
37    pub avg_execution_time_ms: i64,
38    pub total_ai_requests: i64,
39    pub total_cost_cents: i64,
40}
41
42#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
43pub struct AgentListRow {
44    pub agent_name: String,
45    pub task_count: i64,
46    pub success_rate: f64,
47    pub avg_execution_time_ms: i64,
48    pub total_cost_cents: i64,
49    pub last_active: String,
50}
51
52#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
53pub struct AgentListOutput {
54    pub agents: Vec<AgentListRow>,
55    pub total: i64,
56}
57
58#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
59pub struct AgentTrendPoint {
60    pub timestamp: String,
61    pub task_count: i64,
62    pub success_rate: f64,
63    pub avg_execution_time_ms: i64,
64}
65
66#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
67pub struct AgentTrendsOutput {
68    pub agent: Option<String>,
69    pub period: String,
70    pub group_by: String,
71    pub points: Vec<AgentTrendPoint>,
72}
73
74#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
75pub struct AgentShowOutput {
76    pub agent_name: String,
77    pub period: String,
78    pub summary: AgentStatsOutput,
79    pub status_breakdown: Vec<StatusBreakdownItem>,
80    pub top_errors: Vec<ErrorBreakdownItem>,
81    pub hourly_distribution: Vec<HourlyDistributionItem>,
82}
83
84#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
85pub struct StatusBreakdownItem {
86    pub status: String,
87    pub count: i64,
88    pub percentage: f64,
89}
90
91#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
92pub struct ErrorBreakdownItem {
93    pub error_type: String,
94    pub count: i64,
95}
96
97#[derive(Debug, Clone, Copy, Serialize, Deserialize, JsonSchema)]
98pub struct HourlyDistributionItem {
99    pub hour: i32,
100    pub count: i64,
101}
102
103pub async fn execute(command: AgentsCommands, config: &CliConfig) -> Result<()> {
104    match command {
105        AgentsCommands::Stats(args) => stats::execute(args, config).await,
106        AgentsCommands::List(args) => list::execute(args, config).await,
107        AgentsCommands::Trends(args) => trends::execute(args, config).await,
108        AgentsCommands::Show(args) => show::execute(args, config).await,
109    }
110}
111
112pub async fn execute_with_pool(
113    command: AgentsCommands,
114    db_ctx: &DatabaseContext,
115    config: &CliConfig,
116) -> Result<()> {
117    match command {
118        AgentsCommands::Stats(args) => stats::execute_with_pool(args, db_ctx, config).await,
119        AgentsCommands::List(args) => list::execute_with_pool(args, db_ctx, config).await,
120        AgentsCommands::Trends(args) => trends::execute_with_pool(args, db_ctx, config).await,
121        AgentsCommands::Show(args) => show::execute_with_pool(args, db_ctx, config).await,
122    }
123}