Skip to main content

agentics_persistence/repositories/
solution_submissions.rs

1use sqlx::PgPool;
2
3use crate::db;
4use crate::repositories::{
5    AdminSolutionSubmissionListItemRecord, CreateSolutionSubmissionInput,
6    PublicObserverStatsRecord, PublicSolutionSubmissionListItemRecord,
7};
8use agentics_domain::models::evaluation::ScoringMode;
9use agentics_domain::models::ids::{AgentId, SolutionSubmissionId};
10use agentics_domain::models::names::{ChallengeName, TargetName};
11use agentics_error::Result;
12
13#[derive(Debug, Clone, Copy)]
14pub struct SolutionSubmissionsRepository<'a> {
15    pub(super) pool: &'a PgPool,
16}
17
18impl SolutionSubmissionsRepository<'_> {
19    pub async fn create_with_job(
20        &self,
21        input: &CreateSolutionSubmissionInput,
22    ) -> Result<crate::repositories::SolutionSubmissionRecord> {
23        db::solution_submissions::create_solution_submission_with_job(self.pool, input).await
24    }
25
26    pub async fn ensure_parent_matches_scope(
27        &self,
28        parent_solution_submission_id: Option<&SolutionSubmissionId>,
29        agent_id: &AgentId,
30        challenge_name: &ChallengeName,
31        target: &TargetName,
32    ) -> Result<()> {
33        db::solution_submissions::ensure_parent_solution_submission_matches_scope(
34            self.pool,
35            parent_solution_submission_id,
36            agent_id,
37            challenge_name,
38            target,
39        )
40        .await
41    }
42
43    pub async fn delete(&self, solution_submission_id: &SolutionSubmissionId) -> Result<()> {
44        db::solution_submissions::delete_solution_submission(self.pool, solution_submission_id)
45            .await
46    }
47
48    pub async fn get_by_id(
49        &self,
50        id: &SolutionSubmissionId,
51    ) -> Result<Option<crate::repositories::SolutionSubmissionRecord>> {
52        db::solution_submissions::get_solution_submission_by_id(self.pool, id).await
53    }
54
55    pub async fn get_public_by_id(
56        &self,
57        id: &SolutionSubmissionId,
58    ) -> Result<Option<crate::repositories::SolutionSubmissionRecord>> {
59        db::solution_submissions::get_public_solution_submission_by_id(self.pool, id).await
60    }
61
62    pub async fn list_admin(
63        &self,
64        limit: i64,
65    ) -> Result<Vec<AdminSolutionSubmissionListItemRecord>> {
66        db::solution_submissions::list_admin_solution_submissions(self.pool, limit).await
67    }
68
69    pub async fn list_public_for_challenge(
70        &self,
71        challenge_name: &ChallengeName,
72        target: &TargetName,
73        limit: i64,
74    ) -> Result<Vec<PublicSolutionSubmissionListItemRecord>> {
75        db::solution_submissions::list_public_solution_submissions_for_challenge(
76            self.pool,
77            challenge_name,
78            target,
79            limit,
80        )
81        .await
82    }
83
84    pub async fn count_public_for_challenge(
85        &self,
86        challenge_name: &ChallengeName,
87        target: &TargetName,
88    ) -> Result<i64> {
89        db::solution_submissions::count_public_solution_submissions_for_challenge(
90            self.pool,
91            challenge_name,
92            target,
93        )
94        .await
95    }
96
97    pub async fn observer_stats(&self) -> Result<PublicObserverStatsRecord> {
98        db::solution_submissions::public_observer_stats(self.pool).await
99    }
100
101    pub async fn count_recent_runs_for_agent_challenge(
102        &self,
103        agent_id: &AgentId,
104        challenge_name: &ChallengeName,
105        target: &TargetName,
106        eval_type: ScoringMode,
107        window_seconds: i64,
108    ) -> Result<i64> {
109        db::validation_quotas::count_recent_runs_for_agent_challenge(
110            self.pool,
111            agent_id,
112            challenge_name,
113            target,
114            eval_type,
115            window_seconds,
116        )
117        .await
118    }
119
120    pub async fn count_lifetime_runs_for_agent_challenge(
121        &self,
122        agent_id: &AgentId,
123        challenge_name: &ChallengeName,
124        target: &TargetName,
125        eval_type: ScoringMode,
126    ) -> Result<i64> {
127        db::validation_quotas::count_lifetime_runs_for_agent_challenge(
128            self.pool,
129            agent_id,
130            challenge_name,
131            target,
132            eval_type,
133        )
134        .await
135    }
136}