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