systemprompt_cli/commands/analytics/conversations/
mod.rs1mod list;
12mod stats;
13mod trends;
14
15use anyhow::Result;
16use clap::Subcommand;
17use schemars::JsonSchema;
18use serde::{Deserialize, Serialize};
19
20use crate::context::CommandContext;
21use crate::shared::render_result;
22
23#[derive(Debug, Subcommand)]
24pub enum ConversationsCommands {
25 #[command(about = "Conversation statistics")]
26 Stats(stats::StatsArgs),
27
28 #[command(about = "Conversation trends over time")]
29 Trends(trends::TrendsArgs),
30
31 #[command(about = "List conversations")]
32 List(list::ListArgs),
33}
34
35#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
36pub struct ConversationStatsOutput {
37 pub period: String,
38 pub total_contexts: i64,
39 pub total_tasks: i64,
40 pub total_messages: i64,
41 pub avg_messages_per_task: f64,
42 pub avg_task_duration_ms: i64,
43}
44
45#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
46pub struct ConversationTrendPoint {
47 pub timestamp: String,
48 pub context_count: i64,
49 pub task_count: i64,
50 pub message_count: i64,
51}
52
53#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
54pub struct ConversationTrendsOutput {
55 pub period: String,
56 pub group_by: String,
57 pub points: Vec<ConversationTrendPoint>,
58}
59
60#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
61pub struct ConversationListRow {
62 #[serde(rename = "context_id")]
63 pub context: String,
64 pub name: Option<String>,
65 pub task_count: i64,
66 pub message_count: i64,
67 pub created_at: String,
68 pub updated_at: String,
69}
70
71#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
72pub struct ConversationListOutput {
73 pub conversations: Vec<ConversationListRow>,
74 pub total: i64,
75}
76
77pub async fn execute(command: ConversationsCommands, ctx: &CommandContext) -> Result<()> {
78 let db_ctx = ctx.database().await?;
79 match command {
80 ConversationsCommands::Stats(args) => {
81 let result = stats::execute_with_pool(args, &db_ctx, &ctx.cli).await?;
82 render_result(&result, &ctx.cli);
83 Ok(())
84 },
85 ConversationsCommands::Trends(args) => {
86 let result = trends::execute_with_pool(args, &db_ctx, &ctx.cli).await?;
87 render_result(&result, &ctx.cli);
88 Ok(())
89 },
90 ConversationsCommands::List(args) => {
91 let result = list::execute_with_pool(args, &db_ctx, &ctx.cli).await?;
92 render_result(&result, &ctx.cli);
93 Ok(())
94 },
95 }
96}