Skip to main content

StateStore

Struct StateStore 

Source
pub struct StateStore { /* private fields */ }
Expand description

Persistent storage for conversation threads, messages, checkpoints, and jobs.

Backed by a SQLite database and an append-only JSONL session index file. The database schema is automatically initialized and migrated on open.

Implementations§

Source§

impl StateStore

Source

pub fn open(path: Option<PathBuf>) -> Result<Self>

Open (or create) a state store at the given database path.

If path is None, the default location (~/.codewhale/state.db, with ~/.deepseek/state.db as a legacy fallback) is used. The database schema is created automatically if it does not exist.

Source

pub fn db_path(&self) -> &Path

Returns the filesystem path of the underlying SQLite database.

Source

pub fn upsert_thread(&self, thread: &ThreadMetadata) -> Result<()>

Insert or update thread metadata.

This does not update current_leaf_id; use append_message or set_current_leaf_id for that.

Source

pub fn get_thread(&self, id: &str) -> Result<Option<ThreadMetadata>>

Retrieve a single thread by its ID.

Returns None if no thread with the given ID exists.

Source

pub fn list_threads( &self, filters: ThreadListFilters, ) -> Result<Vec<ThreadMetadata>>

List threads ordered by most recently updated.

Use ThreadListFilters to control whether archived threads are included and the maximum number of results returned.

Source

pub fn mark_archived(&self, id: &str) -> Result<()>

Archive a thread, setting its status to ThreadStatus::Archived and recording the current timestamp.

Source

pub fn mark_unarchived(&self, id: &str) -> Result<()>

Unarchive a thread, removing the archived flag and clearing archived_at.

Source

pub fn delete_thread(&self, id: &str) -> Result<()>

Permanently delete a thread and all of its associated data (messages, checkpoints, dynamic tools) via cascading foreign keys.

Source

pub fn set_thread_memory_mode(&self, id: &str, mode: Option<&str>) -> Result<()>

Set the memory mode for a thread.

Pass None to clear the memory mode.

Source

pub fn get_thread_memory_mode(&self, id: &str) -> Result<Option<String>>

Get the memory mode configured for a thread.

Returns None if the thread does not exist or has no memory mode set.

Source

pub fn upsert_thread_goal(&self, goal: &ThreadGoalRecord) -> Result<()>

Insert or replace the persisted goal for a thread.

Source

pub fn record_thread_goal_usage( &self, thread_id: &str, token_delta: i64, time_delta_seconds: i64, now: i64, ) -> Result<Option<ThreadGoalRecord>>

Accrue additional token and wall-clock usage onto a thread’s persisted goal.

This is the durable, additive accounting path for the persistent goal loop: it increments tokens_used and time_used_seconds in a single atomic SQL UPDATE (col = col + ?) so concurrent accruals do not race a read-modify-write. The goal’s updated_at is advanced to the larger of its current value and now, keeping the timestamp monotonic even if a stale now is supplied.

token_delta and time_delta_seconds are added on the database side; callers should pass non-negative deltas (negative values are accepted and will decrement, which is intentionally left to the caller’s discretion).

Returns the updated ThreadGoalRecord, or Ok(None) if the thread has no persisted goal. Unlike upsert_thread_goal this never creates a goal row; it only accumulates onto an existing one.

Source

pub fn record_thread_goal_continuation( &self, thread_id: &str, now: i64, ) -> Result<Option<ThreadGoalRecord>>

Increment the durable cross-turn continuation counter for a thread goal.

The older TUI continuation guard is scoped to one engine turn. This counter is intentionally persisted so a resumed goal loop can feed goal_loop::decide_continuation with the true cross-turn count.

Source

pub fn get_thread_goal( &self, thread_id: &str, ) -> Result<Option<ThreadGoalRecord>>

Retrieve the persisted goal for a thread.

Source

pub fn delete_thread_goal(&self, thread_id: &str) -> Result<bool>

Delete the persisted goal for a thread.

Source

pub fn list_leaf_messages(&self, thread_id: &str) -> Result<Vec<MessageRecord>>

List all leaf messages in a thread.

A leaf message is one that has no other message referencing it as a parent. In a branching conversation tree, there may be multiple leaf messages.

Source

pub fn set_current_leaf_id( &self, thread_id: &str, current_leaf_id: &str, ) -> Result<()>

Update the current leaf message pointer for a thread.

This controls which branch of the conversation tree is considered active when listing messages via list_messages.

Source

pub fn persist_dynamic_tools( &self, thread_id: &str, tools: &[DynamicToolRecord], ) -> Result<()>

Replace the dynamic tools for a thread.

All existing dynamic tools for the thread are deleted and replaced with the provided list. The operation is performed within a transaction.

Source

pub fn get_dynamic_tools( &self, thread_id: &str, ) -> Result<Vec<DynamicToolRecord>>

Retrieve all dynamic tools registered for a thread, ordered by position.

Source

pub fn append_message( &self, thread_id: &str, role: &str, content: &str, item: Option<Value>, ) -> Result<i64>

Append a new message to a thread.

The message is linked to the thread’s current leaf as its parent, and the thread’s current_leaf_id is updated to the new message. Returns the ID of the newly created message.

Source

pub fn list_messages( &self, thread_id: &str, limit: Option<usize>, ) -> Result<Vec<MessageRecord>>

List messages in the current conversation branch, walking backwards from the thread’s current_leaf_id.

Messages are returned in chronological order (oldest first). The limit parameter caps how many ancestor messages are traversed; it defaults to 500.

Source

pub fn fork_at_message( &self, message_id: &str, role: &str, content: &str, item: Option<Value>, ) -> Result<i64>

Fork the conversation at a specific message.

Creates a new message whose parent is message_id and updates the thread’s current_leaf_id to the new message. Returns the ID of the new message. This enables branching conversations from any point in the history.

Source

pub fn clear_messages(&self, thread_id: &str) -> Result<usize>

Delete all messages belonging to a thread and reset its current_leaf_id.

Returns the number of messages deleted.

Source

pub fn save_checkpoint( &self, thread_id: &str, checkpoint_id: &str, state: &Value, ) -> Result<()>

Save (or update) a named checkpoint for a thread.

If a checkpoint with the same thread_id and checkpoint_id already exists, its state and timestamp are overwritten.

Source

pub fn load_checkpoint( &self, thread_id: &str, checkpoint_id: Option<&str>, ) -> Result<Option<CheckpointRecord>>

Load a checkpoint for a thread.

If checkpoint_id is provided, loads that specific checkpoint. Otherwise, loads the most recently created checkpoint for the thread. Returns None if no matching checkpoint exists.

Source

pub fn list_checkpoints( &self, thread_id: &str, limit: Option<usize>, ) -> Result<Vec<CheckpointRecord>>

List checkpoints for a thread, ordered by creation time (newest first).

The limit parameter caps the number of results and defaults to 100.

Source

pub fn delete_checkpoint( &self, thread_id: &str, checkpoint_id: &str, ) -> Result<()>

Delete a specific checkpoint from a thread.

Source

pub fn upsert_job(&self, job: &JobStateRecord) -> Result<()>

Insert or update a background job record.

Source

pub fn get_job(&self, id: &str) -> Result<Option<JobStateRecord>>

Retrieve a single job by its ID.

Returns None if no job with the given ID exists.

Source

pub fn list_jobs(&self, limit: Option<usize>) -> Result<Vec<JobStateRecord>>

List jobs ordered by most recently updated.

The limit parameter caps the number of results and defaults to 100.

Source

pub fn delete_job(&self, id: &str) -> Result<()>

Permanently delete a job record.

Source

pub fn find_rollout_path_by_id(&self, id: &str) -> Result<Option<PathBuf>>

Look up the rollout file path for a thread by its ID.

Source

pub fn append_thread_name( &self, thread_id: &str, thread_name: Option<String>, updated_at: i64, rollout_path: Option<PathBuf>, ) -> Result<()>

Append an entry to the JSONL session index file.

The session index is an append-only log that maps thread IDs to their names, update timestamps, and rollout paths. It is used for fast name-based lookups without opening the SQLite database.

Source

pub fn find_thread_name_by_id(&self, thread_id: &str) -> Result<Option<String>>

Find the display name for a thread by its ID, using the session index.

Returns None if the thread is not in the index or has no name.

Source

pub fn find_thread_names_by_ids( &self, ids: &[String], ) -> Result<HashMap<String, Option<String>>>

Look up display names for multiple thread IDs at once.

Returns a map from thread ID to its name (which may be None).

Source

pub fn find_thread_path_by_name_str( &self, name: &str, ) -> Result<Option<PathBuf>>

Find the rollout path for a thread by its display name (case-insensitive).

If multiple threads share the same name, the most recently updated one is returned. Returns None if no matching thread is found.

Trait Implementations§

Source§

impl Clone for StateStore

Source§

fn clone(&self) -> StateStore

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for StateStore

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.