fix: preserve temporal embeddings on distillation + expose source IDs in recall#380
Merged
Conversation
… in recall Two changes to improve recall detail availability: 1. Stop NULLing embeddings on markDistilled() — distilled temporal messages remain findable via vector search, preserving the semantic search path for specific details the distillation may have dropped. 2. Distillation results in recall now include source message IDs (t:<id> format). The LLM can use these with the recall tool to fetch full message content when the distilled summary lacks specifics (algorithm names, config values, file paths, etc.).
This was referenced May 19, 2026
BYK
added a commit
that referenced
this pull request
May 19, 2026
## Summary Fixes a bug where preserved temporal message embeddings were never used because the vector search query still excluded distilled messages. ## Problem PR #380 stopped NULLing embeddings on `markDistilled()` specifically to keep temporal messages findable via vector search. But `vectorSearchTemporal()` in `embedding.ts` still had `AND distilled = 0` in the SQL query — making the preserved embeddings dead data. ## Fix Remove `distilled = 0` from `vectorSearchTemporal()` only. BM25/LIKE search paths keep the filter (preventing keyword-match duplication with distillations). Only vector search is opened up — this provides the semantic similarity path for finding specific details in distilled messages. ## Results PR-2 at 400K tokens: | Baseline | Before | After | |---|---|---| | **Lore** | 4.20 | **4.68** | | Tail-window | 2.90 | 2.65 | Per-question improvements: - Tests alongside implementation: 2.6 → **4.6** - Error handling expectations: 4.0 → **5.0** ## Files Changed - `packages/core/src/embedding.ts` — remove `distilled = 0` from `vectorSearchTemporal()`
This was referenced May 21, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Two surgical changes to improve recall's ability to surface specific details from prior sessions.
Problem
When a temporal message is distilled,
markDistilled()setsdistilled=1ANDembedding=NULL. This makes the original message invisible to vector search — the only way to find 'bcrypt with 12 salt rounds' is if the distillation preserved it (which it often doesn't).Additionally, when recall returns a distillation hit, the LLM has no way to access the original messages that were distilled — it only sees the compressed summary.
Changes
1. Preserve embeddings on
markDistilled()Changed
UPDATE temporal_messages SET distilled = 1, embedding = NULLto justSET distilled = 1. The embedding is kept so vector search can still find the original message when the query matches its semantic content. BM25/LIKE searches still filter ondistilled=0(unchanged) to avoid result dilution.2. Source message IDs in distillation recall results
Distillation results now include
(sources: t:id1, t:id2, ...)— the IDs of the temporal messages that were distilled into this segment. The existingrecallById()function already handlest:<id>lookups, so the LLM can fetch full message content when the summary lacks specifics.Files Changed
packages/core/src/temporal.ts— stop NULLing embedding inmarkDistilled()packages/core/src/recall.ts—getDistillationSourceIds()+ source refs in distillation rendering