fix(sf): invalidate stale embedding when memory content is updated
updateMemoryContent rewrote the row but left the existing memory_embeddings vector in place — that vector was computed against the old content, so the next cosine query would score the memory by what it used to say, not what it says now. Now drop the embedding row on update; the next runEmbeddingBackfill (agent_end hook) re-embeds. Best-effort: a missing embedding is the silent-fallback case the ranker already handles. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
a3c000de26
commit
7bec2dc2d0
1 changed files with 13 additions and 0 deletions
|
|
@ -6,6 +6,7 @@
|
|||
import {
|
||||
_getAdapter,
|
||||
decayMemoriesBefore,
|
||||
deleteMemoryEmbedding,
|
||||
incrementMemoryHitCount,
|
||||
insertMemoryRow,
|
||||
isDbAvailable,
|
||||
|
|
@ -270,6 +271,12 @@ export function createMemory(fields: {
|
|||
|
||||
/**
|
||||
* Update a memory's content and optionally its confidence.
|
||||
*
|
||||
* Invalidates the existing embedding row (if any): the stored vector was
|
||||
* computed against the old content and would otherwise rank incorrectly
|
||||
* on the next cosine query. The next runEmbeddingBackfill sweep will
|
||||
* re-embed the new content. This is best-effort — a missing embedding
|
||||
* row is the silent-fallback case the ranker already handles.
|
||||
*/
|
||||
export function updateMemoryContent(
|
||||
id: string,
|
||||
|
|
@ -280,6 +287,12 @@ export function updateMemoryContent(
|
|||
|
||||
try {
|
||||
updateMemoryContentRow(id, content, confidence, new Date().toISOString());
|
||||
try {
|
||||
deleteMemoryEmbedding(id);
|
||||
} catch {
|
||||
// Stale-vector window is brief (until next backfill); never fail
|
||||
// the content update because the embedding cleanup raised.
|
||||
}
|
||||
return true;
|
||||
} catch {
|
||||
return false;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue