pub trait SessionStore: Send + Sync {
Show 14 methods
// Required methods
fn save(
&self,
id: &str,
meta: &SessionMeta,
messages: &[AgentMessage],
) -> Result<()>;
fn append(&self, id: &str, messages: &[AgentMessage]) -> Result<()>;
fn load(
&self,
id: &str,
registry: Option<&CustomMessageRegistry>,
) -> Result<(SessionMeta, Vec<AgentMessage>)>;
fn list(&self) -> Result<Vec<SessionMeta>>;
fn delete(&self, id: &str) -> Result<()>;
fn load_with_options(
&self,
id: &str,
options: &LoadOptions,
) -> Result<(SessionMeta, Vec<SessionEntry>)>;
// Provided methods
fn save_full(
&self,
id: &str,
meta: &SessionMeta,
messages: &[AgentMessage],
state: &Value,
) -> Result<SessionMeta> { ... }
fn load_full(
&self,
id: &str,
registry: Option<&CustomMessageRegistry>,
) -> Result<(SessionMeta, Vec<AgentMessage>, Option<Value>)> { ... }
fn save_state(&self, id: &str, state: &Value) -> Result<()> { ... }
fn load_state(&self, id: &str) -> Result<Option<Value>> { ... }
fn save_interrupt(&self, id: &str, state: &InterruptState) -> Result<()> { ... }
fn load_interrupt(&self, id: &str) -> Result<Option<InterruptState>> { ... }
fn clear_interrupt(&self, id: &str) -> Result<()> { ... }
fn search(
&self,
query: &str,
options: &SessionSearchOptions,
) -> Result<Vec<SessionHit>> { ... }
}Expand description
Pluggable session persistence.
All save/load methods use AgentMessage as the canonical message type,
preserving both LLM and custom messages without silent data loss.
The default implementation (JsonlSessionStore)
uses JSONL files, but alternative backends (SQLite, S3, etc.) can
implement this trait directly.
Required Methods§
Sourcefn save(
&self,
id: &str,
meta: &SessionMeta,
messages: &[AgentMessage],
) -> Result<()>
fn save( &self, id: &str, meta: &SessionMeta, messages: &[AgentMessage], ) -> Result<()>
Persist a session, including both LLM and custom messages.
Overwrites any existing session with the same ID. Custom messages that
cannot be serialized are logged and skipped — callers should ensure
custom types implement CustomMessage::to_json and
CustomMessage::type_name.
Sourcefn append(&self, id: &str, messages: &[AgentMessage]) -> Result<()>
fn append(&self, id: &str, messages: &[AgentMessage]) -> Result<()>
Append messages to an existing session without rewriting the entire file.
Sourcefn load(
&self,
id: &str,
registry: Option<&CustomMessageRegistry>,
) -> Result<(SessionMeta, Vec<AgentMessage>)>
fn load( &self, id: &str, registry: Option<&CustomMessageRegistry>, ) -> Result<(SessionMeta, Vec<AgentMessage>)>
Load a session by ID.
If registry is Some, custom messages are deserialized using the
provided registry. If None, custom messages are skipped.
Sourcefn list(&self) -> Result<Vec<SessionMeta>>
fn list(&self) -> Result<Vec<SessionMeta>>
List all saved sessions, sorted by last updated (newest first).
Sourcefn load_with_options(
&self,
id: &str,
options: &LoadOptions,
) -> Result<(SessionMeta, Vec<SessionEntry>)>
fn load_with_options( &self, id: &str, options: &LoadOptions, ) -> Result<(SessionMeta, Vec<SessionEntry>)>
Load a session with filtering options.
Returns metadata and a filtered subset of session entries based on the
provided LoadOptions. Default options return the full session.
Provided Methods§
Sourcefn save_full(
&self,
id: &str,
meta: &SessionMeta,
messages: &[AgentMessage],
state: &Value,
) -> Result<SessionMeta>
fn save_full( &self, id: &str, meta: &SessionMeta, messages: &[AgentMessage], state: &Value, ) -> Result<SessionMeta>
Persist a session transcript plus its state snapshot.
Stores with optimistic-concurrency metadata should return the metadata
as persisted on disk so callers can keep their local sequence in sync.
Backends must implement this explicitly if they support atomic
transcript+state persistence; the default returns
io::ErrorKind::Unsupported so callers do not accidentally rely on a
non-atomic fallback.
Sourcefn load_full(
&self,
id: &str,
registry: Option<&CustomMessageRegistry>,
) -> Result<(SessionMeta, Vec<AgentMessage>, Option<Value>)>
fn load_full( &self, id: &str, registry: Option<&CustomMessageRegistry>, ) -> Result<(SessionMeta, Vec<AgentMessage>, Option<Value>)>
Load a session transcript plus its state snapshot from one consistent read boundary.
Backends must implement this explicitly if they support atomic
transcript+state restore; the default returns
io::ErrorKind::Unsupported so callers do not silently mix
transcript and state revisions via separate reads.
Sourcefn save_state(&self, id: &str, state: &Value) -> Result<()>
fn save_state(&self, id: &str, state: &Value) -> Result<()>
Save session state snapshot.
The default implementation is a no-op that discards the state:
the snapshot is dropped and a later load_state
returns None. It exists only for backward compatibility with
pre-034 store implementations (spec 034 FR-018). The first time the
default runs in a process it emits a tracing::warn! so the data
loss is visible; subsequent calls are silent.
Planned breaking change: save_state will become a required
(non-defaulted) trait method in the next major version bump. Custom
SessionStore implementations should override it (together with
load_state) now.
Sourcefn load_state(&self, id: &str) -> Result<Option<Value>>
fn load_state(&self, id: &str) -> Result<Option<Value>>
Load session state snapshot.
The default implementation always returns Ok(None) (empty state),
even if a matching save_state call appeared to
succeed. It exists only for backward compatibility with pre-034 store
implementations (spec 034 FR-018). The first time the default runs in
a process it emits a tracing::warn! so the silent fallback is
visible; subsequent calls are silent.
Planned breaking change: load_state will become a required
(non-defaulted) trait method in the next major version bump. Custom
SessionStore implementations should override it (together with
save_state) now.
Sourcefn save_interrupt(&self, id: &str, state: &InterruptState) -> Result<()>
fn save_interrupt(&self, id: &str, state: &InterruptState) -> Result<()>
Persist interrupt state for a session.
Stores the interrupt as {session_id}.interrupt.json. Overwrites any
existing interrupt for the same session. Default: no-op.
Sourcefn load_interrupt(&self, id: &str) -> Result<Option<InterruptState>>
fn load_interrupt(&self, id: &str) -> Result<Option<InterruptState>>
Load interrupt state for a session.
Returns Some if an interrupt file exists, None otherwise.
Returns an error if the file exists but is corrupted. Default: None.
Sourcefn clear_interrupt(&self, id: &str) -> Result<()>
fn clear_interrupt(&self, id: &str) -> Result<()>
Clear interrupt state for a session.
Deletes the {session_id}.interrupt.json file. Idempotent — safe to
call if no interrupt exists. Default: no-op.
Sourcefn search(
&self,
query: &str,
options: &SessionSearchOptions,
) -> Result<Vec<SessionHit>>
fn search( &self, query: &str, options: &SessionSearchOptions, ) -> Result<Vec<SessionHit>>
Search across persisted sessions.
Backends that do not support search can rely on the default empty result for backward compatibility.
Dyn Compatibility§
This trait is dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety".