zeroclaw 0.1.7

Zero overhead. Zero compromise. 100% Rust. The fastest, smallest AI assistant.
Documentation
"""
Memory storage tools for persisting data between conversations.
"""

import json
from pathlib import Path

from langchain_core.tools import tool


def _get_memory_path() -> Path:
    """Get the path to the memory storage file."""
    return Path.home() / ".zeroclaw" / "memory_store.json"


def _load_memory() -> dict:
    """Load memory from disk."""
    path = _get_memory_path()
    if not path.exists():
        return {}
    try:
        with open(path, "r", encoding="utf-8") as f:
            return json.load(f)
    except Exception:
        return {}


def _save_memory(data: dict) -> None:
    """Save memory to disk."""
    path = _get_memory_path()
    path.parent.mkdir(parents=True, exist_ok=True)
    with open(path, "w", encoding="utf-8") as f:
        json.dump(data, f, indent=2)


@tool
def memory_store(key: str, value: str) -> str:
    """
    Store a key-value pair in persistent memory.

    Args:
        key: The key to store under
        value: The value to store

    Returns:
        Confirmation message
    """
    try:
        data = _load_memory()
        data[key] = value
        _save_memory(data)
        return f"Stored: {key}"
    except Exception as e:
        return f"Error: {e}"


@tool
def memory_recall(query: str) -> str:
    """
    Search memory for entries matching the query.

    Args:
        query: The search query

    Returns:
        Matching entries or "no matches" message
    """
    try:
        data = _load_memory()
        if not data:
            return "No memories stored yet"

        query_lower = query.lower()
        matches = {
            k: v
            for k, v in data.items()
            if query_lower in k.lower() or query_lower in str(v).lower()
        }

        if not matches:
            return f"No matches for: {query}"

        return json.dumps(matches, indent=2)
    except Exception as e:
        return f"Error: {e}"