Skip to main content

systemprompt_analytics/services/
ai_provider.rs

1//! `AiSessionProvider` implementation backed by analytics session rows.
2//!
3//! Copyright (c) systemprompt.io — Business Source License 1.1.
4//! See <https://systemprompt.io> for licensing details.
5
6use async_trait::async_trait;
7use systemprompt_identifiers::SessionId;
8use systemprompt_traits::{
9    AiProviderError, AiProviderResult, AiSessionProvider, CreateAiSessionParams,
10};
11
12use crate::repository::{CreateSessionParams, SessionRepository};
13
14#[derive(Debug)]
15pub struct AnalyticsAiSessionProvider {
16    session_repo: SessionRepository,
17}
18
19impl AnalyticsAiSessionProvider {
20    pub const fn from_repository(session_repo: SessionRepository) -> Self {
21        Self { session_repo }
22    }
23}
24
25#[async_trait]
26impl AiSessionProvider for AnalyticsAiSessionProvider {
27    async fn create_session(&self, params: CreateAiSessionParams<'_>) -> AiProviderResult<()> {
28        let full_params = CreateSessionParams {
29            session_id: params.session_id,
30            user_id: params.user_id,
31            session_source: params.session_source,
32            fingerprint_hash: None,
33            ip_address: None,
34            user_agent: None,
35            device_type: None,
36            browser: None,
37            os: None,
38            country: None,
39            region: None,
40            city: None,
41            preferred_locale: None,
42            referrer_source: None,
43            referrer_url: None,
44            landing_page: None,
45            entry_url: None,
46            utm_source: None,
47            utm_medium: None,
48            utm_campaign: None,
49            utm_content: None,
50            utm_term: None,
51            is_bot: false,
52            is_ai_crawler: false,
53            expires_at: params.expires_at,
54        };
55
56        self.session_repo
57            .create_session(&full_params)
58            .await
59            .map_err(|e| AiProviderError::Internal(e.to_string()))
60    }
61
62    async fn increment_ai_usage(
63        &self,
64        session_id: &SessionId,
65        tokens: i32,
66        cost_microdollars: i64,
67    ) -> AiProviderResult<()> {
68        self.session_repo
69            .increment_ai_usage(session_id, tokens, cost_microdollars)
70            .await
71            .map_err(|e| AiProviderError::Internal(e.to_string()))
72    }
73}