Skip to main content

systemprompt_analytics/repository/agents/
stats_queries.rs

1use anyhow::Result;
2use chrono::{DateTime, Utc};
3
4use super::AgentAnalyticsRepository;
5use crate::models::cli::{AgentAiStatsRow, AgentStatsRow, AgentTaskRow};
6
7impl AgentAnalyticsRepository {
8    pub async fn get_stats(
9        &self,
10        start: DateTime<Utc>,
11        end: DateTime<Utc>,
12        agent_filter: Option<&str>,
13    ) -> Result<AgentStatsRow> {
14        if let Some(agent) = agent_filter {
15            let pattern = format!("%{}%", agent);
16            sqlx::query_as!(
17                AgentStatsRow,
18                r#"
19                SELECT
20                    COUNT(DISTINCT agent_name)::bigint as "total_agents!",
21                    COUNT(*)::bigint as "total_tasks!",
22                    COUNT(*) FILTER (WHERE status = 'completed')::bigint as "completed_tasks!",
23                    COUNT(*) FILTER (WHERE status = 'failed')::bigint as "failed_tasks!",
24                    COALESCE(AVG(execution_time_ms)::float8, 0) as "avg_execution_time_ms!"
25                FROM agent_tasks
26                WHERE started_at >= $1 AND started_at < $2
27                  AND agent_name ILIKE $3
28                "#,
29                start,
30                end,
31                pattern
32            )
33            .fetch_one(&*self.pool)
34            .await
35            .map_err(Into::into)
36        } else {
37            sqlx::query_as!(
38                AgentStatsRow,
39                r#"
40                SELECT
41                    COUNT(DISTINCT agent_name)::bigint as "total_agents!",
42                    COUNT(*)::bigint as "total_tasks!",
43                    COUNT(*) FILTER (WHERE status = 'completed')::bigint as "completed_tasks!",
44                    COUNT(*) FILTER (WHERE status = 'failed')::bigint as "failed_tasks!",
45                    COALESCE(AVG(execution_time_ms)::float8, 0) as "avg_execution_time_ms!"
46                FROM agent_tasks
47                WHERE started_at >= $1 AND started_at < $2
48                "#,
49                start,
50                end
51            )
52            .fetch_one(&*self.pool)
53            .await
54            .map_err(Into::into)
55        }
56    }
57
58    pub async fn get_ai_stats(
59        &self,
60        start: DateTime<Utc>,
61        end: DateTime<Utc>,
62    ) -> Result<AgentAiStatsRow> {
63        sqlx::query_as!(
64            AgentAiStatsRow,
65            r#"
66            SELECT
67                COUNT(*)::bigint as "total_ai_requests!",
68                COALESCE(SUM(cost_cents), 0)::bigint as "total_cost_cents!"
69            FROM ai_requests
70            WHERE created_at >= $1 AND created_at < $2
71            "#,
72            start,
73            end
74        )
75        .fetch_one(&*self.pool)
76        .await
77        .map_err(Into::into)
78    }
79
80    pub async fn get_tasks_for_trends(
81        &self,
82        start: DateTime<Utc>,
83        end: DateTime<Utc>,
84        agent_filter: Option<&str>,
85    ) -> Result<Vec<AgentTaskRow>> {
86        if let Some(agent) = agent_filter {
87            let pattern = format!("%{}%", agent);
88            sqlx::query_as!(
89                AgentTaskRow,
90                r#"
91                SELECT
92                    started_at as "started_at!",
93                    status,
94                    execution_time_ms
95                FROM agent_tasks
96                WHERE started_at >= $1 AND started_at < $2
97                  AND agent_name ILIKE $3
98                ORDER BY started_at
99                "#,
100                start,
101                end,
102                pattern
103            )
104            .fetch_all(&*self.pool)
105            .await
106            .map_err(Into::into)
107        } else {
108            sqlx::query_as!(
109                AgentTaskRow,
110                r#"
111                SELECT
112                    started_at as "started_at!",
113                    status,
114                    execution_time_ms
115                FROM agent_tasks
116                WHERE started_at >= $1 AND started_at < $2
117                ORDER BY started_at
118                "#,
119                start,
120                end
121            )
122            .fetch_all(&*self.pool)
123            .await
124            .map_err(Into::into)
125        }
126    }
127}