hermes - 💡(How to fix) Fix feat: route built-in session_search and memory tools through OpenViking when configured as memory provider

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…

Fix Action

Fix / Workaround

Despite OpenViking being active, calling session_search() directly imports and runs SessionDB (SQLite FTS5) from hermes_state.py. The dispatch is a hardcoded branch in agent/tool_executor.py (line 610-626) that has zero awareness of the configured memory provider:

  1. Route session_search through the active memory provider when configured:
    • When memory.provider is set to "openviking", make session_search delegate to OpenViking's search internally (or at minimum provide a config flag like memory.route_builtin_search: true)
    • The provider interface (MemoryProvider) could add an optional method like search_sessions(query) -- or the OpenViking plugin could override the tool dispatch for session_search

Code Example

if function_name == "session_search":
    session_db = agent._get_session_db_for_recall()
    from tools.session_search_tool import session_search as _session_search
    function_result = _session_search(db=session_db, ...)

---

{
  "rerank": {
    "provider": "openai",
    "api_base": "http://192.168.1.238:8000/v1/rerank",
    "model": "jina-reranker-v3",
    "threshold": 0.1
  }
}
RAW_BUFFERClick to expand / collapse

Problem

When OpenViking is configured as memory.provider in Hermes, two core memory tools still bypass OpenViking entirely and use Hermes' own built-in backends.

1. session_search always goes to SQLite FTS5

Despite OpenViking being active, calling session_search() directly imports and runs SessionDB (SQLite FTS5) from hermes_state.py. The dispatch is a hardcoded branch in agent/tool_executor.py (line 610-626) that has zero awareness of the configured memory provider:

if function_name == "session_search":
    session_db = agent._get_session_db_for_recall()
    from tools.session_search_tool import session_search as _session_search
    function_result = _session_search(db=session_db, ...)

This means every session_search call is pure FTS5 keyword matching -- no semantic search, no chunking, no RAG -- even though OpenViking provides all of those and is sitting there as the configured memory provider.

2. memory tool is file-based, OpenViking only gets a write mirror

The memory (add/replace/remove/read) tool operates entirely on ~/.hermes/memories/MEMORY.md and USER.md files. After a write, it calls on_memory_write() on the memory provider as a side effect (line 641-653) -- but the read/search path (memory tool action=read) never touches the provider.


OpenViking Search Modes and Rerank

The Hermes plugin's viking_search tool schema exposes mode as {type: "string", enum: ["auto", "fast", "deep"]}, but this parameter is effectively dead code.

Why: The OpenViking server's /api/v1/search/find endpoint uses a FindRequest Pydantic model that has no mode field. When the Hermes plugin sends mode in the POST body, it gets silently dropped by Pydantic's default extra='ignore' behavior.

The actual search behavior is server-side only, controlled by the [rerank] section in ov.conf:

{
  "rerank": {
    "provider": "openai",
    "api_base": "http://192.168.1.238:8000/v1/rerank",
    "model": "jina-reranker-v3",
    "threshold": 0.1
  }
}

The HierarchicalRetriever at init time checks if rerank_config.is_available():

  • Rerank configured_rerank_client initialized → all searches do vector search + reranker re-scoring
  • No rerank config → vector search only

The retriever internally has two modes (RetrieverMode.THINKING = with rerank, RetrieverMode.QUICK = without), but the VikingFS.find() method calls retriever.retrieve() without passing a mode, so it always defaults to THINKING. There is no API surface for clients to switch between fast/deep at all.

Implications for the Hermes plugin

  1. The mode parameter in viking_search's tool schema is misleading -- it does nothing
  2. queue_prefetch() always calls /api/v1/search/find which defaults to THINKING mode, so if the server has rerank configured, every prefetch also runs rerank (potentially wasteful for background context injection)
  3. The plugin has no way to detect or report whether the OpenViking server has rerank enabled
  4. There's no client-side configuration to skip rerank for latency-sensitive or low-priority searches

Suggested approach

  1. Route session_search through the active memory provider when configured:

    • When memory.provider is set to "openviking", make session_search delegate to OpenViking's search internally (or at minimum provide a config flag like memory.route_builtin_search: true)
    • The provider interface (MemoryProvider) could add an optional method like search_sessions(query) -- or the OpenViking plugin could override the tool dispatch for session_search
  2. Route memory (read) through the active memory provider:

    • When OpenViking is active, the memory tool's read/search operations should query OpenViking rather than the local files
    • OpenViking already has on_memory_write() for the write path -- implement the read path symmetrically
  3. Add search mode configuration to the plugin:

    • Expose a memory.openviking.search_mode config option (thinking / quick) so users can control whether prefetch and viking_search use rerank
    • The plugin should detect and report whether the server has rerank enabled (ideally via a get_config_schema() field or a tool for introspection)
    • Remove or deprecate the misleading mode parameter from viking_search's tool schema (or make it actually work)
  4. Document the behavior: The current documentation implies OpenViking replaces Hermes' built-in memory when configured, but it doesn't -- it's additive. This should be made explicit.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING