use crate::{error::StorageError, shared::Message};
use async_trait::async_trait;
use serde::{Deserialize, Serialize};
#[derive(Deserialize, Serialize, Debug, Clone)]
pub struct Transcript {
pub session_id: String,
pub messages: Vec<Message>,
pub parent: Option<String>,
pub subsessions: Vec<String>,
}
impl Transcript {
pub fn new(session_id: &str) -> Self {
Self {
session_id: String::from(session_id),
messages: Vec::new(),
parent: None,
subsessions: Vec::new(),
}
}
pub fn with_parent(session_id: &str, parent_session_id: &str) -> Self {
Self {
parent: Some(parent_session_id.to_string()),
..Self::new(session_id)
}
}
pub fn append(&mut self, message: Message) {
self.messages.push(message);
}
}
#[async_trait]
pub trait TranscriptStorage: Send + Sync {
async fn save_transcript(
&self,
session_id: &str,
transcript: &Transcript,
) -> Result<(), StorageError>;
async fn get_transcript(&self, session_id: &str) -> Result<Option<Transcript>, StorageError>;
async fn append_message(&self, session_id: &str, message: Message) -> Result<(), StorageError> {
self.append_messages(session_id, vec![message]).await
}
async fn append_messages(
&self,
session_id: &str,
messages: Vec<Message>,
) -> Result<(), StorageError> {
let mut transcript = self
.get_transcript(session_id)
.await?
.unwrap_or_else(|| Transcript::new(session_id));
for message in messages {
transcript.append(message);
}
self.save_transcript(session_id, &transcript).await
}
async fn add_subsession(
&self,
parent_session_id: &str,
child_session_id: &str,
) -> Result<(), StorageError> {
let mut transcript = self
.get_transcript(parent_session_id)
.await?
.unwrap_or_else(|| Transcript::new(parent_session_id));
if !transcript
.subsessions
.iter()
.any(|s| s == child_session_id)
{
transcript.subsessions.push(child_session_id.to_string());
self.save_transcript(parent_session_id, &transcript).await?;
}
Ok(())
}
async fn get_subsessions(&self, session_id: &str) -> Result<Vec<String>, StorageError> {
Ok(self
.get_transcript(session_id)
.await?
.map(|t| t.subsessions)
.unwrap_or_default())
}
async fn remove_transcript(&self, session_id: &str) -> Result<(), StorageError>;
async fn delete_transcript(&self, session_id: &str) -> Result<(), StorageError> {
for child in self.get_subsessions(session_id).await? {
self.delete_transcript(&child).await?;
}
self.remove_transcript(session_id).await
}
}