agentdb 0.2.0

Interface for agent persistence.
Documentation

Author's bio: πŸ‘‹πŸ˜€ Hi, I'm CryptoPatrick! I'm currently enrolled as an Undergraduate student in Mathematics, at Chalmers & the University of Gothenburg, Sweden. If you have any questions or need more info, then please join my Discord Channel: AiMath


πŸ›Ž Important Notices

  • This is a trait-based abstraction layer, not a complete database
  • Requires concrete implementations (see agentsql)
  • Designed for AI agent persistence needs

πŸ€” What is AgentDB

agentdb is a unified database abstraction layer that provides a common interface for AI agent storage operations across multiple backend families (SQL, Key-Value, Graph databases). It serves as the middleware between high-level agent operations and concrete database implementations.

Built to enable database flexibility without code changes, AgentDB provides a single trait that works seamlessly across SQLite, PostgreSQL, MySQL, and future backends.

Use Cases

  • Multi-Backend Support: Write agent code once, deploy on any supported backend
  • Database Flexibility: Switch between SQLite, PostgreSQL, MySQL without code changes
  • Type Safety: Rust's type system ensures correctness across database operations
  • Future-Proof: Easy to add new database backends without changing agent code
  • Testing: Mock implementations for unit testing agent logic
  • Custom Backends: Implement your own backend for specialized storage needs

πŸ“· Features

agentdb provides a complete abstraction layer for database operations with type safety and flexibility:

πŸ”§ Core Traits

AgentDB Trait

  • CRUD Operations: Put, get, delete, and scan key-value pairs
  • Query Interface: Execute SQL queries with result sets
  • Transaction Support: Optional transactional operations
  • Capability Discovery: Runtime feature detection
  • Async-First: All operations use async/await

Capabilities Trait

  • Transaction Support: Check if transactions are available
  • Index Support: Determine if indexes are supported
  • Backend Family: Identify backend type (SQL, KV, Graph)
  • Feature Flags: Query specific backend capabilities

Transaction Trait

  • ACID Guarantees: Atomic commit and rollback operations
  • Nested Transactions: Support for savepoints (backend-dependent)
  • Error Handling: Comprehensive error types

πŸ’Ύ Value System

  • Type-Safe Values: Strong typing with Value wrapper
  • Byte-Level Storage: Efficient binary data handling
  • Zero-Copy Operations: Minimize allocations where possible
  • Conversion Traits: Easy conversion to/from Rust types

πŸ”’ Error Handling

  • Unified Error Types: Single error type across all backends
  • Context Preservation: Detailed error messages with context
  • Result Type: Standard Rust Result<T, AgentDbError>
  • Backend Errors: Wrapped backend-specific errors

πŸ“ Architecture

  1. πŸ› Overall Architecture
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚              AgentFS High-Level APIs               β”‚
β”‚   (FileSystem, KvStore, ToolRecorder)              β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                        β”‚
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                  AgentDB Trait                     β”‚
β”‚  β€’ put(key, value) β†’ Result<()>                    β”‚
β”‚  β€’ get(key) β†’ Result<Option<Value>>                β”‚
β”‚  β€’ delete(key) β†’ Result<()>                        β”‚
β”‚  β€’ scan(prefix) β†’ Result<ScanResult>               β”‚
β”‚  β€’ query(sql, params) β†’ Result<QueryResult>        β”‚
β”‚  β€’ capabilities() β†’ &dyn Capabilities              β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                        β”‚
        β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
        β”‚               β”‚               β”‚
β”Œβ”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”
β”‚   AgentSQL   β”‚ β”‚  AgentKV    β”‚ β”‚ AgentGraph β”‚
β”‚   (SQLx)     β”‚ β”‚  (Future)   β”‚ β”‚  (Future)  β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
        β”‚
β”Œβ”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚       β”‚        β”‚            β”‚
β–Ό       β–Ό        β–Ό            β–Ό
SQLite  Postgres MySQL    MariaDB
  1. πŸ”„ Data Flow
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚      Application calls AgentDB::put()       β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                     β”‚
            β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”
            β”‚   AgentDB Trait β”‚
            β”‚   Dispatches to β”‚
            β”‚   Implementationβ”‚
            β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                     β”‚
     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
     β”‚               β”‚               β”‚
β”Œβ”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”
β”‚ SQLite   β”‚  β”‚ PostgreSQL  β”‚  β”‚   MySQL   β”‚
β”‚ Backend  β”‚  β”‚  Backend    β”‚  β”‚  Backend  β”‚
β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”˜
     β”‚               β”‚               β”‚
     β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                     β”‚
            β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”
            β”‚  Actual Storage β”‚
            β”‚   (Database)    β”‚
            β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
  1. πŸ’Ύ Trait System
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚              AgentDB Trait                     β”‚
β”‚  β€’ Core database operations                    β”‚
β”‚  β€’ Required for all implementations            β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                     β”‚
     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
     β”‚                               β”‚
β”Œβ”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  Capabilities     β”‚   β”‚    Transaction        β”‚
β”‚  β€’ Runtime flags  β”‚   β”‚    β€’ commit()         β”‚
β”‚  β€’ Feature detect β”‚   β”‚    β€’ rollback()       β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

πŸš™ How to Use

Installation

Add agentdb to your Cargo.toml:

[dependencies]
agentdb = "0.1"
# Also add a concrete implementation:
agentsql = "0.1"

Or install with cargo:

cargo add agentdb
cargo add agentsql

Basic Example

use agentdb::{AgentDB, Capabilities};

async fn example(db: impl AgentDB) -> Result<(), Box<dyn std::error::Error>> {
    // Check capabilities
    if db.capabilities().supports_transactions() {
        println!("βœ“ Transactions supported");
    }

    // Key-value operations
    db.put("user:123", b"Alice".to_vec().into()).await?;

    if let Some(value) = db.get("user:123").await? {
        println!("User: {}", String::from_utf8_lossy(value.as_bytes()));
    }

    // Scan with prefix
    let result = db.scan("user:").await?;
    println!("Found {} users", result.keys.len());

    // SQL query (if supported)
    let query_result = db.query(
        "SELECT * FROM users WHERE active = 1",
        vec![]
    ).await?;

    for row in query_result.rows {
        // Process rows...
    }

    Ok(())
}

Advanced: Implementing a Custom Backend

use agentdb::{AgentDB, Capabilities, QueryResult, Row, ScanResult, Value};
use async_trait::async_trait;

struct MyCustomBackend {
    // Your backend state...
}

#[async_trait]
impl AgentDB for MyCustomBackend {
    fn capabilities(&self) -> &dyn Capabilities {
        // Return your capabilities
        unimplemented!()
    }

    async fn put(&self, key: &str, value: Value) -> agentdb::Result<()> {
        // Implement put operation
        unimplemented!()
    }

    async fn get(&self, key: &str) -> agentdb::Result<Option<Value>> {
        // Implement get operation
        unimplemented!()
    }

    async fn delete(&self, key: &str) -> agentdb::Result<()> {
        // Implement delete operation
        unimplemented!()
    }

    async fn scan(&self, prefix: &str) -> agentdb::Result<ScanResult> {
        // Implement scan operation
        unimplemented!()
    }

    async fn query(&self, sql: &str, params: Vec<Value>) -> agentdb::Result<QueryResult> {
        // Implement query operation
        unimplemented!()
    }

    // ... implement other required methods
}

πŸ§ͺ Examples

See the agentsql and agentfs crates for complete examples of using AgentDB in practice.

πŸ§ͺ Testing

Run the test suite:

# Run all tests
cargo test

# Run with output
cargo test -- --nocapture

πŸ“š Documentation

Comprehensive documentation is available at docs.rs/agentdb, including:

  • Complete API reference for all traits and types
  • Guide to implementing custom backends
  • Error handling best practices
  • Performance optimization tips

πŸ–Š Author

CryptoPatrick

Keybase Verification: https://keybase.io/cryptopatrick/sigs/8epNh5h2FtIX1UNNmf8YQ-k33M8J-Md4LnAN

🐣 Support

Leave a ⭐ if you think this project is cool.

πŸ—„ License

This project is licensed under MIT. See LICENSE for details.