systemprompt_cli/commands/analytics/tools/
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 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}