Skip to content

SQLite-backed graph database for agent memory on Cloudflare Durable Objects or Node.js

License

Notifications You must be signed in to change notification settings

Divinci-AI/do-graph-memory

Repository files navigation

@divinci-ai/do-graph-memory

SQLite-backed graph database for agent memory. Works with Cloudflare Durable Objects and Node.js (via better-sqlite3).

Inspired by Boris Tane's DO graph DB pattern and Mem0's memory classification.

Features

  • Graph database — Nodes + edges with typed relationships, BFS traversal, neighbor queries
  • Mem0 memory types — Semantic (facts), Procedural (skills), Episodic (events), Working (context)
  • FTS5 search with graceful LIKE fallback when FTS5 isn't available
  • Context aggregation — Build structured memory context for LLM agent reasoning
  • Skill registry — Register, search, track, and relate agent skills (separate subpath export)
  • Two adapters — Cloudflare Durable Object SQL or better-sqlite3 (Node.js)
  • Zero runtime dependencies@cloudflare/workers-types and better-sqlite3 are optional peer deps
  • Schema migrations with rollback support

Install

npm install @divinci-ai/do-graph-memory
# or
pnpm add @divinci-ai/do-graph-memory

For Node.js usage, also install better-sqlite3:

npm install better-sqlite3

Quick Start

Node.js (better-sqlite3)

import { GraphMemory, createBetterSqlite3Adapter } from "@divinci-ai/do-graph-memory";
import Database from "better-sqlite3";

const db = new Database("agent-memory.db");
const adapter = createBetterSqlite3Adapter(db);
const memory = new GraphMemory({ adapter });
memory.initialize();

// Add facts
memory.addFact("user:theme", "User theme preference", "dark");
memory.addFact("config:model", "Default model", "gpt-4");

// Add a skill
memory.addSkill("skill:summarize", "Summarize Text", "Summarizes long text into key points", {
  capabilities: ["text-read"],
});

// Connect nodes
memory.addEdge({
  source: "user:theme",
  target: "config:model",
  relationship: "configured_with",
});

// Traverse the graph
const result = memory.traverse("user:theme", { maxDepth: 3 });
console.log(`Found ${result.nodes.length} connected nodes`);

// Build context for LLM reasoning
const context = memory.buildContext({ anchor: "user:theme", depth: 2 });
// context.facts, context.skills, context.history, context.working

Cloudflare Durable Objects

import { GraphMemory, createDurableObjectAdapter } from "@divinci-ai/do-graph-memory";

export class AgentMemory extends DurableObject {
  private memory: GraphMemory;

  constructor(ctx: DurableObjectState, env: Env) {
    super(ctx, env);
    const adapter = createDurableObjectAdapter(ctx.storage);
    this.memory = new GraphMemory({ adapter });
    ctx.blockConcurrencyWhile(async () => this.memory.initialize());
  }

  async addFact(id: string, label: string, value: unknown) {
    return this.memory.addFact(id, label, value);
  }

  async buildContext(anchor: string) {
    return this.memory.buildContext({ anchor, depth: 3 });
  }
}

API

GraphMemory

new GraphMemory(options: {
  adapter: SqlAdapter;    // Required: DO or better-sqlite3 adapter
  logger?: Logger;        // Optional: defaults to silent
  autoId?: boolean;       // Optional: auto-generate UUIDs for nodes
})

Node Operations:

  • addNode(node) / addNodes(nodes) — Create one or many nodes
  • getNode(id) — Get by ID
  • updateNode(id, updates) — Partial update
  • deleteNode(id) — Delete (cascades to edges)
  • queryNodes(query) — Filter by type, subtype, label, data, dates
  • searchNodes(term, limit?) — Full-text search (FTS5 or LIKE fallback)

Edge Operations:

  • addEdge(edge) / addEdges(edges) — Create relationships
  • getEdges(nodeId, direction?) — Get edges for a node
  • deleteEdge(source, target, relationship) — Remove a relationship
  • findNeighbors(nodeId, options?) — Find connected nodes

Traversal & Context:

  • traverse(startId, options?) — BFS graph traversal
  • buildContext(options) — Aggregate memory context for agent reasoning

Convenience (Mem0-style):

  • addFact(id, label, value, options?) — Semantic node
  • addSkill(id, label, description, options?) — Procedural node
  • addEpisode(id, label, description, options?) — Episodic node
  • setWorkingContext(id, label, state, ttlMs?) — Working memory with TTL
  • getWorkingContext() — Get current working context

SkillRegistry

import { SkillRegistry } from "@divinci-ai/do-graph-memory/skill-registry";

const registry = new SkillRegistry(memory, memory.adapter);
registry.initialize(); // Runs skill_stats migration

registry.registerSkill({
  id: "skill:analyze",
  name: "Analyze Data",
  description: "Analyzes datasets",
  category: "data",
  capabilities: ["data-read"],
});

// Track executions
registry.recordExecution({
  skillId: "skill:analyze",
  outcome: "success",
  duration: 1200,
});

// Query stats
const stats = registry.getSkillStats("skill:analyze");
const topSkills = registry.getMostSuccessfulSkills(5);

Adapters

// Node.js
import { createBetterSqlite3Adapter } from "@divinci-ai/do-graph-memory/adapters/better-sqlite3";
import Database from "better-sqlite3";
const adapter = createBetterSqlite3Adapter(new Database("file.db"));

// Cloudflare Durable Objects
import { createDurableObjectAdapter } from "@divinci-ai/do-graph-memory/adapters/durable-object";
const adapter = createDurableObjectAdapter(ctx.storage);

SqlAdapter Interface

Implement this to bring your own SQLite driver:

interface SqlAdapter {
  exec(query: string, ...bindings: unknown[]): SqlRow[];
  run(query: string, ...bindings: unknown[]): { changes: number };
  transaction<T>(fn: () => T): T;
}

Data Filters

Query nodes by JSON data properties using json_extract:

memory.queryNodes({
  type: "semantic",
  dataFilters: { category: "network", priority: 1 },
});

Exports

Import path What you get
@divinci-ai/do-graph-memory GraphMemory, types, adapters, schema utils
@divinci-ai/do-graph-memory/skill-registry SkillRegistry, skill types
@divinci-ai/do-graph-memory/adapters/better-sqlite3 createBetterSqlite3Adapter, hasFts5
@divinci-ai/do-graph-memory/adapters/durable-object createDurableObjectAdapter

License

MIT

About

SQLite-backed graph database for agent memory on Cloudflare Durable Objects or Node.js

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors 2

  •  
  •