Overview
The workspace provides persistent memory for agents with a flexible filesystem-like structure. Agents can create arbitrary markdown file hierarchies that get indexed for full-text and semantic search. Inspired by OpenClaw, the workspace gives agents long-term memory across sessions.Filesystem-like Structure
Core Types
Workspace
Database-backed memory storage scoped to a user and optionally an agent.String
User identifier from the channel
Option<Uuid>
Optional agent ID for multi-agent isolation
Option<Arc<dyn EmbeddingProvider>>
Embedding provider for semantic search
Constructors
fn(user_id: impl Into<String>, pool: Pool) -> Self
Create a new workspace backed by PostgreSQL (requires
postgres feature)fn(user_id: impl Into<String>, db: Arc<dyn Database>) -> Self
Create a workspace with any Database implementation (libSQL, etc.)
fn(self, agent_id: Uuid) -> Self
Set a specific agent ID for multi-agent isolation
fn(self, provider: Arc<dyn EmbeddingProvider>) -> Self
Set the embedding provider for semantic search
Example
File Operations
Workspace provides a simple filesystem-like API for document management.read
async fn(&self, path: &str) -> Result<MemoryDocument>
Read a file by path. Returns error if file doesn’t exist.
write
async fn(&self, path: &str, content: &str) -> Result<MemoryDocument>
Create or update a file. Creates parent directories implicitly. Re-indexes for search.
append
async fn(&self, path: &str, content: &str) -> Result<()>
Append content to a file. Creates the file if it doesn’t exist. Adds newline separator.
exists
async fn(&self, path: &str) -> Result<bool>
Check if a file exists at the given path.
delete
async fn(&self, path: &str) -> Result<()>
Delete a file and its associated search chunks.
list
async fn(&self, directory: &str) -> Result<Vec<WorkspaceEntry>>
List files and directories at a path. Returns immediate children (not recursive). Use empty string or ”/” for root.
list_all
async fn(&self) -> Result<Vec<String>>
List all files recursively as a flat list of paths.
Convenience Methods
memory
async fn(&self) -> Result<MemoryDocument>
Get the main MEMORY.md document (long-term curated memory). Creates if it doesn’t exist.
today_log
async fn(&self) -> Result<MemoryDocument>
Get today’s daily log (append-only, keyed by date).
daily_log
async fn(&self, date: NaiveDate) -> Result<MemoryDocument>
Get a daily log for a specific date.
append_memory
async fn(&self, entry: &str) -> Result<()>
Append an entry to MEMORY.md with double newline separation. For important facts and decisions.
append_daily_log
async fn(&self, entry: &str) -> Result<()>
Append a timestamped entry to today’s daily log.
heartbeat_checklist
async fn(&self) -> Result<Option<String>>
Get the HEARTBEAT.md checklist for periodic background tasks. Returns seed template if not yet created.
System Prompt
system_prompt
async fn(&self) -> Result<String>
Build the system prompt from identity files (AGENTS.md, SOUL.md, USER.md, IDENTITY.md, MEMORY.md). Includes last 2 days of daily logs.
system_prompt_for_context
async fn(&self, is_group_chat: bool) -> Result<String>
Build system prompt with option to exclude MEMORY.md for group chats (privacy protection).
Search
search
async fn(&self, query: &str, limit: usize) -> Result<Vec<SearchResult>>
Hybrid search combining full-text (BM25) and semantic (vector) search using Reciprocal Rank Fusion.
search_with_config
async fn(&self, query: &str, config: SearchConfig) -> Result<Vec<SearchResult>>
Search with custom configuration for ranking weights and limits.
Seeding
seed_if_empty
async fn(&self) -> Result<usize>
Seed missing core identity files (README, MEMORY, IDENTITY, SOUL, AGENTS, USER, HEARTBEAT). Only creates files that don’t exist - never overwrites. Returns number of files created.
backfill_embeddings
async fn(&self) -> Result<usize>
Generate embeddings for chunks that don’t have them yet. Useful after enabling embedding provider. Returns number of chunks processed.
Data Types
MemoryDocument
A document stored in the workspace.Uuid
Unique document identifier
String
Owner user identifier
Option<Uuid>
Optional agent ID for isolation
String
File path (e.g., “context/vision.md”)
String
Full document content
DateTime<Utc>
Creation timestamp
DateTime<Utc>
Last update timestamp
WorkspaceEntry
An entry in a directory listing.String
Relative path from listing directory
bool
True if this entry has children
Option<DateTime<Utc>>
Last update time (latest among children for directories)
Option<String>
First ~200 characters (None for directories)
SearchResult
A search result with ranking score.String
Document path
String
Matched chunk content
f32
Combined relevance score (0.0 to 1.0)
String
Preview text with context
SearchConfig
Configuration for hybrid search ranking.usize
default:"10"
Maximum results to return
f32
default:"0.5"
Weight for semantic similarity (0.0 to 1.0)
f32
default:"0.5"
Weight for BM25 full-text score (0.0 to 1.0)
usize
default:"60"
RRF constant (higher = less aggressive fusion)
Embedding Providers
Workspace supports multiple embedding providers for semantic search.OpenAiEmbeddings
OllamaEmbeddings
NearAiEmbeddings
MockEmbeddings
For testing without external dependencies.Key Patterns
- Memory is persistence: If you want to remember something, write it to the workspace
- Flexible structure: Create any directory/file hierarchy you need
- Self-documenting: Use README.md files to describe directory structure
- Hybrid search: Vector similarity + BM25 full-text via RRF for best results
- Privacy boundaries: Use
system_prompt_for_context(true)to exclude personal memory in group chats
Related Modules
Agent Module
Core agent orchestration and session management
LLM Module
Language model integration for reasoning