hermes-agent/plugins/memory/openviking
kshitijk4poor 8f0da78f84 fix(openviking): cool down failed refreshes and publish conn identity atomically
Follow-up hardening on the salvaged _ensure_client() (#21130 fix):

- Failed-config cooldown: after a refresh attempt fails for a given
  resolved config, skip re-probing for 30s. Previously every provider
  access against a down endpoint paid a 3s health probe under
  _client_refresh_lock and emitted a warning (2+ per turn, some on
  user-facing threads: prefetch, tool calls, session end). Retries
  still happen after the cooldown or immediately when config changes,
  and the log message now says so instead of the false 'disabled until
  config changes'.
- Atomic connection snapshot: _conn_snapshot (5-tuple, single
  assignment) is published only after a health check passes.
  _new_client() and on_memory_write's writer read it as one load, so
  background writers can no longer observe a torn mix of old/new
  identity fields mid-refresh or target an endpoint that never passed
  health. Field writes in _ensure_client_locked keep tracking the
  attempted config for the unchanged-config dedupe.
- _env_refresh_enabled moves to the top of initialize(): an exception
  mid-initialize (swallowed by MemoryManager) can no longer leave the
  provider silently stuck in never-refresh mode.
- _search_prefetch_context reuses _new_client() and degrades to ''
  on construction failure instead of propagating.

Mutation-checked: neutering the cooldown or publishing the snapshot on
failed health makes the new regression tests fail.
2026-07-24 13:00:53 +05:30
..
__init__.py fix(openviking): cool down failed refreshes and publish conn identity atomically 2026-07-24 13:00:53 +05:30
plugin.yaml feat(memory): improve OpenViking setup UX 2026-06-17 01:02:38 +08:00
README.md docs: clarify OpenViking local setup 2026-07-22 14:05:28 +05:30

OpenViking Memory Provider

Context database by Volcengine (ByteDance) with filesystem-style knowledge hierarchy, tiered retrieval, and automatic memory extraction.

Requirements

  • OpenViking installed with the openviking-server command available
  • OpenViking server config initialized and validated (openviking-server init, then openviking-server doctor)
  • OpenViking server running and reachable from Hermes

Setup

Prepare OpenViking first:

openviking-server init
openviking-server doctor
openviking-server

Then configure Hermes:

hermes memory setup    # select "openviking"

The setup can link to an existing ~/.openviking/ovcli.conf, copy its current connection values into Hermes, or create a minimal ovcli.conf when one does not exist.

Or manually:

hermes config set memory.provider openviking

Add the connection settings to the active profile's .env file. For the default profile that is ~/.hermes/.env; for a named profile use ~/.hermes/profiles/<profile>/.env.

OPENVIKING_ENDPOINT=http://127.0.0.1:1933
# OPENVIKING_API_KEY=...
# OPENVIKING_ACCOUNT=default
# OPENVIKING_USER=default
# OPENVIKING_AGENT=hermes

Config

OpenViking's server config is separate from Hermes:

  • ov.conf configures OpenViking storage, embedding/VLM models, auth, and server behavior. OpenViking reads it from --config, OPENVIKING_CONFIG_FILE, or ~/.openviking/ov.conf.
  • ovcli.conf stores client/CLI connection values such as url, api_key, account, and user. It is read from OPENVIKING_CLI_CONFIG_FILE or ~/.openviking/ovcli.conf.

Hermes-side provider config is read from environment variables in the active profile's .env:

Env Var Default Description
OPENVIKING_ENDPOINT http://127.0.0.1:1933 Server URL
OPENVIKING_API_KEY (none) User/admin API key for authenticated servers
OPENVIKING_ACCOUNT default Tenant account for local/trusted mode
OPENVIKING_USER default Tenant user for local/trusted mode
OPENVIKING_AGENT hermes Hermes peer ID in OpenViking, used for peer-scoped memories

When OPENVIKING_API_KEY is set, Hermes lets OpenViking derive account/user identity from the key. In local or trusted deployments without an API key, Hermes sends OPENVIKING_ACCOUNT and OPENVIKING_USER as identity headers.

Tools

Tool Description
viking_search Semantic search with fast/deep/auto modes
viking_read Read content at a viking:// URI (abstract/overview/full)
viking_browse Filesystem-style navigation (list/tree/stat)
viking_remember Store a fact directly with OpenViking content/write
viking_forget Delete one exact viking:// memory file URI
viking_add_resource Ingest URLs/docs into the knowledge base

Memory Writes And Deletes

viking_remember writes directly to OpenViking with POST /api/v1/content/write and mode=create. It creates peer-scoped memory files under viking://user/peers/${OPENVIKING_AGENT}/memories/...; OpenViking may return a canonical user-scoped form such as viking://user/default/peers/${OPENVIKING_AGENT}/memories/... in API-key mode. Explicit remembers do not depend on session commit extraction.

Hermes built-in memory tool additions are mirrored to OpenViking after the local memory operation succeeds:

Hermes action OpenViking operation
add content/write with mode=create under the configured peer memory namespace

Built-in replace and remove operations are not mirrored because Hermes native memory entries do not yet carry stable OpenViking file URIs. Use viking_forget when the user explicitly asks to delete a specific OpenViking memory URI.

viking_forget is intentionally narrow. It only accepts concrete user memory file URIs, such as viking://user/peers/hermes/memories/preferences/mem_abc123.md or the canonical viking://user/default/peers/hermes/memories/preferences/mem_abc123.md. Files directly under memories/, such as viking://user/default/memories/profile.md, are also allowed because OpenViking supports them. The tool rejects directories, resources, skills, sessions, generated summary files, and URIs with query strings or fragments. Use OpenViking's MCP, CLI, or admin APIs for broader resource and directory cleanup.