fix(memory): synchronous OpenViking prefetch with current turn's query - #33260
fix(memory): synchronous OpenViking prefetch with current turn's query#33260per1970 wants to merge 1 commit into
Conversation
prefetch() now calls /api/v1/search/find synchronously with the actual query parameter instead of returning the background-thread cache from the previous turn. The stale prefetch was injecting context about the wrong topic on every turn after the first. Changes: - prefetch() does synchronous search with query (previously ignored) - Drains stale background cache (discards previous turn's results) - Adds 0.35 minimum score threshold to filter noise - Early return '' when no client configured Background queue_prefetch() is unchanged — it still fires at end of turn for pre-warming, but prefetch() no longer consumes its output. Ref: volcengine/OpenViking#2253
|
Non-coder disclaimer: I am not a coder. This fix was generated by Muninn (my Hermes AI agent) based on the documented analysis at volcengine/OpenViking#2253. I reviewed the change, applied the patch, tested it on a clean clone, and verified the fix works before filing. Happy to make any changes maintainers request. |
|
Re-tested the
Suggestion: switch from |
- Replace stale prefetch_result read with synchronous search/find call - Use "limit" (correct OV field) instead of "top_k" (ignored by endpoint) - Clean query with _derive_openviking_user_text to strip skill scaffolding - Send tenant headers (X-OpenViking-Account/User) proactively when configured, avoiding retry round-trip on every tenant-scoped API call - Add "ROOT requests to tenant-scoped APIs" error pattern to retry guard - Update 6 test assertions for new tenant header behavior (134/134 pass) - Use _PREFETCH_MIN_SCORE named constant for noise filtering - Do NOT pass timeout to _VikingClient.post() to avoid silent TypeError Closes: NousResearch#33260
|
Merged via #51898. Your synchronous-prefetch diagnosis was the original root-cause identification for the stale-context problem, and your fix direction (use the current query in |
Salvage of PR #48927 by @ehz0ah, which consolidates OpenViking recall work from #41706 (@huangxun375-stack), #33260, #49975, and #32444. Replaces stale background post-turn prefetch warming with synchronous current-query recall. The old queue_prefetch warmed the PREVIOUS user message while turn-start recall consumed the CURRENT one, so injected context was always about the wrong topic. Changes: - prefetch() now does session-aware /api/v1/search/search with the current query, falls back to /api/v1/search/find on failure - Contract-safe payloads: limit, score_threshold, context_type, session_id — no top_k, no search-body mode, no target_uri - L2 content reads for items with level=2 or empty abstracts, capped at full_read_limit (default 2) - Local ranking (score + query-token overlap + leaf boost), dedup, score threshold, and injected-char budget - queue_prefetch() is now a no-op (background warming removed) - Additive batched viking_read: uris param accepts up to 3 URIs - Per-request timeout support on _VikingClient.get/post/delete - Removes stale _prefetch_result/_prefetch_thread/_prefetch_generation state and _invalidate_prefetch_state() - Strengthened system_prompt_block guidance Salvage follow-up fixes: - Expose all 8 recall config knobs in get_config_schema() (PR #48927 had removed them; #41706 correctly exposed them). Env vars remain as internal mechanism but are now visible in setup wizard. - Lower default timeout 8s→4s, request_timeout 6s→3s, full_read_limit 3→2 to reduce per-turn blocking latency. Co-authored-by: Hao Zhe <haozhe4547@gmail.com> Co-authored-by: Eurekaxun <eurekaxun@163.com>
Salvage of PR NousResearch#48927 by @ehz0ah, which consolidates OpenViking recall work from NousResearch#41706 (@huangxun375-stack), NousResearch#33260, NousResearch#49975, and NousResearch#32444. Replaces stale background post-turn prefetch warming with synchronous current-query recall. The old queue_prefetch warmed the PREVIOUS user message while turn-start recall consumed the CURRENT one, so injected context was always about the wrong topic. Changes: - prefetch() now does session-aware /api/v1/search/search with the current query, falls back to /api/v1/search/find on failure - Contract-safe payloads: limit, score_threshold, context_type, session_id — no top_k, no search-body mode, no target_uri - L2 content reads for items with level=2 or empty abstracts, capped at full_read_limit (default 2) - Local ranking (score + query-token overlap + leaf boost), dedup, score threshold, and injected-char budget - queue_prefetch() is now a no-op (background warming removed) - Additive batched viking_read: uris param accepts up to 3 URIs - Per-request timeout support on _VikingClient.get/post/delete - Removes stale _prefetch_result/_prefetch_thread/_prefetch_generation state and _invalidate_prefetch_state() - Strengthened system_prompt_block guidance Salvage follow-up fixes: - Expose all 8 recall config knobs in get_config_schema() (PR NousResearch#48927 had removed them; NousResearch#41706 correctly exposed them). Env vars remain as internal mechanism but are now visible in setup wizard. - Lower default timeout 8s→4s, request_timeout 6s→3s, full_read_limit 3→2 to reduce per-turn blocking latency. Co-authored-by: Hao Zhe <haozhe4547@gmail.com> Co-authored-by: Eurekaxun <eurekaxun@163.com>
Salvage of PR NousResearch#48927 by @ehz0ah, which consolidates OpenViking recall work from NousResearch#41706 (@huangxun375-stack), NousResearch#33260, NousResearch#49975, and NousResearch#32444. Replaces stale background post-turn prefetch warming with synchronous current-query recall. The old queue_prefetch warmed the PREVIOUS user message while turn-start recall consumed the CURRENT one, so injected context was always about the wrong topic. Changes: - prefetch() now does session-aware /api/v1/search/search with the current query, falls back to /api/v1/search/find on failure - Contract-safe payloads: limit, score_threshold, context_type, session_id — no top_k, no search-body mode, no target_uri - L2 content reads for items with level=2 or empty abstracts, capped at full_read_limit (default 2) - Local ranking (score + query-token overlap + leaf boost), dedup, score threshold, and injected-char budget - queue_prefetch() is now a no-op (background warming removed) - Additive batched viking_read: uris param accepts up to 3 URIs - Per-request timeout support on _VikingClient.get/post/delete - Removes stale _prefetch_result/_prefetch_thread/_prefetch_generation state and _invalidate_prefetch_state() - Strengthened system_prompt_block guidance Salvage follow-up fixes: - Expose all 8 recall config knobs in get_config_schema() (PR NousResearch#48927 had removed them; NousResearch#41706 correctly exposed them). Env vars remain as internal mechanism but are now visible in setup wizard. - Lower default timeout 8s→4s, request_timeout 6s→3s, full_read_limit 3→2 to reduce per-turn blocking latency. Co-authored-by: Hao Zhe <haozhe4547@gmail.com> Co-authored-by: Eurekaxun <eurekaxun@163.com>
Salvage of PR NousResearch#48927 by @ehz0ah, which consolidates OpenViking recall work from NousResearch#41706 (@huangxun375-stack), NousResearch#33260, NousResearch#49975, and NousResearch#32444. Replaces stale background post-turn prefetch warming with synchronous current-query recall. The old queue_prefetch warmed the PREVIOUS user message while turn-start recall consumed the CURRENT one, so injected context was always about the wrong topic. Changes: - prefetch() now does session-aware /api/v1/search/search with the current query, falls back to /api/v1/search/find on failure - Contract-safe payloads: limit, score_threshold, context_type, session_id — no top_k, no search-body mode, no target_uri - L2 content reads for items with level=2 or empty abstracts, capped at full_read_limit (default 2) - Local ranking (score + query-token overlap + leaf boost), dedup, score threshold, and injected-char budget - queue_prefetch() is now a no-op (background warming removed) - Additive batched viking_read: uris param accepts up to 3 URIs - Per-request timeout support on _VikingClient.get/post/delete - Removes stale _prefetch_result/_prefetch_thread/_prefetch_generation state and _invalidate_prefetch_state() - Strengthened system_prompt_block guidance Salvage follow-up fixes: - Expose all 8 recall config knobs in get_config_schema() (PR NousResearch#48927 had removed them; NousResearch#41706 correctly exposed them). Env vars remain as internal mechanism but are now visible in setup wizard. - Lower default timeout 8s→4s, request_timeout 6s→3s, full_read_limit 3→2 to reduce per-turn blocking latency. Co-authored-by: Hao Zhe <haozhe4547@gmail.com> Co-authored-by: Eurekaxun <eurekaxun@163.com>
Salvage of PR NousResearch#48927 by @ehz0ah, which consolidates OpenViking recall work from NousResearch#41706 (@huangxun375-stack), NousResearch#33260, NousResearch#49975, and NousResearch#32444. Replaces stale background post-turn prefetch warming with synchronous current-query recall. The old queue_prefetch warmed the PREVIOUS user message while turn-start recall consumed the CURRENT one, so injected context was always about the wrong topic. Changes: - prefetch() now does session-aware /api/v1/search/search with the current query, falls back to /api/v1/search/find on failure - Contract-safe payloads: limit, score_threshold, context_type, session_id — no top_k, no search-body mode, no target_uri - L2 content reads for items with level=2 or empty abstracts, capped at full_read_limit (default 2) - Local ranking (score + query-token overlap + leaf boost), dedup, score threshold, and injected-char budget - queue_prefetch() is now a no-op (background warming removed) - Additive batched viking_read: uris param accepts up to 3 URIs - Per-request timeout support on _VikingClient.get/post/delete - Removes stale _prefetch_result/_prefetch_thread/_prefetch_generation state and _invalidate_prefetch_state() - Strengthened system_prompt_block guidance Salvage follow-up fixes: - Expose all 8 recall config knobs in get_config_schema() (PR NousResearch#48927 had removed them; NousResearch#41706 correctly exposed them). Env vars remain as internal mechanism but are now visible in setup wizard. - Lower default timeout 8s→4s, request_timeout 6s→3s, full_read_limit 3→2 to reduce per-turn blocking latency. Co-authored-by: Hao Zhe <haozhe4547@gmail.com> Co-authored-by: Eurekaxun <eurekaxun@163.com>
Salvage of PR NousResearch#48927 by @ehz0ah, which consolidates OpenViking recall work from NousResearch#41706 (@huangxun375-stack), NousResearch#33260, NousResearch#49975, and NousResearch#32444. Replaces stale background post-turn prefetch warming with synchronous current-query recall. The old queue_prefetch warmed the PREVIOUS user message while turn-start recall consumed the CURRENT one, so injected context was always about the wrong topic. Changes: - prefetch() now does session-aware /api/v1/search/search with the current query, falls back to /api/v1/search/find on failure - Contract-safe payloads: limit, score_threshold, context_type, session_id — no top_k, no search-body mode, no target_uri - L2 content reads for items with level=2 or empty abstracts, capped at full_read_limit (default 2) - Local ranking (score + query-token overlap + leaf boost), dedup, score threshold, and injected-char budget - queue_prefetch() is now a no-op (background warming removed) - Additive batched viking_read: uris param accepts up to 3 URIs - Per-request timeout support on _VikingClient.get/post/delete - Removes stale _prefetch_result/_prefetch_thread/_prefetch_generation state and _invalidate_prefetch_state() - Strengthened system_prompt_block guidance Salvage follow-up fixes: - Expose all 8 recall config knobs in get_config_schema() (PR NousResearch#48927 had removed them; NousResearch#41706 correctly exposed them). Env vars remain as internal mechanism but are now visible in setup wizard. - Lower default timeout 8s→4s, request_timeout 6s→3s, full_read_limit 3→2 to reduce per-turn blocking latency. Co-authored-by: Hao Zhe <haozhe4547@gmail.com> Co-authored-by: Eurekaxun <eurekaxun@163.com>
Salvage of PR NousResearch#48927 by @ehz0ah, which consolidates OpenViking recall work from NousResearch#41706 (@huangxun375-stack), NousResearch#33260, NousResearch#49975, and NousResearch#32444. Replaces stale background post-turn prefetch warming with synchronous current-query recall. The old queue_prefetch warmed the PREVIOUS user message while turn-start recall consumed the CURRENT one, so injected context was always about the wrong topic. Changes: - prefetch() now does session-aware /api/v1/search/search with the current query, falls back to /api/v1/search/find on failure - Contract-safe payloads: limit, score_threshold, context_type, session_id — no top_k, no search-body mode, no target_uri - L2 content reads for items with level=2 or empty abstracts, capped at full_read_limit (default 2) - Local ranking (score + query-token overlap + leaf boost), dedup, score threshold, and injected-char budget - queue_prefetch() is now a no-op (background warming removed) - Additive batched viking_read: uris param accepts up to 3 URIs - Per-request timeout support on _VikingClient.get/post/delete - Removes stale _prefetch_result/_prefetch_thread/_prefetch_generation state and _invalidate_prefetch_state() - Strengthened system_prompt_block guidance Salvage follow-up fixes: - Expose all 8 recall config knobs in get_config_schema() (PR NousResearch#48927 had removed them; NousResearch#41706 correctly exposed them). Env vars remain as internal mechanism but are now visible in setup wizard. - Lower default timeout 8s→4s, request_timeout 6s→3s, full_read_limit 3→2 to reduce per-turn blocking latency. Co-authored-by: Hao Zhe <haozhe4547@gmail.com> Co-authored-by: Eurekaxun <eurekaxun@163.com>
Problem
The OpenViking memory provider's
prefetch()method ignores itsqueryparameter entirely.It returns background-thread results from
queue_prefetch()which fired at the end ofthe previous turn — meaning automatic memory context is always about the wrong topic.
First turn of every session gets zero context. Every subsequent turn gets stale context
from the previous topic. The model can manually call
viking_searchto compensate,but the automatic recall that fires on every turn is working against it.
This was identified and analyzed in detail by @hammerhoundai in
volcengine/OpenViking#2253,
which documents the full comparison against Claude Code's synchronous recall approach.
Evidence from source
The
prefetch()method inplugins/memory/openviking/__init__.py:queue_prefetch()fires at end of turn N with query "AWS", stores in_prefetch_result.prefetch()at start of turn N+1 with query "CSS" returns the "AWS" result. The APIsignature takes a
queryparameter but the OpenViking provider throws it away.Fix
prefetch()now does a synchronousPOST /api/v1/search/findwith the currentturn's
queryparameter — matching how Claude Code's plugin works. The stalebackground-thread cache is drained (discarded).
Three changes:
prefetch(query="CSS")searches for "CSS", not "AWS"""when no client configuredqueue_prefetch()is unchanged — it still fires background searches at end of turnfor pre-warming, but
prefetch()no longer consumes those results.How to test
## OpenViking Contextcontains results about B, not ATested on
Related