Sophon 1.15 is here
Sophon Docs
Features

Memory GraphNEW

Explore, query, and export the entity graph built from your memories — the Dashboard graph explorer, Mermaid export, agent graph tools, and duplicate merging.

Every memory entry Sophon stores is wired to entities — the people, projects, places, and concepts it mentions — through wikilinks you write and background LLM extraction. The result is an entity graph the agent can traverse instead of rereading every entry: "who is involved in Atlas?" becomes a graph query, not a text search. The graph is now a first-class surface with its own explorer, export formats, and agent tools.

This page covers exploring, querying, and exporting the graph. For how memory itself works — entries, scopes, daily logs, search, and the memory lifecycle — see the Memory guide.

Wrap any name in double brackets inside a memory entry and Sophon links it:

Met [[Sarah Chen]] at the [[Atlas]] design review.

Both memory.write and POST /api/memory/entries parse wikilinks synchronously: each target is upserted as an entity (default kind concept) and a mentions edge is created from the entry to it.

There is also an alias form for when the canonical name and the natural phrasing differ:

Caught up with [[Sarah Chen|Sarah]] about the launch.

The part before the first | is the canonical entity name; the part after it is display text. [[Sarah Chen|Sarah]] reads as "Sarah" in the entry but links the entity Sarah Chen. The display text is presentation-only — it is never recorded as an alias on the entity, so casual phrasings can't pollute your alias lists. Aliases are managed deliberately, via the entity itself.

The graph explorer

The Dashboard graph page (Memory → Graph, /memory/graph) opens with your entire graph at once — every entity, every connected memory entry, every link, capped at a node budget. The v2 explorer renders it with a force-directed layout: related clusters pull together, and hovering any node surfaces its details without a click. Nodes are color-coded so you can tell entities from memory entries at a glance, and agent-scoped entries carry a per-agent accent color — so you can see immediately which agent a node belongs to, while shared user-scoped entries keep one common color.

The toolbar refines what you see:

  • Search — dims unmatched nodes rather than removing them; matches and their neighbors stay vivid.
  • Kind chips — toggle entity kinds (person, org, place, project, concept, plus any kinds your graph has grown) to filter. Multi-select.
  • Date window — All time (default), or last 7 / 30 / 90 days. Limits which entries appear; entities always show.
  • Node cap — presets Compact (100), Balanced (250, the default), Dense (500), and Maximum (1000). If the cap clips your graph, a banner reports how many nodes were shown of the total.
  • Co-mentions — toggles the overlay described below.

Co-mention overlay

The data model stores entry-to-entity edges, so direct entity-to-entity relationships aren't stored rows. The co-mention overlay surfaces them anyway: when two entities appear together in two or more memory entries, the explorer draws a dashed edge between them labelled with the shared-entry count. If Sarah and Atlas show up together in five entries, that's a strong relationship signal even though no explicit edge exists. The overlay is computed client-side from the graph already on screen — no extra round-trip, nothing stored.

Mermaid export

The graph exports as a Mermaid flowchart from three places:

  • Export dialog — on the graph page, exports the current graph selection as Mermaid source you can paste into any Mermaid-aware tool.
  • memory.diagram agent tool — ask the agent to "draw my memory graph" (or a cluster around one entity) and it renders a Mermaid diagram in chat. Mermaid fences in chat render as live diagrams, theme-aware in light and dark mode.
  • GET /api/memory/graph/mermaid — programmatic export. Takes the same selection parameters as the overview graph (nodeLimit, entryDays, kinds) plus direction (LR or TD) and includeEntries, and returns { mermaid, nodeCount, edgeCount, truncated }. Labels are sanitized against the untrusted memory content they're built from.

Agent graph tools

Two tools give the agent structured access to the graph:

memory.graph — the unified graph inspector, with four operations:

OperationReturns
overviewWhole-graph stats — entity and entry counts, a kind histogram, and the top-connected entities
neighborsThe 1-hop connections of a named node
pathThe shortest path between two named nodes
clusterA depth-limited BFS neighborhood around a seed

memory.diagram — renders the graph as a Mermaid flowchart, with scope=overview for the whole graph or scope=cluster for a neighborhood around one node. The agent reaches for it when you ask to see, draw, or visualize your graph.

memory.traverse is deprecated. It is kept for backward compatibility and delegates to memory.graph with operation=cluster — existing integrations keep working, but new integrations should call memory.graph directly.

Duplicate entities

Graphs accumulate duplicates: a wikilink-created "Sarah" stub next to a fully-formed "Sarah Chen", or simple retyping drift. Sophon's duplicate detector flags candidate pairs via two checks:

  • Exact collision — one entity's canonical name or any alias equals another's, compared case- and whitespace-insensitively.
  • Trigram similarity — character-trigram similarity on normalized names at or above 0.85 (configurable). Very short names are skipped, as are cross-kind pairs unless one side is the generic concept kind.

The Dashboard surfaces candidates in a Duplicates review sheet on the graph page: each pair gets a side-by-side comparison with Merge and Not a duplicate actions. Merging moves the loser's links onto the winner, adds its name and aliases as aliases on the winner, then deletes it. Dismissing remembers the pair so it stops reappearing.

The same operations are available over REST:

EndpointMethodPurpose
/api/memory/entities/duplicates?threshold=0.85&limit=50GETList candidate pairs with score and reasons; dismissed pairs are filtered out
/api/memory/entities/{entityId}/mergePOSTBody { "sourceEntityId": "ent_..." } — merge the source into entityId (the winner)
/api/memory/entities/duplicates/{pairKey}/dismissPOSTMark a reviewed pair as not-a-duplicate

Where to go next

  • Memory — entries, scopes, daily logs, search, and the memory lifecycle the graph is built on
  • MCP Server — expose the graph to MCP clients as read-only resources: sophon://memory/graph (JSON) and sophon://memory/graph.mmd (Mermaid)