Skip to content

Memory for agents

A local-first memory system for AI agents. Store text memories and whole codebases, retrieve them with hybrid semantic + lexical search, and let a self-organizing topic tree + artifact graph + concepts keep everything structured as it grows.
import { makeDimple } from "@ponraaj/dimple-sdk";
const dimple = await makeDimple({ config: "./dimple.jsonc" });
// write a memory — embedded, routed into the topic tree, job-durable
await dimple.write({
logicalKey: "deploy-1",
content: "the deploy pipeline runs on every push",
});
// query — hybrid semantic + lexical search over the tree
const hits = await dimple.query("how does the pipeline deploy", { limit: 3 });
// index a codebase — tree-sitter: one memory unit per file + per definition
await dimple.index({ paths: ["./src"] });
await dimple.dispose(); // graceful shutdown of the durable worker

What just happened in those five calls:

  1. write embedded the text, routed it into the topic tree by similarity, and recorded a durable job — nothing is lost if the process dies mid-write.
  2. query ran the ANN vector leg, then the FTS5 lexical leg, and fused them with Reciprocal Rank Fusion — topic scoping is explicit membership (topics.topicKeys); the beam-descent leaf resolver is benchmarked scaffolding, not the shipped query plan.
  3. index parsed your codebase with tree-sitter and stored one unit per file and per definition, with code_calls edges between them — so “why does this code exist” questions have an answer.

Problem: naive memory stores scan every vector per query (cost grows with memory count), return flat results with no structure, and give the agent no notion of why a memory is relevant, what supersedes it, or what contradicts it.

Approach — three structures maintained automatically by a durable background worker:

  1. Topic tree — memories are routed by embedding similarity into tree leaves. Query scoping is membership-based (topics.topicKeys); a deterministic beam-descent leaf resolver exists for callers, and the SDK query path does not use it yet. A durable worker splits overflowing leaves and merges underflowing ones with deterministic algorithms — same embeddings ⇒ same tree, anywhere.
  2. Hybrid retrieval — vector (cosine ANN) + FTS5 lexical legs fused with Reciprocal Rank Fusion and an optional recency boost. The store can attach per-result graph context; the fused query path does not call that post-pass yet.
  3. Artifact graph + concepts — directed memory_supports / memory_supersedes / memory_contradicts / code_calls edges written by structural rules, code indexing, the agent, and the optional dream job (LLM classification of candidates + deterministic concept clustering). The store’s search legs consume the graph (superseded memories demote, conflicts surface, supports ride along); the fused query path is not wired to that post-pass yet.

All structural decisions are deterministic; everything is durable (two SQLite files — or a Turso remote database — and resume-safe jobs).

Capability How it works
Topic tree self-maintenance Durable jobs split/merge/rebalance leaves; deterministic algorithms
Hybrid retrieval Vector + FTS5 legs fused with RRF, optional recency boost
Codebase indexing tree-sitter — units per file & definition, code_calls edges
Graph post-pass (store legs) Superseded demotes, conflicts surface, supports ride along on the store’s search legs; the fused query path is not wired yet
Dream consolidation Optional LLM classification + deterministic concept clustering
Multi-model support Per-model topic trees; backfill re-embeds with any model
Durable jobs Resume-safe worker with a progress guard — no lost writes
Local-first Two SQLite files; Turso remote option; CLI + SDK + MCP server
  • Quickstart — install the SDK or CLI and write your first memory in a minute.
  • MCP server — expose Dimple to any MCP client: one transparent tool per capability (write, search, graph, maintenance), plus docs search and deep links.
  • Architecture — topic tree, retrieval, graph, dream, durability — how it works under the hood.
  • Configuration reference — every option in dimple.jsonc.