Memory Trees
The Memory Tree is OpenHuman's knowledge base. It is not a vector database with a thin "memory" wrapper. It is a deterministic, bucket-sealed pipeline that turns the messy stream of your day - chats, emails, documents, integration sync results - into structured, queryable, summary-backed Markdown that lives on your machine.
What it does
Every source you connect feeds the same pipeline:
source adapters (chat / email / document)
|
v
canonicalize normalised Markdown + provenance metadata
|
v
chunker deterministic IDs, <=3k-token bounded segments
|
v
content_store atomic .md files on disk (body + tags)
|
v
store persistence (chunks, scores, summaries, jobs)
|
v
score signals + embeddings + entity extraction
|
v
source / topic / global trees per-scope summary trees
|
v
retrieval search / drill_down / topic / global / fetch
The hot path (canonicalize → chunk → fast-score → persist → enqueue follow-up work) is fast. Heavy work - embeddings, entity extraction, sealing summary buckets, daily digests - runs in background workers so the UI never blocks.
Embeddings and summary-tree building can run on-device via Ollama if you turn on Local AI; otherwise they go through the OpenHuman backend like any other model call.
Three trees, three scopes
- Source trees, per-source rolling buffer (L0) that seals into L1 → L2 → … as it fills. One per Gmail label, one per Slack channel, one per uploaded document, etc.
- Topic trees, per-entity summaries materialized lazily by hotness. The more an entity (person, project, ticker, repo) shows up, the more aggressively its topic tree is built and refreshed.
- Global tree, one daily global digest across everything ingested that day.
Retrieval can target any scope: search a single source, drill down a topic, or pull the global digest.
Where it lives on disk
Inside your workspace (default ~/.openhuman, or whatever OPENHUMAN_WORKSPACE points at):
| Path | What's there |
|---|---|
memory_tree/chunks.db | Chunks, scores, summaries, entity index, jobs, hotness |
wiki/ | The Markdown vault - see Obsidian Wiki |
Everything is local. Nothing about your raw data leaves your machine unless you explicitly send a chat message that includes it.
Why a tree, not a vector store
Vector stores answer "what is similar to this query?" Memory needs to answer more than that:
- What happened today? (global digest)
- What's the latest on this person? (topic tree, hotness-driven)
- What did the Stripe webhook say last Tuesday at 3pm? (source tree + provenance)
Trees give you compression and navigation. Embeddings still live inside so semantic search keeps working, but the structure on top is what makes the memory feel like a brain instead of a bag of fragments.
How the pipeline works
1. Ingest
A new chat / email / document arrives. The hot path canonicalizes it into Markdown, splits it into bounded chunks with deterministic IDs, runs a cheap fast-score, persists everything in a single transaction, marks each chunk as pending_extraction, and enqueues follow-up work for the workers.
2. Queue
Follow-up work lands in a durable job queue:
| Kind | What it does |
|---|---|
extract_chunk | Deep score + entity extraction. Decides admitted vs dropped. |
append_buffer | Adds an admitted leaf to the source (or topic) tree's L0 buffer. May trigger a seal. |
seal | Compresses an L0 buffer into an L1 summary; cascades up if the parent buffer is now full. |
topic_route | Routes a leaf into per-entity topic trees, gated by a hotness check. |
digest_daily | Builds the global daily digest node. |
flush_stale | Force-seals buffers that have been sitting too long. |
3. Workers
A small pool of background workers (3 by default) picks jobs off the queue and runs them.
4. Tree state
Three independent trees are built from the same leaf stream:
- Source tree - one per source
- Topic tree - one per high-hotness entity
- Global tree - one tree, growing one node per UTC day
See also
- Obsidian-Style Memory - The Markdown vault on top of the Memory Tree
- Auto-fetch from Integrations - How the vault grows on its own
- Smart Token Compression - What keeps large data handling affordable