Sophon Docs
Features

Memory

User and agent memory, daily logs, the entity graph, semantic search, and the five memory tools.

Sophon's memory system is what keeps the agent coherent across conversations. It stores facts, preferences, and daily activity; builds an entity graph of the people, projects, and places it knows about; and injects relevant context into every LLM call. The agent can write, read, search, forget, and traverse memory during any chat.

What gets remembered

There are two persistent memory surfaces:

Long-term memory — individual entries the agent (or you) chose to keep. Each entry has content, a category (fact, preference, or observation), a scope (user or agent), and is linked into an entity graph. Examples:

  • fact — "Project Atlas ships on March 15"
  • preference — "User prefers dark mode"
  • observation — "User opens GitHub first thing most mornings"

Short-term memory (daily logs) — timestamped summary of what happened each day. One row per interaction; the agent reads the last two days on every turn.

[2026-04-22 10:30] Discussed Atlas deadline — confirmed Mar 15
[2026-04-22 14:15] Uploaded Q1-competitors.pdf; summarized to team
[2026-04-22 16:00] Sent email summary (approved)

Daily logs capture context; long-term entries capture the durable conclusions you want to survive beyond the window.

Scopes — user vs agent

Every long-term entry has a scope:

ScopeVisible toTypical content
userEvery agent you ownCross-cutting facts — where you live, who your team is, your project list
agentOnly the writing agentAgent-specific preferences — "Ada always uses short bullets," "Nora speaks formal German"

When the context assembler builds the system prompt, it fetches both: all user-scoped entries + the active agent's agent-scoped entries. So if you tell the writer agent to use formal tone, the research agent is unaffected.

The entity graph

Every memory entry is automatically linked to entities (people, projects, places, dates) that appear in the content. This turns your memories into a graph you can traverse.

Two extraction paths:

  • LLM link extraction — when you write a memory, a fast-tier LLM scans it for named entities and wires them in.
  • Wikilinks — you can write links explicitly with [[Entity Name]] syntax and Sophon will parse them:
User is planning a trip to [[Tirana]] with [[Ermal]] for the [[Atlas launch]]

That memory links to three entities — Tirana, Ermal, Atlas launch — and any future query that mentions any of those surfaces this entry too. The Dashboard Memory page renders the graph so you can see what knows what.

The five memory tools

The agent has five tools for working with memory:

memory.write

Saves a new entry. The agent calls this when it learns something worth keeping, or when you say "remember that…".

ParameterRequiredDescription
contentyesThe text to remember
categorynofact, preference, or observation
scopenouser (default) or agent
linksnoExplicit entity links to wire in addition to LLM extraction

Risk: Medium — triggers auto-extraction of entities and a write. Not gated unless part of a plan.

memory.search

Semantic + keyword hybrid search. Returns the top matches with relevance scores.

ParameterRequiredDescription
queryyesNatural-language query
scopenoLimit to user, agent, or all
limitnoMax results (default 10)

Risk: None — read-only.

memory.list

Paginated listing of entries (no search). Useful for "show me everything you remember about me."

ParameterRequiredDescription
scopenouser, agent, or all
limitnoDefault 50
cursornoFor pagination

Risk: None.

memory.forget

Deletes an entry by ID. Irreversible — requires user approval.

ParameterRequiredDescription
entryIdyesThe ID from memory.list or memory.search

Risk: Medium — triggers approval gate. "Forget everything" is a separate, Critical-risk flow handled in the Dashboard, not via this tool.

memory.traverse

Walks the entity graph. Given a starting entity, returns the memories linked to it and (optionally) the memories linked to those memories, up to a depth.

ParameterRequiredDescription
entityyesEntity name (e.g., "Atlas launch")
depthnoGraph traversal depth (default 1, max 3)

Risk: None.

Context assembly — what the LLM actually sees

On every turn, the context assembler builds the system prompt:

You are Sophon, an intelligent AI personal assistant.

## Shared Memory (user scope)
- User lives in Tirana, Albania
- Project "Atlas" deadline is March 15
- Prefers TypeScript over JavaScript

## Agent Memory (this agent)
- Ada uses concise responses, no emoji
- Greet user as "Enes"

## Recent Activity (last 2 days)
[2026-04-21 09:15] Reviewed PR #423, merged
[2026-04-22 10:30] Discussed Atlas deadline
[2026-04-22 14:15] Uploaded competitors.pdf, summarized

Budgets:

  • Up to 50 user-scoped entries
  • Up to 50 agent-scoped entries
  • Last 2 days of daily logs
  • Last 100 chat messages

These caps keep the prompt from ballooning. If memory grows past them, the most relevant entries float to the top — long-term entries are scored against the current message and ranked.

Dashboard — the Memory module

The Dashboard has a Memory page at /memory with four tabs:

  • Entries — paginated list of long-term entries. Filter by scope, category, agent. Add, edit, or delete.
  • Logs — daily activity log. Filter by agent and date range.
  • Search — hybrid search UI. Results show relevance scores.
  • Graph — interactive entity graph. Click an entity to expand its neighbors.

Every entry has an ID you can reference in memory.forget or memory.traverse.

CLI

sophon memory search "project deadline"
sophon memory list --scope user --limit 20
sophon memory list --agent writer
sophon memory traverse "Atlas launch" --depth 2
sophon memory forget mem_abc123   # prompts for confirmation

Storage by tier

TierDBVector storeSemantic search
PersonalSQLite (~/.sophon/db/sophon.db)Keyword only
ProPostgreSQLQdrantFull semantic
EnterprisePostgreSQLQdrant / Milvus / pgvectorFull semantic

Schema:

  • MemoryEntries — long-term, indexed on (UserId, AgentId) + tenant
  • DailyLogEntries — short-term, indexed on (UserId, AgentId, CreatedAt) + tenant
  • MemoryEntities / MemoryLinks — the graph, indexed on entity name

SQLite DateTimeOffset doesn't sort in queries, so the engine sorts client-side after fetch. Postgres sorts natively.

Legacy MEMORY.md migration

If you're upgrading from pre-database versions that stored memory in ~/.sophon/memory/MEMORY.md and daily log files, Sophon migrates on first startup:

  1. Reads MEMORY.md, treats each - bullet as a user-scoped long-term entry.
  2. Reads memory/daily/*.md files, imports as daily log rows.
  3. Skips migration if the DB already has entries (idempotent).

No manual step is required.

Security and isolation

  • User isolation — every query filters by authenticated user ID. Cross-user reads are impossible.
  • Agent isolationagent-scoped entries are visible only to the owning agent.
  • Tenant isolation (Enterprise) — EF Core global query filters enforce tenant boundaries on every query.
  • No secrets in memory — the credential vault and memory are separate stores. API keys, OAuth tokens, and other secrets never land in memory and never leak into LLM prompts.
  • Approval for forgetsmemory.forget and any "forget all" operation trigger the approval gate.
  • Vector metadata filtering — semantic search filters results server-side by user + agent before returning, so a malformed query can't return someone else's memories.

Where to go next