recall-graph 0.2.0

Knowledge graph with semantic search for AI memory systems
Documentation

recall-graph

Knowledge graph with semantic search for AI memory systems.

A structured graph layer (Layer 0) that sits underneath flat-file memory systems like recall-echo. Provides entity storage, relationship tracking, episode memory, LLM-powered entity extraction, and semantic search — all backed by SurrealDB with local FastEmbed embeddings.

Features

  • Entity CRUD — create, read, update, delete entities with typed classifications (person, project, tool, concept, etc.)
  • Relationships — directional edges between entities with supersede semantics for evolving knowledge
  • Episodes — temporal memory chunks tied to conversation sessions
  • Semantic search — vector similarity via locally-generated embeddings (FastEmbed, no API calls)
  • Hybrid queries — combines semantic search with graph traversal and optional episode retrieval
  • LLM extraction — extract entities and relationships from conversation archives using any LLM provider
  • Deduplication — LLM-powered entity dedup with skip/create/merge decisions
  • Parallel ingestion — concurrent chunk extraction with sequential dedup for correctness

Architecture

archive text
    |
    v
chunk_conversation (500-line chunks)
    |
    v
[Phase 1] extract_from_chunk (parallel, 10 concurrent LLM calls)
    |
    v
[Phase 2] local_merge_entities (merge same-name candidates, no LLM)
    |
    v
[Phase 3] resolve_entity (sequential dedup against DB)
    |
    v
[Phase 4] create relationships (sequential, no LLM)

Usage

use recall_graph::{GraphMemory, types::*};

// Open or create a graph store
let gm = GraphMemory::open(Path::new("./graph")).await?;

// Add an entity
let entity = gm.add_entity(NewEntity {
    name: "Rust".into(),
    entity_type: EntityType::Tool,
    abstract_text: "Systems programming language".into(),
    overview: None,
    content: None,
    attributes: None,
    source: Some("manual".into()),
}).await?;

// Semantic search
let results = gm.search("programming languages", 5).await?;

// Hybrid query with graph expansion
let result = gm.query("Rust", &QueryOptions {
    limit: 10,
    graph_depth: 2,
    include_episodes: true,
    ..Default::default()
}).await?;

// Ingest a conversation archive (episodes only)
let report = gm.ingest_archive(&text, "session-id", Some(1), None).await?;

// Extract entities with an LLM provider
let report = gm.extract_from_archive(&text, "session-id", Some(1), &llm).await?;

LLM Provider

Implement the LlmProvider trait to plug in any LLM backend:

#[async_trait]
pub trait LlmProvider: Send + Sync {
    async fn complete(
        &self,
        system_prompt: &str,
        user_message: &str,
        max_tokens: u32,
    ) -> Result<String, GraphError>;
}

Storage

Uses SurrealDB (embedded, file-backed via SurrealKV) for graph storage and FastEmbed for local embedding generation. No external services required.

License

AGPL-3.0-only