fix(bolt): embed entities during extraction + add generate_entity_embeddings_batch() - #154
Open
steveonjava wants to merge 1 commit into
Open
fix(bolt): embed entities during extraction + add generate_entity_embeddings_batch()#154steveonjava wants to merge 1 commit into
steveonjava wants to merge 1 commit into
Conversation
…eddings_batch() On the Bolt backend, the LLM extraction pipeline wrote every :Entity with embedding=NULL, hardcoded, ignoring the configured embedder. Recall (long_term.search_entities) is vector-only with no keyword/fulltext fallback, so extracted entities are mathematically unreachable by semantic recall. Fixes: 1. Embed entity names inline during extraction (_extract_and_link_entities and extract_entities_from_session), gated on generate_embeddings=True (default). Uses embed_batch for efficiency, falls back to per-name embed on failure. 2. Add LongTermMemory.generate_entity_embeddings_batch(), the entity analogue of ShortTermMemory.generate_embeddings_batch(). Uses the already-defined GET_ENTITIES_WITHOUT_EMBEDDINGS / UPDATE_ENTITY_EMBEDDING queries. Embeds name only (matching add_entity). Tolerates individual embed failures. Backward compatible: pass generate_embeddings=False for fast structural-only import + deferred batch embedding.
|
@steveonjava is attempting to deploy a commit to the lyonwj's projects Team on Vercel. A member of the Team first needs to authorize it. |
steveonjava
marked this pull request as ready for review
August 10, 2026 05:27
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.
What & why
On the Bolt backend, the LLM extraction pipeline wrote every
:Entitywithembedding = NULL, whilesearch_entities()is vector-only (db.index.vector.queryNodes('entity_embedding_idx', …)). Neteffect: a knowledge graph built via
add_message(extract_entities=True)/extract_entities_from_session()populates the graph but is invisible to semantic recall — everyquery returns empty, with no error. The NAMS backend already embeds extracted entities server-side, so
this fixes a Bolt-vs-NAMS asymmetry and aligns Bolt with the documented prerequisite
("embedding model configured" for automatic extraction). Fixes #NNNNN.
Changes
memory/short_term.py):_extract_and_link_entities()andextract_entities_from_session()now embed each extractedentity's
name(matchingadd_entity()) when an embedder is configured, via a new_embed_names()helper that batches withembedder.embed_batch()and tolerates individualembed failures (leaves NULL for later backfill rather than aborting the message).
generate_embeddings: bool = Truecontrol flag, threaded fromadd_message(...)and exposedon
extract_entities_from_session(...). DefaultTrue= embed (expected behavior); passFalsefor fast structural-only import + deferred batch embedding.
memory/long_term.py):LongTermMemory.generate_entity_embeddings_batch(batch_size=128, on_progress=None)— the entityanalogue of the existing
ShortTermMemory.generate_embeddings_batch(). Uses the already-definedGET_ENTITIES_WITHOUT_EMBEDDINGS/UPDATE_ENTITY_EMBEDDING/COUNT_ENTITIES_WITHOUT_EMBEDDINGSqueries (previously dead code). Idempotent; repairs existing graphs without re-extraction.
No new dependencies, no new imports, no schema/index changes (the
entity_embedding_idxvector indexand the three queries already exist).
Behavior change / compat notes
extraction latency but makes recall actually work. Opt out with
generate_embeddings=False(thencall
generate_entity_embeddings_batch()later) for the previous fast-import behavior. Flagged inCHANGELOG.
nameonly, identical toadd_entity, so manually-added and extracted entities share onevector space.
embedding), so extraction never hard-fails on a single bad embed.
Testing
embeddingon every extracted entity;with
generate_embeddings=False, embeddings are NULL.generate_entity_embeddings_batch()embeds only NULL-embedding entities, is idempotent ona second run (
embedded=0, remaining=0), and reportsfailedon embedder errors without raising.add_message(extract_entities=True)→search_entities()returns the extracted entities by semantic query (the issue's repro now passes).
extract_entities_from_session(generate_embeddings=False)thengenerate_entity_embeddings_batch()→ recall works.Notes for reviewers
mainhere.
add_messagereuse its existinggenerate_embeddingsflag(currently message-only) to also gate entity embedding, or get a dedicated
generate_entity_embeddingsflag? This PR reuses the existing flag for a single intuitive knob;happy to split if you prefer.
Related Issue
Fixes #NNNNN