The MemoPilot memory-governance layer has nine cooperating components plus user controls.
Types: preference, project, decision, mistake, constraint,
deadline, learning_goal, task, critical, temporary, outdated,
deleted_by_user.
States: active, pinned, archived, expired, superseded, deleted.
Only active/pinned memories are ever injected into the model context.
superseded/expired/deleted/archived are retained for the timeline and
history inspection but excluded from retrieval.
final_score =
0.40 * semantic_similarity
+ 0.20 * importance
+ 0.15 * recency_score
+ 0.10 * confidence
+ 0.10 * usage_score
+ 0.15 * project_match
+ 0.20 * critical_bonus
- 0.30 * outdated_penalty
- 0.25 * privacy_penalty
- 0.50 * superseded_penalty
semantic_similarity— cosine(query, memory) in[0,1].recency_score— exponential decay, 14-day half-life.usage_score— diminishing returns onusage_count.project_match— 1.0 when the memory belongs to the active project.critical_bonus— 1.0 for critical/pinned memories.- penalties push outdated, private/sensitive, and superseded memories down.
Critical/pinned memories are additionally sorted first, before score, so they are always considered for inclusion.
similarity = max(dense, 0.5*dense + 0.5*keyword_overlap) — dense vector
search blended with sparse tag/keyword overlap, after structured filtering by
user_id + project_id and exclusion of non-active states.
Token budget defaults to 2,500. Inclusion order: critical/pinned first within the strict budget → top-k semantic → drop the rest. The system prompt and the current user message are always present and not counted against the memory budget. Every decision is recorded in the trace.
- Redact secrets before extraction.
- Qwen "Memory Editor" returns strict JSON (
new_memories,updates,forget). - Drop anything still secret-like.
- Merge near-duplicates (
SequenceMatcher > 0.86) instead of duplicating. - Detect common topic-level contradictions with deterministic rules, then
apply Qwen's structured
updatesas the general fallback for dimensions outside the taxonomy (audience, budget, policy, and similar decisions). Ownership is revalidated before every model-requested update; critical memories are never automatically superseded. - Set
expires_atfor temporary/deadline memories. - Embed and persist; emit a timeline event.
- Expire deadlines/temporary memories once
expires_atpasses. - Archive unused (
usage_count == 0), low-importance (< 0.35) memories after 30 days. - Never hard-deletes silently — only the user (DELETE endpoint / "Forget" button) can hard-delete. Critical memories are never auto-archived.
For every answer the trace exposes: included vs skipped memories, each one's final score and component breakdown, the human-readable reason, approximate token cost, candidates considered, and retrieval latency.
A consolidation "sleep" pass the agent can run over its active memory set:
- Merge near-duplicate memories of the same type (
SequenceMatcher ≥ 0.82); the strongest survives, the rest are archived (non-destructive) and the survivor's importance/usage are boosted. - Promote frequently-used memories (
usage_count ≥ 2) by raising importance. - Create cluster summaries: a type with ≥ 3 active memories produces a
deterministic count summary tagged
consolidation-summary. The API reports its source memory IDs, the graph shows it as a gold ★ node, and creation is idempotent. This is aggregation, not an LLM-derived reasoning claim.
Exposed via POST /api/reflect and the Analytics tab. Feeds the Memory Graph
(GET /api/graph) and Analytics (GET /api/analytics) views.
Runs eval/scenarios.json for the memory agent plus no-memory, raw-history,
and model-generated history-summary answer baselines. It aggregates
strict-keyword accuracy, recall in the assembled context,
outdated-avoidance, historical-context token reduction, and
latency. See judging_mapping.md.