Skip to content

feat(openviking): add full recall prefetch policy - #48927

Closed
ehz0ah wants to merge 5 commits into
NousResearch:mainfrom
ehz0ah:fix/openviking-session-aware-prefetch
Closed

feat(openviking): add full recall prefetch policy#48927
ehz0ah wants to merge 5 commits into
NousResearch:mainfrom
ehz0ah:fix/openviking-session-aware-prefetch

Conversation

@ehz0ah

@ehz0ah ehz0ah commented Jun 19, 2026

Copy link
Copy Markdown
Contributor

What does this PR do?

This PR consolidates the OpenViking session-prefetch work with the useful parts of PR #41706, while updating the implementation to match the current OpenViking server contract.

The main change is that Hermes now uses fuller OpenViking automatic recall without sending stale OpenViking payloads. Recall uses session-aware /api/v1/search/search when a session id is available, falls back to /api/v1/search/find for non-session search failures, filters with context_type, and keeps local ranking, deduplication, L2 reads, and injected context size bounded.

This PR intentionally removes OpenViking's post-turn background prefetch warming. The old queue warmed the previous user message, while turn-start recall consumes the current user message. OpenViking recall is now a single current-query path with a bounded synchronous budget.

It does not send legacy top_k, does not forward tool mode into search bodies, and does not use the invalid viking://agent/memories target.

The cherry-picked PR #41706 commit was preserved with original authorship:

  • c982d947f feat(openviking): add full recall prefetch policy
  • Includes the original cherry-pick trailer for commit 764fb28dc4e5863792a7cda22e2570b24691cc83.

Open PRs Superseded

After this PR merges, these still-open OpenViking-related PRs can be closed as superseded by this branch:

Related Issue

N/A

Type of Change

  • 🐛 Bug fix (non-breaking change that fixes an issue)
  • ✨ New feature (non-breaking change that adds functionality)
  • 🔒 Security fix
  • 📝 Documentation update
  • ✅ Tests (adding or improving test coverage)
  • ♻️ Refactor (no behavior change)
  • 🎯 New skill (bundled or hub)

Changes Made

  • plugins/memory/openviking/__init__.py
    • Uses contract-safe automatic recall payloads: query, limit, score_threshold, context_type, and optional session_id.
    • Avoids top_k, search-body mode, and viking://agent/memories.
    • Uses context_type="memory" by default; advanced env config can opt into resources with OPENVIKING_RECALL_RESOURCES.
    • Removes OpenViking background queue_prefetch() work because the old queue/prefetch query keys did not line up across turns.
    • Keeps current-query recall synchronous but bounded with fixed/env-backed advanced settings:
      • OPENVIKING_RECALL_TIMEOUT_SECONDS default 8.0
      • OPENVIKING_RECALL_REQUEST_TIMEOUT_SECONDS default 6.0
      • OPENVIKING_RECALL_FULL_READ_LIMIT default 3
    • Keeps tuned recall defaults available as fixed/env-backed advanced settings, but removes them from Hermes memory setup schema.
    • Adds recall ranking, deduplication, score threshold, injection budget, and L2 content-read policy.
    • Adds additive batch viking_read support through uris, capped at three URIs, while preserving single-URI output shape.
    • Strengthens system prompt guidance around focused searches, strongest URI reads, repeated-search stopping behavior, treating OpenViking results as evidence, and the upstream viking_forget tool.
  • tests/openviking_plugin/test_openviking.py
    • Adds/updates coverage for hidden recall setup knobs, session-aware context payloads, resource opt-in, L2 reads, current-query recall, prompt guidance, and batched reads.
  • tests/plugins/memory/test_openviking_provider.py
    • Adds/updates provider-level contract tests for session search, fallback search, no top_k, no search-body mode, no invalid target URI, L2 reads, empty-summary fallback behavior, no-op OpenViking queue_prefetch(), per-request recall timeouts, full-read caps, and budget-exhaustion logging.

How to Test

  1. Run targeted OpenViking provider tests:
    scripts/run_tests.sh tests/openviking_plugin/test_openviking.py tests/plugins/memory/test_openviking_provider.py -- -o addopts=
  2. Run memory-manager regression tests:
    scripts/run_tests.sh tests/agent/test_memory_provider.py tests/agent/test_memory_async_sync.py tests/agent/test_memory_skill_scaffolding.py tests/agent/test_memory_session_switch.py -- -o addopts=
  3. Check formatting/whitespace:
    git diff --check
  4. Optional live smoke with a local OpenViking server:
    • Start OpenViking from a local OpenViking checkout with copied local config/env.
    • Use an isolated Hermes profile pointing at that local server.
    • Verify provider initialization, direct content read, batched viking_read, and synchronous current-query prefetch() against the real server.

Validation Performed

Latest validation on this branch:

  • UV_NATIVE_TLS=true uv run python -m py_compile plugins/memory/openviking/__init__.py tests/openviking_plugin/test_openviking.py tests/plugins/memory/test_openviking_provider.py
    • Passed.
  • scripts/run_tests.sh tests/openviking_plugin/test_openviking.py tests/plugins/memory/test_openviking_provider.py -- -o addopts=
    • 176 tests passed, 0 failed.
  • scripts/run_tests.sh tests/agent/test_memory_provider.py tests/agent/test_memory_async_sync.py tests/agent/test_memory_skill_scaffolding.py tests/agent/test_memory_session_switch.py -- -o addopts=
    • 122 tests passed, 0 failed.
  • git diff --check
    • Passed with no output.
  • Contract grep after merge:
    • No conflict markers.
    • No viking://agent/memories.
    • No _RECALL_TARGET_URIS.
    • Remaining top_k matches are only negative assertions in tests.

Earlier live local OpenViking smoke for this PR branch, before the timeout-default-only follow-up, using a local OpenViking checkout as the server source:

  • Started OpenViking in API-key mode on a localhost test port using copied local config/env and an isolated temp workspace copy.
  • Authenticated /api/v1/system/status returned status=ok.
  • Hermes provider initialized against the local server.
  • Wrote real smoke content to a viking://user/peers/hermes/memories/events/... URI.
  • Direct /api/v1/content/read returned the expected content.
  • Synchronous current-query prefetch() returned an OpenViking context block containing the expected smoke marker.
  • Smoke content cleanup succeeded.
  • Temp server/data were stopped and removed; no listener was left on the verification port.

Smoke summary: status_ok=true, read_ok=true, prefetch_ok=true, cleanup_ok=true.

Notes

Recall tuning knobs are intentionally not shown in Hermes memory setup. Users who need to tune them can set env/config directly; otherwise the fixed defaults apply.

Sensitive local paths, credentials, and machine-specific config details are intentionally omitted from this PR description.

Checklist

Code

  • I've read the Contributing Guide
  • My commit messages follow Conventional Commits (fix(scope):, feat(scope):, etc.)
  • I searched for existing PRs to make sure this isn't a duplicate
  • My PR contains only changes related to this fix/feature (no unrelated commits)
  • I've run pytest tests/ -q and all tests pass
  • I've added tests for my changes (required for bug fixes, strongly encouraged for features)
  • I've tested on my platform: macOS

Documentation & Housekeeping

  • I've updated relevant documentation (README, docs/, docstrings) — N/A; behavior covered by provider prompt, PR body, and tests
  • I've updated cli-config.yaml.example if I added/changed config keys — N/A; no new setup config keys exposed
  • I've updated CONTRIBUTING.md or AGENTS.md if I changed architecture or workflows — N/A
  • I've considered cross-platform impact (Windows, macOS) — no platform-specific APIs added
  • I've updated tool descriptions/schemas if I changed tool behavior — viking_read schema updated for additive uris support

Screenshots / Logs

Relevant command summaries are included in Validation Performed above. No UI screenshots apply.

@ehz0ah
ehz0ah marked this pull request as ready for review June 19, 2026 08:28
@alt-glitch alt-glitch added type/feature New feature or request comp/plugins Plugin system and bundled plugins tool/memory Memory tool and memory providers P3 Low — cosmetic, nice to have labels Jun 19, 2026
@ehz0ah
ehz0ah force-pushed the fix/openviking-session-aware-prefetch branch from 2069e80 to 6c4d091 Compare June 19, 2026 08:54
@ehz0ah
ehz0ah marked this pull request as draft June 22, 2026 02:26
@ehz0ah ehz0ah changed the title fix(openviking): improve session-aware prefetch recall feat(openviking): add full recall prefetch policy Jun 23, 2026
ehz0ah and others added 2 commits June 23, 2026 15:21
Use OpenViking's session-aware search endpoint for background prefetch when a session id is available, with fallback to non-session find if the session-aware request fails.

Include skill hits in prefetch output and recover bounded snippets for empty-abstract hits through content/read while keeping the result size capped.
@ehz0ah
ehz0ah force-pushed the fix/openviking-session-aware-prefetch branch from 05f4d1e to c982d94 Compare June 23, 2026 07:23
@ehz0ah
ehz0ah marked this pull request as ready for review June 23, 2026 08:26
@kshitijk4poor

Copy link
Copy Markdown
Collaborator

Merged via #51898. Your full consolidation of the OpenViking recall work was salvaged onto current main with authorship preserved. Salvage follow-up fixes: (1) re-exposed the 8 recall config knobs in get_config_schema() which had been removed, (2) lowered default timeout 8s→4s and full_read_limit 3→2 to reduce per-turn blocking latency. Thanks for the thorough work.

kshitijk4poor added a commit that referenced this pull request Jun 24, 2026
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>
kshitijk4poor added a commit that referenced this pull request Jun 24, 2026
…l-48927

feat(openviking): add full recall prefetch policy (salvage #48927)
pai-scaffolde pushed a commit to pai-scaffolde/hermes-agent that referenced this pull request Jun 28, 2026
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>
waefrebeorn pushed a commit to waefrebeorn/slermes that referenced this pull request Jul 2, 2026
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>
waefrebeorn pushed a commit to waefrebeorn/slermes that referenced this pull request Jul 2, 2026
…viking-recall-48927

feat(openviking): add full recall prefetch policy (salvage NousResearch#48927)
habarmc1223-sudo pushed a commit to habarmc1223-sudo/hermes-agent-fluxmem that referenced this pull request Jul 8, 2026
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>
habarmc1223-sudo pushed a commit to habarmc1223-sudo/hermes-agent-fluxmem that referenced this pull request Jul 8, 2026
…viking-recall-48927

feat(openviking): add full recall prefetch policy (salvage NousResearch#48927)
santhreal pushed a commit to santhreal/hermes-agent that referenced this pull request Jul 13, 2026
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>
santhreal pushed a commit to santhreal/hermes-agent that referenced this pull request Jul 13, 2026
…viking-recall-48927

feat(openviking): add full recall prefetch policy (salvage NousResearch#48927)
Gravezzz pushed a commit to Gravezzz/hermes-agent that referenced this pull request Jul 21, 2026
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>
Gravezzz pushed a commit to Gravezzz/hermes-agent that referenced this pull request Jul 21, 2026
…viking-recall-48927

feat(openviking): add full recall prefetch policy (salvage NousResearch#48927)
leewenjie pushed a commit to leewenjie/hermes-agent that referenced this pull request Aug 7, 2026
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>
leewenjie pushed a commit to leewenjie/hermes-agent that referenced this pull request Aug 7, 2026
…viking-recall-48927

feat(openviking): add full recall prefetch policy (salvage NousResearch#48927)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/plugins Plugin system and bundled plugins P3 Low — cosmetic, nice to have tool/memory Memory tool and memory providers type/feature New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants