pub trait HistoryStore: Send + Sync {
type Error: Error + Send + Sync + 'static;
// Required methods
fn save<'life0, 'life1, 'async_trait>(
&'life0 self,
snapshot: &'life1 ConversationSnapshot,
) -> Pin<Box<dyn Future<Output = Result<(), Self::Error>> + Send + 'async_trait>>
where 'life0: 'async_trait,
'life1: 'async_trait,
Self: 'async_trait;
fn load<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<Option<ConversationSnapshot>, Self::Error>> + Send + 'async_trait>>
where 'life0: 'async_trait,
Self: 'async_trait;
}Expand description
Persistence backend for conversation snapshots.
Implement this trait to durable-back a conversation in any store
you like (Redis, Postgres, S3, sled, …). The crate ships
InMemoryHistoryStore for tests and JsonFileHistoryStore for
single-file local persistence.
§Concurrency
The trait is async; impls are free to use any backend. The
façade Conversation does not serialize
access to a single store across runs — a process running multiple
conversations against the same backend should use one store per
RunId (or implement its own locking). A single Conversation
only writes from one task at a time, so per-conversation impls do
not need internal mutexes for that reason alone.
Required Associated Types§
Sourcetype Error: Error + Send + Sync + 'static
type Error: Error + Send + Sync + 'static
Error type surfaced from save /
load. Use std::convert::Infallible when the
implementation cannot fail (see InMemoryHistoryStore).
Required Methods§
Sourcefn save<'life0, 'life1, 'async_trait>(
&'life0 self,
snapshot: &'life1 ConversationSnapshot,
) -> Pin<Box<dyn Future<Output = Result<(), Self::Error>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
Self: 'async_trait,
fn save<'life0, 'life1, 'async_trait>(
&'life0 self,
snapshot: &'life1 ConversationSnapshot,
) -> Pin<Box<dyn Future<Output = Result<(), Self::Error>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
Self: 'async_trait,
Persist snapshot so a later load returns it.
Implementations should treat this as an overwrite — the façade
passes the full updated ConversationSnapshot every time
rather than diffing.
Sourcefn load<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<Option<ConversationSnapshot>, Self::Error>> + Send + 'async_trait>>where
'life0: 'async_trait,
Self: 'async_trait,
fn load<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<Option<ConversationSnapshot>, Self::Error>> + Send + 'async_trait>>where
'life0: 'async_trait,
Self: 'async_trait,
Return the most recently persisted snapshot, or Ok(None) when
the store has never been written to. Returning Ok(None) lets
callers default-init the conversation on first run instead of
special-casing a missing payload.