Skip to main content

systemprompt_agent/repository/task/constructor/
mod.rs

1//! Reassembly of persisted A2A [`Task`] aggregates from their relational rows.
2//!
3//! [`TaskConstructor`] fans out across the task, message, message-part,
4//! artifact, and execution-step tables and rebuilds the nested [`Task`] graph,
5//! offering both a single-task path and a batched path that amortises the
6//! per-table round trips across many task ids.
7//!
8//! Copyright (c) systemprompt.io — Business Source License 1.1.
9//! See <https://systemprompt.io> for licensing details.
10
11mod batch;
12pub mod batch_builders;
13pub(in crate::repository) mod batch_queries;
14mod converters;
15mod single;
16
17use crate::models::a2a::Task;
18use crate::repository::content::ArtifactRepository;
19use crate::repository::execution::ExecutionStepRepository;
20use sqlx::PgPool;
21use std::sync::Arc;
22use systemprompt_database::DbPool;
23use systemprompt_identifiers::TaskId;
24use systemprompt_traits::RepositoryError;
25
26#[derive(Debug, Clone)]
27pub struct TaskConstructor {
28    pool: Arc<PgPool>,
29    artifact_repo: ArtifactRepository,
30    execution_step_repo: ExecutionStepRepository,
31}
32
33impl TaskConstructor {
34    pub fn new(db: &DbPool) -> Result<Self, crate::error::AgentError> {
35        let pool = db
36            .pool_arc()
37            .map_err(|e| crate::error::AgentError::Init(e.to_string()))?;
38        let artifact_repo = ArtifactRepository::new(db)?;
39        let execution_step_repo = ExecutionStepRepository::new(db)?;
40        Ok(Self {
41            pool,
42            artifact_repo,
43            execution_step_repo,
44        })
45    }
46
47    pub(crate) const fn pool(&self) -> &Arc<PgPool> {
48        &self.pool
49    }
50
51    pub(crate) const fn artifact_repo(&self) -> &ArtifactRepository {
52        &self.artifact_repo
53    }
54
55    pub(crate) const fn execution_step_repo(&self) -> &ExecutionStepRepository {
56        &self.execution_step_repo
57    }
58
59    pub async fn construct_task_from_task_id(
60        &self,
61        task_id: &TaskId,
62    ) -> Result<Task, RepositoryError> {
63        single::construct_task_from_task_id(self, task_id).await
64    }
65
66    pub async fn construct_tasks_batch(
67        &self,
68        task_ids: &[TaskId],
69    ) -> Result<Vec<Task>, RepositoryError> {
70        batch::construct_tasks_batch(self, task_ids).await
71    }
72}