客户端配置字段
ovcli.conf 是 ov CLI 的客户端配置文件,用于保存服务端连接、鉴权身份和命令默认行为。
采用共享配置加载器的 Agent 插件还会读取本文件的 plugin 段、工作区配置和 OPENVIKING_* 环境变量,控制召回、对话捕获和调试。下文分别说明 CLI 与插件的配置;各宿主的支持范围见 Agent 集成。
使用 ov config 管理 CLI 连接,使用 ov config show 查看脱敏后的当前配置。编辑或重命名配置时,CLI 会保留 plugin 等额外顶层字段。切换配置时,新配置显式包含的字段优先;若未包含 plugin,则保留 active 文件已有的插件配置。
默认路径:
~/.openviking/ovcli.conf也可以指定其他文件:
export OPENVIKING_CLI_CONFIG_FILE=/path/to/ovcli.conf完整示例
{
"url": "https://openviking.example.com",
"api_key": "<user-or-admin-key>",
"root_api_key": "<root-key>",
"actor_peer_id": "agent:research-assistant",
"timeout": 60,
"output": "table",
"echo_command": true,
"show_progress": false,
"verbose": false,
"profile": false,
"upload": {
"ignore_dirs": "node_modules,.cache,dist",
"include": "*.md,*.pdf",
"exclude": "*.tmp,*.log"
},
"extra_headers": {
"X-Tenant": "acme"
},
"gateway_token": "<gateway-token>"
}示例用于 API key 模式,不需要的字段可以省略。本地 dev 模式通常只需要 url。trusted 部署按认证指南另配 account、user 和对应凭据;API key 模式下,服务端按 key 确定身份,忽略这两个字段。
连接与鉴权
{
"url": "https://openviking.example.com",
"api_key": "<user-or-admin-key>",
"root_api_key": "<root-key>",
"actor_peer_id": "agent:research-assistant",
"extra_headers": {
"X-Tenant": "acme"
},
"gateway_token": "<gateway-token>"
}| 字段 | 类型 / 可选值 | 默认值 | 作用 |
|---|---|---|---|
url | HTTP(S) URL | http://127.0.0.1:1933 | OpenViking 服务端地址 |
api_key | string / null | null | 普通数据操作使用的 user/admin key |
root_api_key | string / null | null | ov --sudo 管理操作使用的 root key |
account | string / null | null | trusted 部署使用的账号身份 |
user | string / null | null | trusted 部署使用的用户身份 |
actor_peer_id | string / null | null | 默认 Actor Peer 标识 |
agent_id | string / null | null | 兼容字段;新配置使用 actor_peer_id,两者不能同时设置 |
extra_headers | object / null | null | 每个 HTTP 请求附加的自定义请求头;extra_header 是兼容别名 |
gateway_token | string / null | null | 网关挑战重试时使用的 X-Gateway-Token |
API Key 选择
| 配置方式 | 普通命令 | ov --sudo |
|---|---|---|
仅 api_key | 使用 user/admin key | 不可用 |
仅 root_api_key,并配置 account、user | trusted 模式使用 root key 和显式身份;api_key 模式禁止访问租户数据 | 使用 root key |
| 同时配置两种 key | 使用 api_key | 使用 root_api_key |
| 两种 key 都不配置 | 仅适用于未开启鉴权的本地服务 | 不可用 |
ov.conf 中的 server.root_api_key 是服务端接受的凭证;CLI 管理该服务端时,ovcli.conf 中的 root_api_key 需要与其一致。
命令行为
{
"timeout": 120,
"echo_command": true,
"show_progress": true,
"verbose": false,
"profile": false
}| 字段 | 类型 / 可选值 | 默认值 | 作用 |
|---|---|---|---|
timeout | number,秒,> 0 | 60 | HTTP 请求超时 |
echo_command | boolean | true | 是否显示 find、search、ls 等命令的实际请求参数 |
show_progress | boolean | false | 上传时是否默认显示进度 |
verbose | boolean | false | 上传时是否默认输出诊断信息 |
profile | boolean | false | 是否请求性能 profile;服务端还需启用 server.profile_enabled |
output | "table" / "json" | "table" | 默认输出格式;当前命令的 -o table 或 -o json 会覆盖它 |
--profile、--progress、--no-progress、--verbose 等命令行参数会覆盖本次命令的配置。
上传过滤
{
"upload": {
"ignore_dirs": "node_modules,.cache,dist",
"include": "*.md,*.pdf",
"exclude": "*.tmp,*.log"
}
}| 字段 | 类型 / 格式 | 默认值 | 作用 |
|---|---|---|---|
upload.ignore_dirs | 逗号分隔字符串 / null | null | 忽略的目录名 |
upload.include | 逗号分隔 glob / null | null | 只上传匹配的文件 |
upload.exclude | 逗号分隔 glob / null | null | 排除匹配的文件 |
本地目录上传还会遵循 .gitignore。命令行 --include、--exclude 会与配置文件中的规则合并。
插件配置
记忆插件的配置写在 plugin 段下。直接挂在它下面的键作为采用共享加载器的插件默认值;以 harness 命名的嵌套对象(如 claude_code、codex 或 opencode)只覆盖那一个。
{
"url": "https://openviking.example.com",
"api_key": "<user 或 admin key>",
"plugin": {
"recallCompress": "off",
"bypassSessionPatterns": ["/tmp/**", "**/scratch/**"],
"claude_code": {
"captureAssistantTurns": false
}
}
}许多配置项都有对应的 OPENVIKING_* 环境变量,例如 OPENVIKING_RECALL_LIMIT 对应 recallLimit,OPENVIKING_CAPTURE_ASSISTANT_TURNS 对应 captureAssistantTurns。OPENVIKING_BYPASS_SESSION 也有文件配置项 plugin.bypassSession;仅需覆盖当前进程时可使用环境变量。完整共享列表由 examples/memory-plugin-shared/lib/config-schema.mjs 定义。用法见插件 README:Claude Code、Codex。取列表值的配置项(bypassSessionPatterns、recallQueryFilters、captureFilters)在这里是 JSON 数组,而它们的环境变量对应物是逗号分隔的字符串,所以值里带字面逗号的只能写进数组。
优先级从高到低:环境变量 → 工作区各层 → plugin.<harness> → plugin → ov.conf 里遗留的按 harness 分块 → 内置默认值。独立启动的 hook 进程在每次触发时重新读文件;常驻插件何时重载取决于宿主,不确定时重启 Agent。环境变量改动也需要重启,因为 hook 继承的是 Agent 进程的环境。
采用共享配置加载器的记忆插件会读取这一段;各宿主支持的字段和默认值见对应的 集成文档。ov-memory-doctor 会打印它解析到的结果,并对不认识的键给出告警和最接近的正确键名。
工作区配置
仓库可以自带插件配置,这样项目的记忆行为跟着代码走,而不是散落在每位协作者的 home 目录里。工作区根目录下有两个文件,另有一层按机器保存:
<repo-root>/.openviking/config.json # 提交到仓库,团队共享
<repo-root>/.openviking/config.local.json # 私有,不提交
~/.openviking/workspaces/<slot>.json # 本机注册表,每个工作区一个文件工作区根目录是向上查找时最先遇到的、包含 .git 或包含 .openviking/config.json(或 config.local.json)的目录;$HOME 和文件系统根目录永远不会被当作工作区根。两者都没有的目录不是工作区:没有配置层,没有注册表条目,也没有属于自己的 peer。注册表的槽位名由根目录名加上完整路径的哈希组成,因此同一台机器上同一仓库的两个 clone 不会共用同一条记录。这些层由采用共享配置加载器的记忆插件读取,ov 命令不读取。
优先级
从高到低:
| 层 | 生效范围 |
|---|---|
OPENVIKING_* 环境变量 | 当前进程 |
~/.openviking/workspaces/<slot>.json | 本机的这个工作区 |
<repo-root>/.openviking/config.local.json | 本地这份 checkout,私有 |
<repo-root>/.openviking/config.json | 整个仓库,随代码提交 |
ovcli.conf plugin.<harness> | 本机的单个 harness |
ovcli.conf plugin | 本机的所有 harness |
ov.conf harness 段 | 旧部署的兼容层 |
| 内置默认值 |
标量由高优先级的层直接覆盖低优先级的层;列表在各层之间取并集,首元素为 "!reset" 时会丢弃低层贡献的全部条目,即 ["!reset", "*/scratch/*"] 就是最终列表。
注册表文件没有任何命令会写入。按 ov-memory-doctor 打印的路径手工创建即可,写上 version: 1,schema 与工作区文件相同。
Schema
必须写 version: 1。声明其他版本的文件会被跳过并给出警告,而不是按猜测解析。
{
"version": 1,
"peer": { "source": "git" },
"recall": { "peer_scope": "actor", "max_items": 20 },
"capture": { "commit_token_threshold": 20000 },
"labels": { "team": "search" }
}| 键 | 类型 / 可选值 | 作用 |
|---|---|---|
peer.source | "git" / "cwd" / "none" / 模板 / 模板列表 | 工作区 peer 的推导方式;默认只有 git 仓库才会有 peer |
peer.id | string | 直接指定 peer,优先于 peer.source |
recall.enabled | boolean | 是否启用 Recall |
recall.peer_scope | "all" / "actor" | all 会额外扫描该用户的其他 peer 并对命中降分;actor 只读用户级记忆和本工作区的 peer |
recall.dedup_turns | integer,0–20 | 与最近多少轮对话去重 |
recall.max_items | integer,1–100 | Recall 结果条数上限 |
recall.score_threshold | number,0–1 | Recall 结果的最低分数 |
capture.enabled | boolean | 是否启用 Capture |
capture.commit_token_threshold | integer,1000–1000000 | 累计多少 token 后提交一次 Capture |
bypass.session_patterns | glob 列表 | 会话 id 或工作目录命中时跳过 Recall 与 Capture |
usage.view / usage.output | string | Codex OV-Usage 来源摘要:summary / expanded / off,以及 auto / terminal / desktop |
labels | object | 给人看的自由元数据,插件不读取 |
超出范围的数值会被夹到最近的边界并给出提示;无法识别的枚举值会被忽略。表格列出常用字段;完整字段由共享 config-schema.mjs 定义,未识别的键不会生效。
工作区 peer
peer 是用户空间下的一段路径前缀——viking://user/<you>/peers/<peer>/memories——把一个项目的记忆归拢在一起。默认只有 git 仓库会有 peer:优先用归一化后的 origin URL,其次是仓库根路径。不在 git 仓库中的目录不发送任何 peer,在那里记下的内容进入用户级空间 viking://user/<you>/memories。这样,每个任务新建临时目录的应用就不会为每个目录创建一个空 peer。
规则由 peer.source 决定。同一项配置在环境变量中写作 OPENVIKING_PEER_SOURCE,在 ovcli.conf 中写作 plugin.peerSource 或 plugin.<harness>.peerSource。
远端身份只取 origin,不回退到 upstream,避免添加 upstream 时悄悄改变记忆空间。也不使用 root-commit SHA:Fork 共享祖先,浅克隆或新拉取的历史又会改变可见的根提交。Git 仓库没有 origin 时使用仓库根路径。需要多个仓库共享记忆,或希望移动目录后身份不变时,应显式配置 peer.id。非 Git 目录默认仍不派生 peer。
让一个目录拥有独立记忆
在该目录下创建 .openviking/config.json:
{"version": 1, "peer": {"id": "my-project"}}没有更高优先级的 peer 设置或嵌套工作区覆盖时,插件在这个目录及其子目录中捕获的记忆会写入 peer my-project,无论它是否为 Git 仓库。这个 id 不含路径,因此目录移动、改名、换一台机器都不会变;连接同一服务端、使用同一账户和用户的两个目录,写同一个 peer id 就共享同一记忆范围,这正是合并它们的方式。
其余写法,优先级从高到低:
| 写在哪 | 作用 |
|---|---|
OPENVIKING_PEER_ID=my-project | 为单个进程指定 peer;凭据固定从 ovcli.conf 读取时忽略此变量,宿主显式指定的 peer 优先 |
.openviking/config.json 的 peer.id | 指定本工作区的 peer。推荐做法;config.local.json 是同一个键,只是不提交 |
同一文件的 peer.source | 不直接指定,而是推导——"cwd" 用目录路径,"team-{dir}" 用模板 |
ovcli.conf 的 plugin.peerSource,或 OPENVIKING_PEER_SOURCE | 对本机所有目录生效;"cwd" 可整体恢复 git 默认之前的行为 |
peer.source | 含义 |
|---|---|
"git" | 默认值。优先用归一化后的 origin URL,其次是仓库根路径,等价于 ["{git_remote}", "{git_root}"];不在仓库中则什么都不发送,也不添加任何前缀 |
"cwd" | 把工作目录中所有非字母数字字符替换成 -,与旧版本发送的值逐字节一致 |
"none" | 完全不发送 peer;OPENVIKING_WORKSPACE_PEER=0 含义相同 |
| 模板 / 模板列表 | 例如 "git-{git_remote}" 或 ["{git_remote}", "team-{dir}"];按顺序尝试,某个模板的变量为空时落到下一个 |
| 变量 | 取值 | 何时为空 |
|---|---|---|
{git_remote} | 归一化后的 origin,形如 github.com-org-repo | 不在 git 仓库中,或仓库没有 origin |
{git_root} | 仓库根路径,所有非字母数字字符替换成 - | 不在 git 仓库中。仓库内某个子目录放了 .openviking/config.json 时,它仍然是仓库自己的根,因此标记子目录不会拆散默认 peer |
{cwd} | 工作目录,所有非字母数字字符替换成 - | 从不为空——它也不在任何默认链里,裸路径只有在你明确要求时才会成为 peer |
{dir} | 工作区根目录的目录名:仓库根,或放着 .openviking/config.json 的那个目录 | 该目录不是工作区 |
{harness} | 当前 agent 的名字(claude-code、codex、dsh、opencode、pi、cursor、trae、trae-cn、zcode) | 从不为空——但 MCP proxy 不参与推导,所以只走 proxy 的读路径解析不出它 |
在 /Users/x/Dev/OpenViking/examples/codex-memory-plugin 目录下、origin 为 git@github.com:volcengine/OpenViking.git 时,peer 是 github.com-volcengine-openviking——无论从哪个子目录、哪个 worktree、哪台机器、哪份 clone 得到的都是同一个值。因此同一仓库的所有 clone 共享一个 peer,而 fork 的 origin 不同,默认就是独立的 peer。推导过程直接读取仓库文件而不调用 git,因此 PATH 中没有 git 时同样可用;URL 会先归一化,使同一仓库的 ssh 与 https 写法收敛到同一个值,URL 中内嵌的 token 也不会进入 peer id。
按场景选择
| 场景 | 怎么做 |
|---|---|
有 origin 的仓库 | 什么都不用做。所有 clone、worktree、子目录共用一个 peer |
| Fork | origin 不同,默认与上游分开。要合并两边的记忆,就在两边写同一个 peer.id |
| 没有 remote 的本地仓库 | 默认用仓库根路径,换台机器就会变。长期项目建议写一个 peer.id |
| 长期使用但不是仓库的目录 | 创建 .openviking/config.json,写上 peer.id |
| monorepo 里某个子项目要单独记忆 | 在子目录放 config.json,写 peer.source: "{git_remote}-{dir}"。只放标记文件仍会沿用仓库 peer,因为 {git_remote} 先解析成功 |
| 一次性任务目录(应用按日期新建的目录、临时解包目录) | 什么都不用做,记忆进入用户级空间 |
| 同一仓库下各个 agent 想各存各的 | peer.source: "{git_remote}-{harness}"。需要显式设置;默认按项目共享,不区分 Agent |
| 几个目录共享一份记忆 | 各处写同一个 peer.id |
| 不想按项目区分 | peer.source: "none"(等同于 OPENVIKING_WORKSPACE_PEER=0) |
召回隔离
peer.source 决定记忆写到哪里,recall.peer_scope 决定读回什么。peer 是路径前缀,不是租户边界。同一项配置在 ovcli.conf 中写作 plugin.recallPeerScope,环境变量为 OPENVIKING_RECALL_PEER_SCOPE。
recall.peer_scope | 召回读什么 |
|---|---|
"all"(默认) | 用户级记忆与本工作区 peer 全权重参与,再对该用户的其他 peer 做一次扫描,命中结果按类别降分——服务端 other_peer_penalty 默认对 events、entities 为 0.1,对 preferences、experiences、resources、skills 为 0.02。扣分会降低其他项目内容的排序,但不会保证它们始终排在最后 |
"actor" | 只看用户级记忆和本工作区的 peer。插件会额外查询一次此处按 git 默认之前的规则推导出的 peer,因此旧版本写下的内容不会丢 |
两档之下用户级记忆都是全权重,这也是"不在仓库中就不发 peer"的代价:一次性任务里学到的东西,之后在每个项目里都会参与召回。要把这类目录后续产生的记忆分开存放,给它设置独立的 peer.id,并用 "actor" 限制跨 peer 召回。"actor" 仍会读取已有的用户级记忆;它不会把这些记忆重新归属或隐藏。
切换到 git 默认值不需要迁移,也不会搬动任何数据:写在旧的 cwd 派生 peer 下的记忆原地不动,召回仍然读得到——"all" 下靠跨 peer 扫描,"actor" 下靠那次额外查询。peer_scope 是逐请求参数;服务端版本过旧、不认识它时,插件会记录一次降级并告警,而不是静默地读取全部。
工作区文件不能设置的内容
hook 是非交互进程,因此这些文件不经确认即被信任;被拒绝的是结构性的内容:
- 连接与凭证类的键——
url、api_key、root_api_key、account、user、extra_headers等——无论出现在哪一层都会被剥离并给出警告。“数据发往哪个服务端”这个问题始终只看ovcli.conf和环境变量就能回答。 - 这些文件中不会展开
${VAR}。
提交到仓库的文件关掉了什么,采用提示而不是拦截的方式:插件的 ov-memory-doctor 会列出每一项工作区级配置的值、来源层,以及它覆盖掉的内容。
.gitignore 不能忽略整个 .openviking/,否则 config.json 永远无法提交。请把规则收窄到解析器的临时目录和私有文件:
.openviking/media/
.openviking/downloads/
.openviking/config.local.json存在整目录忽略规则时,ov-memory-doctor 会给出警告。
相关环境变量
ov CLI 直接使用的环境变量只有少量几个:
| 环境变量 | 作用 |
|---|---|
OPENVIKING_CLI_CONFIG_FILE | 指定要读取的 ovcli.conf 路径 |
OPENVIKING_UPLOAD_MODE | 指定临时上传模式:local 或 shared |
ov config add 和 ov config edit 的 --api-key-env <变量名>、--root-api-key-env <变量名> 可以从指定环境变量读取密钥,并写入配置文件。
Agent 插件读取 OPENVIKING_AUTO_RECALL、OPENVIKING_RECALL_LIMIT、OPENVIKING_AUTO_CAPTURE、OPENVIKING_DEBUG 等环境变量。不要把环境变量名直接写成 JSON 键;支持的文件配置使用 plugin 段中的对应字段。
多服务配置
普通 ov 命令以及 ov config show、ov config validate 按以下顺序解析实际配置:
- 设置
OPENVIKING_CLI_CONFIG_FILE后,该路径具有最高优先级;文件不存在时会直接报错。 - 未设置该变量时,使用默认 Active 文件:
~/.openviking/ovcli.conf交互式管理器以及 ov config list、switch、add、edit、delete 使用相同的实际配置路径。命名配置与 Active 文件位于同一目录;未设置覆盖路径时为:
~/.openviking/ovcli.conf.<name>例如,一份生产环境配置可以写成:
{
"url": "https://openviking.example.com",
"api_key": "<production-api-key>",
"timeout": 120
}常用命令:
ov config
ov config list
ov config switch <name>
ov config validate
ov config showov config switch <name> 会把命名配置复制到实际 Active 文件,包括 OPENVIKING_CLI_CONFIG_FILE 指定的路径。这会覆盖所选文件;如果要切换默认的 ~/.openviking/ovcli.conf,请先取消该环境变量。直接选中的 ovcli.conf.<name> 会显示为当前配置,即使另一个配置的内容完全相同;选中期间不能删除或重命名该文件。新的 ov 命令会重新读取实际配置文件;已经运行的 Agent 客户端需要重启后才会读取变更。
交互式配置和 Agent 辅助配置步骤见OpenViking CLI 配置指南。