pub struct SessionManager<P: Platform> { /* private fields */ }Expand description
Manages conversation sessions with in-memory caching and JSONL persistence.
Sessions are identified by a string key (typically "{channel}:{chat_id}").
The manager uses a write-through cache: reads check the in-memory cache
first, then fall back to loading from disk. Writes update both the cache
and the JSONL file.
§JSONL format
Each session file is named {sanitized_key}.jsonl and contains:
- Line 1: metadata object with
_type,created_at,updated_at,metadata, andlast_consolidatedfields. - Lines 2+: message objects with
role,content, andtimestampfields.
§Platform abstraction
All filesystem I/O goes through the Platform::fs() trait, making
SessionManager testable with mock filesystems and WASM-portable.
Implementations§
Source§impl<P: Platform> SessionManager<P>
impl<P: Platform> SessionManager<P>
Sourcepub async fn new(platform: Arc<P>) -> Result<Self>
pub async fn new(platform: Arc<P>) -> Result<Self>
Create a new session manager using the given platform.
Discovers the sessions directory by checking:
~/.clawft/workspace/sessions/~/.nanobot/workspace/sessions/(legacy fallback)
If neither exists, defaults to ~/.clawft/workspace/sessions/ and
creates it. Returns an error if the home directory cannot be determined.
Sourcepub fn with_dir(platform: Arc<P>, sessions_dir: PathBuf) -> Self
pub fn with_dir(platform: Arc<P>, sessions_dir: PathBuf) -> Self
Create a session manager with an explicit sessions directory.
Useful for testing or when the directory is already known.
Sourcepub async fn get_or_create(&self, key: &str) -> Result<Session>
pub async fn get_or_create(&self, key: &str) -> Result<Session>
Get an existing session or create a new one.
Checks the in-memory cache first, then attempts to load from disk. If neither succeeds, creates a fresh empty session and caches it.
§Errors
Returns an error if key fails session-ID validation.
Sourcepub async fn load_session(&self, key: &str) -> Result<Session>
pub async fn load_session(&self, key: &str) -> Result<Session>
Load a session from its JSONL file on disk.
Parses the first line as metadata and remaining lines as messages. Returns an error if the file does not exist or contains invalid JSON.
Includes a migration path: if the percent-encoded file does not exist but the old underscore-encoded file does, the content is copied to the new filename (the old file is preserved for safety).
Sourcepub async fn save_session(&self, session: &Session) -> Result<()>
pub async fn save_session(&self, session: &Session) -> Result<()>
Save a session to its JSONL file on disk.
Writes the full session: metadata line followed by all message lines. Also updates the in-memory cache.
Sourcepub async fn append_turn(
&self,
key: &str,
role: &str,
content: &str,
) -> Result<()>
pub async fn append_turn( &self, key: &str, role: &str, content: &str, ) -> Result<()>
Append a single conversation turn to a session.
Updates both the in-memory cache and appends to the JSONL file on disk.
If the session does not exist yet, it is created via [get_or_create].
Sourcepub async fn list_sessions(&self) -> Result<Vec<String>>
pub async fn list_sessions(&self) -> Result<Vec<String>>
List all session keys (derived from .jsonl filenames on disk).
Decodes percent-encoded filenames back to the original session key. Files that cannot be decoded as valid UTF-8 are skipped with a warning.
Sourcepub async fn invalidate(&self, key: &str)
pub async fn invalidate(&self, key: &str)
Remove a session from the in-memory cache.
The JSONL file on disk is not deleted; only the cached copy is
evicted. The next [get_or_create] call will reload from disk.
Sourcepub async fn delete_session(&self, key: &str) -> Result<()>
pub async fn delete_session(&self, key: &str) -> Result<()>
Delete a session file from disk and remove from cache.
Sourcepub fn sessions_dir(&self) -> &PathBuf
pub fn sessions_dir(&self) -> &PathBuf
Get the sessions directory path.
Auto Trait Implementations§
impl<P> Freeze for SessionManager<P>
impl<P> !RefUnwindSafe for SessionManager<P>
impl<P> Send for SessionManager<P>
impl<P> Sync for SessionManager<P>
impl<P> Unpin for SessionManager<P>
impl<P> UnsafeUnpin for SessionManager<P>
impl<P> !UnwindSafe for SessionManager<P>
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more