@openviking/openclaw-plugin 2026.5.10-dev.3 → 2026.5.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/INSTALL-AGENT.md +13 -13
- package/INSTALL-ZH.md +11 -11
- package/INSTALL.md +11 -11
- package/README.md +53 -32
- package/client.ts +111 -0
- package/context-engine.ts +52 -15
- package/dist/client.js +30 -0
- package/dist/context-engine.js +40 -8
- package/dist/index.js +295 -5
- package/dist/process-manager.js +0 -87
- package/dist/runtime-utils.js +0 -3
- package/dist/text-utils.js +31 -51
- package/images/openclaw-plugin-engine-overview.png +0 -0
- package/images/openclaw-plugin-recall-flow.png +0 -0
- package/images/openclaw-plugin-runtime-routing.png +0 -0
- package/images/openclaw-plugin-session-lifecycle.png +0 -0
- package/index.ts +351 -5
- package/openclaw.plugin.json +4 -1
- package/package.json +3 -2
- package/process-manager.ts +0 -124
- package/runtime-utils.ts +0 -3
- package/skills/install-openviking-memory/SKILL.md +9 -9
- package/text-utils.ts +35 -52
package/INSTALL-AGENT.md
CHANGED
|
@@ -9,14 +9,14 @@ User-facing docs:
|
|
|
9
9
|
|
|
10
10
|
## Identity
|
|
11
11
|
|
|
12
|
-
This package is the OpenClaw plugin `@openclaw
|
|
12
|
+
This package is the OpenClaw plugin `@openviking/openclaw-plugin`.
|
|
13
13
|
|
|
14
14
|
| User intent | Command |
|
|
15
15
|
| --- | --- |
|
|
16
|
-
| Fresh install, latest | `openclaw plugins install
|
|
17
|
-
| Upgrade plugin to latest | `openclaw plugins install
|
|
16
|
+
| Fresh install, latest | `openclaw plugins install clawhub:@openviking/openclaw-plugin` |
|
|
17
|
+
| Upgrade plugin to latest | `openclaw plugins install clawhub:@openviking/openclaw-plugin` |
|
|
18
18
|
| Install or upgrade a specific release | Use the published ClawHub package selector if available; otherwise ask before using backup `ov-install --plugin-version=<REF>` |
|
|
19
|
-
| Upgrade only the plugin | `openclaw plugins install
|
|
19
|
+
| Upgrade only the plugin | `openclaw plugins install clawhub:@openviking/openclaw-plugin` |
|
|
20
20
|
| Show installed plugins | `openclaw plugins list` |
|
|
21
21
|
| Backup install when ClawHub is unavailable | `npx -y openclaw-openviking-setup-helper@latest --base-url <URL> [--api-key <KEY>]` |
|
|
22
22
|
| Operate on a specific OpenClaw instance | add `--workdir <path>` |
|
|
@@ -31,7 +31,7 @@ clawhub install openviking
|
|
|
31
31
|
That installs an AgentSkill, not the plugin. The plugin install command is:
|
|
32
32
|
|
|
33
33
|
```bash
|
|
34
|
-
openclaw plugins install
|
|
34
|
+
openclaw plugins install clawhub:@openviking/openclaw-plugin
|
|
35
35
|
```
|
|
36
36
|
|
|
37
37
|
## Required Inputs
|
|
@@ -53,7 +53,7 @@ Never silently replace another context engine.
|
|
|
53
53
|
Use this workflow for normal installs and upgrades from published packages.
|
|
54
54
|
|
|
55
55
|
```bash
|
|
56
|
-
openclaw plugins install
|
|
56
|
+
openclaw plugins install clawhub:@openviking/openclaw-plugin
|
|
57
57
|
openclaw openviking setup --base-url <OPENVIKING_URL> --api-key <API_KEY> --json
|
|
58
58
|
openclaw gateway restart
|
|
59
59
|
openclaw openviking status --json
|
|
@@ -62,7 +62,7 @@ openclaw openviking status --json
|
|
|
62
62
|
If the registry prefix is required:
|
|
63
63
|
|
|
64
64
|
```bash
|
|
65
|
-
openclaw plugins install clawhub:@openclaw
|
|
65
|
+
openclaw plugins install clawhub:@openviking/openclaw-plugin
|
|
66
66
|
```
|
|
67
67
|
|
|
68
68
|
## Setup JSON Contract
|
|
@@ -157,7 +157,7 @@ Requirements:
|
|
|
157
157
|
|
|
158
158
|
Version boundaries:
|
|
159
159
|
|
|
160
|
-
- `2026.4.8` is the minimum supported OpenClaw version for the current `@openclaw
|
|
160
|
+
- `2026.4.8` is the minimum supported OpenClaw version for the current `@openviking/openclaw-plugin` plugin.
|
|
161
161
|
- `2026.5.3` starts requiring compiled JavaScript runtime output during package install when a plugin package declares TypeScript entries.
|
|
162
162
|
- `2026.5.4` and later no longer fall back to `.ts` source for installed/global plugin runtime loading when the compiled JavaScript output is missing; the plugin may be skipped.
|
|
163
163
|
- Published ClawHub packages are built before release and include `dist/*.js`, so normal users do not need to build locally.
|
|
@@ -220,7 +220,7 @@ openclaw plugins list
|
|
|
220
220
|
Fresh install:
|
|
221
221
|
|
|
222
222
|
```bash
|
|
223
|
-
openclaw plugins install
|
|
223
|
+
openclaw plugins install clawhub:@openviking/openclaw-plugin
|
|
224
224
|
openclaw openviking setup --base-url <OPENVIKING_URL> --api-key <API_KEY> --json
|
|
225
225
|
openclaw gateway restart
|
|
226
226
|
openclaw openviking status --json
|
|
@@ -307,7 +307,7 @@ Same plugin ID (openviking, >= 0.3.x):
|
|
|
307
307
|
|
|
308
308
|
```bash
|
|
309
309
|
rm -rf ~/.openclaw/extensions/openviking/
|
|
310
|
-
openclaw plugins install
|
|
310
|
+
openclaw plugins install clawhub:@openviking/openclaw-plugin
|
|
311
311
|
openclaw openviking setup --reconfigure
|
|
312
312
|
openclaw gateway restart
|
|
313
313
|
openclaw openviking status --json
|
|
@@ -319,7 +319,7 @@ Old plugin ID (memory-openviking, < 0.3.x):
|
|
|
319
319
|
openclaw plugins uninstall memory-openviking 2>/dev/null || true
|
|
320
320
|
openclaw config set plugins.slots.memory none
|
|
321
321
|
rm -rf ~/.openclaw/extensions/memory-openviking/
|
|
322
|
-
openclaw plugins install
|
|
322
|
+
openclaw plugins install clawhub:@openviking/openclaw-plugin
|
|
323
323
|
openclaw openviking setup --base-url <OPENVIKING_URL> --api-key <API_KEY> --json
|
|
324
324
|
openclaw gateway restart
|
|
325
325
|
openclaw openviking status --json
|
|
@@ -333,7 +333,7 @@ Existing config fields are preserved during migration. The new plugin reads old
|
|
|
333
333
|
|
|
334
334
|
## Backup Path: ov-install
|
|
335
335
|
|
|
336
|
-
`ov-install` is the backup path, not the primary user install path. Use it when `openclaw plugins install
|
|
336
|
+
`ov-install` is the backup path, not the primary user install path. Use it when `openclaw plugins install clawhub:@openviking/openclaw-plugin` cannot reach ClawHub, is rate-limited, or when the user explicitly wants a source ref / Git branch install.
|
|
337
337
|
|
|
338
338
|
Backup install:
|
|
339
339
|
|
|
@@ -352,4 +352,4 @@ Backup/source commands:
|
|
|
352
352
|
| Show helper-tracked version | `ov-install --current-version` |
|
|
353
353
|
| Update helper-managed install | `ov-install --update` |
|
|
354
354
|
|
|
355
|
-
For user installs, always try `openclaw plugins install
|
|
355
|
+
For user installs, always try `openclaw plugins install clawhub:@openviking/openclaw-plugin` first. Choose `ov-install` only as the backup path.
|
package/INSTALL-ZH.md
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
# 为 OpenClaw 安装 OpenViking
|
|
2
2
|
|
|
3
|
-
OpenViking 通过 `@openclaw
|
|
3
|
+
OpenViking 通过 `@openviking/openclaw-plugin` 插件为 OpenClaw 提供长期记忆、知识库检索、语义搜索和 RAG 上下文能力。
|
|
4
4
|
|
|
5
5
|
这份文档同时面向用户和自动化 agent:用户可以按步骤执行,agent 可以按命令和 JSON 结果判断下一步。
|
|
6
6
|
|
|
7
7
|
## 不要把插件和 Skill 装混
|
|
8
8
|
|
|
9
|
-
`@openclaw
|
|
9
|
+
`@openviking/openclaw-plugin` 是 OpenClaw 插件。
|
|
10
10
|
|
|
11
11
|
不要用下面这个命令安装本插件:
|
|
12
12
|
|
|
@@ -19,7 +19,7 @@ clawhub install openviking
|
|
|
19
19
|
安装插件应使用:
|
|
20
20
|
|
|
21
21
|
```bash
|
|
22
|
-
openclaw plugins install
|
|
22
|
+
openclaw plugins install clawhub:@openviking/openclaw-plugin
|
|
23
23
|
```
|
|
24
24
|
|
|
25
25
|
## 前置要求
|
|
@@ -36,7 +36,7 @@ OpenClaw 插件包版本边界:
|
|
|
36
36
|
- `2026.4.8` 是当前插件支持的最低 OpenClaw 版本。
|
|
37
37
|
- `2026.5.3` 开始,OpenClaw 在安装包时会校验 TypeScript 插件入口是否有编译后的 JavaScript 产物。
|
|
38
38
|
- `2026.5.4` 及之后,已安装/全局插件如果缺少编译后的 JavaScript,运行时不再回退加载 `.ts` 源码,插件可能被跳过。
|
|
39
|
-
- 推荐的 `openclaw plugins install
|
|
39
|
+
- 推荐的 `openclaw plugins install clawhub:@openviking/openclaw-plugin` 会安装已经发布并包含 `dist/*.js` 的插件包,普通用户不需要本地编译。
|
|
40
40
|
- `ov-install` 是备用/源码安装路径。当 ClawHub 或 OpenClaw 插件管理器路径不可用、被限流,或者明确需要测试源码 ref 时才使用。目标 OpenClaw `>= 2026.5.3` 时,它会在安装过程中编译插件。
|
|
41
41
|
|
|
42
42
|
快速检查:
|
|
@@ -87,13 +87,13 @@ curl http://127.0.0.1:1933/health
|
|
|
87
87
|
### 1. 安装插件
|
|
88
88
|
|
|
89
89
|
```bash
|
|
90
|
-
openclaw plugins install
|
|
90
|
+
openclaw plugins install clawhub:@openviking/openclaw-plugin
|
|
91
91
|
```
|
|
92
92
|
|
|
93
93
|
如果你的 OpenClaw 环境需要显式 registry 前缀,使用:
|
|
94
94
|
|
|
95
95
|
```bash
|
|
96
|
-
openclaw plugins install clawhub:@openclaw
|
|
96
|
+
openclaw plugins install clawhub:@openviking/openclaw-plugin
|
|
97
97
|
```
|
|
98
98
|
|
|
99
99
|
### 2. 配置插件
|
|
@@ -271,7 +271,7 @@ python examples/openclaw-plugin/health_check_tools/ov-healthcheck.py
|
|
|
271
271
|
|
|
272
272
|
## 备用路径:ov-install
|
|
273
273
|
|
|
274
|
-
`ov-install` 是备用路径,不是主安装方式。仅当 `openclaw plugins install
|
|
274
|
+
`ov-install` 是备用路径,不是主安装方式。仅当 `openclaw plugins install clawhub:@openviking/openclaw-plugin` 无法访问 ClawHub、被限流,或者你明确需要从 Git 分支/源码 ref 安装测试时使用。
|
|
275
275
|
|
|
276
276
|
先尝试 OpenClaw 插件管理器。如果该路径不可用,再执行:
|
|
277
277
|
|
|
@@ -285,14 +285,14 @@ ov-install
|
|
|
285
285
|
| 参数 | 含义 |
|
|
286
286
|
| --- | --- |
|
|
287
287
|
| `--workdir PATH` | 指定 OpenClaw state 目录 |
|
|
288
|
-
| `--version
|
|
288
|
+
| `--plugin-version=REF` | 指定插件版本:npm 版本、npm dist-tag 或 Git ref |
|
|
289
289
|
| `--current-version` | 查看 helper 记录的当前版本 |
|
|
290
290
|
| `--base-url URL` | OpenViking 服务器地址(启用非交互模式) |
|
|
291
291
|
| `--api-key KEY` | OpenViking API key |
|
|
292
292
|
| `--agent-prefix PREFIX` | Agent 路由前缀 |
|
|
293
293
|
| `--update` | 更新 helper 管理的安装 |
|
|
294
294
|
|
|
295
|
-
面向用户的安装,请先使用 `openclaw plugins install
|
|
295
|
+
面向用户的安装,请先使用 `openclaw plugins install clawhub:@openviking/openclaw-plugin`。只有作为备用路径时才选择 `ov-install`。
|
|
296
296
|
|
|
297
297
|
## 从 ov-install 迁移到 openclaw plugin install
|
|
298
298
|
|
|
@@ -307,7 +307,7 @@ ov-install 的 context-engine 部署会将文件写入 `~/.openclaw/extensions/o
|
|
|
307
307
|
rm -rf ~/.openclaw/extensions/openviking/
|
|
308
308
|
|
|
309
309
|
# 通过 OpenClaw 插件管理器安装
|
|
310
|
-
openclaw plugins install
|
|
310
|
+
openclaw plugins install clawhub:@openviking/openclaw-plugin
|
|
311
311
|
|
|
312
312
|
# 重新配置(openclaw.json 中的已有配置会保留)
|
|
313
313
|
openclaw openviking setup --reconfigure
|
|
@@ -330,7 +330,7 @@ openclaw config set plugins.slots.memory none
|
|
|
330
330
|
rm -rf ~/.openclaw/extensions/memory-openviking/
|
|
331
331
|
|
|
332
332
|
# 安装新插件
|
|
333
|
-
openclaw plugins install
|
|
333
|
+
openclaw plugins install clawhub:@openviking/openclaw-plugin
|
|
334
334
|
openclaw openviking setup --base-url <OPENVIKING_URL> --api-key <API_KEY> --json
|
|
335
335
|
openclaw gateway restart
|
|
336
336
|
openclaw openviking status --json
|
package/INSTALL.md
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
# Install OpenViking for OpenClaw
|
|
2
2
|
|
|
3
|
-
OpenViking provides long-term memory, knowledge base search, semantic retrieval, and RAG-style context for OpenClaw through the `@openclaw
|
|
3
|
+
OpenViking provides long-term memory, knowledge base search, semantic retrieval, and RAG-style context for OpenClaw through the `@openviking/openclaw-plugin` plugin.
|
|
4
4
|
|
|
5
5
|
This guide describes the current plugin install flow. It is written for both people and automation agents.
|
|
6
6
|
|
|
7
7
|
## Do Not Install The Skill By Mistake
|
|
8
8
|
|
|
9
|
-
`@openclaw
|
|
9
|
+
`@openviking/openclaw-plugin` is an OpenClaw plugin.
|
|
10
10
|
|
|
11
11
|
Do not use this command for plugin installation:
|
|
12
12
|
|
|
@@ -19,7 +19,7 @@ That command installs an AgentSkill named `openviking`, not the OpenClaw plugin.
|
|
|
19
19
|
Use this plugin command instead:
|
|
20
20
|
|
|
21
21
|
```bash
|
|
22
|
-
openclaw plugins install
|
|
22
|
+
openclaw plugins install clawhub:@openviking/openclaw-plugin
|
|
23
23
|
```
|
|
24
24
|
|
|
25
25
|
## Requirements
|
|
@@ -36,7 +36,7 @@ OpenClaw plugin package boundaries:
|
|
|
36
36
|
- `2026.4.8` is the minimum supported OpenClaw version for the current plugin.
|
|
37
37
|
- `2026.5.3` starts validating package installs so TypeScript plugin entries need compiled JavaScript output.
|
|
38
38
|
- `2026.5.4` and later stop falling back to `.ts` source for installed/global plugin runtime loading when compiled JavaScript is missing.
|
|
39
|
-
- The recommended `openclaw plugins install
|
|
39
|
+
- The recommended `openclaw plugins install clawhub:@openviking/openclaw-plugin` path installs a published package that already includes `dist/*.js`.
|
|
40
40
|
- `ov-install` is the backup/source install path. Use it when ClawHub or the OpenClaw plugin manager path is unavailable/rate-limited, or when explicitly testing a source ref. For OpenClaw `>= 2026.5.3`, it builds the plugin during installation.
|
|
41
41
|
|
|
42
42
|
Quick check:
|
|
@@ -87,13 +87,13 @@ Use this path for normal users, production installs, and agent-assisted installs
|
|
|
87
87
|
### 1. Install The Plugin
|
|
88
88
|
|
|
89
89
|
```bash
|
|
90
|
-
openclaw plugins install
|
|
90
|
+
openclaw plugins install clawhub:@openviking/openclaw-plugin
|
|
91
91
|
```
|
|
92
92
|
|
|
93
93
|
If your OpenClaw installation requires an explicit registry prefix, use:
|
|
94
94
|
|
|
95
95
|
```bash
|
|
96
|
-
openclaw plugins install clawhub:@openclaw
|
|
96
|
+
openclaw plugins install clawhub:@openviking/openclaw-plugin
|
|
97
97
|
```
|
|
98
98
|
|
|
99
99
|
### 2. Configure The Plugin
|
|
@@ -253,7 +253,7 @@ This checks the Gateway to OpenViking path by injecting a real conversation and
|
|
|
253
253
|
|
|
254
254
|
## Backup Path: ov-install
|
|
255
255
|
|
|
256
|
-
`ov-install` is the backup path, not the primary install path. Use it when `openclaw plugins install
|
|
256
|
+
`ov-install` is the backup path, not the primary install path. Use it when `openclaw plugins install clawhub:@openviking/openclaw-plugin` cannot reach ClawHub, is rate-limited, or when you explicitly need to install/test plugin files from a Git branch or source ref.
|
|
257
257
|
|
|
258
258
|
Try the OpenClaw plugin manager first. If that path is unavailable, run:
|
|
259
259
|
|
|
@@ -267,14 +267,14 @@ Useful backup/source flags:
|
|
|
267
267
|
| Flag | Meaning |
|
|
268
268
|
| --- | --- |
|
|
269
269
|
| `--workdir PATH` | Target OpenClaw state directory |
|
|
270
|
-
| `--version
|
|
270
|
+
| `--plugin-version=REF` | Plugin version: npm version, npm dist-tag, or Git ref to install |
|
|
271
271
|
| `--current-version` | Print the version tracked by the helper |
|
|
272
272
|
| `--base-url URL` | OpenViking server URL (enables non-interactive mode) |
|
|
273
273
|
| `--api-key KEY` | OpenViking API key |
|
|
274
274
|
| `--agent-prefix PREFIX` | Agent routing prefix |
|
|
275
275
|
| `--update` | Update an existing helper-managed install |
|
|
276
276
|
|
|
277
|
-
For user-facing installs, use `openclaw plugins install
|
|
277
|
+
For user-facing installs, use `openclaw plugins install clawhub:@openviking/openclaw-plugin` first. Choose `ov-install` only as the backup path.
|
|
278
278
|
|
|
279
279
|
## Migrate From ov-install To openclaw plugin install
|
|
280
280
|
|
|
@@ -289,7 +289,7 @@ The ov-install context-engine deployment writes files to `~/.openclaw/extensions
|
|
|
289
289
|
rm -rf ~/.openclaw/extensions/openviking/
|
|
290
290
|
|
|
291
291
|
# Install via the OpenClaw plugin manager
|
|
292
|
-
openclaw plugins install
|
|
292
|
+
openclaw plugins install clawhub:@openviking/openclaw-plugin
|
|
293
293
|
|
|
294
294
|
# Reconfigure (your existing config in openclaw.json is preserved)
|
|
295
295
|
openclaw openviking setup --reconfigure
|
|
@@ -347,7 +347,7 @@ openclaw config set plugins.slots.memory none
|
|
|
347
347
|
rm -rf ~/.openclaw/extensions/memory-openviking/
|
|
348
348
|
|
|
349
349
|
# Install new plugin
|
|
350
|
-
openclaw plugins install
|
|
350
|
+
openclaw plugins install clawhub:@openviking/openclaw-plugin
|
|
351
351
|
openclaw openviking setup --base-url <OPENVIKING_URL> --api-key <API_KEY> --json
|
|
352
352
|
openclaw gateway restart
|
|
353
353
|
openclaw openviking status --json
|
package/README.md
CHANGED
|
@@ -1,59 +1,78 @@
|
|
|
1
|
-
#
|
|
1
|
+
# OpenViking for OpenClaw
|
|
2
2
|
|
|
3
|
-
OpenClaw context
|
|
3
|
+
Use [OpenViking](https://github.com/volcengine/OpenViking) as OpenClaw's long-term context engine: automatic recall, session archive, memory extraction, semantic search, and RAG over a remote OpenViking server.
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## Quick Start
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
7
|
+
```bash
|
|
8
|
+
openclaw plugins install clawhub:@openviking/openclaw-plugin
|
|
9
|
+
openclaw openviking setup --base-url http://my-server:1933 --api-key sk-xxx --json
|
|
10
|
+
openclaw gateway restart
|
|
11
|
+
openclaw openviking status --json
|
|
11
12
|
```
|
|
12
13
|
|
|
13
|
-
|
|
14
|
+
That's it. The `setup` command activates the context-engine slot and validates the connection.
|
|
14
15
|
|
|
15
|
-
|
|
16
|
+
### Or ask your agent
|
|
16
17
|
|
|
17
|
-
|
|
18
|
+
> 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`.
|
|
18
19
|
|
|
19
|
-
|
|
20
|
+
The agent runs install → setup → restart → verify automatically. See [INSTALL-AGENT.md](./INSTALL-AGENT.md).
|
|
20
21
|
|
|
21
|
-
|
|
22
|
+
## How It Works
|
|
22
23
|
|
|
23
|
-
|
|
24
|
+
| Stage | What happens |
|
|
25
|
+
|-------|-------------|
|
|
26
|
+
| **Every turn** (`afterTurn`) | Your messages are archived into an OpenViking session |
|
|
27
|
+
| **On `/compact`** (`compact`) | Archived messages are extracted into long-term memories |
|
|
28
|
+
| **Before each reply** (`assemble`) | Relevant memories are auto-retrieved and injected into context |
|
|
24
29
|
|
|
25
|
-
|
|
30
|
+
## Tools
|
|
26
31
|
|
|
27
|
-
|
|
32
|
+
Once installed, the plugin provides these agent tools:
|
|
28
33
|
|
|
29
|
-
|
|
34
|
+
| Tool | Purpose |
|
|
35
|
+
|------|---------|
|
|
36
|
+
| `memory_recall` | Explicit long-term memory search |
|
|
37
|
+
| `memory_store` | Persist important information immediately |
|
|
38
|
+
| `memory_forget` | Delete memories by URI or query |
|
|
39
|
+
| `ov_archive_search` | Search across archives by keyword |
|
|
40
|
+
| `ov_archive_expand` | Expand an archive back to raw messages |
|
|
41
|
+
| `add_resource` | Import documents, URLs, or Git repos |
|
|
42
|
+
| `add_skill` | Import agent skills |
|
|
43
|
+
| `memory_search` | Search imported resources and skills |
|
|
30
44
|
|
|
31
|
-
|
|
32
|
-
openclaw plugins install @openclaw/openviking
|
|
33
|
-
openclaw openviking setup --base-url http://my-server:1933 --api-key sk-xxx --json
|
|
34
|
-
openclaw gateway restart
|
|
35
|
-
openclaw openviking status --json
|
|
36
|
-
```
|
|
45
|
+
## Data Flow & Privacy
|
|
37
46
|
|
|
38
|
-
|
|
47
|
+
- **What is sent**: User/assistant message text from each turn (after stripping injected memory blocks and metadata noise).
|
|
48
|
+
- **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.
|
|
49
|
+
- **Storage**: All data lives on your OpenViking server under `viking://user/*`, `viking://agent/*`, and `viking://session/*`.
|
|
50
|
+
- **API Key**: Sent as `X-OpenViking-Key` header over your configured connection. Never logged or forwarded.
|
|
51
|
+
- **Multi-tenant isolation**: Supports `accountId`, `userId`, and `agent_prefix` for per-tenant scoping.
|
|
39
52
|
|
|
40
|
-
##
|
|
53
|
+
## Verify
|
|
41
54
|
|
|
42
|
-
|
|
55
|
+
```bash
|
|
56
|
+
openclaw openviking status --json # one-shot health check
|
|
57
|
+
openclaw config get plugins.slots.contextEngine # should output: openviking
|
|
58
|
+
```
|
|
43
59
|
|
|
44
60
|
## Documentation
|
|
45
61
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
62
|
+
| Doc | Description |
|
|
63
|
+
|-----|-------------|
|
|
64
|
+
| [INSTALL.md](./INSTALL.md) | Full install, upgrade, and uninstall guide |
|
|
65
|
+
| [INSTALL-ZH.md](./INSTALL-ZH.md) | Chinese install guide |
|
|
66
|
+
| [INSTALL-AGENT.md](./INSTALL-AGENT.md) | Agent-oriented operator guide |
|
|
49
67
|
|
|
50
|
-
|
|
68
|
+
> **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.
|
|
51
69
|
|
|
52
|
-
|
|
70
|
+
---
|
|
53
71
|
|
|
54
|
-
|
|
72
|
+
<details>
|
|
73
|
+
<summary><b>Technical Overview (for integrators and engineers)</b></summary>
|
|
55
74
|
|
|
56
|
-
|
|
75
|
+
This plugin is registered as the `openviking` context engine in OpenClaw.
|
|
57
76
|
|
|
58
77
|
## Design Positioning
|
|
59
78
|
|
|
@@ -315,3 +334,5 @@ ov tui
|
|
|
315
334
|
---
|
|
316
335
|
|
|
317
336
|
For installation, upgrade, and uninstall operations, use [INSTALL.md](./INSTALL.md).
|
|
337
|
+
|
|
338
|
+
</details>
|
package/client.ts
CHANGED
|
@@ -67,6 +67,24 @@ export type OVMessagePart = {
|
|
|
67
67
|
tool_output?: string;
|
|
68
68
|
tool_status?: string;
|
|
69
69
|
skill_uri?: string;
|
|
70
|
+
duration_ms?: number;
|
|
71
|
+
prompt_tokens?: number;
|
|
72
|
+
completion_tokens?: number;
|
|
73
|
+
tool_output_ref?: string;
|
|
74
|
+
tool_output_truncated?: boolean;
|
|
75
|
+
tool_output_original_chars?: number;
|
|
76
|
+
tool_output_preview_chars?: number;
|
|
77
|
+
tool_output_sha256?: string;
|
|
78
|
+
tool_output_storage_uri?: string;
|
|
79
|
+
tool_output_mime_type?: string;
|
|
80
|
+
tool_output_source_ref?: string;
|
|
81
|
+
tool_output_source_offset?: number;
|
|
82
|
+
tool_output_source_limit?: number;
|
|
83
|
+
tool_output_externalization_error?: string;
|
|
84
|
+
tool_output_group_id?: string;
|
|
85
|
+
tool_output_externalized_reason?: string;
|
|
86
|
+
tool_output_group_original_chars?: number;
|
|
87
|
+
tool_output_group_budget_chars?: number;
|
|
70
88
|
};
|
|
71
89
|
|
|
72
90
|
export type OVMessage = {
|
|
@@ -96,6 +114,30 @@ export type SessionContextResult = {
|
|
|
96
114
|
};
|
|
97
115
|
};
|
|
98
116
|
|
|
117
|
+
export type ToolResultReadResult = {
|
|
118
|
+
tool_result_id: string;
|
|
119
|
+
content: string;
|
|
120
|
+
offset: number;
|
|
121
|
+
limit: number;
|
|
122
|
+
offset_unit: "unicode_code_point";
|
|
123
|
+
total_chars: number;
|
|
124
|
+
has_more: boolean;
|
|
125
|
+
metadata?: Record<string, unknown>;
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
export type ToolResultSearchResult = {
|
|
129
|
+
tool_result_id: string;
|
|
130
|
+
matches: Array<{
|
|
131
|
+
offset: number;
|
|
132
|
+
offset_unit: "unicode_code_point";
|
|
133
|
+
snippet: string;
|
|
134
|
+
}>;
|
|
135
|
+
};
|
|
136
|
+
|
|
137
|
+
export type ToolResultListResult = {
|
|
138
|
+
tool_results: Array<Record<string, unknown>>;
|
|
139
|
+
};
|
|
140
|
+
|
|
99
141
|
export type SessionArchiveResult = {
|
|
100
142
|
archive_id: string;
|
|
101
143
|
abstract: string;
|
|
@@ -433,6 +475,61 @@ export class OpenVikingClient {
|
|
|
433
475
|
);
|
|
434
476
|
}
|
|
435
477
|
|
|
478
|
+
async readToolResult(
|
|
479
|
+
sessionId: string,
|
|
480
|
+
toolResultId: string,
|
|
481
|
+
options?: { offset?: number; limit?: number; includeMetadata?: boolean },
|
|
482
|
+
agentId?: string,
|
|
483
|
+
): Promise<ToolResultReadResult> {
|
|
484
|
+
const params = new URLSearchParams();
|
|
485
|
+
if (options?.offset !== undefined) params.set("offset", String(options.offset));
|
|
486
|
+
if (options?.limit !== undefined) params.set("limit", String(options.limit));
|
|
487
|
+
if (options?.includeMetadata !== undefined) {
|
|
488
|
+
params.set("include_metadata", String(options.includeMetadata));
|
|
489
|
+
}
|
|
490
|
+
const query = params.toString();
|
|
491
|
+
return this.request<ToolResultReadResult>(
|
|
492
|
+
`/api/v1/sessions/${encodeURIComponent(sessionId)}/tool-results/${encodeURIComponent(toolResultId)}${query ? `?${query}` : ""}`,
|
|
493
|
+
{},
|
|
494
|
+
agentId,
|
|
495
|
+
);
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
async searchToolResult(
|
|
499
|
+
sessionId: string,
|
|
500
|
+
toolResultId: string,
|
|
501
|
+
queryText: string,
|
|
502
|
+
options?: { limit?: number; contextChars?: number },
|
|
503
|
+
agentId?: string,
|
|
504
|
+
): Promise<ToolResultSearchResult> {
|
|
505
|
+
const params = new URLSearchParams({ q: queryText });
|
|
506
|
+
if (options?.limit !== undefined) params.set("limit", String(options.limit));
|
|
507
|
+
if (options?.contextChars !== undefined) {
|
|
508
|
+
params.set("context_chars", String(options.contextChars));
|
|
509
|
+
}
|
|
510
|
+
return this.request<ToolResultSearchResult>(
|
|
511
|
+
`/api/v1/sessions/${encodeURIComponent(sessionId)}/tool-results/${encodeURIComponent(toolResultId)}/search?${params.toString()}`,
|
|
512
|
+
{},
|
|
513
|
+
agentId,
|
|
514
|
+
);
|
|
515
|
+
}
|
|
516
|
+
|
|
517
|
+
async listToolResults(
|
|
518
|
+
sessionId: string,
|
|
519
|
+
options?: { toolName?: string; limit?: number },
|
|
520
|
+
agentId?: string,
|
|
521
|
+
): Promise<ToolResultListResult> {
|
|
522
|
+
const params = new URLSearchParams();
|
|
523
|
+
if (options?.toolName) params.set("tool_name", options.toolName);
|
|
524
|
+
if (options?.limit !== undefined) params.set("limit", String(options.limit));
|
|
525
|
+
const query = params.toString();
|
|
526
|
+
return this.request<ToolResultListResult>(
|
|
527
|
+
`/api/v1/sessions/${encodeURIComponent(sessionId)}/tool-results${query ? `?${query}` : ""}`,
|
|
528
|
+
{},
|
|
529
|
+
agentId,
|
|
530
|
+
);
|
|
531
|
+
}
|
|
532
|
+
|
|
436
533
|
async uploadTempFile(filePath: string, agentId?: string): Promise<string> {
|
|
437
534
|
const fileBytes = await readFile(filePath);
|
|
438
535
|
const form = new FormData();
|
|
@@ -614,6 +711,20 @@ export class OpenVikingClient {
|
|
|
614
711
|
tool_status?: string;
|
|
615
712
|
tool_input?: Record<string, unknown>;
|
|
616
713
|
tool_id?: string;
|
|
714
|
+
tool_output_ref?: string;
|
|
715
|
+
tool_output_truncated?: boolean;
|
|
716
|
+
tool_output_original_chars?: number;
|
|
717
|
+
tool_output_preview_chars?: number;
|
|
718
|
+
tool_output_sha256?: string;
|
|
719
|
+
tool_output_storage_uri?: string;
|
|
720
|
+
tool_output_mime_type?: string;
|
|
721
|
+
tool_output_source_ref?: string;
|
|
722
|
+
tool_output_source_offset?: number;
|
|
723
|
+
tool_output_source_limit?: number;
|
|
724
|
+
tool_output_group_id?: string;
|
|
725
|
+
tool_output_externalized_reason?: string;
|
|
726
|
+
tool_output_group_original_chars?: number;
|
|
727
|
+
tool_output_group_budget_chars?: number;
|
|
617
728
|
uri?: string;
|
|
618
729
|
abstract?: string;
|
|
619
730
|
context_type?: "memory" | "resource" | "skill";
|
package/context-engine.ts
CHANGED
|
@@ -25,6 +25,8 @@ type AgentMessage = {
|
|
|
25
25
|
timestamp?: unknown;
|
|
26
26
|
};
|
|
27
27
|
|
|
28
|
+
type ExtractedTurnMessage = ReturnType<typeof extractNewTurnMessages>["messages"][number];
|
|
29
|
+
|
|
28
30
|
type ContextEngineInfo = {
|
|
29
31
|
id: string;
|
|
30
32
|
name: string;
|
|
@@ -153,10 +155,6 @@ function allocateContextBudget(totalBudget: number, instructionTokens = 0): Cont
|
|
|
153
155
|
return { archiveMemory, sessionContext, reserved };
|
|
154
156
|
}
|
|
155
157
|
|
|
156
|
-
function estimateTokens(messages: AgentMessage[]): number {
|
|
157
|
-
return Math.max(1, messages.length * 80);
|
|
158
|
-
}
|
|
159
|
-
|
|
160
158
|
function roughEstimate(messages: AgentMessage[]): number {
|
|
161
159
|
return Math.ceil(JSON.stringify(messages).length / 4);
|
|
162
160
|
}
|
|
@@ -407,6 +405,10 @@ export function convertToAgentMessages(msg: { role: string; parts: unknown[] }):
|
|
|
407
405
|
const toolName = typeof p.tool_name === "string" ? p.tool_name : undefined;
|
|
408
406
|
const status = typeof p.tool_status === "string" ? p.tool_status : "unknown";
|
|
409
407
|
const output = typeof p.tool_output === "string" ? p.tool_output : "";
|
|
408
|
+
const ref = typeof p.tool_output_ref === "string" ? p.tool_output_ref : "";
|
|
409
|
+
const originalChars = typeof p.tool_output_original_chars === "number"
|
|
410
|
+
? p.tool_output_original_chars
|
|
411
|
+
: undefined;
|
|
410
412
|
|
|
411
413
|
if (toolId) {
|
|
412
414
|
// Structured path: emit canonical toolCall + toolResult pair (works for any role)
|
|
@@ -417,9 +419,15 @@ export function convertToAgentMessages(msg: { role: string; parts: unknown[] }):
|
|
|
417
419
|
arguments: p.tool_input ?? {},
|
|
418
420
|
});
|
|
419
421
|
|
|
420
|
-
|
|
422
|
+
let resultText = (status === "completed" || status === "error")
|
|
421
423
|
? (output || "(no output)")
|
|
422
424
|
: "(interrupted — tool did not complete)";
|
|
425
|
+
if (ref && !resultText.includes(ref)) {
|
|
426
|
+
const suffix = originalChars !== undefined
|
|
427
|
+
? `\n[tool-result-ref] ${ref} original_chars=${originalChars}`
|
|
428
|
+
: `\n[tool-result-ref] ${ref}`;
|
|
429
|
+
resultText += suffix;
|
|
430
|
+
}
|
|
423
431
|
const resultPayload: Record<string, unknown> = {
|
|
424
432
|
role: "toolResult",
|
|
425
433
|
toolCallId: toolId,
|
|
@@ -474,6 +482,36 @@ export function convertToAgentMessages(msg: { role: string; parts: unknown[] }):
|
|
|
474
482
|
return result;
|
|
475
483
|
}
|
|
476
484
|
|
|
485
|
+
function isToolOnlyMessage(msg: ExtractedTurnMessage): boolean {
|
|
486
|
+
return msg.role === "user" && msg.parts.length > 0 && msg.parts.every((part) => part.type === "tool");
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
function coalesceConsecutiveToolMessages(messages: ExtractedTurnMessage[]): ExtractedTurnMessage[] {
|
|
490
|
+
const result: ExtractedTurnMessage[] = [];
|
|
491
|
+
let pendingTools: ExtractedTurnMessage | undefined;
|
|
492
|
+
|
|
493
|
+
const flush = () => {
|
|
494
|
+
if (pendingTools) {
|
|
495
|
+
result.push(pendingTools);
|
|
496
|
+
pendingTools = undefined;
|
|
497
|
+
}
|
|
498
|
+
};
|
|
499
|
+
|
|
500
|
+
for (const msg of messages) {
|
|
501
|
+
if (isToolOnlyMessage(msg)) {
|
|
502
|
+
if (!pendingTools) {
|
|
503
|
+
pendingTools = { role: "user", parts: [] };
|
|
504
|
+
}
|
|
505
|
+
pendingTools.parts.push(...msg.parts);
|
|
506
|
+
continue;
|
|
507
|
+
}
|
|
508
|
+
flush();
|
|
509
|
+
result.push(msg);
|
|
510
|
+
}
|
|
511
|
+
flush();
|
|
512
|
+
return result;
|
|
513
|
+
}
|
|
514
|
+
|
|
477
515
|
function normalizeAssistantContent(messages: AgentMessage[]): void {
|
|
478
516
|
for (let i = 0; i < messages.length; i++) {
|
|
479
517
|
const msg = messages[i];
|
|
@@ -1279,7 +1317,8 @@ export function createMemoryOpenVikingContextEngine(params: {
|
|
|
1279
1317
|
? afterTurnParams.prePromptMessageCount
|
|
1280
1318
|
: 0;
|
|
1281
1319
|
|
|
1282
|
-
const { messages:
|
|
1320
|
+
const { messages: extractedMessagesRaw, newCount } = extractNewTurnMessages(messages, start);
|
|
1321
|
+
const extractedMessages = coalesceConsecutiveToolMessages(extractedMessagesRaw);
|
|
1283
1322
|
|
|
1284
1323
|
if (extractedMessages.length === 0) {
|
|
1285
1324
|
diag("afterTurn_skip", OVSessionId, {
|
|
@@ -1387,15 +1426,13 @@ export function createMemoryOpenVikingContextEngine(params: {
|
|
|
1387
1426
|
`openviking: Phase2 memory extraction runs asynchronously on the server (task_id=${commitResult.task_id}). ` +
|
|
1388
1427
|
"memories_extracted appears only after that task completes — not in this immediate response.",
|
|
1389
1428
|
);
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
);
|
|
1398
|
-
}
|
|
1429
|
+
void pollPhase2ExtractionOutcome(
|
|
1430
|
+
getClient,
|
|
1431
|
+
commitResult.task_id,
|
|
1432
|
+
agentId,
|
|
1433
|
+
logger,
|
|
1434
|
+
OVSessionId,
|
|
1435
|
+
);
|
|
1399
1436
|
}
|
|
1400
1437
|
} catch (err) {
|
|
1401
1438
|
logger.warn?.(`openviking: afterTurn failed: ${String(err)}`);
|