@openviking

OpenViking

OpenClaw context-engine plugin — OpenViking AI memory, long-term memory, knowledge base, semantic search, RAG, context engine. 长期记忆 · 知识库 · 语义检索 · 上下文引擎

当前版本
v2026.10.3
code-plugin社区source-linked

OpenViking for OpenClaw

Use OpenViking as OpenClaw's long-term context engine: automatic recall, session archive, memory extraction, semantic search, and RAG over a remote OpenViking server.

Quick Start

openclaw plugins install clawhub:@openviking/openclaw-plugin
openclaw openviking setup --base-url http://my-server:1933 --api-key sk-xxx --json
openclaw gateway restart
openclaw openviking status --json

That's it. The setup command activates the context-engine slot and validates the connection.

Or ask your agent

Install the OpenClaw plugin @openviking/openclaw-plugin for OpenViking remote memory. My server is at http://my-server:1933 and my API key is sk-xxx.

The agent runs install → setup → restart → verify automatically. See INSTALL-AGENT.md.

How It Works

StageWhat happens
Every turn (afterTurn or commitTurn, depending on host/runner)New messages are appended to an OpenViking session; commit/extraction is threshold-triggered
Explicit remember (memory_store)Important long-term facts can be written and committed immediately
On /compact (compact)Pending session messages are committed and extracted into long-term memories
Before each reply (assemble)Relevant memories are auto-retrieved and injected into context

Tools

Once installed, the plugin provides these agent tools:

ToolPurpose
memory_recallExplicit long-term memory search
memory_storePersist explicit long-term facts immediately
memory_forgetDelete memories by URI or query
ov_archive_searchSearch across archives by keyword
ov_archive_expandExpand an archive back to raw messages
ov_recall_traceInspect why recall/search returned or injected specific results
add_resourceImport documents, URLs, or Git repos when explicitly enabled
add_skillImport OpenViking skills
ov_searchSearch imported resources and skills
ov_readRead the full original content of one exact OpenViking URI
ov_multi_readRead the full original content of multiple OpenViking URIs
ov_listList OpenViking directories after search to inspect sibling chunks and overview files
openviking_tool_result_readRestore the full original content of an externalized tool result
openviking_tool_result_searchSearch inside an externalized tool result by keyword
openviking_tool_result_listList externalized tool results in the current session

add_resource is hidden from agents by default (enableAddResourceTool=false), while manual /add-resource remains available. Configure recallTargetTypes to choose default recall targets (user, agent, resource); legacy recallResources=true appends resource only when recallTargetTypes is unset.

Data Flow & Privacy

  • What is sent: User/assistant message text from each turn (after stripping injected memory blocks and metadata noise).
  • Where it goes: Your configured OpenViking server (baseUrl). The plugin only sends data to that server; downstream model/provider data handling (embedding, VLM) depends on the server's configuration.
  • Storage: All data lives on your OpenViking server under viking://user/* (including viking://user/sessions/*) and viking://resources/*.
  • API Key: Sent as X-API-Key header over your configured connection. Never logged or forwarded.
  • Multi-tenant isolation: Supports accountId and userId. Optional peer_role / peer_prefix controls whether OpenClaw speakers are written as OpenViking peer_id.

Verify

openclaw openviking status --json     # one-shot health check
openclaw config get plugins.slots.contextEngine  # should output: openviking

Documentation

DocDescription
INSTALL.mdFull install, upgrade, and uninstall guide
INSTALL-ZH.mdChinese install guide
INSTALL-AGENT.mdAgent-oriented operator guide
docs/openviking-tos-install-guide.mdTOS release bundle publishing and installer guide
docs/openviking-openclaw-plugin-guide.mdComprehensive Chinese guide for usage, configuration, debugging, testing, build, release, deployment, and rollback
docs/openviking-websocket-rpc-api.mdGateway WebSocket RPC usage for OpenViking tools
docs/openviking-runtime-query-config.mdRuntime query config scopes, fields, and commands
docs/openviking-install-package-contract.mdPackage and install contract verification notes

Plugin vs Skill: This page is for @openviking/openclaw-plugin (the context-engine plugin). Do not use clawhub install openviking — that installs a different AgentSkill.


<details> <summary><b>Technical Overview (for integrators and engineers)</b></summary>

This plugin is registered as the openviking context engine in OpenClaw.

Design Positioning

  • OpenClaw still owns the agent runtime, prompt orchestration, and tool execution.
  • OpenViking owns long-term memory retrieval, session archiving, archive summaries, and memory extraction.
  • examples/openclaw-plugin is not a narrow "memory lookup" plugin. It is an integration layer that spans the OpenClaw lifecycle.

In the current implementation, the plugin plays four roles at once:

  • context-engine: implements assemble, afterTurn, and compact
  • hook layer: handles session_start, session_end, and before_reset
  • tool provider: registers memory/archive tools plus OpenViking resource and skill import tools
  • runtime manager: connects to and monitors a remote OpenViking service

Overall Architecture

Overall OpenClaw and OpenViking plugin architecture

The diagram above reflects the current implementation boundary:

  • OpenClaw remains the primary runtime on the left. The plugin does not take over agent execution.
  • The middle layer combines hooks, the context engine, tools, and runtime management in one plugin registration.
  • All HTTP traffic goes through OpenVikingClient, which centralizes tenant headers and routing logs.
  • The OpenViking service owns sessions, memories, archives, and Phase 2 extraction, with storage under viking://user/* (including viking://user/sessions/*) and viking://resources/*.

That split lets OpenClaw stay focused on reasoning and orchestration while OpenViking becomes the source of truth for long-lived context.

Identity and Routing

The plugin keeps OpenClaw session identity in session and peer metadata. It does not send an OpenViking agent identity or create an agent namespace.

The main rules are:

  • reuse sessionId directly when it is already a UUID
  • prefer sessionKey when deriving a stable ovSessionId
  • normalize unsafe path characters, or fall back to a stable SHA-256 when needed
  • peer_role=none is the default: messages have no peer attribution and memory stays in the shared user scope, for example viking://user/alice/memories/...; no peer-specific memory subtree is used
  • peer_role=assistant writes assistant messages with peer_id=<sessionAgent> and uses peer-scoped memory such as viking://user/alice/peers/main/memories/...; if peer_prefix is set, the peer id becomes <peer_prefix>_<sessionAgent>
  • peer_role=sender writes user messages with the OpenClaw sender identity as peer_id and uses peer-scoped memory such as viking://user/support-agent/peers/customer-42/memories/...; assistant messages do not get peer_id
  • person remains accepted as a legacy config alias for sender, but new configuration and documentation use sender
  • data-plane recall/search/read/import/delete sends the same resolved peer identity as X-OpenViking-Actor-Peer when peer_role is assistant or sender
  • when OpenClaw does not provide a session agent, use its default agent main for local session and assistant peer metadata
  • only add X-OpenViking-Account / X-OpenViking-User when accountId / userId are explicitly configured

This matters because OpenViking tenant identity is account/user-scoped, while OpenClaw agent identity is runtime metadata.

Choose the scope from what viking://user/<user_id> represents:

ModelExampleResult
General/shared (none)user_id=alice uses any OpenClaw assistantShared user memory under viking://user/alice/memories/...
Human is the OpenViking user (assistant)Alice uses OpenClaw assistants main and researchAssistant-scoped memories are separated under .../peers/main/memories/... and .../peers/research/memories/...
Agent is the OpenViking user (sender)user_id=support-agent receives messages from customer-42 and customer-99Sender-scoped memories are separated under .../peers/customer-42/memories/... and .../peers/customer-99/memories/...

OpenViking creates the managed peers/ container as part of the user namespace. none means that the plugin does not create or route into a specific peers/<peer_id>/memories subtree. With assistant or sender, actor-peer recall includes the shared user memory plus the current peer's memory; changing the setting does not move existing memories.

The recommended remote-mode configuration only needs:

  • baseUrl
  • apiKey
  • optionally peer_role
  • optionally peer_prefix when peer_role=assistant

In this setup:

  • apiKey should usually be a user key
  • new installs default to peer_role=none
  • accountId / userId are advanced options only when the deployment needs explicit identity headers, such as root-key or trusted-server flows

User namespace

The plugin writes and searches user-scoped memory through viking://user/...; OpenViking resolves that alias from the request tenant and actor-peer context. Deprecated agent URI paths are not used by the plugin.

assemble Recall Flow

Automatic recall flow before prompt build

Auto-recall now runs through assemble(). OpenClaw calls the same context engine method in two shapes, and the plugin assigns different responsibilities to each shape:

  1. Preflight assemble: params include prompt; messages is still old history. The plugin reads archive/session context back from OpenViking and rebuilds history.
  2. transformContext assemble: params do not include prompt; the latest messages entry is already the current user turn. The plugin only runs long-term recall and prepends the memory block to that user message content.

During recall, the plugin:

  1. Extracts query text from the latest user message.
  2. Resolves the agent routing for the current sessionId/sessionKey.
  3. Runs a quick availability precheck so model requests do not stall when OpenViking is unavailable.
  4. Sends one session-aware context search for the configured recallTargetTypes (user,agent by default; optionally resource; use ov_archive_search and ov_archive_expand to inspect raw session history).
  5. Lets OpenViking expand the query from session history, filter and rank candidates, apply cross-turn deduplication, select detail tiers, and assemble the result under the injection budget.
  6. Prepends the server-rendered context inside <relevant-memories> to the current user message; it does not append a standalone synthetic user message.

Session Lifecycle

Session lifecycle and compaction boundary

Session handling is the main axis of this design. In the current implementation it covers history assembly, incremental append, asynchronous commit, and blocking compaction readback.

What assemble() does

During preflight, assemble() is not just replaying old chat history. It reads session context back from OpenViking under a token budget, then rebuilds OpenClaw-facing messages:

  • latest_archive_overview becomes [Session History Summary]
  • pre_archive_abstracts becomes [Archive Index]
  • active session messages stay in message-block form
  • assistant tool parts become toolCall (input compatible: toolUse/input is normalized to toolCall/arguments)
  • tool output becomes separate toolResult
  • the final message list goes through a tool-use/result pairing repair pass

That means OpenClaw sees "compressed history summary + archive index + active messages", not an ever-growing raw transcript.

What afterTurn() does

afterTurn() has a narrower job: append only the new turn into the OpenViking session.

Capture ownership depends on the host version from api.runtime.version:

  • Before OpenClaw 2026.9.3, afterTurn captures messages; commitTurn only acknowledges the turn to avoid writing those messages twice.
  • Starting with 2026.9.3, admitted/deferred turns are captured inside commitTurn before acknowledgment. Standalone runners still capture via afterTurn.
  • The minimum supported OpenClaw version remains 2026.5.27. Missing/unparseable versions and ambiguous 2026.9.3 prereleases reject commitTurn rather than silently discarding queued messages; afterTurn remains available. Numeric packaging revisions such as 2026.9.3-1 use the 9.3 behavior.

Durable capture propagates client/write/commit failures to the host for retry and shares one in-flight write between concurrent deliveries of the same advancement key. Disabled capture, heartbeats, bypassed sessions, and empty turns are intentional skips. The legacy afterTurn callback retains best-effort error handling.

The host's durable delivery does not supply the model token budget or sender runtime context: this path uses the 128,000-token fallback and cannot attach the runtime sender ID to user messages. Message writes remain non-transactional: replay after partial writes or a process crash can duplicate messages. The in-memory advancement-key cache does not provide server-side exactly-once delivery.

  • it slices only the newly added messages
  • it keeps only user / assistant capture text
  • it preserves toolCall / toolResult content in the serialized turn text
  • it strips injected <openviking-context> blocks, historical <relevant-memories> blocks, and metadata noise before capture
  • it appends the sanitized turn text into the OpenViking session

After that, the plugin checks pending_tokens. Once it reaches commitTokenThresholdRatio of the model context window (tokenBudget), it triggers commit(wait=false):

  • archive generation and Phase 2 memory extraction continue asynchronously on the server
  • the current turn is not blocked waiting for extraction
  • if logFindRequests is enabled, the logs include the task id and follow-up extraction detail

Memory extraction on this automatic path is commit-dependent. Short but important facts can stay only in the live session until a threshold commit, /compact, or an explicit store happens.

Auto-commit keeps the most recent 10 messages by default (commitKeepRecentCount). This count-based window can start mid-turn. With a server that supports turn-aware retention, set "commitRetentionMode": "turn_budget" in the plugin config to opt in:

  • commitKeepRecentCount is ignored. The server defaults apply: up to 3 recent user turns, a 12,000-token retention budget, and at least the final assistant/tool step.
  • For an oversized newest turn, the server retains its user question and recent steps and checkpoints the archived prefix. The mandatory tail can exceed the retention budget.
  • pending_tokens counts only messages that will leave the live window, not a user question shared with the archive.

Manual commit and /compact still archive everything. Leave the option unset (or use "message_count") to preserve existing behavior.

Explicit long-term memory writes

When the user explicitly asks the agent to remember, save, or store an important long-term fact, preference, project, or decision, prefer memory_store over waiting for normal auto-capture. memory_store writes the text to an OpenViking session and calls commit(wait=true), so it is the reliable integration-side path for facts that should be available as long-term memory as soon as possible.

Use it as a complement to auto-capture, not a replacement:

  • auto-capture still preserves ordinary conversation flow and batches extraction for cost and latency
  • memory_store is for explicit durable-memory intent such as "remember my main project is X" or "save this preference"
  • if memory_store commits but extracts 0 memories, check the OpenViking server extraction/model configuration; the explicit path triggered extraction, but the extractor did not produce a memory

What compact() does

compact() is the stricter synchronous boundary:

  • it calls commit(wait=true) and blocks for completion
  • when an archive exists, it re-reads latest_archive_overview
  • it returns updated token estimates, the latest archive id, and summary content
  • if the summary is too coarse, the model can call ov_archive_expand to reopen a specific archive

So afterTurn() is closer to "incremental append plus threshold-triggered async commit", while compact() is the explicit "wait for archive and compaction to finish" boundary.

Tools and Expandability

Beyond automatic behavior, the plugin exposes these tools directly:

  • memory_recall: explicit long-term memory search
  • memory_store: write explicit long-term facts into an OpenViking session and trigger commit
  • memory_forget: delete by URI, or search first and remove a single strong match
  • ov_archive_expand: expand a concrete archive back into raw messages
  • ov_recall_trace: inspect recent recall/search trace records when traceRecall is enabled
  • add_resource: import a document, directory, URL, or Git repository as an OpenViking resource when explicitly enabled
  • add_skill: import or register an OpenViking skill
  • ov_search: search OpenViking resources and skills, especially after importing them
  • ov_read: read one exact viking:// URI returned by ov_search or ov_list
  • ov_multi_read: read multiple exact viking:// URIs, useful for an overview plus sibling chunks
  • ov_list: list a hit's parent directory after ov_search to recover sibling chunks, .overview.md, and related split-document context

They serve different roles:

  • automatic recall covers the default case where the model does not know what to search yet
  • memory_recall gives the model an explicit follow-up search path
  • memory_store is for immediately persisting clearly important information when the user expresses durable-memory intent
  • ov_archive_expand is the "go back to archive detail" escape hatch when summaries are not enough
  • add_resource lets the agent save explicit document or repository import requests without asking the user to remember slash commands
  • add_skill imports skills into OpenViking, while add_resource imports resources
  • ov_search closes the loop after import by letting the user or agent confirm and consume resources and skills
  • ov_read turns a ranked hit into original evidence before answering precise documentation, codebase, configuration, or procedural questions
  • ov_multi_read reads overview and sibling chunks together when a split document needs more context than a single hit
  • ov_list complements ov_search when a ranked hit is only one chunk of a larger procedure or document

ov_archive_expand is especially important because assemble() normally returns archive summaries and indexes, not the full raw transcript.

Resource and Skill Import

Resource and skill imports are intentionally separate because they land in different OpenViking namespaces and use different server APIs:

  • resources go through /api/v1/resources and land under viking://resources/...
  • skills go through /api/v1/skills and land under viking://user/<uid>/skills/...

The plugin also registers explicit slash commands for manual imports:

/add-resource ./README.md --to viking://resources/openviking-readme --wait
/add-skill ./skills/install-openviking-memory --wait
/ov-search "OpenViking install" --uri viking://resources/openviking-readme
/ov-search "memory install skill" --uri viking://~/skills

Resource import supports remote URLs, Git URLs, local files, local directories, and uploaded zip files. OpenViking's built-in parsers cover common documents and media such as Markdown, text, PDF, HTML, Word, PowerPoint, Excel, EPUB, images, audio, and video. Directory imports also accept common code, documentation, and config file extensions such as .py, .js, .ts, .go, .rs, .java, .cpp, .json, .yaml, .toml, .csv, .rst, .proto, .tf, and .vue.

For HTTP safety, the plugin never sends a direct local filesystem path to the OpenViking server. Local files and directories are first uploaded through /api/v1/resources/temp_upload; directories are zipped locally with a pure JavaScript zip implementation before upload.

Runtime Mode

Runtime modes and routing behavior

The plugin operates exclusively in remote mode as a pure HTTP client:

  • baseUrl and optional apiKey come from plugin config
  • no local subprocess is started or managed
  • session context, memory search/read, commit, and archive expansion behavior stays the same

The OpenViking service must be deployed and running independently before the plugin can connect to it.

Context lifecycle reference

For the current assemble, recall, capture, and compaction behavior, see the OpenClaw integration guide. The guide also explains the retained agentExperience settings and their current limits.

Operator and Debugging Surfaces

If you need to debug this plugin, start with these entry points.

Inspect the current setup

openclaw openviking status --json
openclaw plugins list
openclaw config get plugins.entries.openviking.config
openclaw config get plugins.slots.contextEngine

Watch logs

OpenClaw plugin logs:

openclaw logs --follow

OpenViking service logs:

cat ~/.openviking/data/log/openviking.log

Web Console

python -m openviking.console.bootstrap --host 0.0.0.0 --port 8020 --openviking-url http://127.0.0.1:1933

ov tui

ov tui

Common things to check

SymptomMore likely causeFirst check
plugins.slots.contextEngine is not openvikingThe plugin slot was never set, or another plugin replaced itopenclaw config get plugins.slots.contextEngine
Cannot connect to OpenViking servicebaseUrl is wrong or the service is downCheck baseUrl in config and test connectivity manually
recall behaves inconsistently across sessionsRouting identity is not what you expectedEnable logFindRequests, then inspect openclaw logs --follow
long chats stop extracting memorypending_tokens never crosses the threshold, or Phase 2 fails server-sideCheck plugin config and ~/.openviking/data/log/openviking.log
summaries are too coarse for detailed questionsYou need archive-level detail, not just summaryUse an ID from [Archive Index] with ov_archive_expand

For installation, upgrade, and uninstall operations, use INSTALL.md.

</details>

Cloud recall compression

Set OPENVIKING_RECALL_COMPRESS=server to enable cloud recall compression, or auto to let the server decide whether to rewrite. Both use search mode=context; server sends rewrite=true, and auto sends rewrite="auto". The server digest takes precedence over raw rendered context, and no_relevant suppresses injection. The default remains off; no local compressor is launched.

The plugin config equivalent is recallCompress: "server".

源码与版本

源码仓库

volcengine/OpenViking

打开仓库

源码提交

d9a21bc77bf15d02080b5883b8a167f8e7110e5d

查看提交

安装命令

openclaw plugins install clawhub:@openviking/openclaw-plugin

元数据

  • 包名: @openviking/openclaw-plugin
  • 创建时间: 2026/03/31
  • 更新时间: 2026/10/02
  • 执行代码: 否
  • 源码标签: refs/heads/main

兼容性

  • 构建于 OpenClaw: 2026.5.27
  • 插件 API 范围: >=2026.5.27
  • 标签: dev, latest, latest dev, test
  • 文件数: 129