systemprompt_cli/commands/analytics/
mod.rs1pub mod agents;
13pub mod content;
14pub mod conversations;
15pub mod costs;
16pub mod overview;
17pub mod projection;
18pub mod requests;
19pub mod sessions;
20pub mod shared;
21pub mod tools;
22pub mod traffic;
23
24use anyhow::{Context, Result};
25use clap::Subcommand;
26
27use crate::context::CommandContext;
28use crate::shared::render_result;
29
30#[derive(Debug, Subcommand)]
31pub enum AnalyticsCommands {
32 #[command(subcommand, about = "Reporting projection status and recovery")]
33 Projection(projection::ProjectionCommands),
34 #[command(about = "Dashboard overview of all analytics")]
35 Overview(overview::OverviewArgs),
36
37 #[command(subcommand, about = "Conversation analytics")]
38 Conversations(conversations::ConversationsCommands),
39
40 #[command(subcommand, about = "Agent performance analytics")]
41 Agents(agents::AgentsCommands),
42
43 #[command(subcommand, about = "Tool usage analytics")]
44 Tools(tools::ToolsCommands),
45
46 #[command(about = "AI request analytics; defaults to the stats aggregate")]
47 Requests(requests::RequestsArgs),
48
49 #[command(subcommand, about = "Session analytics")]
50 Sessions(sessions::SessionsCommands),
51
52 #[command(subcommand, about = "Content performance analytics")]
53 Content(content::ContentCommands),
54
55 #[command(subcommand, about = "Traffic analytics")]
56 Traffic(traffic::TrafficCommands),
57
58 #[command(about = "Cost analytics; defaults to the spend summary")]
59 Costs(costs::CostsArgs),
60}
61
62pub async fn execute(command: AnalyticsCommands, ctx: &CommandContext) -> Result<()> {
63 if !matches!(&command, AnalyticsCommands::Projection(_)) {
64 let database = ctx.database().await?;
65 let status = systemprompt_runtime::reporting::status(database.db_pool())
66 .await
67 .context("Reporting schema unavailable; apply database migrations first")?;
68 anyhow::ensure!(
69 status.initialized,
70 "Reporting baseline is not initialized; run analytics projection rebuild"
71 );
72 }
73 match command {
74 AnalyticsCommands::Projection(command) => projection::execute(command, ctx).await,
75 AnalyticsCommands::Overview(args) => {
76 let result =
77 overview::execute_with_pool(args, &ctx.database().await?, &ctx.cli).await?;
78 render_result(&result, &ctx.cli);
79 Ok(())
80 },
81 AnalyticsCommands::Conversations(cmd) => conversations::execute(cmd, ctx).await,
82 AnalyticsCommands::Agents(cmd) => agents::execute(cmd, ctx).await,
83 AnalyticsCommands::Tools(cmd) => tools::execute(cmd, ctx).await,
84 AnalyticsCommands::Requests(cmd) => requests::execute(cmd, ctx).await,
85 AnalyticsCommands::Sessions(cmd) => sessions::execute(cmd, ctx).await,
86 AnalyticsCommands::Content(cmd) => content::execute(cmd, ctx).await,
87 AnalyticsCommands::Traffic(cmd) => traffic::execute(cmd, ctx).await,
88 AnalyticsCommands::Costs(cmd) => costs::execute(cmd, ctx).await,
89 }
90}