use crate::models::TaskRow;
use crate::models::a2a::{Message, MessageRole, Part, TaskState};
use crate::models::database_rows::TaskMessage;
use systemprompt_models::a2a::TaskMetadata;
use systemprompt_models::errors::ParseEnumError;
use systemprompt_traits::RepositoryError;
pub(super) fn parse_task_state(row: &TaskRow) -> Result<TaskState, RepositoryError> {
row.status
.parse()
.map_err(|e: ParseEnumError| RepositoryError::decode("stored task state", e))
}
pub(super) fn message_from_row(row: TaskMessage, parts: Vec<Part>) -> Message {
let reference_task_ids = row.reference_task_ids.map(|ids| {
ids.into_iter()
.map(systemprompt_identifiers::TaskId::new)
.collect()
});
let mut final_metadata = row.metadata.unwrap_or_else(|| serde_json::json!({}));
if let Some(client_id) = &row.client_message_id
&& let Some(obj) = final_metadata.as_object_mut()
{
obj.insert(
"clientMessageId".to_owned(),
serde_json::Value::String(client_id.clone()),
);
}
let role = match row.role.as_str() {
"user" | "ROLE_USER" => MessageRole::User,
_ => MessageRole::Agent,
};
Message {
role,
parts,
message_id: row.message_id,
task_id: Some(row.task_id),
context_id: row.context_id,
metadata: if final_metadata == serde_json::json!({}) {
None
} else {
Some(final_metadata)
},
extensions: None,
reference_task_ids,
}
}
pub(super) fn construct_metadata(row: &TaskRow) -> Result<TaskMetadata, RepositoryError> {
let agent_name = row
.agent_name
.as_ref()
.map(ToString::to_string)
.ok_or_else(|| {
RepositoryError::invalid_data("agent_name", format!("missing for task {}", row.task_id))
})?;
let mut metadata = match row.metadata.as_ref() {
None => TaskMetadata::new_agent_message(agent_name.clone()),
Some(value) if value.as_object().is_some_and(serde_json::Map::is_empty) => {
TaskMetadata::new_agent_message(agent_name.clone())
},
Some(value) => serde_json::from_value::<TaskMetadata>(value.clone())
.map_err(|e| RepositoryError::decode(format!("task {} metadata", row.task_id), e))?,
};
metadata.agent_name = agent_name;
metadata.created_at = row.created_at.to_rfc3339();
metadata.updated_at = Some(row.updated_at.to_rfc3339());
metadata.started_at = row.started_at.map(|dt| dt.to_rfc3339());
metadata.completed_at = row.completed_at.map(|dt| dt.to_rfc3339());
metadata.execution_time_ms = row.execution_time_ms.map(i64::from);
Ok(metadata)
}