OpenViking Memory Directories Split by Language: Unify With Custom Templates

Contents

OpenViking memory paths ended up with two parallel directory trees: entities/infrastructure/ and entities/基础设施/ holding the same kind of content. The cause is in the session commit auto-extraction pipeline, which names directories in the detected conversation language. Editing the memory template fixes the naming at the source; steps below.

Symptom

viking://user/<user>/memories/entities/ contained both:

entities/infrastructure/   ← dmit.md, surface.md (written by Hermes via viking_remember)
entities/基础设施/         ← backrest_backup.md, legion_wsl.md (auto-extracted by session commit)
entities/services/         ← hermes_gateway_sessions.md
entities/服务/             ← same content, second copy

The two write paths use different directory languages: Hermes writes English directories, OpenViking’s auto-extraction writes Chinese ones, splitting the same class of content in two.

Root cause

During session commit, OpenViking detects the output language from conversation content (_detect_language() in session_extract_context_provider.py). A Chinese conversation sets the template variable {{ language }} to zh-CN.

In the memory type YAML templates, the entities directory comes from the category field:

# prompts/templates/memory/entities.yaml
filename_template: "{{ category }}/{{ name }}.md"

fields:
  - name: category
    description: |
      Category written in {{ language }}.
      {% if language == 'en' %}Use lowercase with underscores, max 3 words.{% else %}Keep it concise and natural in {{ language }}.{% endif %}

The language-adaptive instruction makes the LLM write category in Chinese (“基础设施”, “服务”), producing Chinese directories. The name field already allows Chinese or English, and filenames do not affect path-level consistency, so leave it alone.

Editing the template

OpenViking supports memory.custom_templates_dir: YAML files loaded from this directory override built-in templates of the same name (MemoryTypeRegistry.load_from_directory(..., replace=True)).

  1. Copy the built-in entities.yaml to the custom directory:
mkdir -p /path/to/openviking/data/custom_templates
podman cp systemd-openviking:/app/.venv/lib/python3.13/site-packages/openviking/prompts/templates/memory/entities.yaml \
  /path/to/openviking/data/custom_templates/entities.yaml
  1. Change the category description to be unconditionally English (independent of {{ language }}):
# custom_templates/entities.yaml
  - name: category
    type: string
    description: |
      ALWAYS English: lowercase with underscores, max 3 words.
      Never use Chinese or any other language for this field, even if the conversation is in Chinese.
    merge_op: immutable

Leave the name field untouched.

  1. Enable it in ov.conf (container path /app/.openviking/ov.conf):
"memory": {
    "custom_templates_dir": "/app/.openviking/custom_templates"
}
  1. Restart the service to apply.

Verification

After the template change, new entities extracted from normal conversations all land in English directories:

Entity mentioned in chat Resulting path
netcup server entities/infrastructure/netcup.md (merged into existing English dir)
wireguard tunnel entities/networking/wireguard_tunnel.md
PEAK (co-op climbing game with mods) entities/game/peak.md

No new Chinese directories. Event filenames may still be Chinese (events/2026/08/12/WireGuard隧道配置完成.md) — filenames do not affect path-level consistency.

Other memory types (events, preferences, cases, …) use fixed directory structures (dates, usernames) with no LLM-named directory level, so they need no changes.

Edit this page

Contents