Skip to content

feat: memory content editing with versioning via update_memory (by Wren)#431

Open
conoremclaughlin wants to merge 3 commits into
mainfrom
wren/feat/memory-content-edit
Open

feat: memory content editing with versioning via update_memory (by Wren)#431
conoremclaughlin wants to merge 3 commits into
mainfrom
wren/feat/memory-content-edit

Conversation

@conoremclaughlin

Copy link
Copy Markdown
Owner

Summary

update_memory previously only updated salience/topics/metadata — correcting a memory required forget + remember, which destroys the history trail. This PR adds content and summary editing with versioning: the prior version is preserved in memory_history, visible via get_memory_history, and reversible via restore_memory. This matters most for "current state" memories that get revised as understanding improves.

How history capture works (no migration needed)

The existing archive_memory_on_update DB trigger already fires when content, summary, salience, topics, or topic_key change: it snapshots the OLD row into memory_history and bumps version. Content edits are versioned automatically — verified with integration tests against the real database.

Changes

Repository (memory-repository.ts)

  • updateMemory accepts optional content and summary. undefined = leave unchanged (per upsert-safety conventions); empty-string summary clears it.
  • Embedding refresh: content/summary changes re-embed through the same tryEmbedMemory pipeline remember() uses (chunked embeddings + primary vector + metadata).
  • tryEmbedMemory now returns success and trims stale higher-index chunk rows when a re-embed produces fewer chunks.
  • Stale-vector safety: if re-embedding fails (provider disabled/unavailable, persistence failure), the old vector, chunk rows, and embedding metadata are cleared so semantic recall falls back to text search rather than matching pre-edit text.
  • restoreMemory gets the same embedding refresh — rollback also rewrites the memory text (and the recreate-after-delete branch previously produced a memory with no embedding at all).

MCP tool (memory-handlers.ts, index.ts)

  • update_memory schema gains content (min 1 char) and summary; calls with no update fields are rejected before hitting the DB.
  • Tool description explains when to edit in place (correct/revise while preserving history) vs forget + remember (replacing a topic entirely).
  • Response now includes content, summary, and the bumped version.

Tests

  • Unit (memory-repository.test.ts, memory-handlers.test.ts): content+summary update persists with only provided fields written; salience-only update unchanged and skips embedding refresh; empty summary clears; stale embedding cleanup on failed re-embed (and skipped when never embedded); schema accepts/rejects correctly; handler pass-through, no-op guard, and not-found paths.
  • Integration (memory-hierarchical.integration.test.ts, real DB): content edit archives prior version (content, summary, version, change_type='update') and bumps version; restoreMemory rolls back to the pre-edit content; metadata-only updates create no history entry. All 17 integration tests pass.
  • Full npx vitest run: 155 files, 2837 passed / 4 skipped.
  • yarn type-check: only the known baseline errors (channels/gateway.ts Json, mcp/server.ts:451).

🤖 Generated with Claude Code

conoremclaughlin and others added 3 commits July 5, 2026 00:43
…epository (by Wren)

updateMemory now accepts content and summary. The existing
archive_memory_on_update DB trigger snapshots the prior row into
memory_history and bumps version, so edits are fully versioned with no
migration needed.

Content/summary changes refresh semantic embeddings via the same
tryEmbedMemory pipeline remember() uses; tryEmbedMemory now reports
success and trims stale higher-index chunk rows on re-embed. If
re-embedding fails (provider disabled/unavailable), stale vectors,
chunk rows, and embedding metadata are cleared so recall falls back to
text search instead of matching pre-edit text. restoreMemory gets the
same refresh since rollback also rewrites the memory text.

Co-Authored-By: Wren <noreply@anthropic.com>
Adds optional content (min 1 char) and summary params to the
update_memory schema and handler. Undefined fields are left unchanged
per repo upsert-safety conventions; an empty-string summary clears it.
Calls with no update fields are rejected before hitting the DB.

Tool description now explains when to edit in place (correct/revise
while preserving the history trail) vs forget + remember (replacing a
topic entirely). Response includes content, summary, and the bumped
version.

Co-Authored-By: Wren <noreply@anthropic.com>
… Wren)

Verifies against the real DB that a content edit archives the prior
version to memory_history (visible via getMemoryHistory), bumps
version, supports restore_memory rollback, and that metadata-only
updates create no history entry.

Co-Authored-By: Wren <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant