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
impl ClawEngine
Sourcepub async fn open(config: ClawConfig) -> ClawResult<Self>
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;Sourcepub async fn open_default() -> ClawResult<Self>
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;Sourcepub async fn migrate(&self) -> ClawResult<()>
pub async fn migrate(&self) -> ClawResult<()>
Apply any pending embedded SQL migrations.
§Errors
Returns ClawError::Migration if a migration step fails.
Sourcepub fn pool(&self) -> &SqlitePool
pub fn pool(&self) -> &SqlitePool
Return a reference to the underlying SqlitePool.
Sourcepub fn config(&self) -> &ClawConfig
pub fn config(&self) -> &ClawConfig
Return a reference to the engine’s ClawConfig.
Sourcepub async fn insert_memory(&self, record: &MemoryRecord) -> ClawResult<Uuid>
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?;Sourcepub async fn get_memory(&self, id: Uuid) -> ClawResult<MemoryRecord>
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");Sourcepub async fn update_memory(&self, id: Uuid, content: &str) -> ClawResult<()>
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?;Sourcepub async fn delete_memory(&self, id: Uuid) -> ClawResult<()>
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?;Sourcepub async fn list_memories(
&self,
type_filter: Option<MemoryType>,
) -> ClawResult<Vec<MemoryRecord>>
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?;Sourcepub async fn list_memories_paginated(
&self,
type_filter: Option<MemoryType>,
opts: ListOptions,
) -> ClawResult<(Vec<MemoryRecord>, Option<String>)>
pub async fn list_memories_paginated( &self, type_filter: Option<MemoryType>, opts: ListOptions, ) -> ClawResult<(Vec<MemoryRecord>, Option<String>)>
Sourcepub async fn search_by_tag(&self, tag: &str) -> ClawResult<Vec<MemoryRecord>>
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?;Sourcepub async fn fts_search(&self, query: &str) -> ClawResult<Vec<MemoryRecord>>
pub async fn fts_search(&self, query: &str) -> ClawResult<Vec<MemoryRecord>>
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?;Sourcepub async fn expire_ttl_memories(&self) -> ClawResult<u64>
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");Sourcepub async fn start_session(&self) -> ClawResult<String>
pub async fn start_session(&self) -> ClawResult<String>
Sourcepub async fn end_session(&self, session_id: &str) -> ClawResult<()>
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?;Sourcepub async fn get_session(&self, session_id: &str) -> ClawResult<Session>
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());Sourcepub async fn list_sessions(&self) -> ClawResult<Vec<Session>>
pub async fn list_sessions(&self) -> ClawResult<Vec<Session>>
Sourcepub async fn record_tool_output(
&self,
output: &ToolOutputRecord,
) -> ClawResult<()>
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?;Sourcepub async fn list_tool_outputs(
&self,
session_id: &str,
) -> ClawResult<Vec<ToolOutputRecord>>
pub async fn list_tool_outputs( &self, session_id: &str, ) -> ClawResult<Vec<ToolOutputRecord>>
Sourcepub async fn transaction(&self) -> ClawResult<ClawTransaction<'_>>
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?;Sourcepub async fn begin_transaction(&self) -> ClawResult<ClawTransaction<'_>>
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.
Sourcepub async fn snapshot_create(&self) -> ClawResult<SnapshotMeta>
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());Sourcepub async fn restore(&mut self, snapshot_path: &Path) -> ClawResult<()>
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?;Sourcepub fn snapshot_manifest(&self) -> ClawResult<SnapshotManifest>
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.
Sourcepub async fn cache_stats(&self) -> CacheStats
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);Sourcepub async fn stats(&self) -> ClawResult<ClawStats>
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);Trait Implementations§
Auto Trait Implementations§
impl Freeze for ClawEngine
impl !RefUnwindSafe for ClawEngine
impl Send for ClawEngine
impl Sync for ClawEngine
impl Unpin for ClawEngine
impl UnsafeUnpin for ClawEngine
impl !UnwindSafe for ClawEngine
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