systemprompt_analytics/services/
ai_provider.rs1use async_trait::async_trait;
7use systemprompt_database::DbPool;
8use systemprompt_identifiers::SessionId;
9use systemprompt_traits::{
10 AiProviderError, AiProviderResult, AiSessionProvider, CreateAiSessionParams,
11};
12
13use crate::repository::{CreateSessionParams, SessionRepository};
14
15#[derive(Debug)]
16pub struct AnalyticsAiSessionProvider {
17 session_repo: SessionRepository,
18}
19
20impl AnalyticsAiSessionProvider {
21 pub fn new(pool: &DbPool) -> crate::Result<Self> {
22 Ok(Self {
23 session_repo: SessionRepository::new(pool)?,
24 })
25 }
26
27 pub const fn from_repository(session_repo: SessionRepository) -> Self {
28 Self { session_repo }
29 }
30}
31
32#[async_trait]
33impl AiSessionProvider for AnalyticsAiSessionProvider {
34 async fn session_exists(&self, session_id: &SessionId) -> AiProviderResult<bool> {
35 self.session_repo
36 .exists(session_id)
37 .await
38 .map_err(|e| AiProviderError::Internal(e.to_string()))
39 }
40
41 async fn create_session(&self, params: CreateAiSessionParams<'_>) -> AiProviderResult<()> {
42 let full_params = CreateSessionParams {
43 session_id: params.session_id,
44 user_id: params.user_id,
45 session_source: params.session_source,
46 fingerprint_hash: None,
47 ip_address: None,
48 user_agent: None,
49 device_type: None,
50 browser: None,
51 os: None,
52 country: None,
53 region: None,
54 city: None,
55 preferred_locale: None,
56 referrer_source: None,
57 referrer_url: None,
58 landing_page: None,
59 entry_url: None,
60 utm_source: None,
61 utm_medium: None,
62 utm_campaign: None,
63 utm_content: None,
64 utm_term: None,
65 is_bot: false,
66 is_ai_crawler: false,
67 expires_at: params.expires_at,
68 };
69
70 self.session_repo
71 .create_session(&full_params)
72 .await
73 .map_err(|e| AiProviderError::Internal(e.to_string()))
74 }
75
76 async fn increment_ai_usage(
77 &self,
78 session_id: &SessionId,
79 tokens: i32,
80 cost_microdollars: i64,
81 ) -> AiProviderResult<()> {
82 self.session_repo
83 .increment_ai_usage(session_id, tokens, cost_microdollars)
84 .await
85 .map_err(|e| AiProviderError::Internal(e.to_string()))
86 }
87}