Skip to main content

clawdesk-storage

Defines the storage traits (ports) that persistence backends must implement. This crate contains no concrete implementations — it establishes the contract for session, conversation, config, and vector storage.

Dependencies

Internal: clawdesk-types

External: async-trait, thiserror

Modules

This crate exposes traits at the crate root. No submodules.

Key Traits

use async_trait::async_trait;
use clawdesk_types::*;

/// Stores and retrieves chat sessions
#[async_trait]
pub trait SessionStore: Send + Sync {
async fn get(&self, id: &SessionId) -> Result<Option<Session>, StorageError>;
async fn save(&self, session: &Session) -> Result<(), StorageError>;
async fn delete(&self, id: &SessionId) -> Result<(), StorageError>;
async fn list(&self, limit: usize, offset: usize) -> Result<Vec<Session>, StorageError>;
async fn list_by_channel(&self, channel: &ChannelId) -> Result<Vec<Session>, StorageError>;
}

/// Stores conversation message history
#[async_trait]
pub trait ConversationStore: Send + Sync {
async fn get_messages(
&self,
session_id: &SessionId,
limit: usize,
) -> Result<Vec<Message>, StorageError>;
async fn append_message(
&self,
session_id: &SessionId,
message: &Message,
) -> Result<(), StorageError>;
async fn clear(&self, session_id: &SessionId) -> Result<(), StorageError>;
}

/// Stores and retrieves application configuration
#[async_trait]
pub trait ConfigStore: Send + Sync {
async fn get_config(&self) -> Result<AppConfig, StorageError>;
async fn save_config(&self, config: &AppConfig) -> Result<(), StorageError>;
}

/// Vector storage for semantic search / RAG
#[async_trait]
pub trait VectorStore: Send + Sync {
async fn upsert(&self, id: &str, vector: &[f32], metadata: serde_json::Value) -> Result<(), StorageError>;
async fn search(&self, query: &[f32], top_k: usize) -> Result<Vec<VectorResult>, StorageError>;
async fn delete(&self, id: &str) -> Result<(), StorageError>;
}

Error Types

#[derive(Debug, thiserror::Error)]
pub enum StorageError {
#[error("item not found: {0}")]
NotFound(String),

#[error("storage connection failed: {0}")]
ConnectionFailed(String),

#[error("serialization error: {0}")]
Serialization(String),

#[error("storage I/O error: {0}")]
Io(#[from] std::io::Error),
}

Example Usage

use clawdesk_storage::{SessionStore, StorageError};
use clawdesk_types::SessionId;

async fn find_session(
store: &dyn SessionStore,
id: &SessionId,
) -> Result<(), StorageError> {
match store.get(id).await? {
Some(session) => println!("Found: {:?}", session),
None => println!("Session not found"),
}
Ok(())
}
info

Concrete implementations live in clawdesk-sochdb. Test code uses in-memory mock stores.