pub trait AssistantSessionStore:
Send
+ Sync
+ 'static {
// Required methods
fn put_assistant_session<'life0, 'async_trait>(
&'life0 self,
record: AssistantSessionRecord,
) -> Pin<Box<dyn Future<Output = Result<(), StoreError>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait;
fn get_assistant_session<'life0, 'life1, 'async_trait>(
&'life0 self,
session_id: &'life1 AssistantSessionId,
) -> Pin<Box<dyn Future<Output = Result<Option<AssistantSessionRecord>, StoreError>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait;
fn list_assistant_sessions<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<AssistantSessionListing, StoreError>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait;
fn append_assistant_transcript_event<'life0, 'life1, 'async_trait>(
&'life0 self,
session_id: &'life1 AssistantSessionId,
recorded_at: DateTime<Utc>,
payload: Payload,
) -> Pin<Box<dyn Future<Output = Result<u64, StoreError>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait;
fn assistant_transcript_head<'life0, 'life1, 'async_trait>(
&'life0 self,
session_id: &'life1 AssistantSessionId,
) -> Pin<Box<dyn Future<Output = Result<u64, StoreError>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait;
fn assistant_transcript<'life0, 'life1, 'async_trait>(
&'life0 self,
session_id: &'life1 AssistantSessionId,
after: Option<u64>,
) -> Pin<Box<dyn Future<Output = Result<Vec<AssistantTranscriptEvent>, StoreError>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait;
fn put_assistant_default_harness<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
subject: &'life1 str,
harness: &'life2 str,
) -> Pin<Box<dyn Future<Output = Result<(), StoreError>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait;
fn assistant_default_harness<'life0, 'life1, 'async_trait>(
&'life0 self,
subject: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<Option<String>, StoreError>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait;
}Expand description
Durable assistant-session persistence contract.
Implemented by every backend and exercised by
crate::conformance::run_assistant_session_suite against all of them, so
the index-assignment and poisoned-row guarantees are properties of the
CONTRACT rather than of whichever backend a deployment happens to run.
Required Methods§
Sourcefn put_assistant_session<'life0, 'async_trait>(
&'life0 self,
record: AssistantSessionRecord,
) -> Pin<Box<dyn Future<Output = Result<(), StoreError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn put_assistant_session<'life0, 'async_trait>(
&'life0 self,
record: AssistantSessionRecord,
) -> Pin<Box<dyn Future<Output = Result<(), StoreError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Create or replace a session’s record.
Sourcefn get_assistant_session<'life0, 'life1, 'async_trait>(
&'life0 self,
session_id: &'life1 AssistantSessionId,
) -> Pin<Box<dyn Future<Output = Result<Option<AssistantSessionRecord>, StoreError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn get_assistant_session<'life0, 'life1, 'async_trait>(
&'life0 self,
session_id: &'life1 AssistantSessionId,
) -> Pin<Box<dyn Future<Output = Result<Option<AssistantSessionRecord>, StoreError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Look up one session by id.
Sourcefn list_assistant_sessions<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<AssistantSessionListing, StoreError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn list_assistant_sessions<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<AssistantSessionListing, StoreError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
List decodable sessions and report every undecodable row, ordered by
created_at then session id.
Unfiltered: a store enumerates what it holds, and the per-caller narrowing is the server’s authorization decision, made where the caller identity is.
Sourcefn append_assistant_transcript_event<'life0, 'life1, 'async_trait>(
&'life0 self,
session_id: &'life1 AssistantSessionId,
recorded_at: DateTime<Utc>,
payload: Payload,
) -> Pin<Box<dyn Future<Output = Result<u64, StoreError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn append_assistant_transcript_event<'life0, 'life1, 'async_trait>(
&'life0 self,
session_id: &'life1 AssistantSessionId,
recorded_at: DateTime<Utc>,
payload: Payload,
) -> Pin<Box<dyn Future<Output = Result<u64, StoreError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Append one event to a session’s transcript, returning the index the store assigned it.
The index is the store’s to give: it is the next index after the last
stored one, committed under the backend’s optimistic-concurrency
discipline so two appenders racing on one session get n and n+1 and
never n twice. A caller cannot pass an index and so cannot mint a
duplicate.
§Errors
StoreError::AssistantSessionNotFound when no record exists for
session_id — an append never silently creates a session, because a
transcript with no record is a conversation with no owner. Otherwise a
backend or serialization error.
Sourcefn assistant_transcript_head<'life0, 'life1, 'async_trait>(
&'life0 self,
session_id: &'life1 AssistantSessionId,
) -> Pin<Box<dyn Future<Output = Result<u64, StoreError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn assistant_transcript_head<'life0, 'life1, 'async_trait>(
&'life0 self,
session_id: &'life1 AssistantSessionId,
) -> Pin<Box<dyn Future<Output = Result<u64, StoreError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
The next index the store would assign this session — equivalently, how many events its transcript holds.
An unwritten transcript reads 0. Cheap on every backend (it reads
stream metadata, never the events), which is what lets a listing find
each session’s last record without reading its whole conversation.
Sourcefn assistant_transcript<'life0, 'life1, 'async_trait>(
&'life0 self,
session_id: &'life1 AssistantSessionId,
after: Option<u64>,
) -> Pin<Box<dyn Future<Output = Result<Vec<AssistantTranscriptEvent>, StoreError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn assistant_transcript<'life0, 'life1, 'async_trait>(
&'life0 self,
session_id: &'life1 AssistantSessionId,
after: Option<u64>,
) -> Pin<Box<dyn Future<Output = Result<Vec<AssistantTranscriptEvent>, StoreError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
A session’s transcript in index order, excluding every event at or below
after.
None reads the whole transcript. An unknown session reads empty rather
than refusing: a read of a session that is not there is an absence, and
the refusal that matters is on the WRITE.
Sourcefn put_assistant_default_harness<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
subject: &'life1 str,
harness: &'life2 str,
) -> Pin<Box<dyn Future<Output = Result<(), StoreError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
fn put_assistant_default_harness<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
subject: &'life1 str,
harness: &'life2 str,
) -> Pin<Box<dyn Future<Output = Result<(), StoreError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Remember the harness subject last opened a session on.
Written by createSession and by nothing else: the memory is a record of
what the operator DID, not a preference they set, so there is no second
door through which it could say something a session never said.
It lives in the store rather than in the process because it must survive a restart — an operator who picked Claude Code yesterday must not be asked again this morning — and CALLER-scoped because it is one person’s last choice, not a deployment default.
Dyn Compatibility§
This trait is dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety".