mirror of
https://github.com/deepseek-ai/deepseek-harness.git
synced 2026-08-29 04:26:38 +00:00
Merge remote-tracking branch 'origin/master' into claude/docs-model-providers
# Conflicts: # docs/user/guide/quickstart.i18n.yaml
This commit is contained in:
@@ -2,5 +2,5 @@
|
||||
# side as of the last confirmed-consistent state. Both languages carry equal authority;
|
||||
# after editing either side, bring the other along and re-record with:
|
||||
# pnpm run verify-translation-pairing --write docs/user/develop/basic/config.md
|
||||
config.md: 11a2311464789f74537cc7c4435f83ec07ca26fd
|
||||
config.zh.md: 4e827ecafa6bfaf87c3e3f118425e656e1254787
|
||||
config.md: 02998c32415b5ba7acf82700034cabc1f7314f33
|
||||
config.zh.md: 42af432b36d8f82871aa7d7b6a3a2eaf7427cdae
|
||||
|
||||
@@ -101,5 +101,6 @@ A configuration edit hot-replaces the plugin: the framework unloads the old inst
|
||||
|
||||
## Next steps
|
||||
|
||||
- [Package and install a plugin](./publish.md) — ship the plugin as an installable package
|
||||
- [Plugins and lifecycle](../framework/) — understand the full plugin lifecycle
|
||||
- [Services and dependencies](../framework/service.md) — provide a service to other plugins
|
||||
|
||||
@@ -101,5 +101,6 @@ export interface Config {
|
||||
|
||||
## 下一步
|
||||
|
||||
- [打包与安装插件](./publish.md) — 把插件以可安装包的形式交付
|
||||
- [插件与生命周期](../framework/) — 深入了解插件的完整生命周期
|
||||
- [服务与依赖](../framework/service.md) — 让你的插件对外提供服务
|
||||
|
||||
@@ -2,5 +2,5 @@
|
||||
# side as of the last confirmed-consistent state. Both languages carry equal authority;
|
||||
# after editing either side, bring the other along and re-record with:
|
||||
# pnpm run verify-translation-pairing --write docs/user/develop/basic/index.md
|
||||
index.md: 45c8dfe495cd99da46a7b259b407af8deff570b3
|
||||
index.zh.md: 9d8ee47e6f07fb4a897f49487cb7327904573c1b
|
||||
index.md: efedb07c8d757ef1f90d99fe1bf503a35c0f1a37
|
||||
index.zh.md: 2293a6086dc80fa77c88ef734ae17576ea513a10
|
||||
|
||||
@@ -56,7 +56,7 @@ Create `scratch-plugin/cordis.yml` as a Web overlay that inserts the local plugi
|
||||
Start the Web UI with that overlay:
|
||||
|
||||
```sh
|
||||
pnpm run dsh web --config ./scratch-plugin/cordis.yml
|
||||
pnpm run dsh web --patch ./scratch-plugin/cordis.yml
|
||||
```
|
||||
|
||||
Open `http://127.0.0.1:3080`. The terminal prints `[hello-plugin] plugin loaded!` during startup.
|
||||
|
||||
@@ -56,7 +56,7 @@ export function apply(ctx: Context) {
|
||||
使用该覆盖层启动 Web UI:
|
||||
|
||||
```sh
|
||||
pnpm run dsh web --config ./scratch-plugin/cordis.yml
|
||||
pnpm run dsh web --patch ./scratch-plugin/cordis.yml
|
||||
```
|
||||
|
||||
打开 `http://127.0.0.1:3080`。启动期间,终端会打印 `[hello-plugin] plugin loaded!`。
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
# Bilingual-pair consistency record (docs/i18n/README.md): the git blob hash of each
|
||||
# side as of the last confirmed-consistent state. Both languages carry equal authority;
|
||||
# after editing either side, bring the other along and re-record with:
|
||||
# pnpm run verify-translation-pairing --write docs/user/develop/basic/publish.md
|
||||
publish.md: 1d1179a78c4d3a7e9e7055e3f5ee41381e28147e
|
||||
publish.zh.md: 26d1c2b737a3498bce0757d5b2d14e254fc13527
|
||||
@@ -0,0 +1,140 @@
|
||||
# Package and install a plugin
|
||||
|
||||
English | [中文](publish.zh.md)
|
||||
|
||||
The previous tutorials loaded a local plugin through a `--patch` overlay. This tutorial packages it as an installable **bundle**, installs it into a **profile** with `dsh plugin add`, and explains the layer order that determines the composed configuration. Complete [plugin configuration](./config.md) first.
|
||||
|
||||
## Two concepts, two manifests
|
||||
|
||||
Installation is built on two concepts. Both are described by a `package.json`, but they carry different kinds of manifest under the `dsh` key, and they answer different questions:
|
||||
|
||||
- A **bundle** is an npm package that ships a configuration layer. Its manifest declares `dsh.bundle`, answering "what does this package contribute?": a patch file that inserts or overrides plugin rows.
|
||||
- A **profile** is a directory under `$DSH_HOME/profiles/<name>` describing one runnable composition. Its manifest declares `dsh.profile`, answering "which bundles compose this setup, in what order?".
|
||||
|
||||
A bundle is what you author and distribute; a profile is what a user boots with `dsh --profile <name>`. Nothing is both.
|
||||
|
||||
### The bundle manifest
|
||||
|
||||
```
|
||||
hello-plugin/
|
||||
├── package.json # declares dsh.bundle
|
||||
├── cordis.patch.yml # the layer applied when a profile lists this bundle
|
||||
└── index.js # plugin modules the patch rows reference
|
||||
```
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "dsh-hello-plugin",
|
||||
"version": "0.1.0",
|
||||
"type": "module",
|
||||
"main": "index.js",
|
||||
"files": ["index.js", "cordis.patch.yml"],
|
||||
"dsh": { "bundle": { "patch": "./cordis.patch.yml" } }
|
||||
}
|
||||
```
|
||||
|
||||
The patch file has the same shape as the `--patch` overlays you have been writing — a YAML array of patch entries — except plugin rows reference the package by name instead of a relative source path, so Node resolution finds the installed code:
|
||||
|
||||
```yaml
|
||||
- insert:
|
||||
- id: hello
|
||||
name: dsh-hello-plugin
|
||||
```
|
||||
|
||||
A package without the `dsh.bundle` declaration still installs, but only as a plain dependency: `dsh plugin` prints a warning and activates no layer. That is the correct shape for a library that plugin packages import rather than a plugin users enable.
|
||||
|
||||
### The profile manifest
|
||||
|
||||
A profile directory holds two files:
|
||||
|
||||
- `package.json` — the profile's out-of-tree plugin dependencies (managed by pnpm) plus the `dsh.profile` manifest with its ordered `bundles` list.
|
||||
- `cordis.patch.yml` — the user's own patch layer, applied after every bundle layer.
|
||||
|
||||
You never write a profile manifest by hand: `dsh plugin` creates and maintains it. The next section shows the result.
|
||||
|
||||
## Install into a profile
|
||||
|
||||
`dsh plugin --profile <name> <args...>` forwards to pnpm in the profile directory, so every pnpm verb works. Install your package from its checkout:
|
||||
|
||||
```sh
|
||||
cd hello-plugin
|
||||
dsh plugin --profile demo add .
|
||||
```
|
||||
|
||||
The first use initializes the profile (with `@deepseek-ai/dsh-base` as its first bundle), pnpm links the checkout, and `dsh` appends the bundle to `dsh.profile.bundles` because the package declares `dsh.bundle`:
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "dsh-profile-demo",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"dsh-hello-plugin": "link:/path/to/hello-plugin"
|
||||
},
|
||||
"dsh": {
|
||||
"profile": {
|
||||
"bundles": [
|
||||
"@deepseek-ai/dsh-base",
|
||||
"dsh-hello-plugin"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Verify the layer without booting, then boot:
|
||||
|
||||
```sh
|
||||
dsh --profile demo --dump-config # shows a "# == dsh-hello-plugin" layer
|
||||
dsh --profile demo
|
||||
```
|
||||
|
||||
`dsh plugin --profile demo remove dsh-hello-plugin` removes both the dependency and the layer.
|
||||
|
||||
## The loading order
|
||||
|
||||
The effective configuration composes over an empty root by applying, in order:
|
||||
|
||||
1. Each bundle patch named in the profile's `dsh.profile.bundles` list, in list order — `@deepseek-ai/dsh-base` first, then each installed bundle in the order it was added.
|
||||
2. The profile's own `cordis.patch.yml`.
|
||||
3. The home-level `$DSH_HOME/cordis.patch.yml` — machine-local preferences shared by every profile.
|
||||
4. Each `--patch <path>` overlay, in argv order.
|
||||
5. Launcher flag patches (for example `dsh web --port`).
|
||||
|
||||
Later layers win per row, and a patch replaces a row's entire `config` value rather than deep-merging keys. Two consequences for bundle authors:
|
||||
|
||||
- Your patch can override rows from earlier layers by `id` — the same way [the `dsh-web-app` bundle](../../../../packages/bundle/web-app/cordis.patch.yml) overrides `dsh-base` rows — but must restate every key the row needs, not just the changed one.
|
||||
- Users can override your rows in their profile's `cordis.patch.yml` without touching your package, so prefer configuration defaults users are likely to keep and let the schema carry the rest.
|
||||
|
||||
In-box bundle names always resolve from the dsh installation itself; pnpm manages only out-of-tree packages, so your bundle can rely on `@deepseek-ai/dsh-base` being present and current.
|
||||
|
||||
## Installing from GitHub: the build-script catch
|
||||
|
||||
Publishing to a registry is not required — users can install straight from a git host:
|
||||
|
||||
```sh
|
||||
dsh plugin --profile demo add github:you/hello-plugin
|
||||
```
|
||||
|
||||
But a git install fetches **sources, not built artifacts**: nothing runs your `build` script, so a TypeScript package arrives without its `lib/` output and fails to load. Two things must happen, one on each side:
|
||||
|
||||
- **The author** ships a `prepare` script — pnpm runs it after a git install — that builds the published entry points from source, self-contained: it must not assume dev-only context such as a sibling monorepo checkout. [turtle-ui](https://github.com/deepseek-harness/turtle-ui) is a working example: its `prepare` runs a dedicated tsdown config that transpiles `src/` without project references or type checking.
|
||||
- **The user** allowlists the build. pnpm ≥10 refuses to run a git dependency's `prepare` script until it is explicitly allowed, so the first `add` fails; `dsh` points at the fix — copy the exact package key pnpm printed into the profile's `pnpm-workspace.yaml`:
|
||||
|
||||
```yaml
|
||||
allowBuilds:
|
||||
dsh-hello-plugin: true
|
||||
```
|
||||
|
||||
and re-run the `add`.
|
||||
|
||||
Treat that allowance as what it is: **permission to execute the package's code on your machine at install time**, outside any sandbox the agent runs under. Only allow packages whose source you trust, and pin a commit (`github:you/hello-plugin#<sha>`) so a later push cannot silently change what runs.
|
||||
|
||||
If you would rather not ask users for the allowance, distribute built artifacts instead — neither form needs any build permission:
|
||||
|
||||
- **Publish to npm** with `lib/` built at `pnpm publish` time; `dsh plugin add your-package` then installs prebuilt code.
|
||||
- **Ship a tarball** from `pnpm pack`; users run `dsh plugin add ./hello-plugin-0.1.0.tgz`.
|
||||
|
||||
## Next steps
|
||||
|
||||
- [Plugins and lifecycle](../framework/) — the full plugin lifecycle
|
||||
- [CLI behavior reference](../../../../apps/cli/reference/README.md) — exact layer precedence, flags, and profile mechanics
|
||||
@@ -0,0 +1,140 @@
|
||||
# 打包与安装插件
|
||||
|
||||
[English](publish.md) | 中文
|
||||
|
||||
前几篇教程通过 `--patch` overlay 加载本地插件。本教程把它打包成可安装的**组合包**(bundle),用 `dsh plugin add` 安装进一个 **profile**,并解释决定组合后配置的层顺序。请先完成[插件配置](./config.md)。
|
||||
|
||||
## 两个概念,两种 manifest
|
||||
|
||||
安装机制建立在两个概念之上。二者都由一份 `package.json` 描述,但它们在 `dsh` 键下携带的 manifest(元数据清单)种类不同,回答的问题也不同:
|
||||
|
||||
- **组合包**是附带一个配置层的 npm 包。它的 manifest 声明 `dsh.bundle`,回答的是"这个包贡献什么?":一个插入或覆盖插件行的 patch 文件。
|
||||
- **profile** 是位于 `$DSH_HOME/profiles/<name>` 下、描述一份可启动组合的目录。它的 manifest 声明 `dsh.profile`,回答的是"这套配置由哪些组合包按什么顺序组成?"。
|
||||
|
||||
组合包是你编写并分发的东西;profile 是用户用 `dsh --profile <name>` 启动的东西。没有东西同时是两者。
|
||||
|
||||
### 组合包 manifest
|
||||
|
||||
```
|
||||
hello-plugin/
|
||||
├── package.json # declares dsh.bundle
|
||||
├── cordis.patch.yml # the layer applied when a profile lists this bundle
|
||||
└── index.js # plugin modules the patch rows reference
|
||||
```
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "dsh-hello-plugin",
|
||||
"version": "0.1.0",
|
||||
"type": "module",
|
||||
"main": "index.js",
|
||||
"files": ["index.js", "cordis.patch.yml"],
|
||||
"dsh": { "bundle": { "patch": "./cordis.patch.yml" } }
|
||||
}
|
||||
```
|
||||
|
||||
patch 文件的形状与你一直在写的 `--patch` overlay 相同——一个 patch 条目的 YAML 数组——只是插件行按包名而不是相对源码路径引用这个包,这样 Node 的模块解析才能找到已安装的代码:
|
||||
|
||||
```yaml
|
||||
- insert:
|
||||
- id: hello
|
||||
name: dsh-hello-plugin
|
||||
```
|
||||
|
||||
没有 `dsh.bundle` 声明的包仍然可以安装,但只作为普通依赖:`dsh plugin` 会打印警告,且不激活任何层。这正是"供插件包 import 的库"应有的形状,区别于"供用户启用的插件"。
|
||||
|
||||
### profile manifest
|
||||
|
||||
profile 目录包含两个文件:
|
||||
|
||||
- `package.json` — profile 的树外插件依赖(由 pnpm 管理),加上 `dsh.profile` manifest 及其有序的 `bundles` 列表。
|
||||
- `cordis.patch.yml` — 用户自己的 patch 层,在每个组合包层之后应用。
|
||||
|
||||
profile manifest 从不需要手写:`dsh plugin` 负责创建和维护它。下一节展示其结果。
|
||||
|
||||
## 安装进 profile
|
||||
|
||||
`dsh plugin --profile <name> <args...>` 在 profile 目录内转发给 pnpm,因此所有 pnpm 子命令都可用。从 checkout 安装你的包:
|
||||
|
||||
```sh
|
||||
cd hello-plugin
|
||||
dsh plugin --profile demo add .
|
||||
```
|
||||
|
||||
首次使用会初始化 profile(`@deepseek-ai/dsh-base` 作为它的第一个组合包),pnpm 链接该 checkout,而 `dsh` 因为这个包声明了 `dsh.bundle`,把它追加进 `dsh.profile.bundles`:
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "dsh-profile-demo",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"dsh-hello-plugin": "link:/path/to/hello-plugin"
|
||||
},
|
||||
"dsh": {
|
||||
"profile": {
|
||||
"bundles": [
|
||||
"@deepseek-ai/dsh-base",
|
||||
"dsh-hello-plugin"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
先不启动、只验证该层,再启动:
|
||||
|
||||
```sh
|
||||
dsh --profile demo --dump-config # shows a "# == dsh-hello-plugin" layer
|
||||
dsh --profile demo
|
||||
```
|
||||
|
||||
`dsh plugin --profile demo remove dsh-hello-plugin` 会同时移除依赖和对应的层。
|
||||
|
||||
## 加载顺序
|
||||
|
||||
生效配置在空根之上按以下顺序逐层组合:
|
||||
|
||||
1. profile 的 `dsh.profile.bundles` 列表所列的各个组合包 patch,按列表顺序——先是 `@deepseek-ai/dsh-base`,然后是每个已安装组合包,按其加入顺序。
|
||||
2. profile 自己的 `cordis.patch.yml`。
|
||||
3. home 级的 `$DSH_HOME/cordis.patch.yml`——各 profile 共享的机器本地偏好。
|
||||
4. 每个 `--patch <path>` overlay,按 argv 顺序。
|
||||
5. 启动器 flag patch(例如 `dsh web --port`)。
|
||||
|
||||
后应用的层按行胜出,且 patch 会替换目标行的整个 `config` 值,而不是深度合并各键。这给组合包作者带来两个推论:
|
||||
|
||||
- 你的 patch 可以按 `id` 覆盖前面各层的行——就像 [`dsh-web-app` 组合包](../../../../packages/bundle/web-app/cordis.patch.yml)覆盖 `dsh-base` 的行那样——但必须重述该行需要的每一个键,而不是只写改动的那个。
|
||||
- 用户可以在自己 profile 的 `cordis.patch.yml` 中覆盖你的行,无需改动你的包,所以优先给出用户大概率会保留的配置默认值,其余交给 schema 承担。
|
||||
|
||||
内置组合包名称始终从 dsh 安装目录本身解析;pnpm 只管理树外的包,所以你的组合包可以放心依赖 `@deepseek-ai/dsh-base` 存在且与安装保持一致。
|
||||
|
||||
## 从 GitHub 安装:构建脚本这道坎
|
||||
|
||||
发布到注册表不是必须的——用户可以直接从 git 托管安装:
|
||||
|
||||
```sh
|
||||
dsh plugin --profile demo add github:you/hello-plugin
|
||||
```
|
||||
|
||||
但 git 安装拉取的是**源码,不是构建产物**:没有任何环节运行你的 `build` 脚本,因此 TypeScript 包到手时没有 `lib/` 输出,加载会失败。必须两边各做一件事:
|
||||
|
||||
- **作者**提供一个 `prepare` 脚本——pnpm 在 git 安装后运行它——从源码构建出发布入口,且必须自包含:不能假设仅开发环境才有的上下文,例如旁边有一份 monorepo checkout。[turtle-ui](https://github.com/deepseek-harness/turtle-ui) 是一个可用的例子:它的 `prepare` 运行一份专用的 tsdown 配置,直接转译 `src/`,不用项目引用,也不做类型检查。
|
||||
- **用户**为构建授权。pnpm ≥10 在得到显式允许之前拒绝运行 git 依赖的 `prepare` 脚本,所以第一次 `add` 会失败;`dsh` 会指出修法——把 pnpm 打印的确切包键复制进该 profile 的 `pnpm-workspace.yaml`:
|
||||
|
||||
```yaml
|
||||
allowBuilds:
|
||||
dsh-hello-plugin: true
|
||||
```
|
||||
|
||||
然后重新执行 `add`。
|
||||
|
||||
请如实看待这项授权:**允许该包的代码在安装时于你的机器上执行**,且不在 agent 运行的任何沙箱之内。只对源码可信的包授权,并锁定 commit(`github:you/hello-plugin#<sha>`),让后续推送无法悄悄改变实际运行的内容。
|
||||
|
||||
如果不想让用户做这项授权,就改为分发构建产物——以下两种形式都不需要任何构建权限:
|
||||
|
||||
- **发布到 npm**,在 `pnpm publish` 时构建好 `lib/`;`dsh plugin add your-package` 安装的就是预构建代码。
|
||||
- **交付 tarball**:用 `pnpm pack` 打包;用户执行 `dsh plugin add ./hello-plugin-0.1.0.tgz`。
|
||||
|
||||
## 下一步
|
||||
|
||||
- [插件与生命周期](../framework/) — 插件的完整生命周期
|
||||
- [CLI 行为参考](../../../../apps/cli/reference/README.md) — 确切的层优先级、flag 与 profile 机制
|
||||
@@ -2,5 +2,5 @@
|
||||
# side as of the last confirmed-consistent state. Both languages carry equal authority;
|
||||
# after editing either side, bring the other along and re-record with:
|
||||
# pnpm run verify-translation-pairing --write docs/user/develop/basic/tool.md
|
||||
tool.md: 93a1a96feba814a564f8800c8e7b865fe9c0cb73
|
||||
tool.zh.md: 18e6b9b5d9c17b00c26aa7b98e6ac4531315dc5e
|
||||
tool.md: 8505bdaf6fcece3235b0302d54e82ee8aed3cbab
|
||||
tool.zh.md: 1831afa9be74756cb9bb1e96515fefd3685ee4c2
|
||||
|
||||
@@ -40,7 +40,7 @@ export function apply(ctx: Context) {
|
||||
Restart the development command if it is not running:
|
||||
|
||||
```sh
|
||||
pnpm run dsh web --config ./scratch-plugin/cordis.yml
|
||||
pnpm run dsh web --patch ./scratch-plugin/cordis.yml
|
||||
```
|
||||
|
||||
Open `http://127.0.0.1:3080` and ask: `Use the greet tool to greet Ada.` The model can call `greet` and receives `Hello, Ada!` as the tool result.
|
||||
|
||||
@@ -40,7 +40,7 @@ export function apply(ctx: Context) {
|
||||
如果开发命令未在运行,请重新启动:
|
||||
|
||||
```sh
|
||||
pnpm run dsh web --config ./scratch-plugin/cordis.yml
|
||||
pnpm run dsh web --patch ./scratch-plugin/cordis.yml
|
||||
```
|
||||
|
||||
打开 `http://127.0.0.1:3080`,然后输入:`Use the greet tool to greet Ada.` 模型可以调用 `greet`,并收到 `Hello, Ada!` 这一工具结果。
|
||||
|
||||
@@ -2,5 +2,5 @@
|
||||
# side as of the last confirmed-consistent state. Both languages carry equal authority;
|
||||
# after editing either side, bring the other along and re-record with:
|
||||
# pnpm run verify-translation-pairing --write docs/user/guide/config.md
|
||||
config.md: ddf4df264e5534fc3b74991941c2f3f82376d53f
|
||||
config.zh.md: 56ac0146ddae83dbfc86f479030efdb5772a3aaf
|
||||
config.md: 0f1a99ed0afdab13d052ae2714fc2e1718d3d85e
|
||||
config.zh.md: 74e14e4e6e1fbb38a7a8d5167a4747080a662128
|
||||
|
||||
@@ -8,8 +8,8 @@ Harness uses `cordis.yml` to describe which plugins an agent loads and the confi
|
||||
|
||||
The repository examples are runnable configurations and the most reliable starting points for a new project:
|
||||
|
||||
- [the shared `dsh` base](../../../apps/cli/config/base.cordis.yml) provides the common model, tools, persistence, policy, and telemetry rows; raw `dsh --config <path>` requires a patch list that selects deployment-specific agents and front doors.
|
||||
- [the Web overlay](../../../apps/cli/config/web.cordis.yml) adds the browser host, Workspace management, browser interaction, and client plugins.
|
||||
- [the `dsh-base` bundle patch](../../../packages/bundle/base/cordis.patch.yml) provides the common model, tools, persistence, policy, and telemetry rows every profile starts from.
|
||||
- [the `dsh-web-app` bundle patch](../../../packages/bundle/web-app/cordis.patch.yml) adds the browser host, Workspace management, browser interaction, and client plugins.
|
||||
- [headless-agent](../../../examples/headless-agent/cordis.yml) exposes the coding composition as a one-shot task.
|
||||
- [acp-agent](../../../examples/acp-agent/cordis.yml) exposes fresh sessions to programmatic ACP clients.
|
||||
|
||||
@@ -49,9 +49,9 @@ A minimal configuration is a list of plugin entries:
|
||||
|
||||
Cordis starts sibling entries concurrently. A plugin declares required services through `inject`; Cordis waits for those services before applying the plugin, so file order does not establish dependency readiness. Missing models, tools, and plugins fail as early as possible instead of being silently ignored.
|
||||
|
||||
## CLI overlays
|
||||
## CLI patch layers
|
||||
|
||||
Raw `dsh --config <path>` requires a patch list and applies it directly over `base.cordis.yml`. It does not add a surface overlay or `~/.dsh/config.yaml`, and the named file is not a complete replacement tree. `dsh web` composes `base.cordis.yml` and `web.cordis.yml`, then applies `~/.dsh/config.yaml`; `dsh web --config <path>` replaces that personal layer with the named overlay. Web profile and CLI-flag patches follow the user layer.
|
||||
`dsh --profile <name>` composes the profile's bundle patch layers (its manifest's `dsh.profile.bundles` list, in order) over an empty root, then the profile's own `~/.dsh/profiles/<name>/cordis.patch.yml`, then each `--patch <path>` overlay, then CLI-flag patches. Later layers win per row.
|
||||
|
||||
A patch replaces a row's entire `config` value; it does not deep-merge keys. For example, patching `llm-deepseek` with only `config: { thinking: disabled }` also removes that row's configured `apiKey` and `baseURL`, so restate every key the row must retain.
|
||||
|
||||
|
||||
@@ -8,8 +8,8 @@ Harness 使用 `cordis.yml` 描述 agent(智能体)加载哪些插件以及
|
||||
|
||||
仓库中的示例就是可以运行的配置,也是新项目最可靠的起点:
|
||||
|
||||
- [共享的 `dsh` base](../../../apps/cli/config/base.cordis.yml) 提供通用的模型、工具、持久化、策略与遥测配置项;原始 `dsh --config <path>` 要求传入一份 patch 列表,用于选择部署特定的 agent 和前端入口。
|
||||
- [Web overlay](../../../apps/cli/config/web.cordis.yml) 添加浏览器宿主、Workspace 管理、浏览器交互与客户端插件。
|
||||
- [`dsh-base` 组合包补丁](../../../packages/bundle/base/cordis.patch.yml) 提供通用的模型、工具、持久化、策略与遥测配置项,每个 profile 都以此为起点。
|
||||
- [`dsh-web-app` 组合包补丁](../../../packages/bundle/web-app/cordis.patch.yml) 添加浏览器宿主、Workspace 管理、浏览器交互与客户端插件。
|
||||
- [headless-agent](../../../examples/headless-agent/cordis.yml) 以单次任务形式暴露 coding 组装。
|
||||
- [acp-agent](../../../examples/acp-agent/cordis.yml) 向程序化 ACP(Agent Client Protocol)客户端提供全新会话。
|
||||
|
||||
@@ -49,9 +49,9 @@ Harness 使用 `cordis.yml` 描述 agent(智能体)加载哪些插件以及
|
||||
|
||||
Cordis 会并发启动同级配置项。插件通过 `inject` 声明必需服务;Cordis 会等到这些服务就绪后再应用该插件,因此文件顺序不能保证依赖已就绪。引用不存在的模型、工具或插件会尽早报错,而不是被静默忽略。
|
||||
|
||||
## CLI 覆盖层
|
||||
## CLI 补丁层
|
||||
|
||||
原始 `dsh --config <path>` 要求传入一份 patch 列表,并将其直接应用在 `base.cordis.yml` 之上。它不会添加 surface overlay 或 `~/.dsh/config.yaml`,指定文件也不是完整替换树。`dsh web` 先组合 `base.cordis.yml` 与 `web.cordis.yml`,再应用 `~/.dsh/config.yaml`;`dsh web --config <path>` 会以指定 overlay 替代该个人层。Web profile 与 CLI(命令行界面)标志 patch 位于用户层之后。
|
||||
`dsh --profile <name>` 按该 profile 的 manifest(元数据清单)中 `dsh.profile.bundles` 列表的顺序,在空根之上组合各组合包补丁层,随后依次应用该 profile 自己的 `~/.dsh/profiles/<name>/cordis.patch.yml`、每个 `--patch <path>` overlay,最后是 CLI(命令行界面)标志补丁。同一行以较后的层为准。
|
||||
|
||||
补丁会替换目标行的整个 `config` 值,而不是深度合并各个键。例如,只用 `config: { thinking: disabled }` 修补 `llm-deepseek`,也会移除该行原有的 `apiKey` 与 `baseURL`;因此必须重新写出该行需要保留的全部键。
|
||||
|
||||
|
||||
@@ -2,5 +2,5 @@
|
||||
# side as of the last confirmed-consistent state. Both languages carry equal authority;
|
||||
# after editing either side, bring the other along and re-record with:
|
||||
# pnpm run verify-translation-pairing --write docs/user/guide/quickstart.md
|
||||
quickstart.md: e81e0ff57384156ee2963d4788519d2384c362ea
|
||||
quickstart.zh.md: 9755da8bf078c817f9c2a00134360b5169c536bf
|
||||
quickstart.md: 72cc5a52c33faf81098f747799692b384fcd5f1a
|
||||
quickstart.zh.md: ebb831c1e1bec02117c78a4c2426a84af3bb9478
|
||||
|
||||
@@ -53,7 +53,7 @@ Open `http://127.0.0.1:3080`. The agent can read and write files, run commands,
|
||||
|
||||
## What happened
|
||||
|
||||
headless-agent uses the `@deepseek-ai/dsh-cli-demo` app. `dsh web` instead composes [`apps/cli/config/base.cordis.yml`](../../../apps/cli/config/base.cordis.yml) with [`apps/cli/config/web.cordis.yml`](../../../apps/cli/config/web.cordis.yml) and no app bundle. Both select the DeepSeek model and capability plugins appropriate to their entry mode.
|
||||
headless-agent uses the `@deepseek-ai/dsh-cli-demo` app. `dsh web` instead boots the `web` profile: the [`dsh-base`](../../../packages/bundle/base/cordis.patch.yml) and [`dsh-web-app`](../../../packages/bundle/web-app/cordis.patch.yml) bundle patch layers composed over an empty root. Both select the DeepSeek model and capability plugins appropriate to their entry mode.
|
||||
|
||||
## Next steps
|
||||
|
||||
|
||||
@@ -53,7 +53,7 @@ pnpm run dsh web
|
||||
|
||||
## 回头看
|
||||
|
||||
headless-agent 使用 `@deepseek-ai/dsh-cli-demo` app。`dsh web` 则组合 [`apps/cli/config/base.cordis.yml`](../../../apps/cli/config/base.cordis.yml) 与 [`apps/cli/config/web.cordis.yml`](../../../apps/cli/config/web.cordis.yml),不使用 app 组合包。二者都会根据各自入口模式选择 DeepSeek 模型和能力插件。
|
||||
headless-agent 使用 `@deepseek-ai/dsh-cli-demo` app。`dsh web` 则启动 `web` profile:由 [`dsh-base`](../../../packages/bundle/base/cordis.patch.yml) 与 [`dsh-web-app`](../../../packages/bundle/web-app/cordis.patch.yml) 两个组合包的 patch 层在空根之上组合而成。二者都会根据各自入口模式选择 DeepSeek 模型和能力插件。
|
||||
|
||||
## 下一步
|
||||
|
||||
|
||||
Reference in New Issue
Block a user