use crate::thread::Thread;
use crate::thread::ThreadChangeSet;
use crate::thread::Version;
use async_trait::async_trait;
use super::{
paginate_in_memory, Committed, MessagePage, MessageQuery, RunPage, RunQuery, RunRecord,
ThreadHead, ThreadListPage, ThreadListQuery, ThreadStoreError, VersionPrecondition,
};
#[async_trait]
pub trait ThreadReader: Send + Sync {
async fn load(&self, thread_id: &str) -> Result<Option<ThreadHead>, ThreadStoreError>;
async fn load_thread(&self, thread_id: &str) -> Result<Option<Thread>, ThreadStoreError> {
Ok(self.load(thread_id).await?.map(|h| h.thread))
}
async fn load_messages(
&self,
thread_id: &str,
query: &MessageQuery,
) -> Result<MessagePage, ThreadStoreError> {
let head = self
.load(thread_id)
.await?
.ok_or_else(|| ThreadStoreError::NotFound(thread_id.to_string()))?;
Ok(paginate_in_memory(&head.thread.messages, query))
}
async fn list_threads(
&self,
query: &ThreadListQuery,
) -> Result<ThreadListPage, ThreadStoreError>;
async fn list(&self) -> Result<Vec<String>, ThreadStoreError> {
let page = self
.list_threads(&ThreadListQuery {
offset: 0,
limit: 200,
resource_id: None,
parent_thread_id: None,
})
.await?;
Ok(page.items)
}
async fn list_paginated(
&self,
query: &ThreadListQuery,
) -> Result<ThreadListPage, ThreadStoreError> {
self.list_threads(query).await
}
async fn message_count(&self, thread_id: &str) -> Result<usize, ThreadStoreError> {
let head = self
.load(thread_id)
.await?
.ok_or_else(|| ThreadStoreError::NotFound(thread_id.to_string()))?;
Ok(head.thread.messages.len())
}
async fn load_run(&self, _run_id: &str) -> Result<Option<RunRecord>, ThreadStoreError> {
Ok(None)
}
async fn list_runs(&self, _query: &RunQuery) -> Result<RunPage, ThreadStoreError> {
Ok(RunPage {
items: vec![],
total: 0,
has_more: false,
})
}
async fn active_run_for_thread(
&self,
_thread_id: &str,
) -> Result<Option<RunRecord>, ThreadStoreError> {
Ok(None)
}
}
#[async_trait]
pub trait ThreadWriter: ThreadReader {
async fn create(&self, thread: &Thread) -> Result<Committed, ThreadStoreError>;
async fn append(
&self,
thread_id: &str,
delta: &ThreadChangeSet,
precondition: VersionPrecondition,
) -> Result<Committed, ThreadStoreError>;
async fn delete(&self, thread_id: &str) -> Result<(), ThreadStoreError>;
async fn save(&self, thread: &Thread) -> Result<(), ThreadStoreError>;
}
#[async_trait]
pub trait ThreadSync: ThreadWriter {
async fn load_deltas(
&self,
thread_id: &str,
after_version: Version,
) -> Result<Vec<ThreadChangeSet>, ThreadStoreError>;
}
pub trait ThreadStore: ThreadWriter {}
impl<T: ThreadWriter + ?Sized> ThreadStore for T {}