Skip to main content

systemprompt_cli/commands/analytics/conversations/
mod.rs

1mod list;
2mod stats;
3mod trends;
4
5use anyhow::Result;
6use clap::Subcommand;
7use schemars::JsonSchema;
8use serde::{Deserialize, Serialize};
9use systemprompt_runtime::DatabaseContext;
10
11use crate::CliConfig;
12
13#[derive(Debug, Subcommand)]
14pub enum ConversationsCommands {
15    #[command(about = "Conversation statistics")]
16    Stats(stats::StatsArgs),
17
18    #[command(about = "Conversation trends over time")]
19    Trends(trends::TrendsArgs),
20
21    #[command(about = "List conversations")]
22    List(list::ListArgs),
23}
24
25#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
26pub struct ConversationStatsOutput {
27    pub period: String,
28    pub total_contexts: i64,
29    pub total_tasks: i64,
30    pub total_messages: i64,
31    pub avg_messages_per_task: f64,
32    pub avg_task_duration_ms: i64,
33}
34
35#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
36pub struct ConversationTrendPoint {
37    pub timestamp: String,
38    pub context_count: i64,
39    pub task_count: i64,
40    pub message_count: i64,
41}
42
43#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
44pub struct ConversationTrendsOutput {
45    pub period: String,
46    pub group_by: String,
47    pub points: Vec<ConversationTrendPoint>,
48}
49
50#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
51pub struct ConversationListRow {
52    pub context_id: String,
53    pub name: Option<String>,
54    pub task_count: i64,
55    pub message_count: i64,
56    pub created_at: String,
57    pub updated_at: String,
58}
59
60#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
61pub struct ConversationListOutput {
62    pub conversations: Vec<ConversationListRow>,
63    pub total: i64,
64}
65
66pub async fn execute(command: ConversationsCommands, config: &CliConfig) -> Result<()> {
67    match command {
68        ConversationsCommands::Stats(args) => stats::execute(args, config).await,
69        ConversationsCommands::Trends(args) => trends::execute(args, config).await,
70        ConversationsCommands::List(args) => list::execute(args, config).await,
71    }
72}
73
74pub async fn execute_with_pool(
75    command: ConversationsCommands,
76    db_ctx: &DatabaseContext,
77    config: &CliConfig,
78) -> Result<()> {
79    match command {
80        ConversationsCommands::Stats(args) => stats::execute_with_pool(args, db_ctx, config).await,
81        ConversationsCommands::Trends(args) => {
82            trends::execute_with_pool(args, db_ctx, config).await
83        },
84        ConversationsCommands::List(args) => list::execute_with_pool(args, db_ctx, config).await,
85    }
86}