Skip to main content

systemprompt_cli/commands/analytics/tools/
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 ToolsCommands {
16    #[command(about = "Aggregate tool statistics")]
17    Stats(stats::StatsArgs),
18
19    #[command(about = "List tools with metrics")]
20    List(list::ListArgs),
21
22    #[command(about = "Tool usage trends over time")]
23    Trends(trends::TrendsArgs),
24
25    #[command(about = "Deep dive into specific tool")]
26    Show(show::ShowArgs),
27}
28
29#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
30pub struct ToolStatsOutput {
31    pub period: String,
32    pub total_tools: i64,
33    pub total_executions: i64,
34    pub successful: i64,
35    pub failed: i64,
36    pub timeout: i64,
37    pub success_rate: f64,
38    pub avg_execution_time_ms: i64,
39    pub p95_execution_time_ms: i64,
40}
41
42#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
43pub struct ToolListRow {
44    pub tool_name: String,
45    pub server_name: String,
46    pub execution_count: i64,
47    pub success_rate: f64,
48    pub avg_execution_time_ms: i64,
49    pub last_used: String,
50}
51
52#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
53pub struct ToolListOutput {
54    pub tools: Vec<ToolListRow>,
55    pub total: i64,
56}
57
58#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
59pub struct ToolTrendPoint {
60    pub timestamp: String,
61    pub execution_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 ToolTrendsOutput {
68    pub tool: Option<String>,
69    pub period: String,
70    pub group_by: String,
71    pub points: Vec<ToolTrendPoint>,
72}
73
74#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
75pub struct ToolShowOutput {
76    pub tool_name: String,
77    pub period: String,
78    pub summary: ToolStatsOutput,
79    pub status_breakdown: Vec<StatusBreakdownItem>,
80    pub top_errors: Vec<ErrorItem>,
81    pub usage_by_agent: Vec<AgentUsageItem>,
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 ErrorItem {
93    pub error_message: String,
94    pub count: i64,
95}
96
97#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
98pub struct AgentUsageItem {
99    pub agent_name: String,
100    pub count: i64,
101    pub percentage: f64,
102}
103
104pub async fn execute(command: ToolsCommands, config: &CliConfig) -> Result<()> {
105    match command {
106        ToolsCommands::Stats(args) => stats::execute(args, config).await,
107        ToolsCommands::List(args) => list::execute(args, config).await,
108        ToolsCommands::Trends(args) => trends::execute(args, config).await,
109        ToolsCommands::Show(args) => show::execute(args, config).await,
110    }
111}
112
113pub async fn execute_with_pool(
114    command: ToolsCommands,
115    db_ctx: &DatabaseContext,
116    config: &CliConfig,
117) -> Result<()> {
118    match command {
119        ToolsCommands::Stats(args) => stats::execute_with_pool(args, db_ctx, config).await,
120        ToolsCommands::List(args) => list::execute_with_pool(args, db_ctx, config).await,
121        ToolsCommands::Trends(args) => trends::execute_with_pool(args, db_ctx, config).await,
122        ToolsCommands::Show(args) => show::execute_with_pool(args, db_ctx, config).await,
123    }
124}