Skip to main content

ClawEngine

Struct ClawEngine 

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

The main entry point for claw-core.

Construct a ClawEngine via ClawEngine::open or ClawEngine::open_default, passing a validated ClawConfig. The engine holds the underlying SQLx SqlitePool, an internal LRU memory cache, and serves as the root accessor for all store, transaction, and snapshot APIs.

§Example

use claw_core::{ClawEngine, ClawConfig};

let config = ClawConfig::builder()
    .db_path("/tmp/my_agent.db")
    .build()?;
let engine = ClawEngine::open(config).await?;
engine.close().await;

Implementations§

Source§

impl ClawEngine

Source

pub async fn open(config: ClawConfig) -> ClawResult<Self>

Open (or create) the database at the path specified in config.

When config.auto_migrate is true, any pending embedded migrations are applied before the engine is returned.

§Errors

Returns a ClawError if the pool cannot be created or migrations fail.

§Example
let config = ClawConfig::builder()
    .db_path("/tmp/claw.db")
    .build()?;
let engine = ClawEngine::open(config).await?;
engine.close().await;
Source

pub async fn open_default() -> ClawResult<Self>

Open the database using the default ClawConfig.

The database is created at $XDG_DATA_HOME/clawdb/claw.db (or platform equivalent). All migrations are applied automatically.

§Errors

Returns a ClawError if the pool cannot be created or migrations fail.

§Example
use claw_core::ClawEngine;

let engine = ClawEngine::open_default().await?;
engine.close().await;
Source

pub async fn migrate(&self) -> ClawResult<()>

Apply any pending embedded SQL migrations.

§Errors

Returns ClawError::Migration if a migration step fails.

Source

pub fn pool(&self) -> &SqlitePool

Return a reference to the underlying SqlitePool.

Source

pub fn config(&self) -> &ClawConfig

Return a reference to the engine’s ClawConfig.

Source

pub async fn close(self)

Close the connection pool, waiting for in-flight queries to complete.

Source

pub async fn insert_memory(&self, record: &MemoryRecord) -> ClawResult<Uuid>

Insert a new MemoryRecord into the database.

The record is also inserted into the in-memory LRU cache.

§Errors

Returns a ClawError if the SQL execution fails.

§Example
let record = MemoryRecord::new("hello world", MemoryType::Semantic, vec![], None);
let id = engine.insert_memory(&record).await?;
Source

pub async fn get_memory(&self, id: Uuid) -> ClawResult<MemoryRecord>

Retrieve a MemoryRecord by its UUID.

Results are served from the in-memory LRU cache when available.

§Errors

Returns ClawError::NotFound if no record with the given id exists.

§Example
let record = MemoryRecord::new("hello", MemoryType::Semantic, vec![], None);
let id = engine.insert_memory(&record).await?;
let fetched = engine.get_memory(id).await?;
assert_eq!(fetched.content, "hello");
Source

pub async fn update_memory(&self, id: Uuid, content: &str) -> ClawResult<()>

Update the content of an existing MemoryRecord.

The updated_at timestamp is set to the current UTC time. The cache entry is invalidated so the next read fetches fresh data.

§Errors

Returns ClawError::NotFound if no record with the given id exists.

§Example
let record = MemoryRecord::new("old content", MemoryType::Semantic, vec![], None);
let id = engine.insert_memory(&record).await?;
engine.update_memory(id, "new content").await?;
Source

pub async fn delete_memory(&self, id: Uuid) -> ClawResult<()>

Delete a MemoryRecord from the database by its UUID.

The cache entry is also invalidated.

§Errors

Returns ClawError::NotFound if no record with the given id exists.

§Example
let record = MemoryRecord::new("to delete", MemoryType::Episodic, vec![], None);
let id = engine.insert_memory(&record).await?;
engine.delete_memory(id).await?;
Source

pub async fn list_memories( &self, type_filter: Option<MemoryType>, ) -> ClawResult<Vec<MemoryRecord>>

List all MemoryRecords, optionally filtered by MemoryType.

Results are ordered by created_at ascending.

§Errors

Returns a ClawError if the query fails.

§Example
let all = engine.list_memories(None).await?;
let semantic = engine.list_memories(Some(MemoryType::Semantic)).await?;
Source

pub async fn list_memories_paginated( &self, type_filter: Option<MemoryType>, opts: ListOptions, ) -> ClawResult<(Vec<MemoryRecord>, Option<String>)>

List memories with keyset pagination.

§Errors

Returns a ClawError if the query fails.

§Example
let (page, cursor) = engine.list_memories_paginated(
    Some(MemoryType::Semantic),
    ListOptions { limit: 50, cursor: None },
).await?;
Source

pub async fn search_by_tag(&self, tag: &str) -> ClawResult<Vec<MemoryRecord>>

Search for MemoryRecords whose tag list contains tag.

§Errors

Returns a ClawError if the query fails.

§Example
let results = engine.search_by_tag("important").await?;

Full-text search over all MemoryRecord contents using SQLite FTS5.

The query string follows FTS5 query syntax (e.g. "hello world" for phrase search, hello AND world for AND search).

§Errors

Returns a ClawError if the query fails.

§Example
let results = engine.fts_search("hello world").await?;
Source

pub async fn expire_ttl_memories(&self) -> ClawResult<u64>

Expire all MemoryRecords whose TTL has elapsed.

Returns the number of records deleted. The cache is cleared if any records were deleted, since we do not know which IDs were affected.

§Errors

Returns a ClawError if the underlying deletion fails.

§Example
let expired = engine.expire_ttl_memories().await?;
println!("deleted {expired} expired records");
Source

pub async fn start_session(&self) -> ClawResult<String>

Start a new session and return its unique ID.

§Errors

Returns a ClawError if the SQL execution fails.

§Example
let session_id = engine.start_session().await?;
Source

pub async fn end_session(&self, session_id: &str) -> ClawResult<()>

Mark the session identified by session_id as ended.

§Errors

Returns ClawError::NotFound if the session does not exist.

§Example
let sid = engine.start_session().await?;
engine.end_session(&sid).await?;
Source

pub async fn get_session(&self, session_id: &str) -> ClawResult<Session>

Retrieve the Session record for session_id.

§Errors

Returns ClawError::NotFound if the session does not exist.

§Example
let sid = engine.start_session().await?;
let session = engine.get_session(&sid).await?;
assert!(session.ended_at.is_none());
Source

pub async fn list_sessions(&self) -> ClawResult<Vec<Session>>

List all sessions, ordered by started_at descending.

§Errors

Returns a ClawError if the query fails.

§Example
let sessions = engine.list_sessions().await?;
Source

pub async fn record_tool_output( &self, output: &ToolOutputRecord, ) -> ClawResult<()>

Record a tool-output entry.

§Errors

Returns a ClawError if the SQL execution fails.

§Example
let output = ToolOutput {
    id: Uuid::new_v4(),
    session_id: "sess-1".to_string(),
    tool_name: "my_tool".to_string(),
    output: serde_json::json!({"result": 42}),
    success: true,
    created_at: chrono::Utc::now(),
};
engine.record_tool_output(&output).await?;
Source

pub async fn list_tool_outputs( &self, session_id: &str, ) -> ClawResult<Vec<ToolOutputRecord>>

List all tool-output records for a given session_id.

§Errors

Returns a ClawError if the query fails.

§Example
let outputs = engine.list_tool_outputs("sess-1").await?;
Source

pub async fn transaction(&self) -> ClawResult<ClawTransaction<'_>>

Begin a new crate::transaction::ClawTransaction against this engine.

§Errors

Returns ClawError::Transaction if the pool cannot start a transaction.

§Example
let mut tx = engine.transaction().await?;
let r = MemoryRecord::new("hello", MemoryType::Semantic, vec![], None);
tx.insert_memory(&r).await?;
tx.commit().await?;
Source

pub async fn begin_transaction(&self) -> ClawResult<ClawTransaction<'_>>

Begin a new crate::transaction::ClawTransaction against this engine.

This is an alias for ClawEngine::transaction.

§Errors

Returns ClawError::Transaction if the pool cannot start a transaction.

Source

pub async fn snapshot_create(&self) -> ClawResult<SnapshotMeta>

Create a snapshot of the current database state.

Requires config.snapshot_dir to be set. A WAL checkpoint is performed before the file copy to ensure all committed data is in the main DB file.

§Errors

Returns ClawError::Config if no snapshot directory is configured, or ClawError::Snapshot if the snapshot file cannot be written.

§Example
let meta = engine.snapshot_create().await?;
println!("snapshot at {}", meta.path.display());
Source

pub async fn restore(&mut self, snapshot_path: &Path) -> ClawResult<()>

Restore the database from a snapshot file.

This method validates the snapshot is a genuine SQLite 3 file, closes the connection pool, replaces the live database, removes stale WAL/SHM sidecars, re-opens the pool, re-runs migrations, and clears the LRU cache.

§Errors

Returns ClawError::Snapshot if the snapshot is invalid or the copy fails, or a database error if the pool cannot be re-opened.

§Example
engine.restore(Path::new("/tmp/snaps/snapshot.db")).await?;
Source

pub fn snapshot_manifest(&self) -> ClawResult<SnapshotManifest>

Load the SnapshotManifest from the configured snapshot directory.

Returns an empty manifest if no snapshot has been taken yet.

§Errors

Returns ClawError::Config if no snapshot_dir is configured.

Source

pub async fn cache_stats(&self) -> CacheStats

Return a snapshot of the current in-memory cache statistics.

§Example
let stats = engine.cache_stats().await;
println!("hits: {}, misses: {}", stats.hit_count, stats.miss_count);
Source

pub async fn stats(&self) -> ClawResult<ClawStats>

Return comprehensive runtime statistics.

Reports the total memory count, rolling cache hit rate (last 1000 ops), last snapshot timestamp, and on-disk database/WAL sizes.

§Errors

Returns a ClawError if the memory count query fails.

§Example
let s = engine.stats().await?;
println!("hit rate: {:.1}%", s.cache_hit_rate * 100.0);
Source

pub async fn db_stats(&self) -> ClawResult<DbStats>

Return database-level statistics.

§Errors

Returns a ClawError if any of the count queries fail.

§Example
let stats = engine.db_stats().await?;
println!("memories: {}", stats.memory_count);

Trait Implementations§

Source§

impl Debug for ClawEngine

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> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
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> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts 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 more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts 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
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
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.
Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more