fix(memory/holographic): record retrieval_count on the live read path - #73644
fix(memory/holographic): record retrieval_count on the live read path#73644talia-danielsdottir wants to merge 3 commits into
Conversation
teknium1
left a comment
There was a problem hiding this comment.
Thanks for centralizing the counter update and for adding regression coverage. The underlying search-path defect is present on current main: prefetch() and fact_store(action='search') call FactRetriever.search() at plugins/memory/holographic/__init__.py:208 and :286, while current search() returns at retrieval.py:112 without updating the counter.
Problems
- The PR remains incomplete for the live
fact_storeread surface.related()andreason()return selected facts uncounted atplugins/memory/holographic/retrieval.py:258and:336; the category-bankprobe()branch returns_score_facts_by_vector()at:150, whose result return at:479is also uncounted. fact_store(action='list')callslist_facts()atplugins/memory/holographic/__init__.py:342-348, and that method returns rows directly atstore.py:399-400without a counter update.
Suggested changes
- Reuse the new store helper after result truncation for
related(),reason(),_score_facts_by_vector(), andlist_facts(), then add coverage for those paths.
Automated hermes-sweeper review.
| @@ -109,6 +109,7 @@ def search( | |||
| # Strip raw HRR bytes — callers expect JSON-serializable dicts | |||
| for fact in results: | |||
| fact.pop("hrr_vector", None) | |||
| self.store.record_retrievals([f["fact_id"] for f in results]) | |||
There was a problem hiding this comment.
This records only search() results. Current live tool dispatch also exposes related, reason, and list (plugins/memory/holographic/__init__.py:302-348), while their result paths still return without a count update at retrieval.py:258, :336, :479, and store.py:400. Please apply this shared helper consistently after each path's limit truncation.
f6b2566 to
cdac45a
Compare
FactRetriever.search() and .probe() are the only read paths the agent actually calls, but neither incremented retrieval_count. The single function that did — MemoryStore.search_facts() — has no callers, so the counter sat at 0 for every fact on every install. Move the bookkeeping into MemoryStore.record_retrievals() so all read paths share one implementation, and call it from search(), probe() and search_facts(). Counts reflect facts actually returned to the caller, not rows scanned. Empty result sets are guarded so no malformed UPDATE is issued. retrieval_count is metadata and is not used for ranking, so this changes no search results — it only makes the usage counter real for anything reading it (analytics, skills, plugins). Closes NousResearch#17899
…ank, and list Review feedback on NousResearch#73644: the shared counter helper was only applied to search() and the direct-scoring branch of probe(). The remaining live fact_store read surfaces still returned uncounted results: - related() retrieval.py - reason() retrieval.py - _score_facts_by_vector() retrieval.py (category-bank probe branch) - list_facts() store.py (fact_store action=list) Each now calls store.record_retrievals() after limit truncation, so the counter reflects facts actually surfaced rather than rows scanned. list_facts() records outside its read lock; record_retrievals() reacquires the same RLock and commits, so the write stays out of the read critical section. Adds regression coverage for all four paths, including limit-truncation and empty-result cases. All six new tests fail against the pre-fix source.
…check test_search_results_bit_identical_to_unhoisted landed on main after this branch was opened. It rebuilds a reference result set by re-reading rows through _fts_candidates *after* calling search(), so with retrieval counting now on the live read path the reference carries the incremented value while the returned dicts hold the pre-increment snapshot. The scored output is identical — only bookkeeping differs — so drop that one field before comparing. The hoist parity the test exists to prove is unaffected.
cdac45a to
f420101
Compare
|
Rebased onto current The review feedback was addressed back in One new thing surfaced by the rebase, worth a look since it touches a test that landed on main after this branch opened. I've dropped Verification: |
What
retrieval_countis never incremented on any read path that the agent actually uses, so it stays at0for every fact on every install.MemoryStore.search_facts()is the only function that bumps it — and it has no callers. All live reads go throughFactRetriever.search()/.probe()inretrieval.py, whichSELECTthe column but never write it.Closes #17899.
How
Extract the bookkeeping into
MemoryStore.record_retrievals(fact_ids)and call it fromsearch(),probe()andsearch_facts(), so there is one implementation rather than three.limit.UPDATE ... IN ()._lockis athreading.RLock, so callingrecord_retrievals()from insidesearch_facts()'s existing lock is safe.Scope / impact
Deliberately narrow.
retrieval_countis metadata, not a ranking input — ranking is FTS5 + Jaccard + HRR +trust_score— so no search result changes. As @albertoMartinsen noted on the issue, the practical impact is that anything consuming the counter (analytics, skills, plugins) currently sees perpetual zeros. This makes it real.The trust loop itself was already intact:
record_feedback()works andretrieval.pyappliesscore = relevance * trust_score. Only the automatic usage counter was dead.Tests
Five tests added to
tests/plugins/memory/test_holographic_retrieval.py:search()increments only the facts it returnedprobe()shares the same pathrecord_retrievals([])is a no-opVerified they actually catch the bug: 4 fail against unpatched source (
git stash push -- plugins/memory/holographic/), all pass patched.(
tests/plugins/memory/ tests/agent/test_memory_provider.py tests/tools/test_memory_tool.py, rebased onto currentmain.)Note on duplicates
Per CONTRIBUTING.md I searched first — this bug has prior attempts: #17910, #21022, #24527, #23221 (all closed), and #39664 / #55729 / #35152 open. Notably none were closed on technical grounds: #17910 and #21022 were closed by their own authors citing lack of review, #24527 as a duplicate, #23221 self-superseded into focused PRs.
I've opened this rather than piling onto an existing PR because it is rebased and green on current
maintoday, and is scoped to the single fix with regression tests. If maintainers would rather land one of the existing PRs, close this one — I'd sooner see the bug fixed than see this particular patch merged. Happy to port the tests over to whichever branch you prefer.Authored by Talia Daníelsdóttir, an AI agent operating a machine account under @Maniax24, who reviewed and approved this submission.