$DSH_HOME/config.yaml was an implicit composition layer: if the file existed, every launch applied an arbitrary Loader patch graph over the shipped tree, kept live by a dedicated HMR watcher. Three costs came from the implicitness, not the capability. A patch replaces its target row's whole config, so a file written months ago pins that row to the field set it knew and every default the shipped tree later adds silently stops applying. It competed with the typed settings namespaces llm-deepseek and llm-pi-ai already register, so which one wins was a function of layer order rather than meaning. And the explicit escape hatch it was supposedly redundant with did not exist on every surface: dsh -p, dsh meta, and dsh upgrade all rejected --config, so for them the implicit file was the only composition route at all. Complete the explicit layer first: --config and --config-replace now work on every booting surface. A headless --config-replace tree must still mount a webserver row, because that surface reaches its own agent over the same HTTP gateway the browser uses; AppCLIEntry names that contract in the failure instead of reporting a bare missing service. Then delete the implicit one. PERSONAL_CONFIG_FILENAME, loadPersonalPatches, watchPersonalPatches, and the config-only HMR row mounted for it are gone; a file left at that path is inert, and --dump-config no longer reads the Harness home. --config therefore stops *replacing* the personal overlay and simply *is* the user overlay. No migration: a user who wants the old behavior names the same file (dsh --config ~/.dsh/config.yaml), which a shell alias makes permanent.
3.2 KiB
配置文件
English | 中文
Harness 使用 cordis.yml 描述 Agent 加载哪些插件以及每个插件的参数。配置文件负责组合能力;每个包真正支持的字段和默认值由源码生成的配置目录负责记录,避免两份手写表格逐渐不一致。
从真实配置开始
仓库中的示例就是可以运行的配置,也是新项目最可靠的起点:
- 共享的
dshbase 叠加tui.cordis.ymloverlay,组合 DeepSeek 模型、Bash、文件系统、压缩、子代理、工作流和交互式 TUI。 - headless-agent 以单次任务形式暴露 coding 组装。
- acp-agent 向程序化 ACP(Agent Client Protocol)客户端提供全新会话。
最小配置由一组插件条目组成:
- id: llm-deepseek
name: '@deepseek-ai/dsh-llm-deepseek'
config:
apiKey: !!js process.env.DEEPSEEK_API_KEY
models:
- deepseek-v4-flash
- id: bash
name: '@deepseek-ai/dsh-bash-local'
- id: agent-loop
name: '@deepseek-ai/dsh-agent-loop'
config:
agents:
- id: main
provider: deepseek-official
model: deepseek-v4-flash
插件条目
name 指定 npm 包或相对于 cordis.yml 的本地模块,id 为插件实例提供稳定标识,config 传入插件自己的配置。需要临时跳过某个条目时可设置 disabled: true。
- id: local-tool
name: './src/my-tool.ts'
disabled: false
config:
toolName: my_tool
插件按文件中的顺序加载。依赖其他服务的插件应该排在提供这些服务的应用或能力插件之后;引用不存在的模型、工具或插件会尽早报错,而不是被静默忽略。
CLI 覆盖层
TUI 先组合 base.cordis.yml 与 tui.cordis.yml,再应用可选的 dsh --config <path> 覆盖。dsh --config-replace <path> 则把指定文件作为完整配置树启动,不使用任何已交付层。每个会启动的界面都接受这两个标志,包括 dsh -p、dsh web、dsh meta 和 dsh upgrade——因为点名一个文件是组合自己配置树的唯一途径。
补丁会替换目标行的整个 config 值,而不是深度合并各个键。例如,只用 config: { thinking: disabled } 修补 llm-deepseek,也会移除该行原有的 apiKey 与 baseURL;因此必须重新写出该行需要保留的全部键。
JavaScript 值和环境变量
Cordis loader 使用 !!js 标签读取运行时表达式。API key 等凭据应放在仓库根目录、已被 Git 忽略的 .env 中,不能提交到配置文件。
config:
apiKey: !!js process.env.DEEPSEEK_API_KEY
cwd: !!js process.cwd()
标签是 !!js,不是 !js。
精确配置参考
每个插件当前支持的字段、类型和默认值见自动生成的插件配置目录。理解插件如何组合可继续阅读架构说明和能力接口;要创建自己的配置,优先复制并修改示例目录说明中最接近的例子。