Skip to content

集成能力参考

导读

你想知道去哪里
特定 harness 下,agent 可主动调用的工具列表§1.1 主动工具面 + §2.1(MCP 面)+ 各档案卡
不同关闭方式下,记忆归档的时机§3.3.3 关闭方式 × harness 终局矩阵
自动召回是否携带 session_id 及其影响§3.2.2 / §3.2.3
如何开启召回再摘要,以及服务端与客户端的职责划分§3.2.5
forget 操作与删除功能的类型边界§3.5
特定环境变量在不同 harness 下的生效情况§3.1.4 配置体系分层 + 各档案卡"配置"
服务端是否具备自动 commit 兜底机制§2.3
ov CLI 命令全集§5
自定义 agent 如何接入 OpenViking§6
某个集成怎么安装、怎么配、怎么排障该集成的单独页面(§4 各档案卡首行给出链接)

1. 能力总览

1.1 主动工具面(Agentic 调用能力)

  • MCP 型 harness(claude-code、codex/trae-cli、cursor、trae/trae-cn、zcode、opencode)的主动工具面完全一致,共 15 个工具:这些工具由服务端统一定义,插件通过代理获得 ~/.openviking/ovcli.conf 配置后连接服务器定义的 MCP 工具。

  • trae-cli 指 TraeCode CLI 2.0(仅支持 2.0),经 codex 插件别名安装,插件与 codex 格式兼容,下文矩阵并入 codex 行。

harness工具面形态工具数(默认开)搜 memory搜 resource搜 skill写 memory写 resource写 skill删除类型边界
claude-codeMCP 透传15❌¹无类型区分²
codex / trae-cliMCP 透传15❌¹无类型区分²
cursorMCP 透传15❌¹无类型区分²
trae / trae-cnMCP 透传15❌¹无类型区分²
zcodeMCP 透传15❌¹无类型区分²
opencodeMCP 透传(宿主加 openviking_ 前缀)15❌¹无类型区分²
dshMCP 透传15❌¹无类型区分²
pi原生注册(7 个 viking_*7(注册需前置检查⁴)viking_rememberviking_add_resource(仅 URL)无类型区分;query 删除需 score>0.8³
openclaw原生注册(15 个 memory_*/ov_* 等)15(默认开 14⁵)memory_recallov_search(默认双 scope)ov_searchmemory_store默认关⁵add_skillmemory-only 白名单 + 单候选 score≥0.85 才自动删
hermes原生注册(6 个 viking_*6(provider 激活即全开)viking_remember(直写文件,不走抽取)✅ 多协议摄取(HTTP/Git/SSH/本地文件/目录 zip)memory-only + .md 叶子校验
ov CLICLI 命令~40 命令组ov findov findov findov add-memoryov add-resourceov add-skillov rm 直接执行(TUI 删除有确认 + root/scope 禁删)

¹ MCP write 的可写域是 viking://resources|user|agent,暂不支持 MCP 新增 skill;新增 skill 的入口是 openclaw add_skillov add-skill 与 REST。 ² MCP forget 不区分 memory/resource/skill 类型;存储层保留了命名空间根保护机制(裸 viking://viking://userviking://agent 根拒删),详见 §3.5。 ³ pi 的 viking_forget:其 recursive 参数固定为 false(不删除目录),按 query 删除要求匹配分 >0.8。 ⁴ pi 工具注册前置:需未命中 bypassPatterns、client.health() 通过、ensureSession 成功(index.ts:66-113);health 未通过时本轮不注册工具面。 ⁵ openclaw 的 add_resource 需经过双重 opt-in 后方可开启。

skill 的增删边界:新增入口包含 openclaw add_skill(默认开)、ov add-skill 与 REST;删除边界分四档,详见 §3.5

1.2 自动 hook 面(通过 Harness 自动实现)

harness接入方式自动召回召回带 session_id再摘要(客户端)*profile 注入接管宿主压缩离线补偿(pending queue)statusline
claude-code9 hook + MCP 代理 + slash + statusline + skill✅ 本地 claude -p / 服务端 rewrite(默认 auto)✅(10000)❌(PreCompact 只 commit)
codex / trae-cli4 hook + MCP 代理 + skill✅ 本地 codex exec(默认开)✅(10000)❌ 无磁盘队列(靠游标不推进、下一轮重发补偿)
cursor7 hook + MCP 代理 + rule + skill✅(6000)
trae / trae-cn4 hook + MCP 代理✅(6000)
zcode4 hook + MCP 代理✅(6000)
opencode7 plugin hook + MCP 代理✅(10000)+ repo 列表进 system prompt❌(compacting 前后各 commit 一次)❌(有 toast)
dshCordis 原生插件(同进程)+ MCP 代理 + skill✅(10000,每 session 一次)
pi原生扩展(8 事件)✅(10000,进 systemPrompt 每轮重拼)takeover(默认开)
openclawcontext-engine 插件(ownsCompaction:true❌(走 /find,该接口无 session_id 字段)ContextEngine 全接管❌ 失败轮次不重放
hermesMemoryProvider 原生插件部分(仅 search/search 首选路径;降级 /find 不带)❌(静态工具指引块)✅ 进程内队列(不落盘)
ov CLI一次性命令❌(ov find/search 是显式命令)—(ov search --session-id 为显式参数)

* 此列指客户端是否内建了针对召回结果的本地压缩;服务端则在 context 检索面上,统一为所有调用方提供 digest 能力(rewrite 参数,§3.2.5)。

session_id 携带现状:除 openclaw(其调用的 /find 接口无该字段)与 hermes 的降级路径外,其余所有 harness 的自动召回均显式携带 session_id,并有跨插件回归测试钉死(examples/memory-plugin-shared/recall-session-wiring.test.mjs:16-39)。

1.3 形态分组

  • 全家桶型(hook 自动化 + MCP 工具面 + 周边 UX 齐全):claude-code、codex(trae-cli 经别名安装同属此档)。
  • 瘦 hook 型(共享 agent-hook-runtime,核心行为基本一致,差异仅体现在宿主事件与阈值上):cursor、trae/trae-cn、zcode。
  • plugin 事件型:opencode(宿主事件面最丰富,dispose 覆盖关闭)。
  • 同进程原生型:dsh(Cordis)、pi(扩展 + takeover 压缩接管)、openclaw(context-engine 全接管)、hermes(MemoryProvider)。
  • 工具型:ov CLI(所有操作均为显式调用,不存在任何自动行为)。
  • 非 coding:Open WebUI(工具服务器)、LangChain(SDK 库)、Agent Plugins 便携包(MCP+skill 规范包)、通用 MCP 直连、log ingestion(日志反向导入)、Helper(桌面端)。

2. 公共能力核

per-harness 章节(档案卡)只写差异;所有共享事实均在本章一次性说明完毕。

2.1 服务端 MCP 工具面

这些工具定义在服务端,后续更新也会在服务端统一发布,Harness 只需通过插件代理 MCP 拿到最新的 ~/.openviking/ovcli.conf 即可。

#工具名功能参数要点(定义行号)
1find不依赖会话上下文的快速语义检索query, target_uri="", limit=10, min_score=0.35, level, context_type:259
2search深检索,可带 session_id + 意图分析session_id 仅在服务端 retrieval.enable_intent(默认 true)开启时才会加载会话(:285:302-304
3read读取单个或多个 viking:// 文件全文并发信号量 10;单条失败返回 (nothing found at <uri>) 不抛错(:389
4list列目录(函数名 ls,注册名显式改写为 listrecursive=False:423
5tree递归目录树level_limit=3, node_limit=1000, include_abstract=False:449
6remember写长期记忆内部建一次性会话 mcp-store-<uuid12> 并立即 commit_async:504-523)——这是 MCP 面唯一的 commit 入口;MCP 没有显式 commit 工具
7writeviking:// 文件mode=replace|append|create:replace 覆盖或在缺失时创建,append 追加或在缺失时创建,create 仅创建缺失文件且已存在时返回冲突;显式 create 的文件扩展名白名单为 .md .txt .json .yaml .yml .toml .py .js .ts;可写域 resources/user/agent;用户根下 skills/ peers/ privacy/ sessions/ 只读;已存在的 .abstract.md/.overview.md sidecar 可改正文,但公共 API 不能创建(:529content_write.py:60-81
8edit精确字符串替换old_string 空/0 命中/多命中且非 replace_all 均报错,且文件内容不变(:569
9add_resource资源摄取(远程 URL / 本地文件签名上传 / Connector)watch_interval 单位为分钟(0=不 watch);本地路径分支返回签名上传 URL(TTL 默认 600s),上传后自动入库,无需二次调用(:723-947
10list_watches列 watch 订阅,商业版尚未支持scheduler 未运行时返回错误串(:958
11cancel_watchto_uri 取消,商业版尚未支持刻意不暴露 pause/resume/trigger/update(:990
12grep正则内容检索多 pattern 并发(信号量 10),node_limit=10:1032
13glob文件名 globnode_limit=100:1084
14forget删除 URI(不可恢复)默认 recursive=False;类型边界详见 §3.5:1110-1117
15health健康检查无参(:1123

配套机制:

  • 可移植 schema 重写:1149-1218):模块导入时把所有工具的 anyOf/$ref 折成扁平类型,以兼容 Gemini 等 OpenAPI 3.0 子集客户端;运行时校验仍用原始 Python 签名(例如 read 广播的 schema 是 array,但仍接受裸字符串)。所有 MCP 客户端拿到的 schema 都由服务端统一产出,客户端无差异。
  • 身份中间件:149-233):与 REST 共用 resolve_identity,依次读 x-api-key / authorization / x-openviking-account / x-openviking-user / x-openviking-actor-peer;account/user 缺省回落 "default"

2.2 memory-plugin-shared 共享层

examples/memory-plugin-shared/lib/ 下共 18 个 .mjs 模块,是 JS 系 harness 的唯一事实源。两种消费形态:

  1. Vendoring(复制):由 sync.mjs 分发到 7 个目标,每个文件首行加 // GENERATED FROM ... DO NOT EDIT.(因此 vendored 副本行号 = lib 源行号 + 1,交叉读行号引用时要换算)。分发清单:claude-code / codex / opencode 各 17 个(HARNESS 13 + mcp-proxy-core + mcp-proxy-config + async-writer + batch-send);dsh 15 个(HARNESS 13 + stdio 代理需要的两个 mcp-proxy-* 模块);pi 13 个;zcode 全量 19 个;agent-plugins 5 个。当前 HEAD 各目标与 lib 源零漂移。
  2. 相对路径直接 import(不复制):cursor / trae / trae-cn 直接 import "../../memory-plugin-shared/lib/...";安装器把包与共享 lib 一起复制到 ~/.openviking/agent-integrations/{<client>,memory-plugin-shared}/,使相对层级成立。运行期这个共享目录被这几个 harness 共用,任一重装都会整体覆盖。

核心模块速览(细节在各维度章展开):

模块职责消费方
recall-core.mjs召回请求构造 + 三级降级 + 本地兜底排序注入全部 JS 系 harness
agent-hook-runtime.mjs"瘦 hook"一体化运行时(配置面 19 个 env、session id 派生、跨进程锁、fetch、commit)cursor / trae / trae-cn / zcode
mcp-proxy-core.mjsstdio↔streamable-HTTP MCP 代理内核全部 MCP 型 + agent-plugins
pending-queue.mjs磁盘离线队列 + 会话启动重放cc / cursor / trae×2 / zcode / opencode / dsh / pi
batch-send.mjs100 条/批写入 + 404/405 逐条降级 + 连续前缀入队cc / codex / opencode + agent-hook 系
profile-inject.mjssession-start 的 profile + 可用记忆清单注入9 个 harness(openclaw / hermes 除外)
recall-compress-core.mjs召回压缩 prompt + URI 编辑距离修复 + 缓存claude-code
capture-utils.mjs消息归一 + 注入回流防护 + 捕获过滤codex / opencode / dsh / pi
credentials.mjs凭据解析链(详见 §3.1.3全部 JS 系
session-model.mjs会话 id 前缀派生 + bypass glob全部 JS 系
async-writer.mjs写路径 detach(drain stdin → spawn → approve → write → unref;spawn 失败回落同步)cc / codex / zcode
workspace-peer.mjscwd → actor peer(非字母数字全替换成 -全部 JS 系
uri-guard.mjs / agent-uri-guard.mjs拦截 viking:// 被误当成本地路径的情况各 harness 的 PreToolUse/tool.execute.before 类 hook
plugin-config.mjsovcli.conf plugin 段读取claude-code / codex
setup-wizard.mjs交互式写 ovcli.confcc / codex / opencode / pi 暴露入口
retryable.mjs可重试判定:status 0/408/429/≥500,或 409 且 error.details.retryable===true;4xx(含 401/403)不重试全部 JS 系

2.3 服务端会话与 commit 语义

  • 会话隐式创建:插件普遍不显式调用 POST /sessions(dsh 例外,它会发一个只含 session_id 的 create);首次 POST /sessions/{id}/messages(/batch) 时由服务端 auto_create=True 建会话。召回侧 mode="context"_load_session(auto_create=True) 也会建(第一次召回即在服务端创建会话)。
  • commit 两阶段POST /sessions/{id}/commit 的 Phase 1(归档 archive)同步完成后才返回,Phase 2(记忆抽取)作为后台任务返回 task_idkeep_recent_count 服务端默认 0(全量归档,不留 live tail)。
  • 服务端自动 commit 默认关闭,且插件建会话的路径不会打开它
    • memory.session_auto_commit.default_enabled = falseidle_enabled = falsememory_config.py:15-16);无存储 policy 的会话自动 commit 关闭(session_service.py:637-638);idle 扫描器在 idle_enabled=false 时根本不创建(core.py:440-448),构成双重门控。
    • POST /messages 的 auto_create 不接受 policy 参数;只有 POST /sessions(create)与 PATCH /sessions/{id}/config 能设 auto_commit_policy
    • 当前没有插件下发 auto_commit_policy;第一方客户端中会下发该字段的是 ov CLIov session new --auto-commit-policy-json / --no-auto-commitov session config set)。
    • policy 显式启用时,服务端默认阈值是 pending_token_threshold=150000(严格大于)/ message_count_threshold=100 / idle_timeout_seconds=86400 / keep_recent_count=0 / min_commit_interval_seconds=0。注意这组服务端默认值与各插件客户端的 20000/10 是相互独立的两层配置。
  • 由此:现状下所有自动 commit 都是客户端各自实现的阈值逻辑(§3.3),服务端不做兜底;进程异常终止后遗留的 pending 消息,需在同一会话后续再触发 commit 才会归档与抽取。
  • tool output 外置:服务端 tool_output_externalization.enabled=Truethreshold_chars=20000server/config.py:257-258)——客户端普遍把 captureToolMaxChars 设到 1000000 仅作兜底,真正的截断/外置在服务端做,externalized 结果通过 tool_output_ref 引用(openclaw 有三个专门工具读它)。
  • 服务端召回相关熔断retrieval.recall_intent_timeout_s=5.0(query expansion)、recall_rewrite_timeout_s=30.0(digest,§3.2.5)、enable_intent=true。客户端超时预算按这两条推导(§3.2.4)。

3. 维度详解

3.1 接入形态、安装与配置体系

3.1.1 判定矩阵

harness集成形态安装通道会话 id 前缀/格式配置来源独立 setup 向导
claude-codeCC 插件(marketplace):包含 9 hook + MCP 代理 + slash + statusline + skill一键 install.sh --harness claude(支持现代 plugin 路径与 legacy claude mcp add 兼容路径)/ 手动 marketplace / TOS 镜像cc-<CC session_id 原文>;subagent 格式为 …__subagent-<agent_id>env + ovcli.conf plugin.claude_code + ov.conf claude_codescripts/setup.mjs
codexCodex 插件(marketplace):包含 4 hook + MCP 代理 + skill一键 --harness codex / codex plugin marketplace add(TOS 走 dumb-HTTP git 以保留远程更新能力)cx-<safeId>(确定性推导,不读取 state)env + ovcli.conf plugin.codex + ov.conf codex
trae-clicodex 插件别名安装(TraeCode CLI 2.0,仅支持 2.0;Codex 系:binary traecli、配置 ~/.trae/traecli.toml;能力面与 codex 一致)一键 --harness trae-cli(复用 codex 安装流程;marketplace 命令会随指向的 binary 执行,如 traecli plugin marketplace add与 codex 的派生规则一致与 codex 一致(env + ovcli.conf plugin.codex + ov.conf)✅(同 codex)
cursor配置驱动(写入 ~/.cursor/hooks.json+mcp.json)+ rule + skill一键 --harness cursorcu-<conversation_id>仅 env❌(共用安装器 TUI)
trae / trae-cn配置驱动(~/.trae{,-cn}/hooks.json + 平台相关 mcp.json)一键 --harness trae,trae-cntr- / trcn-仅 env
zcode配置驱动(合并进 ~/.zcode/cli/config.json,并强制 hooks.enabled=true一键 --harness zcodezc-<sess_…>仅 env
opencodenpm 插件 @openviking/opencode-plugin(config hook 自注入 MCP 条目)一键 --harness opencode(npm 注册 + 代理快照兜底)/ 手动 npm / 源码oc-<id>;subagent 格式为 oc-<parent>__subagent-<child>openviking-config.json(4 级搜索)+ env
dshCordis 同进程插件(cordis.patch.yml plugin group)统一安装器(会询问 profile,默认 web),或执行 dsh plugin --profile web add @openviking/dsh-memory-plugindsh-<session.id 原样>;subagent 各自独立会话cordis patch config + 4 个 env(凭据优先级 patch>env,行为开关优先级 env>patch)
pipi 原生扩展(目录装载,jiti 直译 TS)一键 --harness pi(含 pi install 注册)pi-<piSessionId>config.json(凭据字段由凭据链统一解析)+ env
openclawcontext-engine 插件(ownsCompaction:true)+ 15 工具 + 5 slash + 4 hook + HTTP 路由ClawHub 执行 openclaw plugins install clawhub:@openviking/openclaw-plugin 搭配 openclaw openviking setup / npm 安装器 / TOS 离线包UUID 原样小写,否则 sha256(sessionKey)memory_store 临时会话 memory-store-<ts>-<rand>openclaw.jsonplugins.entries.openviking.config(严格校验:存在未知键/非法值时插件进入 setup-only 模式)+ 少量 envopenclaw openviking setup(交互/非交互 + key 角色探测 + 版本兼容检查)
hermesHermes bundled MemoryProvider(随 Hermes 发布,无需装插件)执行 hermes memory setup openviking(curses 向导)或手动 config set memory.provider openviking + .env由 Hermes 生成 %Y%m%d_%H%M%S_<hex6>,插件原样使用.envOPENVIKING_*)或 ovcli.conf 联动(use_ovcli_config 模式会清空 .env 里的 5 个对应变量)+ config.yaml✅(多层菜单)
ov CLIRust 原生二进制npm @openviking/cli / uv tool install openviking / cargo / GitHub Releases无自有会话(ov chat 默认使用 machine-uid)ovcli.conf(多 profile)+ 少量 envov config(TUI 向导)

3.1.2 统一安装器

统一安装脚本 examples/memory-plugin-shared/install.sh(3424 行)覆盖 10 个 harness id:claude, codex, cursor, trae, trae-cn, trae-cli, zcode, opencode, pi, dsh(其中 openclaw 走自有渠道;trae-cli 则复用 codex 安装流程,§3.1.1)。要点如下:

  • 双分发:--dist github|tos;三源:--source remote|archive|dev。以 bash <(curl …) 方式执行时会从 /dev/tty 读取输入,从而保留交互。
  • 官方 docs 的规范一键命令是不带 --harness 的裸命令(执行后进入 TUI 多选);而各插件自带的 setup-helper 转发脚本在调用时会自动补 --harness
  • 幂等合并:hooks/mcp 条目按 OPENVIKING_INTEGRATION_ID 标记识别自有条目,做到剔旧追新的同时不动第三方;写入采用原子操作——先备份 .bak,写 tmp 后 rename 覆盖,权限 0600。
  • 凭据向导写 ~/.openviking/ovcli.conf:三选一(本地 http://127.0.0.1:1933 / 火山云 https://api.vikingdb.cn-beijing.volces.com/openviking / 自定义),已有配置先展示当前值再问"沿用/重配",API key 掩码。
  • 卸载:--uninstall 覆盖 cursor / trae / trae-cn / zcode,并顺带清理 trae-cli 遗留的旧 hook 配置;claude / codex / trae-cli / opencode / pi 这些 Codex 格式或宿主托管的插件,通过各自宿主的插件管理卸载。
  • 安装后自检:grep 配置 + node --check + 一次 OPENVIKING_MEMORY_ENABLED=0 的 smoke run。
  • Node 门槛:安装器检查 18+。

3.1.3 凭据体系

代码中并存着四套并行的凭据解析体系,env 变量名与认证头各不相同,排障时先分清对象:

家族消费者URL envKey env身份 env认证头
A. JS 共享核credentials.mjsclaude-code / codex(含 trae-cli)/ cursor / trae×2 / zcode / opencode / pi / dsh / agent-pluginsOPENVIKING_URLOPENVIKING_BASE_URLOPENVIKING_BEARER_TOKENOPENVIKING_API_KEYOPENVIKING_ACCOUNT / OPENVIKING_USER / OPENVIKING_PEER_IDAuthorization: Bearer;注意 codex 的 4 个 hook 脚本会额外发送 X-API-Key 兼容头
B. openclaw(自有 config.tsopenclawOPENVIKING_BASE_URLOPENVIKING_URLOPENVIKING_API_KEY(支持 SecretRef env/file)OPENVIKING_ACCOUNT_ID / OPENVIKING_USER_ID(注意此处带 _IDX-API-Key(指向 OV Cloud 时注意其实际采用 Bearer 认证)
C. hermes(Python)hermesOPENVIKING_ENDPOINTOPENVIKING_API_KEYOPENVIKING_ACCOUNT / OPENVIKING_USER / OPENVIKING_AGENT(=actor peer)X-API-Key + Bearer 双发;有 key 时默认不发租户头(被服务端以 trusted 报错拒绝时会自动补头重试一次)
D. ov CLI(Rust)ovconf 文件为主conf--account/--user/--actor-peer-idX-API-Key;LDAP Basic / OIDC Bearer 按 auth_mode 切换;api_key 含 ≥2 个 . 时自动附加 Bearer(JWT 兜底)

家族 A 的解析链如下(其余家族见档案卡):

  1. 模式由 OPENVIKING_CREDENTIAL_SOURCE(别名 _CREDENTIALS_SOURCE)控制,取值 ∈ env|cli|auto(默认 auto)。
  2. auto 语义是 env 优先:只要任一 env 凭据字段存在,整体就走 env;只有 env 全空、且 ovcli.conf 存在并含凭据字段时,才整体切换到文件(此时 key/account/user/peer 全部只从文件取)。
  3. baseUrl:env → ovcli url → ov.conf server.urlhttp://{server.host|127.0.0.1}:{server.port|1933}(其中 0.0.0.0 归一为 127.0.0.1);兜底 http://127.0.0.1:1933
  4. apiKey:BEARER_TOKENAPI_KEY → ovcli api_key → ov.conf codex.apiKeyserver.root_api_key
  5. mcpUrl:OPENVIKING_MCP_URL(非 cli 模式)→ ${baseUrl}/mcp
  6. 统一请求头:Authorization: Bearer + X-OpenViking-Account/User/Actor-Peer + User-Agent: openviking-memory-<harness>/<version>

workspace peer(家族 A 全体 + agent-plugins):无显式 peerId 且 OPENVIKING_WORKSPACE_PEER≠0 时用 cwd 派生——把路径中所有非字母数字字符替换成 -/Users/x/Dev/OpenViking-Users-x-Dev-OpenViking),该值随 X-OpenViking-Actor-Peer 发送;服务端会对该头校验,含 /\ 返回 400。openclaw 的 peer 由 peer_role/peer_prefix 推导(peer_role=person 时需保证 sender 信息可用,否则工具调用报错);hermes 的 peer 就是 OPENVIKING_AGENT(默认 hermes)。

3.1.4 配置体系分层

配置层生效范围备注
env OPENVIKING_*各家族见上;行为旋钮见各档案卡唯一横跨所有 JS 系的层
ovcli.conf plugin 段(plugin.claude_code / plugin.codex / 共享标量)claude-code / codex其余 harness 名下的 plugin.<x> 条目不参与解析。注意:ov config add/edit 会以 Rust Config 结构重写整个文件,从而丢弃其不识别的 plugin 段;而 ov config switch 为字节复制,不受影响
ov.conf harness 段(claude_code.* / codex.*claude-code / codex(legacy 回落)
harness 自有配置文件opencode openviking-config.json、pi config.json、dsh cordis patch、openclaw openclaw.json、hermes config.yaml+.env

配置项生效范围速查(这些旋钮只在列出的 harness 上生效):

  • OPENVIKING_COMMIT_TURN_THRESHOLD:仅 cursor(trae×2/zcode 每 Stop 必 commit,不走该阈值)。
  • OPENVIKING_WRITE_PATH_ASYNC:claude-code / codex / zcode。
  • 召回再摘要相关(OPENVIKING_RECALL_COMPRESS / OPENVIKING_RECALL_REWRITE 及配套项):claude-code / codex(服务端 rewrite 参数本身对所有调用方可用,§3.2.5)。
  • OPENVIKING_RECALL_DEDUP_TURNSOPENVIKING_RECALL_QUERY_EXPANSION:claude-code / codex。
  • ovcli.conf plugin 段:claude-code / codex。

3.2 自动召回与注入

3.2.1 机制底座:一条共享管线,两条服务端路径

JS 系 harness 的召回逻辑均由 recall-core.mjs 中的三级降级链处理:

  1. context face:调用 POST /api/v1/search/search,参数设定为 mode:"context"purpose:"coding"。其核心设计原则为"只声明意图,机制交服务端":对于 quotas/max_tokens/query_expansion/rewrite_max_bullets 等参数,仅在用户显式配置时(带有 configured 哨兵字段)才会发送,否则直接采用服务端的默认设定。
  2. legacy /recall:若 context face 请求返回 400/422 错误,且响应报文包含 extra/mode/unexpected 等特征字段,则判定对接了旧版服务端。此时会在本地写入 6 小时的负缓存(路径为 ~/.openviking/state/context-face.json,该文件全机共享,一旦被任一 harness 标记,同机所有 JS 系 harness 均会跳过 context face 阶段)。随后降级调用已弃用的 /api/v1/search/recall 接口;若 peer_scope 被拒,则去掉该参数重试一次。
  3. raw find 兜底:并发请求 viking://~/memoriesviking://~/skills,调用两次 POST /search/find(注意:resources 被刻意排除在自动召回之外,资源类文档由模型主动调用 search 获取)。客户端收到结果后进行本地重排(权重规则为:leaf +0.12 / 时间意图 +0.10 / 偏好意图 +0.08 / 词面重叠 ≤0.2)、去重,最后按客户端 token 预算装填。recallTokenBudgetrecallMaxContentCharsrecallPreferAbstract 三个旋钮只在这一级生效;而在 context face 下,注入预算由服务端 max_tokens(默认 1600)决定。

服务端在处理 session_id 时,分为两条截然不同的执行路径:

  • 路径 A:mode="context"(适用于 context face 与 /recall preset)。此路径负责 query expansion 与跨轮去重台账。expansion 设有三重闸门:retrieval.enable_intent 需开启(默认 true) → 会话必须已物化(即 messages.jsonl 文件存在) → latest_archive_overviewcurrent_messages 不能为空。扩写后原 query 永远排第一,追加的 planned queries 上限为 3。台账(.recall_log.json)按 dedup_turns 冷却已发正文的 URI;若"当轮只发了 URI 没发正文",该记录则不参与冷却;digest 判定 no_relevant 时亦不记账。
  • 路径 B:mode="list"(不写 mode 时的默认行为)。此路径下,IntentAnalyzer 会整体替换 typed_queries(原 query 不保证保留),无台账、无原-query 保底。实际落在这条路径上的调用方包括:codex 的第二级降级 searchScope、hermes 的 viking_search(mode="deep") 以及 prefetch 的首选路径。尽管它们带了 session_id,但拿不到 context 面的 expansion 与去重机制。

dedup_turns 的三点说明:① 服务端 context 面的默认值是 0,常见的"5"实则源自客户端 recall-core.mjs 兜底与 /recall preset(后者仅当带 session_id)——不经共享库直接打 API 的第三方即使带了 session_id,也要显式发 dedup_turns 才有跨轮去重;② "turn"的计数单位是消息条数而非对话轮(_resolve_turntotal_message_count),对同时推 user+assistant 的 harness,默认 5 ≈ 1-2 个真实对话轮;③ 注意:autoCapture=0autoRecall=1 时消息数恒 0 → 台账时钟不走 → 已发过正文的 URI 在本会话内持续冷却;可用 OPENVIKING_RECALL_DEDUP_TURNS=0 关闭去重(claude-code / codex)。

3.2.2 判定矩阵

harness触发点query 构造session_id服务端路径注入格式 / 位置再摘要(客户端)*
claude-code每轮 UserPromptSubmitprompt 原文 trimcc-A(context face)<openviking-context>hookSpecificOutput.additionalContext✅ 本地/服务端(默认 auto,§3.2.5
codex / trae-cli每轮 UserPromptSubmit(整 hook 120s 硬截止)prompt 原文cx-(确定性推导,不读 state)A;二级降级 searchScope 落入 B<openviking-context source="auto-recall" format="digest">✅ 本地 codex exec§3.2.5
cursorbeforeSubmitPromptprompt 原文;基于事件 id 与 500ms 窗口去重,同 promptHash 复用缓存块cu-Aadditional_context
trae / trae-cnUserPromptSubmit剥离历史注入块后的 prompt(只认 input.prompttr-/trcn-AadditionalContext
zcodeUserPromptSubmit剥离三类注入块(含 <system-reminder>zc-AadditionalContext(严格 JSON)
opencode每条 chat.message 中的 user 消息拼接非 synthetic text part;若正文已含 <openviking-context 则跳过本轮召回oc-A(timeoutMs=30000)合成 synthetic part 并 unshift 到 parts 最前
dshagent/pre-step waterfall(先 await next 再 append)claimed batch 全部消息(过滤自身注入的内容)dsh-A借由 createUserMessage append 到 decision.messages 尾部(source: plugin/openviking-memory)
pibefore_agent_start 阶段排队;在 context 事件内检索(当前轮 prompt 拿当前轮记忆)prompt 原文pi-(会话未建立时不带)A前置到最后一条真实 user 消息(通过 <openviking-context 幂等检测)
openclawcontext-engine transformContext assemble(设有 7 道 passthrough 门)最后一条 user 消息纯 text,清洗后截 4000 字符❌(/find 无该字段)/find<relevant-memories> + Source: openviking-auto-recall 格式前置进最后一条 user 消息
hermes每轮 API 调用前同步执行 prefetch原始用户输入,双层剥 skill 脚手架;<5 字符跳过部分携带(仅 search/search 首选路径,落 B;降级 /find 时不带)B / find<memory-context> fenced 块追加到当轮 user 消息(只进 API 请求体,不写回持久化)

* 同 §1.2:此列的"再摘要"特指客户端本地压缩,而服务端 digest 对所有调用方均可用(§3.2.5)。ov CLI 无自动召回,不在本表。

3.2.3 profile / 开场注入

  • 实现profile-inject.mjs——读 viking://user/<space>/memories/profile.md 全文 + preferences/entities/ 递归清单(abs_limit=512)。预算估算引入 CJK 感知(≥U+3000 记 1.5 token/字,其余 chars/4);profile 占一半预算,超限则采用"头 8 行 + 尾部"的中段省略;清单超限则追加 ... +N more 提示。
  • 谁注入、何时、预算:claude-code(SessionStart 全部 source,10000);codex(SessionStart startup/clear/resume,10000);cursor/trae×2/zcode(SessionStart,6000,2s 去抖);opencode(每会话首条 chat.message 一次,10000,进程内 Set 去重,subagent 会话跳过;注意开场注入每会话只尝试一次,失败后本进程内不重试);dsh(每 session 投一次 profileDelivered,10000;compaction 之后不重投);pi(进 systemPrompt,每个 prompt 重拼,10000 常驻)。openclaw、hermes 无 profile 注入。
  • archive 注入(resume 场景把上次归档摘要拉回来):claude-code(source=resume/compact,token_budget=32000,≤5 条 pre_archive_abstracts);codex(resume 且本地 ovSessionId 已清时,32000/截 6000 字符);opencode(开场注入 B 部分,32000);pi 非 takeover 模式(32000)。
  • repo 上下文注入:opencode 独有——通过 experimental.chat.system.transform 把已索引仓库列表放进 system prompt。

3.2.4 超时与预算链

  • 家族 A 客户端推导:带 rewrite → max(timeoutMs, 45000);带 expansion → max(timeoutMs, 15000);对应服务端熔断 5s(expansion)/30s(rewrite)——设计上让客户端预算覆盖服务端各阶段,防止客户端提前 abort 丢掉整个响应。
  • 实际值:cc 15s(hook 预算 60s);codex 召回整 hook 120s 硬截止 + 压缩子进程 110s;cursor/trae×2/zcode 15s(宿主 hook 预算 20s);opencode 30s;dsh 15s(阻塞 pre-step);pi 15s;openclaw 整个召回流程外层 5s 硬超时(500ms health precheck;默认 recallPreferAbstract=false 时每条 leaf 记忆多一次 read,预算内最多 1 find + 6 read + 1 health);hermes 总预算 4s / 单请求 3s(可配)。
  • 注入体预算:服务端 max_tokens 默认 1600(家族 A 默认不发、由服务端决定);openclaw / hermes 用字符预算 4000(两家都是"装不下整条跳过"而非截断)。

3.2.5 召回再摘要

服务端实现(对所有调用方可用):context 检索面(涵盖 REST 的 mode="context" 与 legacy 的 /recall)支持传入 rewrite 参数——可选值为 false | true | "auto",默认为 false;并配套提供 rewrite_max_bullets(默认 6,1-20)。开启后,服务端会用 query_planner 模型(rewrite=true 时未配置则回落主 vlm"auto" 仅在显式配置了 query_planner 时生效)把召回结果改写成带引用的 digest:OpenViking memory digest: 头 + - bullets,每条 ≤500 字符且必须引用一条本次命中的 viking:// URI(无引用或引用越界的 bullet 被丢弃);判定无相关记忆时输出哨兵并清空注入块(该轮不记入去重台账)。模型调用受 retrieval.recall_rewrite_timeout_s=30s 熔断,超时回落未改写的 rendered 块(rewrite.py:78-141pipeline.py:122-130search.py:195-196)。

客户端侧现状

  • claude-coderecallRewrite 四态 off|client|server|auto,默认 auto——先探测本地压缩器是否可用(claude --version 探测,缓存 7 天),若可用则在本地起 claude -p --model sonnet --effort low --strict-mcp-config 子进程压缩(30s 超时,输入 <1500 字不压缩,digest 单条缓存;子进程环境强制降级防递归;失败回落未压缩块;URI 编辑距离吸附回真实 URI,修不回的整条丢弃)。若本地不可用,则下发 rewrite:"auto" 交服务端。这是唯一接入服务端 rewrite 的 harness。
  • codex:布尔 recallCompress 默认 true,完全依赖本地压缩(不使用服务端 rewrite):模型 profile 从 ~/.codex/models_cache.json 读,候选 gpt-5.3-codex-sparkgpt-5.6-luna,缓存 7 天;命令 codex --sandbox read-only --ask-for-approval never exec --ephemeral --ignore-user-config --skip-git-repo-check --output-last-message <tmp> -,超时 110s;运行期失败后同一会话内跳过压缩、下次 SessionStart 自愈重测;输出规范化截 4000 字符;压缩关闭或失败时用确定性 fallbackDigest 兜底。
  • 其余 harness:均不发送 rewrite、无本地压缩,而是直接注入服务端返回的原始召回块。直连 API 的第三方可自行传 rewrite 获得服务端 digest。

3.2.6 注入回流防护

为防止注入内容被二次捕获,注入时会加确定性包装(<openviking-context> 等),捕获时再机械剥离:capture-utils 的 sanitizeCapturedText 剥注入块、digest 块、元数据围栏与时间戳前缀。各端的特殊处理包括:trae/zcode 用各自的 clean 函数(其中 zcode 剥三类注入块);openclaw 在 afterTurn 写回与下轮 query 构造时各剥一次 <relevant-memories>;hermes 则更彻底,直接把三个召回类工具的 tool_call/result 从 sync batch 里整条剔除(写类工具保留)。

3.3 会话与 commit 生命周期

3.3.1 机制底座

  • 写入路径:JS 系统一通过 batch-send.mjs 处理(对应接口 POST /messages/batch,每批最多 100 条,与服务端的 max_length=100 限制保持一致;若遇 404/405 错误则降级为逐条发送)。增量游标由各家自行实现(cc 按 transcript turn 序号计算,codex 机制相同;cursor 采用 sha256(index+role+content);zcode 基于 rollout 的 turn_id;opencode 依赖事件流 Map;dsh 基于事件白名单;pi 依据 branch 条目水位;hermes 则按当前轮切片)。
  • commit 是客户端触发的(详见 §2.3):服务端默认不自动 commit。下表所有的"阈值/触发"条件,均指客户端逻辑。
  • keep_recent_count 差异(即 commit 后给宿主留多少 live tail):服务端默认值为 0。各家传参如下:cc/codex 阈值提交传 10;cursor、trae×2、zcode 发空 body {},即传 0(每次均为全量归档);opencode 传 10;dsh 传 10;pi 在非 takeover 模式传 10,takeover 模式传 3(本地含义是"保留 3 个用户轮",而服务端按消息条数解释,实际保留更少);openclaw 在 afterTurn 阈值触发时传 10,在 compact/reset/memory_store 操作时传 0;hermes 恒定传 0。
  • 写路径 detachasync-writer.mjs,cc/codex/zcode 的 Stop 默认开):drain stdin → spawn detached worker → approve → write payload → unref(注:spawn 失败时尚未 approve,回落同步恰好只输出一次)。detached worker 自成进程组,不受终端信号波及——这是保证 cc 在关闭链路时具有高可靠性、zcode 在按下 Ctrl+C 时不丢失写入数据的关键机制。附带效果:执行 detach 后,Stop 的 appended N turn(s) 提示将不再展示(设置 OPENVIKING_WRITE_PATH_ASYNC=0 可恢复该提示)。

3.3.2 常规 commit 触发条件

harness轮内阈值触发显式/边界触发压缩触发
claude-codeStop:pending_tokens ≥ 20000(读服务端值),keep 10SessionEnd:无条件触发;SubagentStop:无条件触发(无阈值);SessionStart:重放 pendingPreCompact:无条件触发(同步执行,不 detach)
codex / trae-cliStop:同上,20000 / keep 10SessionStart(startup|clear):基于 active-window 的启发式(2min 内恰好 1 个 state → commit;≥2 个则跳过) + idle-TTL 扫描(>30min 一律 commit 并清理)PreCompact:全量 commit(发空 body {}),随后置 ovSessionId=null
cursorstop:capturedSinceCommit ≥ 8(按消息条数计算,≈4 轮问答;纯客户端计数),keep 0sessionEnd:已注册该事件(但实践中不触达,见 §3.3.3preCompact:无条件触发
trae / trae-cn每个有内容的 Stop 都 commit(无阈值),keep 0无(上游无 PreCompact 事件)
zcode同 trae(每 Stop 都 commit,keep 0;rollout 增量游标保守推进,若有漏掉的轮次,将在同会话的下个 Stop 补齐)无(上游无 PreCompact 事件)
opencodesession.idle 路径:flush 执行后,需满足 pending_tokens ≥ 20000 才 commit,keep 10session.deleted / session.error:强制 commit;dispose:强制 commitexperimental.session.compacting 前与 session.compacted 后各触发一次(即一次宿主压缩 = 两次 commit)
dshturn/endpending_tokens ≥ 20000(30s 超时),keep 10teardown(见 §3.3.3无(不监听 compaction 事件)
pi(takeover 默认开)onTurnSynced:本地估算 pendingTokens ≥ 30000lastSeenUserTurns > 3 时,执行 commitAndAdvance(keep 3;overview 15×2s 轮询,拿不到则边界不推进,但 pendingTokens 会清零,重新累计后重试)手动执行 /viking commitsession_before_compact(需 firstKeptEntryId 非空)
pi(takeover off)syncBranch 执行后:服务端 pending_tokens ≥ 20000,keep 10session_shutdown:无条件 commit;手动执行 /viking commitsession_before_compact:无条件 commit
openclawafterTurn:pending_tokens ≥ floor(tokenBudget × 0.5)(ratio 默认 0.5,tokenBudget 缺省 128000,即阈值 ~64000),wait=false,keep 10before_reset(执行 /new /reset):wait=true,keep 0;memory_store 工具:wait=true,keep 0compact():wait=true,keep 0(Phase2 轮询上限 5 分钟)
hermes无阈值 commit——触发面全是会话边界:on_session_end(drain 10s,drain 不净则本次不 commit)、on_session_switch(涉及 /new/resume/branch 或压缩 fork,异步 drain 预算 65s)、gateway 缓存驱逐;/undo 与原地压缩不 commit。用幂等集合防二次 commit;keep 0atexit 兜底fork 型压缩边界 commit;原地压缩不 commit
ov CLIov session commitov add-memory 第三步固定 commit
ingestpending ≥ 6000 或 idle 5s,keep 0;backfill 在每个会话结束时执行 commit_if_needed退出时执行 _flush_all()
LangChainCommitPolicy.mode 默认 neverpending_tokens 模式阈值为 8000;always 模式每次 record 均触发调用方自理

3.3.3 关闭方式 × harness 终局矩阵

图例:C = 会 commit;C* = 会 commit 但有前提(见注); = 不 commit(已 POST 的消息仍留在服务端 live 区:不丢消息本体,等待后续触发归档与抽取);n/a = 无此形态。所有行的服务端侧行为一律为 §2.3)。

harness正常退出Ctrl+CSIGTERMSIGHUP/关终端/关窗口·tabkill -9/崩溃补救路径
claude-codeC(SessionEnd → detach 子进程 commit,用户不等待)CCC(detached worker 自成进程组,不受 SIGHUP 波及)下次 Stop 越阈值 / /compact / 下次 SessionEnd
codex / trae-cli(上游不提供 SessionEnd 类事件)下次 SessionStart(startup|clear) 的启发式(2min 内恰好 1 个活跃 → commit)或 30min idle-TTL 扫描;≥2 并发会话时启发式让位于 TTL 扫描
cursor(chat 关闭 / new-chat 无事件)sessionEnd 已注册且仅 window_close 触发,但此时宿主已销毁 shell-exec host,hook 在 spawn 前中止)结束在 <8 条消息水位的会话,尾部依赖同一会话的后续消息触发 commit
trae / trae-cn(无 session-end 类事件)每 Stop 已 commit,最大待归档量 = 最后一轮 in-flight
zcode(无 session-end 类事件)C*C* 前提:Ctrl+C 时该轮 Stop 已触发(detached worker 照常写完);每 Stop 已 commit,漏掉的轮次靠 rollout 游标在同一会话的下个 Stop 补回
opencodeC*(≥1.15.11 的 disposeflushAll({commit:true}),覆盖全部四种关闭;<1.15.11 无该 hook → —)C*C*C*C* 前提:宿主 shutdown 预算 5s,单会话最坏 health 5s + batch 10s + commit 30s,多会话串行累加——超预算的 commit 会被截断,且 pending queue 不覆盖此场景(fetch 未 settle 不入队);重启后 init() 不主动 flush 遗留会话
dshC(Cordis teardown → 每 session 一次 3s 超时 commit,无阈值)C(第一次;第二次 Ctrl+C 强退 → —)C(无 SIGHUP 监听)teardown commit 与阈值 commit 共享同一条串行写链,5s 进程 grace 内前方有慢请求时可能挤不进;web 形态关浏览器 tab 不触发 teardown
pi(takeover 默认)session_shutdown 全关闭方式都触发且被 await,handler 持久化本地 takeover 状态,不 commit)下次续跑攒满 30000,或手动 /viking commit
pi(takeover off)Cawait sync.commit(),失败入 pending 队列)CCC
openclaw(上游发 awaited session_end(reason=shutdown|restart),handler 缓存 agentId 后返回,不触发 commit;gateway_stop 未注册;无信号处理)显式 /new /reset 与 ~50% 阈值;低于阈值的会话依赖这两条路径归档
hermesC(atexit _run_cleanup → flush 10s → on_session_end)C(交互与非交互最终都走 atexit)C_signal_handler,grace 默认 1.5s → 干净退出 → atexit)C(SIGHUP 同 SIGTERM 路径)(atexit 不执行)drain 不净时本次不 commit(避免提交半截数据);退出看门狗 30s 终止慢 commit
ov CLIn/a(一次性命令)n/an/an/an/a无 pending queue;命令失败重跑即可
ingestCfinally _flush_allC(SIGINT → stop)C(无 SIGHUP handler)唯一有崩溃恢复的写路径:needs_commit 持久化在游标库,下次运行 reconcile 补 commit
LangChain / Open WebUI / Agent Plugins / 通用 MCP(无会话生命周期挂钩;MCP 代理退出时的 DELETE /mcp 只释放协议会话,与记忆 commit 无关)LangChain 靠调用方 close();进程内 pending-commit 集合随进程消失

三点阅读提示

  1. 正常退出即 commit 的有五家:claude-code、opencode(≥1.15.11)、dsh、pi(takeover off)、hermes;其余各家均依赖表中"补救路径"列的回收机制。
  2. kill -9 场景所有集成都不触发 commit——已提交的消息保留在服务端 live 区,后续同一会话再触发 commit 时一并归档;服务端提供 per-session idle 兜底能力(§2.3),当前插件默认不下发该 policy。
  3. 每轮必 commit 的 trae×2 / zcode 关闭语义最简单(即最大待归档量 = 最后一个未走到 Stop 的回合),代价是每个 Stop 都触发一次全量归档 + 记忆抽取(keep 0)。

3.3.4 pending queue / 离线补偿对照

harness机制要点
cc / cursor / trae×2 / zcode / opencode / dsh / pi磁盘队列 ~/.openviking/pending(0700/0600)仅可重试的失败入队(4xx 含 401/403 判为不可重试,不入队,debug 日志可见);重放在会话启动时执行:≤50 条/次、≤3 次/条、TTL 7 天;.processing 原子认领,10min 陈旧回收;addMessage 失败即 break 保序
codex / trae-cli无磁盘队列服务端不可达时,靠 capturedTurnCount 游标不推进、下一轮 Stop 重发同批实现补偿(进程存活且有下一轮时生效)
openclaw无本地队列addSessionMessage 失败被 catch,该轮消息不重放
hermes进程内 daemon 线程队列drain 有预算(10s/65s);不落盘
LangChain进程内 _pending_commit_sessions 集合commit 失败下次 record 自动重试;不落盘。部分成功时抛 OpenVikingPartialWriteError(携带 messages_writteninput_messages_consumedcontext_attached,调用方可按位置切片重试后缀)——全部集成里唯一的部分成功上报协议
ingestSQLite 游标库 + 单实例锁append 前持久化意图,崩溃后 reconcile 按服务端消息数判定该批是否落地——唯一有崩溃恢复语义的写路径

3.3.5 subagent 会话对照

harness处理方式
claude-code隔离最完整:SubagentStart 派生 cc-<sid>__subagent-<agent_id> 独立会话,SubagentStop 读 subagent transcript 推送后无条件 commit 并清 state
codex / trae-cli不单独建会话:subagent 输出(agent_message / sub_agent_activity)折叠进主会话的 assistant/tool part
opencodeoc-<parent>__subagent-<child> 挂在父命名空间下;开场注入跳过 subagent(召回不跳过);ID 派生依赖事件顺序——chat.message 先于 session.created 到达时会丢 __subagent- 后缀
dsh每个 subagent = 独立 dsh-<id> 会话,父子关系不保留;N 个 subagent = N 份 profile 注入 + N 个独立会话
hermesdelegate_taskskip_memory=True → subagent 不接 OV(无会话/召回/工具面);子任务产出不回灌
cursor / trae×2 / zcode / pi / openclaw无 subagent 处理(有独立会话 id 就各自成会话,否则混入主会话;openclaw 可用 bypassSessionPatterns 屏蔽)
ingestclaude_code 适配器跳过 isSidechain / isMeta 记录——subagent 对话不入库

3.4 压缩 / compaction 接管

3.4.1 判定矩阵

harness对宿主压缩的姿态压缩前动作压缩后动作
claude-code不接管PreCompact 同步 commit(唯一不 detach 的写路径,因为 CC 随后立刻重写 transcript)source="compact" 的 SessionStart 会把 OV 的 latest_archive_overview + ≤5 条 abstracts 重新注回
codex / trae-cli不接管PreCompact 补齐未捕获轮次 → 全量 commit → ovSessionId=null(补齐不全时不 commit,留待重试);无 PostCompact 接线,依靠 Stop 的转录收缩做防御性纠偏resume 时注入 archive digest
cursor / trae×2 / zcode不接管cursor:preCompact 无条件 commit(trae×2/zcode 上游无该事件)
opencode不接管compacting 前 flush+commitsession.compacted 触发后再 flush+commit(共两次)
dsh不感知(不监听 compaction 事件;注入走 pre-step user 消息,随宿主压缩一起收缩,profile 不重投)
pitakeover 双层接管(默认开,§3.4.2session_before_compact:flush → commit → pollOverview。成功则返回自定义 compaction 摘要覆盖 pi 的;失败则 fail-open 回退到 pi 默认压缩成功后 resetBoundary
openclaw全接管ownsCompaction: true,宿主不再跑自己的摘要(§3.4.3compact() = commit(wait=true, keep 0) → 读回 overview 当 summary主 assemble 用 [Session History Summary] 重建上下文
hermes不接管(on_pre_compress 接口预留,当前不参与压缩摘要)fork 型压缩边界会触发旧会话 commit;原地压缩不动

3.4.2 pi takeover

  • 接管面是 context 事件的 messages 改写,不接管 pi 的历史存储。触发是 token 压力(30000 + 保留 3 轮),而非 pi 的压缩事件。
  • 替换动作:先定位边界,再把边界前的全部消息替换成一条合成 user 消息 [OpenViking Session Context]。其中 overview 按 3000 token 截断;timestamp 取保留首条 -1,以稳定 provider payload 吃 prompt cache。
  • 数据源是 GET /sessions/{id}/contextlatest_archive_overview(轮询 15×2s);状态持久化在 pi 自己的 branch custom entry ov-takeover
  • 失败姿态 = fail-open 回完整历史(指纹不匹配 / 历史短于边界 / overview 拿不到三重回退)。
  • 与 pi 原生压缩的关系:session_before_compact 成功时返回 {compaction:{summary, firstKeptEntryId, …, details:{source:"openviking"}}} 覆盖 pi 摘要;缺 firstKeptEntryId 时走 pi 默认压缩。

3.4.3 openclaw ContextEngine

  • 实现宿主 ContextEngine 接口,assemble() 分两个分支:transformContext(只做召回前置注入,5 道 passthrough 守卫)与 main-assemble(getSessionContext(tokenBudget) → 用服务端返回替换宿主 live 历史,四层预算切分,3 道 passthrough 保护 + provider 消息 sanitize 管线)。
  • compact() = commit(wait=true, keep 0)(500ms 轮询,Phase2 上限 5 分钟)→ latest_archive_overview 当 summary、archive_uri 末段当 firstKeptEntryIdcustomInstructions/compactionTarget 保留接口,当前不参与压缩产物。
  • ingest()/ingestBatch() 是刻意 no-op,写入全走 afterTurn
  • 有归档时额外注入 20 行 "Session Context Guide" systemPromptAddition,指示模型在说"没有信息"之前先重读摘要,并用 ov_archive_search 尝试至少 2 组关键词。

3.4.4 pi 与 openclaw 接管方式对照

维度pi takeoveropenclaw ContextEngine
宿主契约一个 context 钩子的 messages 改写注册 ContextEngine,ownsCompaction: true
历史真相源仍是 pi 本地 branchOV 服务端 getSessionContext
触发客户端 token 阈值 30000 + 保留 3 轮宿主调用 assemble/compact
压缩产物一条合成 user 消息(3000 token 截断)重建后的整个 messages 数组 + compaction summary
失败姿态fail-open 回完整历史passthrough 回宿主 live 消息
召回与 sessioncontext face 带 session_id/find 不带(expansion/台账不参与)

3.5 写入与删除的类型边界

3.5.1 写入边界

MCP write / REST content/write 的三道 guard(content_write.py):可写域限 viking://resources|user|agent;新建文件扩展名需符合白名单 .md .txt .json .yaml .yml .toml .py .js .ts;用户根下 skills/ peers/ privacy/ sessions/ 四个托管子树只读(_USER_MANAGED_SUBTREES)。已存在的 .abstract.md/.overview.md sidecar 可以改正文,但公共写入 API 不能创建它们。

3.5.2 删除边界

第一档:服务端通用防线(所有删除入口共享)VikingFS.rm 第一句 _ensure_delete_access_access.py:182-229)实施 5 道检查:命名空间可访问性;用户删除进行中 → FailedPrecondition;actor-peer 隐藏视图 → PermissionDenied;命名空间根保护:裸 viking://viking://user 根、viking://agent 根一律拒删;非 ROOT 删 viking://temp 拒。这一档按命名空间根设防,不区分 memory/resource/skill 类型——类型级差异由后三档在客户端实施。

第二档:客户端零附加(MCP 面 + dsh/pi/langchain/ov rm)。差异只在参数面:dsh/pi 的 viking_forgetrecursive 固定 false(不删除目录),且 query 删除需 score>0.8;LangChain viking_forgetrecursive 是模型可控参数(但默认不在工具面);ov rm -r 则显式开递归、无确认提示(TUI 的 d 键有 y/n 确认 + root/scope 目录禁删)。

第三档:memory-only 的两个删除面

  • openclaw memory_forget:三条白名单正则只放行 viking://user/[…/]memoriesviking://user/<u>/peers/<p>/memoriesviking://agent/[…/]memories;显式 uri 不匹配直接拒绝;搜索路径候选先过同一 guard,且只有在候选唯一且 score≥0.85 时才自动删,否则列出候选让 agent 指名;底层 URL 固定 recursive=false
  • hermes viking_forget:六道顺序校验——非 str / 空拒;scheme≠viking 拒;带 query/fragment 拒;目录或非 .md 结尾拒;必须命中 4 种 memories 路径形状之一,且 memories 段后至少还有 2 段(不删除 memories/ 与分类目录本身);文件名不能是 .abstract.md/.overview.md

第四档:默认不提供删除(LangChain / Open WebUI)。LangChain viking_forget 需配置 profile="admin"allow_forget=True 才加入工具面;Open WebUI 则完全不提供删除工具。

skill 的增删边界:新增入口是 openclaw add_skill(默认开)、ov add-skill 与 REST。对 skill 完全只读(不增不删)的删除面是 openclaw memory_forget 与 hermes viking_forget;相对地,MCP 面、dsh、pi、ov rm 加不了 skill 但删得掉——加不了是写路径 _USER_MANAGED_SUBTREES 的保护,删得掉是删除路径不检查该集合。

3.6 降级与容错

3.6.1 判定矩阵

harness服务端不可达时负缓存HTTP 重试失败阻塞宿主
claude-code各 hook catch→approve,不阻塞;session-start 时连 pending 重放都跳过context-face 6h + host-cli 探测 7d + health 5s无(靠 pending 重放);peer_scope 降级 1 次;batch→逐条否(uri-guard deny 是设计意图)
codex / trae-cli各 hook catch→noopcontext-face 6h + 压缩器 runtime_failed(至下次启动)同上(无磁盘 pending,靠游标重发)
cursor/trae×2/zcodefetch 吞成 status:0,catch 返回空注入;锁 5s 拿不到则静默跳过context-face 6h(服务端整体不可达时无负缓存,每轮等满 15s)
opencode各路径 catch→WARN;event/dispose hook 无 try/catch(不可重试的 commit 失败会冒泡宿主)仅 context-face 6h;/health 无缓存(每轮一次往返)无同步重试;MCP 代理 401/403、400/404 各一次基本否(event/dispose 例外)
dshclient 全吞异常;ensureState 失败不缓存(服务端不可达时每 pre-step 两次 health 各 5s)context-face 6h + user-space 缓存进程内不过期无;pending 跨进程重放 3 次是(pre-step 串行 profile+recall;session/flush 阻塞)
pihealth 失败时 start() 提前返回,此后每 prompt 静默重试连接context-face 6h无;仅 pending queue部分(session_shutdown 被 await:takeover 近 0、非 takeover 最坏 30s;turn_end 网络异常时逐条各等 10s)
openclawclient 构造永不失败;health 吞异常;召回 500ms precheck 失败跳过无负缓存(每轮一次 500ms health 预检)无(单次 fetch);commit/afterTurn 的 Phase2 轮询否(memory_store 重抛例外;compact() 最长阻塞 5 分钟)
hermes_client=None 即运行期负缓存(本进程不再重试,除本地自启 waiter 外)无独立结构(_client=None 承担)trusted 补身份 1 次、sync 全新 client 1 次、多档降级;commit 失败不重试否(后台单 worker + 逐 provider try/except)
ov CLI多数 exit 1;ov status 表格模式始终退 0;ov health 即使 unhealthy 也退 0仅网关 401 挑战重试 1 次n/a(无宿主)

3.6.2 通用超时

通用 HTTP 15000ms(下限 1000);MCP 代理请求 15000ms、DELETE 固定 2000ms;跨进程锁等待 5s、陈旧 60s;pending .processing 陈旧回收 10min。需注意 MCP 代理未注册 SIGHUP(关终端不发 DELETE /mcp;但服务端 stateless_http=True,影响有限)。

3.7 附加 UX 对照

harnessstatuslineslash commandrule/skillsetup 向导其他
claude-code✅ 独立进程写 settings.json(段位丰富,1min TTL)/openviking-memory:ov(服务状态 + 身份 + 注入溯源)1 experience skill✅ 行式问答debug-recall/debug-capture 诊断脚本;uri-guard 不受插件开关门控
codex / trae-cli1 experience skillVERIFICATION.md 8 步 SOP
cursorrule(alwaysApply)+ skill❌(共用安装器 TUI)独立 uri-guard,不受插件开关控制
trae/trae-cn
zcode
opencode❌(有 toast)无(设计上不提供)
dsh1 个 openviking-memory 技能(独立的 ctx.skills provider)ctx.provide("openvikingMemory") 供其他 Cordis 插件二次开发
pictx.ui.setStatus/viking /viking commite2e-live.sh
openclaw✅ 5 个(/add-resource /add-skill /ov-search /ov-query-config /ov-recall-trace)3 skill 随插件分发✅(key 角色探测 + 版本兼容检查 + status 命令)Gateway HTTP 路由做 recall trace 可视化;feature-gate RPC;健康检查脚本
hermes✅ curses 多层菜单hermes memory status(含 env 覆盖列表);hermes backup 带 ovcli.conf
ov CLI❌(自身即命令)✅ TUI 向导完整 help 系统(63 条 curated);语言门禁;ov tui 全屏文件浏览器(含终端内图片预览)

4. Harness 档案卡

每卡都是检索入口,只写该 harness 的独有事实与差异,共享机制回链维度章。统一字段:形态 / 能力亮点 / 行为要点 / 配置 / 维度索引。

claude-code

  • 集成文档Claude Code 记忆插件
  • 形态:CC 插件(marketplace),采用四合一架构:9 hook + MCP 代理(15 工具透传)+ slash command + statusline + 1 experience skill。版本 0.4.4。
  • 能力亮点:hook 覆盖最全的 harness——SessionStart(120s) / UserPromptSubmit(60s) / PostToolUse:Read(5s,默认关的 skill-experience) / PreToolUse:Read|Glob|Grep(5s,uri-guard) / Stop(45s) / PreCompact(30s) / SessionEnd(30s) / SubagentStart(10s) / SubagentStop(45s);默认启用召回再摘要(本地 claude -p,本地不可用时自动回落服务端 rewrite,§3.2.5);支持 SubagentStart/Stop 的完整子会话隔离(§3.3.5);statusline + slash + uri-guard;关闭链路除 kill -9 外全部 commit(§3.3.3)。
  • 行为要点:session id 为 cc-<CC session_id 原文>,subagent 为 …__subagent-<agent_id>;Stop 阈值 commit 20000/keep 10,PreCompact 同步 commit;自动召回排除 resources(§3.2.1);增量游标存于 /tmp(被系统清理后,同一会话会整段重推)。
  • 配置:env + ovcli.conf plugin.claude_code + ov.conf claude_code§3.1.4),约 40 个旋钮;压缩器命令与模型固定为 claude/sonnet/low/30s。
  • 维度索引:工具面 §2.1 |召回 §3.2 |commit §3.3.2/§3.3.3 |压缩 §3.4 |降级 §3.6 |UX §3.7

codex

  • 集成文档Codex 记忆插件
  • 形态:Codex 插件(marketplace),4 hook(SessionStart 70s / UserPromptSubmit 130s / Stop 30s / PreCompact 60s)+ MCP 代理 + 1 experience skill。版本 0.7.5。
  • 能力亮点:本地召回压缩管线(codex exec§3.2.5);SessionStart 的 active-window 启发式 + idle-TTL 扫描,可自动回收历史会话中未归档的消息(§3.3.3)。
  • 行为要点:session id 为 cx-<safeId>(确定性推导,不读 state);关闭时无 hook(上游不提供 SessionEnd),commit 依赖下次启动的回收路径;不使用磁盘 pending queue(离线靠游标不推进、下一轮重发补偿,§3.3.4);active-window 120000ms / idle-TTL 1800000ms(env 配置);Stop 默认 detach(appended N turn(s) 提示默认不展示)。
  • 配置:env + ovcli.conf plugin.codex + ov.conf codex;hooks 同时发送 Bearer 与 X-API-Key 兼容头(§3.1.3)。
  • 维度索引:工具面 §2.1 |召回 §3.2 |commit §3.3.2/§3.3.3 |降级 §3.6

trae-cli(TraeCode CLI 2.0)

  • 集成文档TRAE 记忆集成
  • 形态:TraeCode CLI 2.0 是 Codex 系 CLI(binary traecli,用户配置 ~/.trae/traecli.toml,TUI 支持 /plugins /skills /mcp)。OpenViking 经 codex 插件别名安装接入:--harness trae-cli 复用 codex 安装流程,仅安装参数(binary / home / 配置路径)指向 TraeCode CLI。
  • 能力面:与 codex 完全一致——4 hook + MCP 代理 + experience skill、本地召回压缩、active-window/idle-TTL commit 回收、resume archive 注入等,详见 codex 档案卡。
  • 版本支持:仅支持 TraeCode CLI 2.0。1.0 与 2.0 不是同一套 CLI,2.0 才是 Codex 系、才能走 codex 插件别名安装;早期面向 1.0 的独立插件 examples/trae-cli-memory-hooks~/.trae/cli/hooks.json + [mcp_servers."openviking-memory"] 方案)已废弃。
  • 维度索引:同 codex 卡。

cursor

  • 集成文档Cursor 记忆集成
  • 形态:配置驱动(写 ~/.cursor/hooks.json+mcp.json)+ MCP 代理 + always-on rule + skill。7 hook:sessionStart(30s) / beforeSubmitPrompt(20s) / beforeReadFile(5s) / beforeShellExecution(5s) / stop(30s) / preCompact(30s) / sessionEnd(30s)。相对 import 共享 lib(不 vendoring)。
  • 能力亮点:beforeReadFile/beforeShellExecution 双 uri-guard(不受插件开关控制);rule + skill 随装。
  • 行为要点:session id 为 cu-<conversation_id>;stop 每 8 条消息 commit(commitTurnThreshold=8,消息条数计数,keep 0);sessionEnd 仅 window_close 触发,且此时宿主已销毁 shell-exec host,实践中不执行(§3.3.3)——结束在 <8 条消息水位的会话,尾部依赖后续同会话消息触发归档(§3.3.3);服务端不可达时,每轮等满 15s 召回超时。
  • 配置:仅 env(plugin 段不参与解析)。
  • 维度索引:工具面 §2.1 |召回 §3.2 |commit §3.3.2/§3.3.3 |降级 §3.6

trae / trae-cn(IDE 版)

  • 集成文档TRAE 记忆集成
  • 形态:配置驱动(~/.trae{,-cn}/hooks.json + 平台相关 mcp.json)+ MCP 代理。4 hook:SessionStart(30s) / UserPromptSubmit(20s) / PreToolUse:Read|Glob|Grep|Bash|RunCommand(5s) / Stop(30s)。相对 import 共享 lib。MCP server 名为 openviking
  • 能力亮点:行为最简单直接的一档——每个有内容的 Stop 都 commit(keep 0),关闭场景下最大待归档量只有最后一轮 in-flight(§3.3.3)。
  • 行为要点:trae 与 trae-cn 的差异是 session id 前缀 tr- / trcn- 与安装路径——同一份记忆在两个客户端落到两组不同 session,跨客户端共享靠服务端抽取后的记忆空间而非 session 复用;无 PreCompact/statusline/skill/subagent 处理。
  • 配置:仅 env。
  • 维度索引:工具面 §2.1 |召回 §3.2 |commit §3.3.2/§3.3.3

zcode

  • 集成文档社区插件 → ZCode
  • 形态:配置驱动(合并进 ~/.zcode/cli/config.json,强制 hooks.enabled=true)+ MCP 代理。4 hook:SessionStart(30s) / UserPromptSubmit(20s) / PreToolUse:Read|Glob|Grep(5s) / Stop(30s)。唯一全量 vendoring 18 个共享文件的 harness。版本 0.1.1。
  • 能力亮点:以 rollout 文件 ~/.zcode/cli/rollout/model-io-<sid>.jsonl 为增量真相源(lastTurnId 差集补齐漏掉的 Stop);Stop 默认 detach(Ctrl+C 不丢写入)。
  • 行为要点:每 Stop commit(keep 0);捕获路径仅剥离三类注入块(不做额外文本清洗,§3.2.6);首次捕获会一次性读取整个 rollout(长会话首装时单次推送量大)。
  • 配置:仅 env;OPENVIKING_WRITE_PATH_ASYNC 对 zcode 生效。
  • 维度索引:工具面 §2.1 |召回 §3.2 |commit §3.3.2/§3.3.3

opencode

  • 集成文档OpenCode 插件
  • 形态:npm 插件 @openviking/opencode-plugin,config hook 自注入 MCP 条目(工具带 openviking_ 前缀)。7 个 plugin hook:config / event / tool.execute.before / experimental.chat.system.transform / chat.message / experimental.session.compacting / dispose。版本 0.2.4。
  • 能力亮点dispose hook 覆盖全部四种常规关闭方式(宿主 ≥1.15.11);repo 列表进 system prompt(§3.2.3);宿主事件面最丰富(session.idle/compacted/deleted/error 各有语义)。
  • 行为要点commitTokenThreshold=20000(取正数,0 回落默认值);commit 超时 30000ms;一次宿主压缩 = 两次 commit;dispose 的 5s 宿主预算下,多会话慢 commit 可能被截断,且 pending queue 不覆盖此场景(§3.3.3);<1.15.11 无 dispose 时关闭不 commit;重启后不主动 flush 遗留会话;开场注入每会话尝试一次(§3.2.3);bypassSessionPatterns 的目录匹配在 opencode 上不适用(input 无 cwd)。
  • 配置openviking-config.json(4 级搜索)+ env。
  • 维度索引:工具面 §2.1 |召回 §3.2 |commit §3.3.2/§3.3.3 |subagent §3.3.5

dsh(DeepSeek Harness)

  • 形态:唯一同进程 Cordis 原生插件(export function apply),原生注册 7 个 viking_* 工具(viking_search/read/browse/remember/forget/add_resource/archive_expand),REST 直连。4 事件:agent/session-start(emit)/ agent/pre-step(waterfall)/ session/event / session/flush。版本 0.1.0。
  • 能力亮点ctx.provide("openvikingMemory") 供其他 Cordis 插件二次开发;pre-step 注入走 user 消息,适配 DSH persona 的 complete:true 渲染模式。
  • 行为要点:统一安装器已覆盖 dsh,会询问装到哪个 profile(默认 web,可用 --dsh-profile 指定);npm 是该插件唯一的分发渠道,因此 github/tos 选择对它不适用,除 dev 外的模式一律装已发布的包;dev 会先把 checkout 打包再装——dsh plugin 转发给 pnpm,link 一个源码目录无法解析插件 import 的 dsh peer;teardown commit 3s 无阈值,SIGHUP/二次 Ctrl+C 不触发(§3.3.3);compaction 不感知(注入内容随宿主压缩收缩,profile 不重投);subagent 各自独立会话(§3.3.5);工具面即服务端自身的 MCP 面,经与其他集成同一个 stdio 代理接入、以 mcp__openviking__* 发布,服务端升级即可增加工具而无需发版;代价是代理每个 profile 只起一个进程,因此工具调用带的是进程级 actor peer、remember 也不绑当前会话(召回/捕获/commit 仍按会话解析 peer);另随包附带共享的 openviking-memory 技能;uri-guard 匹配工具名不做大小写归一化。
  • 配置:cordis patch + 4 个 env;凭据 patch>env,行为开关 env>patch。
  • 维度索引:工具面 §1.1 |召回 §3.2 |commit §3.3.2/§3.3.3 |降级 §3.6

pi(pi Coding Agent Extension)

  • 集成文档pi Coding Agent 扩展
  • 形态:pi 原生扩展(目录装载,jiti 直译 TS),原生注册 7 个 viking_* 工具,REST 直连(pi 无 MCP 支持)。8 事件 + /viking 命令。版本 0.1.0。
  • 能力亮点:takeover 压缩接管(默认开,§3.4.2);两段式召回(before_agent_start 排队 + context 事件同步检索,当前轮 prompt 拿当前轮记忆);statusline;session_shutdown 在所有关闭方式下都触发且被 await。
  • 行为要点:默认 takeover 下退出不 commit(handler 持久化本地状态,归档靠下次续跑攒满阈值或 /viking commit§3.3.3);takeover 阈值 30000 token + 保留 3 轮(keep 3,服务端按消息条数解释);非 takeover 阈值 20000/keep 10、退出无条件 commit;工具注册需 health+ensureSession 前置(§1.1);viking_add_resource 仅 HTTP URL(guard 在服务端);非 takeover 模式下 pi -c 续跑会重新上报整条 branch。
  • 配置config.json 行为旋钮 + env(凭据统一走凭据链,§3.1.3);bypassPatterns 为前缀匹配(非 glob)。
  • 维度索引:工具面 §1.1 |召回 §3.2 |takeover §3.4.2 |commit §3.3.2/§3.3.3

openclaw

  • 集成文档OpenClaw 插件
  • 形态:唯一 context-engine 全接管型(ownsCompaction:true)。15 原生工具(默认开 14)+ 5 slash + 4 hook + Gateway HTTP 路由 + feature-gate RPC。remote-only。版本 2026.6.18。
  • 能力亮点:检索拆两个默认不重叠入口——memory_recall 默认搜 memory、ov_search 默认搜 resource+user skills(都可显式参数越界);add_skill 默认开;memory_forget memory-only 白名单(§3.5);三个 tool-result 工具读服务端外置输出(跨会话 guard);ContextEngine 全接管(§3.4.3);setup 向导带 key 角色探测与版本兼容检查。
  • 行为要点:召回走 /find 不带 session_id(expansion/去重台账不参与,长会话中同一记忆可能重复注入);关闭不触发 commit,归档依赖显式 /new//reset 与 ~50% 阈值(§3.3.3);无本地 pending queue(失败轮次不重放);compact() 最长阻塞 5 分钟;召回默认对每条 leaf 记忆多一次 read(recallPreferAbstract=false);配置严格校验,存在未知键/非法值时插件进入 setup-only 模式。
  • 配置openclaw.jsonplugins.entries.openviking.config + 少量 env;认证头 X-API-Key§3.1.3);commit 阈值由 commitTokenThresholdRatio 控制(默认 0.5);召回字符预算 4000。
  • 维度索引:工具面 §1.1 |召回 §3.2 |ContextEngine §3.4.3 |删除 §3.5 |commit §3.3.2/§3.3.3

hermes(Nous Research)

  • 集成文档Hermes Agent
  • 形态:Hermes bundled MemoryProvider(Python 单文件实现,共 3725 行,随 Hermes 一同发布)。通过 httpx 直连,无需额外安装插件。提供 6 工具及 10+ 生命周期 hook(prefetch/sync_turn/on_session_end/on_session_switch/on_memory_write/…)。基线为发行版 e12626b3(= brew 2026.7.7.2)。
  • 能力亮点:具备最全面的资源摄取面——viking_add_resource 支持 HTTP、Git、SSH、file://、本地文件 temp_upload 以及本地目录 zip 打包上传(跳过 symlink + 越界文件);viking_remember 直写记忆文件(不依赖 session commit/抽取);支持本地服务端自启(当 endpoint 位于本地且不可达时,通过 subprocess.Popen openviking-server 拉起);支持 trusted 补身份重试;无论正常退出还是接收到 Ctrl+C、SIGTERM、SIGHUP 信号,均能保证完成 commit(详见 §3.3.3)。
  • 行为要点:在召回上,仅有 search/search 的首选路径携带 session_id 并落到路径 B(mode="deep";而 auto/fast/find 且不带 session_id,详见 §3.2.2)。queue_prefetch 为同步实现,无预热;subagent 传入 skip_memory=True 时不接 OV(详见 §3.3.5)。无 profile 注入/statusline/slash;commit 恒 keep 0,drain 不净则本次不 commit;进程内队列不落盘。session id 格式为 %Y%m%d_%H%M%S_<hex6>。召回参数:6 条/阈值 0.15/字符预算 4000/总超时 4s。记忆 URI 为 viking://~/peers/{agent}/memories/{subdir}/mem_<uuid12>.md。退出机制包含 SIGTERM grace 1.5s 与退出看门狗 30s。互补路径支持 openviking-server ingest hermes(离线重放,默认关,详见 §7 E)。
  • 配置:通过 OPENVIKING_ENDPOINT(非 _URL)、8 个 OPENVIKING_RECALL_* env 以及 config.yaml 进行配置。在 use_ovcli_config 模式下,系统会清空 .env 里的对应变量。
  • 维度索引:工具面 §1.1 |召回 §3.2 |commit §3.3.2/§3.3.3 |删除 §3.5

ov CLI

  • 集成文档部署指南 → CLI
  • 形态:Rust 原生二进制,把服务端 REST 包成命令行;无宿主事件、无自动召回、不接管压缩。
  • 能力亮点:唯一会下发 auto_commit_policy 的第一方客户端(ov session new --auto-commit-policy-jsonov session config set);提供多 profile、admin、privacy、snapshot、TUI 等插件面没有的能力(详见 §5.3)。
  • 维度索引:完整命令参考请见 §5

5. ov CLI 命令参考

ov(clap 内部名 openviking)是 Rust HTTP 客户端,所有能力都在服务端,CLI 只做参数拼装、本地打包上传、输出渲染与多 profile 管理。它不是 harness 集成——没有宿主事件、不自动召回、不接管压缩;本章覆盖它作为"人/脚本直接使用 OV"的完整命令面,以及它独有于插件面的能力(TUI、多 profile、admin、--sudo、privacy、snapshot 等)。

版本说明:以 HEAD 源码为准(HEAD tag 已到 cli@0.4.14),0.4.10 等旧版本的差异处已标注。需要注意的是,ov doctor 不在 Rust 二进制里——pip 装的 Python wrapper 会拦截 argv[1]=="doctor" 并走 openviking_cli.doctor,读取的是服务端 ov.conf 而非 ovcli.conf;npm/cargo 装的纯 Rust ov 无该子命令。

5.1 命令树

命令 doc-comment 前缀 [Data]/[Interactive]/[Admin]/[Experimental] 等只影响 help 渲染,不影响运行时——即使是 [Experimental] 命令,默认也可用。

数据写入add-resource(支持本地文件/目录/URL/Git/sitemap/RSS;目标 --to/--parent/-p 三选一;manifest 模式 -m;Connector --add-type;注意本地路径 + watch>0 会报错)|add-skillwrite--content/--from-file 互斥)|mkdirrm(别名 del/delete,无确认提示,-r 显式递归)|mv(别名 rename)|set-tags(顶层隐藏,用 attrs set-tags)|add-memory(实验性;执行逻辑为建 session → 批量 add → commit 三步串行)

读取/检索ls(别名 list)|tree-L 默认 3)|statattrs getreadabstractoverview(分别对应 L2/L0/L1)|get(下载)|find(query 或 --image 至少一个非空;--image 支持本地路径、data URI、http、viking://)|search(实验性,比 find 多一个 --session-id)|grepglob

Skillsskills add(支持本地路径、git 及 GitHub tree URL,-s 选装、* 全装,有交互确认)|skills list/find/show/update/removeskills validate(唯一完全离线的命令)

会话/记忆session new--auto-commit-policy-json--no-auto-commit 互斥——唯一下发 policy 的第一方客户端)|session list/get/deletesession get-session-context--token-budget 默认 128000)|session get-session-archivesession add-message(s)session config set(改可变配置)|session commit

导入导出/快照exportbackupimportrestore(.ovpack)|snapshot commit/restore/show/log/diff/ignore-*(工作区快照,前向 commit 回滚)

隐私privacy categories/list/get/versions/version/activate/upsert--key-<name> 语法糖)

状态/可观测health(healthy=false 时仍退 0)|status(表格模式始终退 0)|observer {queue,vikingdb,models,retrieval,filesystem,system}waittask status/cancel/listtask watch {ls,show,rm,pause,resume,update,trigger}version(独立 3s 超时探服务端)

配置/交互config(TUI 向导,5 项菜单含 User Management)|config show(固定 json+compact 输出)|config validateconfig list/switch/add/edit/delete(面向 Agent,退出码 2-6 语义化)|config add ov-service(云)/config add customlanguage(别名 lang)|tui(全屏文件浏览器 + 终端内图片预览 + 向量视图 + 删除确认)|chat(VikingBot,300s 超时)|compile(用 Skill 整理素材,--wait 本地轮询)

管理(多为 ROOT/--sudoadmin create-account/list-accounts/delete-account/set-role/migrate/register-user/list-users/remove-user/regenerate-keysystem wait/status/health/consistencysystem crypto init-key(纯本地生成 32 字节 root key,权限 0600)|system backend sync-status/sync-retryreindex--mode 默认 vectors_only;--wait 默认 true,全 CLI 唯一)|doctor(仅 Python wrapper)

5.2 全局选项与独有机制

  • -o/--output table|json(默认取 conf output)|-c/--compact(默认 true)|--account/--user/--actor-peer-id--sudo(用 root_api_key,只允许 admin/system/reindex/task status/task list)|--profile(隐藏)
  • 多 profile:active 为 ~/.openviking/ovcli.conf,命名规范为 ovcli.conf.<name>switch 是字节复制(保留 plugin 段),而 add/edit 走 serde 重写(会丢弃 Rust Config 不识别的键,含 plugin 段,见 §3.1.4)。
  • 语言门禁:跑任何命令前要求先存显示语言(未存 + 非交互 → exit 2);HEAD 起 --help 在门禁前豁免(0.4.10 尚无此豁免),但 --version 仍需先过门禁。
  • 三种 JSON 输出格式(按命令组不同):普通命令 compact 下输出 {"ok":true,"result":…}-c false 输出裸 payload,失败输出 {"ok":false,"error":…};config 系为 {"status":"ok","result":…};带 profile 时追加 "profile":[…]。脚本解析时需注意;此外 echo_command 默认 true 且不受 -o json 抑制(stdout 第一行是 cmd: …)。
  • envOPENVIKING_CLI_CONFIG_FILEOPENVIKING_UPLOAD_MODE(local/shared)、OPENVIKING_ASSETS_CREDENTIALS_FILEOPENVIKING_LANG/LC_*/LANG,以及 chat 用的 VIKINGBOT_ENDPOINT/VIKINGBOT_API_KEY/OPENVIKING_URL

5.3 CLI 独有于插件面的能力

以下是插件面拿不到、只有 CLI/TUI 能做的:多 profile 切换与向导、admin 全套账号/用户管理、--sudo root 操作、privacy 隐私策略 CRUD + 版本、snapshot/backup/restore/export/import 数据搬运、reindex 重建索引、system crypto init-key 生成 root key、ov tui 交互浏览、依赖 VikingBot 能力的 ov chatov compile,以及 ov session config set 显式设 auto_commit_policy(唯一能开服务端自动 commit 的第一方入口)。


6. 自定义 agent 接入指南

如果你使用的 agent/harness 不在上面 11 家里,可以参考以下三条接入路径(按投入成本从低到高排列)。

6.1 接入路径 × 能获得的能力

路径投入agent 主动工具面自动召回/捕获 hook会话/commit压缩接管
通用 MCP 直连分钟级(填写一段 config 即可)✅ 15 工具全量❌ 由模型主动调用remember 建临时会话
② HTTP API / SDK / LangChain小时级(需写代码)自选(按需调 REST)自己实现自己实现(或用 LangChain middleware)
③ 复用 shared-core / Agent Plugins 便携包天级(需写 hook 适配)✅ 15 工具(经 MCP 代理)✅ 召回/捕获/commit/pending 全套视接入哪些事件而定

6.2 路径①:通用 MCP 直连(推荐起步)

任何支持 MCP 的 agent,只需在其 mcpServers 配置里指向服务端 /mcp(各客户端的具体配置位置见 MCP 客户端),即可立刻获得全部 15 个工具(§2.1)。最小配置如下:

json
{
  "mcpServers": {
    "openviking": {
      "url": "http://127.0.0.1:1933/mcp",
      "headers": {
        "Authorization": "Bearer <api_key>",
        "X-OpenViking-Account": "<account>",
        "X-OpenViking-User": "<user>",
        "X-OpenViking-Actor-Peer": "<workspace-peer>"
      }
    }
  }
}

后三个 header 可选,缺省时没有 workspace peer 隔离与租户路由。stdio-only 的客户端可用便携代理(路径③)把 stdio 桥到 streamable-HTTP。该路径得到的是纯工具面——无自动召回、无捕获、无 commit(除非模型主动调 remember)。

6.3 路径②:程序化接入

  • 直连 REST:召回用 POST /api/v1/search/search(必须 mode:"context" + session_id 才有 expansion/去重,§3.2.1;可传 rewrite 获得服务端 digest,§3.2.5);写入用 POST /api/v1/sessions/{id}/messages/batch(≤100 条/批,auto_create);提交用 POST /api/v1/sessions/{id}/commit;读取用 GET /api/v1/content/read 等。要用服务端自动 commit,需在 POST /api/v1/sessions 时显式带 auto_commit_policy,或通过 PATCH /{id}/config 修改(§2.3)。
  • LangChain / LangGraph SDKpip install langchain-openviking):OpenVikingContextMiddleware 提供 wrap_model_call(把召回内容注入 <openviking_context>)与 after_agent(捕获 + 按 CommitPolicy 提交,默认 never)。这是本组唯一带 session + token 预算的现成自动召回;容错是"只读方法重试一次、写方法不重试",部分成功时抛 OpenVikingPartialWriteError(可按 input_messages_consumed 切片重试)。参考 §7 B。
  • Open WebUI(OpenAPI 工具服务器):python -m openviking_openwebui 起独立进程,在 Open WebUI 里添加 Tool Server URL,即可得 7 个工具(无删除、无 hook)。参考 §7 A。

6.4 路径③:要自动 hook 面时复用参考实现

如果希望实现召回、捕获、commit、pending 的全套自动化,完全不必从零开始编写。建议直接参考并复用以下两个现成的实现:

  • examples/memory-plugin-shared/lib/(Node):包含完整的核心功能模块,例如 recall-core(三级降级召回)、profile-injectcapture-utils(消息归一 + 注入回流防护)、pending-queue(离线重放)、batch-sendmcp-proxy-core(stdio↔HTTP 代理)、session-model(会话 id 派生)以及 credentials。构建瘦 harness 时,只需实现一个适配层,把宿主生命周期事件映射到这些模块即可(例如 agent-hook-runtime.mjs 就是 cursor、trae、zcode 共用的现成一体化运行时,接新宿主时的主要工作只是解析其 stdin JSON 字段名)。
  • Agent Plugins 1.0 便携包(位于 agent-plugins/):采用 plugin.json + skills/ + mcp.json(stdio→HTTP 代理)的规范化便携格式。该方案刻意不含 hooks(召回/沉淀靠 skill 教模型自调工具),非常适合符合 Agent Plugins 规范的客户端直接加载;此外,plugin.test.mjs 定义了规范一致性校验(schema URL、name 规则、静态 headers 不含机密、mcp.json 引用不逃逸插件根等),可作为自行打包的 lint 依据。

接入时务必对齐的三个约定(与现有 harness 保持一致的行为):① 召回调用点必须转发 session_id,这样才有服务端 expansion + 跨轮去重(详见 §3.2.1);② 适配器不要用自己的超时压过 helper 下发的 deadline;③ 关闭时要安排一条 commit 路径,否则未达阈值的尾部对话需等待后续触发才能归档(详见 §3.3.3)——若宿主不提供关闭事件,可依赖服务端 idle 兜底(在服务端开 memory.session_auto_commit.idle_enabled 并下发 per-session policy)。这三条正是 recall-session-wiring.test.mjs 用跨插件正则钉死的。


7. 附录:非 coding 集成速览

集成形态工具面会话/commit容错默认状态
A. Open WebUI独立的 FastAPI OpenAPI 工具服务器7 个本地 OpenAPI 路由(ov_search/ov_recall_memories/ov_add_memory/ov_list_memories/ov_read_resource/ov_add_resource/ov_session_status),无删除工具无会话概念最薄:裸 httpx,无 retry/负缓存;/health 仅回显配置,不探测 OV进程不启动即不存在
B. LangChain/LangGraphPython SDK 适配层(retriever/tools/store/middleware/recorder)create_openviking_tools() 提供 12 个 StructuredTool(viking_forget 默认不在 agent profile 中)thread_id/session_id 由调用方给;CommitPolicy 默认 never本组最稳:只读方法自动重试 1 次、写方法不重试(防重复)、部分成功抛结构化异常可切片重试需全部显式构造才生效
C. Agent Plugins 1.0便携包 plugin.json + skills/ + mcp.json(stdio→HTTP 代理)MCP 透传 15 工具;刻意无 hooks(召回靠 skill 教模型)remember 建临时会话MCP 代理层重试(401/403 换凭据、400/404 重初始化各 1 次)客户端加载后工具即用
D. 通用 MCP 直连零本地组件,直连 /mcp同 C(15 工具)同 C由客户端自定/mcp 常驻
E. log ingestionopenviking-server ingest CLI(跑在日志所在机器,反向导入)无(只写不召回)会话 id {prefix}__{harness}__{sanitized native id};commit token 6000/idle 5s/keep 0唯一有崩溃恢复:SQLite 游标库 + 单实例锁 + reconcile 判定批次落地双重默认关(ingest.enabled + 每 harness enabled 都 false);支持 claude_code/codex/hermes/opencode/openclaw/cursor 适配器
F. OpenViking Helper闭源桌面 App不在本文代码基线内

各集成的安装、配置与排障以对应的单独集成页面为准;当本页与单独页面不一致时,以单独页面为准。

参见

Released under the Apache-2.0 License.