systemprompt_cli/commands/analytics/agents/
mod.rs1mod 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}