dsh-plugin-dev-kb 1.0.2 → 1.0.4
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/CHANGELOG.md +31 -0
- package/kb/README.md +1 -1
- package/kb/extra/cookbook/adding-a-vendored-package.zh.md +3 -3
- package/kb/extra/cookbook/maintaining-dsh-code-review.zh.md +1 -1
- package/kb/extra/cookbook/responding-to-pr-review-on-a-stack.zh.md +1 -1
- package/kb/extra/defensive-patterns.zh.md +3 -1
- package/kb/extra/development.zh.md +15 -9
- package/kb/extra/event-producer-consumer.md +5 -2
- package/kb/extra/event-producer-consumer.zh.md +5 -2
- package/kb/extra/graph-atlas.zh.md +7 -7
- package/kb/extra/i18n/README.md +3 -3
- package/kb/extra/i18n/README.zh.md +9 -7
- package/kb/extra/i18n/style-samples.md +1 -1
- package/kb/extra/i18n/translation-prompt.md +3 -3
- package/kb/extra/i18n/translation-rules.md +2 -2
- package/kb/extra/i18n/translation-rules.zh.md +3 -3
- package/kb/extra/module-graph.md +18 -9
- package/kb/extra/module-graph.zh.md +18 -9
- package/kb/extra/postmortem/0001-acp-default-export-drops-inject.zh.md +1 -1
- package/kb/extra/postmortem/0002-js-expression-disabled-filesystem-tools.zh.md +1 -1
- package/kb/extra/postmortem/0004-landlock-partial-notice-misclassified-child-failures.zh.md +1 -1
- package/kb/extra/postmortem/README.zh.md +5 -5
- package/kb/extra/rescope.zh.md +1 -1
- package/kb/extra/subsystems/agent-team.md +2 -2
- package/kb/extra/subsystems/agent-team.zh.md +6 -6
- package/kb/extra/subsystems/attachment.md +63 -12
- package/kb/extra/subsystems/attachment.zh.md +63 -12
- package/kb/extra/subsystems/extensions.md +9 -9
- package/kb/extra/subsystems/extensions.zh.md +12 -12
- package/kb/extra/subsystems/feedback.md +2 -2
- package/kb/extra/subsystems/feedback.zh.md +2 -2
- package/kb/extra/testing.md +1 -1
- package/kb/extra/testing.zh.md +7 -7
- package/kb/extra/web-styling.zh.md +2 -2
- package/kb/meta/search-index.json +132 -132
- package/kb/meta/source.json +2 -2
- package/kb/meta/topics.md +2 -2
- package/kb/site/develop/basic/index.md +1 -1
- package/kb/site/develop/basic/publish.md +3 -3
- package/kb/site/develop/cordis-tutorial/index.md +1 -1
- package/kb/site/en/reference/capability-seams.md +5 -0
- package/kb/site/en/reference/config-catalog.md +52 -17
- package/kb/site/en/reference/persistence-catalog.md +1 -1
- package/kb/site/en/reference/subsystems/approval.md +3 -3
- package/kb/site/en/reference/subsystems/client-modules.md +7 -7
- package/kb/site/en/reference/subsystems/code-runtime.md +2 -2
- package/kb/site/en/reference/subsystems/commands.md +3 -3
- package/kb/site/en/reference/subsystems/compaction.md +3 -3
- package/kb/site/en/reference/subsystems/core.md +19 -19
- package/kb/site/en/reference/subsystems/credentials.md +163 -8
- package/kb/site/en/reference/subsystems/filesystem.md +5 -5
- package/kb/site/en/reference/subsystems/goal.md +3 -3
- package/kb/site/en/reference/subsystems/invariants.md +2 -2
- package/kb/site/en/reference/subsystems/jobs.md +2 -2
- package/kb/site/en/reference/subsystems/llm-streaming.md +16 -4
- package/kb/site/en/reference/subsystems/lsp.md +2 -2
- package/kb/site/en/reference/subsystems/permission-presets.md +2 -2
- package/kb/site/en/reference/subsystems/persistence.md +2 -2
- package/kb/site/en/reference/subsystems/plan.md +2 -2
- package/kb/site/en/reference/subsystems/sandbox.md +3 -3
- package/kb/site/en/reference/subsystems/session-projection.md +60 -35
- package/kb/site/en/reference/subsystems/session-query.md +2 -2
- package/kb/site/en/reference/subsystems/session-reference.md +3 -3
- package/kb/site/en/reference/subsystems/session-telemetry.md +3 -3
- package/kb/site/en/reference/subsystems/session-title.md +2 -2
- package/kb/site/en/reference/subsystems/session.md +6 -6
- package/kb/site/en/reference/subsystems/settings.md +4 -4
- package/kb/site/en/reference/subsystems/shell.md +3 -3
- package/kb/site/en/reference/subsystems/skills.md +3 -3
- package/kb/site/en/reference/subsystems/spill.md +2 -2
- package/kb/site/en/reference/subsystems/storage.md +4 -4
- package/kb/site/en/reference/subsystems/subagent.md +6 -6
- package/kb/site/en/reference/subsystems/subprocess.md +3 -3
- package/kb/site/en/reference/subsystems/system-prompt.md +4 -4
- package/kb/site/en/reference/subsystems/terminal.md +2 -2
- package/kb/site/en/reference/subsystems/token-meter.md +2 -2
- package/kb/site/en/reference/subsystems/tools.md +8 -8
- package/kb/site/en/reference/subsystems/typert.md +4 -4
- package/kb/site/en/reference/subsystems/user-questions.md +2 -2
- package/kb/site/en/reference/subsystems/web-server.md +46 -6
- package/kb/site/en/reference/subsystems/web.md +2 -2
- package/kb/site/en/reference/subsystems/workflow.md +8 -8
- package/kb/site/en/reference/subsystems/workspace.md +3 -3
- package/kb/site/en/reference/tool-catalog.md +3 -3
- package/kb/site/guide/providers.md +2 -2
- package/kb/site/guide/python-sdk.md +2 -2
- package/kb/site/guide/quickstart.md +2 -2
- package/kb/site/reference/capability-seams.md +5 -0
- package/kb/site/reference/config-catalog.md +53 -18
- package/kb/site/reference/cookbook/adding-a-conversation-node.md +1 -1
- package/kb/site/reference/cookbook/adding-a-package.md +5 -3
- package/kb/site/reference/cookbook/adding-a-settings-card.md +1 -1
- package/kb/site/reference/cookbook/adding-a-tool.md +6 -6
- package/kb/site/reference/cookbook/adding-an-llm-adapter.md +2 -2
- package/kb/site/reference/cookbook/extension-cookbook.md +6 -4
- package/kb/site/reference/index.md +4 -4
- package/kb/site/reference/persistence-catalog.md +5 -5
- package/kb/site/reference/subsystems/approval.md +3 -3
- package/kb/site/reference/subsystems/client-modules.md +8 -8
- package/kb/site/reference/subsystems/code-runtime.md +4 -4
- package/kb/site/reference/subsystems/commands.md +5 -5
- package/kb/site/reference/subsystems/compaction.md +7 -7
- package/kb/site/reference/subsystems/core.md +26 -24
- package/kb/site/reference/subsystems/credentials.md +163 -8
- package/kb/site/reference/subsystems/filesystem.md +6 -6
- package/kb/site/reference/subsystems/goal.md +5 -5
- package/kb/site/reference/subsystems/index.md +5 -5
- package/kb/site/reference/subsystems/invariants.md +5 -5
- package/kb/site/reference/subsystems/jobs.md +4 -4
- package/kb/site/reference/subsystems/llm-streaming.md +21 -9
- package/kb/site/reference/subsystems/lsp.md +3 -3
- package/kb/site/reference/subsystems/permission-presets.md +3 -3
- package/kb/site/reference/subsystems/persistence.md +6 -6
- package/kb/site/reference/subsystems/plan.md +4 -4
- package/kb/site/reference/subsystems/sandbox.md +7 -5
- package/kb/site/reference/subsystems/schedule.md +1 -1
- package/kb/site/reference/subsystems/scope.md +1 -1
- package/kb/site/reference/subsystems/session-projection.md +61 -36
- package/kb/site/reference/subsystems/session-query.md +2 -2
- package/kb/site/reference/subsystems/session-reference.md +3 -3
- package/kb/site/reference/subsystems/session-telemetry.md +5 -5
- package/kb/site/reference/subsystems/session-title.md +2 -2
- package/kb/site/reference/subsystems/session.md +13 -11
- package/kb/site/reference/subsystems/settings.md +4 -4
- package/kb/site/reference/subsystems/shell.md +6 -6
- package/kb/site/reference/subsystems/skills.md +3 -3
- package/kb/site/reference/subsystems/spill.md +3 -3
- package/kb/site/reference/subsystems/storage.md +7 -7
- package/kb/site/reference/subsystems/subagent.md +11 -9
- package/kb/site/reference/subsystems/subprocess.md +4 -4
- package/kb/site/reference/subsystems/system-prompt.md +5 -5
- package/kb/site/reference/subsystems/terminal.md +3 -3
- package/kb/site/reference/subsystems/token-meter.md +2 -2
- package/kb/site/reference/subsystems/tools.md +9 -9
- package/kb/site/reference/subsystems/typert.md +5 -5
- package/kb/site/reference/subsystems/user-questions.md +2 -2
- package/kb/site/reference/subsystems/web-server.md +48 -8
- package/kb/site/reference/subsystems/web.md +3 -3
- package/kb/site/reference/subsystems/workflow.md +11 -11
- package/kb/site/reference/subsystems/workspace.md +5 -5
- package/kb/site/reference/tool-catalog.md +9 -5
- package/lib/index.js +9 -1
- package/package.json +2 -1
- package/skills/dsh-plugin-dev-kb.md +1 -1
|
@@ -5,7 +5,7 @@ outline: [2,3]
|
|
|
5
5
|
|
|
6
6
|
# 存储
|
|
7
7
|
|
|
8
|
-
存储子系统持久保存一切不属于会话事件日志的数据(会话日志有自己的 seam——见 [persistence.md](./persistence.md))。它是一项可选能力,不属于 agent loop(智能体循环)主干,并按[能力 seam](https://github.com/deepseek-ai/deepseek-harness/blob/master/.agents/notes/implemented/architecture/2026-06-13-capability-seams.md) 拆分:枢纽(hub)与 Service Definition([dsh-storage](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/storage/storage),`ctx.storage`)、Service Provider(注册为 `json` 的 [dsh-storage-json](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/storage/storage-json) 与注册为 `sqlite` 的 [dsh-storage-sqlite](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/storage/storage-sqlite)),以及 Consumer 数据形式([dsh-storage-domain](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/storage/storage-domain),`ctx.storageDomain`,也可经 `ctx.storage.domain` 访问)——它是后端约定的唯一 Consumer,也是其他一切所使用的类型化 API。枢纽自身不做任何 IO:后端拥有介质,数据形式拥有语义,产品包绝不直接触碰后端。设计记录:[领域 KV 存储 Agent Note](https://github.com/deepseek-ai/deepseek-harness/blob/master/.agents/notes/proposed/architecture/2026-07-24-domain-kv-storage-and-workspace.md)。
|
|
8
|
+
存储子系统持久保存一切不属于会话事件日志的数据(会话日志有自己的 seam——见 [persistence.md](./persistence.md))。它是一项可选能力,不属于 agent loop(智能体循环)主干,并按[能力 seam](https://github.com/deepseek-ai/deepseek-harness/blob/master/.agents/notes/implemented/architecture/2026-06-13-capability-seams.zh.md) 拆分:枢纽(hub)与 Service Definition([dsh-storage](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/storage/storage),`ctx.storage`)、Service Provider(注册为 `json` 的 [dsh-storage-json](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/storage/storage-json) 与注册为 `sqlite` 的 [dsh-storage-sqlite](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/storage/storage-sqlite)),以及 Consumer 数据形式([dsh-storage-domain](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/storage/storage-domain),`ctx.storageDomain`,也可经 `ctx.storage.domain` 访问)——它是后端约定的唯一 Consumer,也是其他一切所使用的类型化 API。枢纽自身不做任何 IO:后端拥有介质,数据形式拥有语义,产品包绝不直接触碰后端。设计记录:[领域 KV 存储 Agent Note](https://github.com/deepseek-ai/deepseek-harness/blob/master/.agents/notes/proposed/architecture/2026-07-24-domain-kv-storage-and-workspace.zh.md)。
|
|
9
9
|
|
|
10
10
|
源码:[`packages/storage/storage/src/backend.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/storage/storage/src/backend.ts) · [`packages/storage/storage-domain/src/spec.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/storage/storage-domain/src/spec.ts) · [`packages/storage/storage-domain/src/events.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/storage/storage-domain/src/events.ts)
|
|
11
11
|
|
|
@@ -47,7 +47,7 @@ interface StorageBackend {
|
|
|
47
47
|
}
|
|
48
48
|
```
|
|
49
49
|
|
|
50
|
-
一个后端拥有一个介质(一棵文件树的根目录、一个数据库文件),并提供可选的操作组;目前 `kv` 是唯一一组。`KvFacet.open(descriptor)` 打开一个具名 unit——`KvUnitDescriptor` 携带名称、格式版本、表名清单,以及是否存在全局单例 slot——并返回提供 `loadAll`、`putRecord`、`deleteRecord`、`setGlobal` 和 `close` 的 `KvUnit`。unit 名与表名必须匹配 `UNIT_NAME_RE`(既可安全用作文件名,也可安全用作 SQL 标识符片段);记录键是任意字符串,绝不进入文件路径。unit 不对并发写入做串行化——顺序由调用方负责——但每次单独调用在介质上都是原子的,且 resolve 后即已持久。介质上记录的版本与之不同时拒绝 `version-mismatch`;无法按该 unit 解析的介质拒绝 `malformed-medium`(不做迁移:预发布立场)。[`backend.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/storage/storage/src/backend.ts) 是逐条款的规范性约定,[`tests/contract.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/storage/storage/tests/contract.ts) 中的共享一致性套件会针对每个后端检查每项条款。[json 后端](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/storage/storage-json/README.md)以原子方式为每个 unit 整文件重新发布一份人类可读文件;[sqlite 后端](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/storage/storage-sqlite/README.md)在单个数据库中每行存储一份文档,用于频繁更新的数据。
|
|
50
|
+
一个后端拥有一个介质(一棵文件树的根目录、一个数据库文件),并提供可选的操作组;目前 `kv` 是唯一一组。`KvFacet.open(descriptor)` 打开一个具名 unit——`KvUnitDescriptor` 携带名称、格式版本、表名清单,以及是否存在全局单例 slot——并返回提供 `loadAll`、`putRecord`、`deleteRecord`、`setGlobal` 和 `close` 的 `KvUnit`。unit 名与表名必须匹配 `UNIT_NAME_RE`(既可安全用作文件名,也可安全用作 SQL 标识符片段);记录键是任意字符串,绝不进入文件路径。unit 不对并发写入做串行化——顺序由调用方负责——但每次单独调用在介质上都是原子的,且 resolve 后即已持久。介质上记录的版本与之不同时拒绝 `version-mismatch`;无法按该 unit 解析的介质拒绝 `malformed-medium`(不做迁移:预发布立场)。[`backend.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/storage/storage/src/backend.ts) 是逐条款的规范性约定,[`tests/contract.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/storage/storage/tests/contract.ts) 中的共享一致性套件会针对每个后端检查每项条款。[json 后端](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/storage/storage-json/README.zh.md)以原子方式为每个 unit 整文件重新发布一份人类可读文件;[sqlite 后端](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/storage/storage-sqlite/README.zh.md)在单个数据库中每行存储一份文档,用于频繁更新的数据。
|
|
51
51
|
|
|
52
52
|
## 声明领域
|
|
53
53
|
|
|
@@ -125,7 +125,7 @@ interface DomainChangedBase {
|
|
|
125
125
|
type DomainChanged = DomainChangedPut | DomainChangedDeleted
|
|
126
126
|
```
|
|
127
127
|
|
|
128
|
-
`put`(插入、覆写和 global 写入)在 `value` 中携带新快照——绝不携带旧值;需要做差异比较的消费方自行保留上一份快照。`deleted` 是不携带值的墓碑。该事件是通知,不是事务参与者:发出时提交点已经过去,因此同步抛出的监听器会被兜住并记录一条警告,而不会让已经持久的写入被拒绝;发出的值等于发出时刻的内存态。该事件仅限进程内;跨进程的变更推送是一项已记录的限制([包 README](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/storage/storage-domain/README.md))。
|
|
128
|
+
`put`(插入、覆写和 global 写入)在 `value` 中携带新快照——绝不携带旧值;需要做差异比较的消费方自行保留上一份快照。`deleted` 是不携带值的墓碑。该事件是通知,不是事务参与者:发出时提交点已经过去,因此同步抛出的监听器会被兜住并记录一条警告,而不会让已经持久的写入被拒绝;发出的值等于发出时刻的内存态。该事件仅限进程内;跨进程的变更推送是一项已记录的限制([包 README](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/storage/storage-domain/README.zh.md))。
|
|
129
129
|
|
|
130
130
|
<!-- BEGIN GENERATED cordis-surface (gen-cordis-catalog.ts) — do not edit between markers -->
|
|
131
131
|
|
|
@@ -133,7 +133,7 @@ type DomainChanged = DomainChangedPut | DomainChangedDeleted
|
|
|
133
133
|
|
|
134
134
|
## Cordis API
|
|
135
135
|
|
|
136
|
-
Generated from source by `scripts/gen-cordis-catalog.ts` (verified fresh by `pnpm run verify-cordis-catalog` in doc-sync; regenerate with `pnpm run gen-cordis-catalog`) —
|
|
136
|
+
Generated from source by `scripts/gen-cordis-catalog.ts` (verified fresh by `pnpm run verify-cordis-catalog` in doc-sync; regenerate with `pnpm run gen-cordis-catalog`) — the language sides differ only in locale-specific paired document paths. Signature blocks use a `ts cordis-catalog` fence and keep the original source JSDoc; dispatch modes are defined in the [primer](../cordis-primer.md#dispatch-modes), and the framework-inherited `ctx` API lives in [cordis-api/inherited.md](../cordis-api/inherited.md).
|
|
137
137
|
|
|
138
138
|
<a id="ctxstorage--storage"></a>
|
|
139
139
|
|
|
@@ -159,7 +159,7 @@ mount<K extends keyof StorageForms>(form: K, facility: StorageForms[K]): () => v
|
|
|
159
159
|
form<K extends keyof StorageForms>(form: K): StorageForms[K]
|
|
160
160
|
```
|
|
161
161
|
|
|
162
|
-
Source: [`packages/storage/storage/src/index.ts
|
|
162
|
+
Source: [`packages/storage/storage/src/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/storage/storage/src/index.ts)
|
|
163
163
|
|
|
164
164
|
<a id="ctxstoragedomain--domainfacility"></a>
|
|
165
165
|
|
|
@@ -204,7 +204,7 @@ get(name: string): DomainImpl | undefined
|
|
|
204
204
|
async closeAll(): Promise<void>
|
|
205
205
|
```
|
|
206
206
|
|
|
207
|
-
Source: [`packages/storage/storage-domain/src/index.ts
|
|
207
|
+
Source: [`packages/storage/storage-domain/src/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/storage/storage-domain/src/index.ts)
|
|
208
208
|
|
|
209
209
|
<a id="domain-events"></a>
|
|
210
210
|
|
|
@@ -228,5 +228,5 @@ A domain record or the global singleton changed, emitted once per write strictly
|
|
|
228
228
|
'domain/changed'(change: DomainChanged): void
|
|
229
229
|
```
|
|
230
230
|
|
|
231
|
-
Source: [`packages/storage/storage-domain/src/events.ts
|
|
231
|
+
Source: [`packages/storage/storage-domain/src/events.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/storage/storage-domain/src/events.ts)
|
|
232
232
|
<!-- END GENERATED cordis-surface -->
|
|
@@ -7,7 +7,7 @@ outline: [2,3]
|
|
|
7
7
|
|
|
8
8
|
subagent seam 让一个 agent(智能体)将工作委派给子 agent。与 [bash](./shell.md) 一样,它是**一项可选能力**,不属于 agent loop(智能体循环),因此其类型定义在此而非 [core.md](./core.md) 中。它不同于其他能力 seam,因为**同一上下文中可共存多个提供方实现**,并按名称注册(`ctx.subagents`),而 bash 只允许一个执行器。该注册表遵循 [LLM(大语言模型)适配器注册表](./llm-streaming.md),而非单服务的 bash 执行器。
|
|
9
9
|
|
|
10
|
-
Service Definition:[dsh-subagent](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/subagent/subagent)(`ctx.subagents` + 下文词汇)。Service Provider 是六个兄弟包:`dsh-subagent-spawn-in-process`、`-fork`、`-acp`、`-codex`、`-claude-code`、`-dsh-sdk`;面向模型的 Consumer 包括 [dsh-tool-subagent](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/subagent/tool-subagent)(按提供方委派)、[dsh-tool-subagent-control](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/subagent/tool-subagent-control)(可选的全局 `send_message`、`interrupt_agent` 与 `list_agents` 控制工具)和 [dsh-tool-subagent-report](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/subagent/tool-subagent-report)(可选的 child 作用域 `report` 返回通道)。同一个 `ctx.subagents` 服务通过内部激活管理器负责可继续子 agent 编排,并直接基于会话存储和可选的会话持久化提供只读的 child 与后代发现。产品提供方设计理由见 [Codex 与 Claude Code Agent Note](https://github.com/deepseek-ai/deepseek-harness/blob/master/.agents/notes/implemented/feature/2026-08-04-claude-code-and-codex-subagent-backends.md);通用 seam 的设计理由见 [subagent Agent Note](https://github.com/deepseek-ai/deepseek-harness/blob/master/.agents/notes/implemented/feature/2026-06-21-subagent-capability-seam.md)、[可继续 subagent Agent Note](https://github.com/deepseek-ai/deepseek-harness/blob/master/.agents/notes/implemented/feature/2026-07-28-continuable-subagent-conversations.md)、[report 工具 Agent Note](https://github.com/deepseek-ai/deepseek-harness/blob/master/.agents/notes/implemented/feature/2026-07-30-continuable-subagent-report-tool.md)、[持久化目录 Agent Note](https://github.com/deepseek-ai/deepseek-harness/blob/master/.agents/notes/implemented/feature/2026-07-22-durable-subagent-catalog-and-list-agents.md)、[列表身份投影 Agent Note](https://github.com/deepseek-ai/deepseek-harness/blob/master/.agents/notes/implemented/architecture/2026-08-06-subagent-list-identity-projection.md)和[服务合并 Agent Note](https://github.com/deepseek-ai/deepseek-harness/blob/master/.agents/notes/implemented/simplification/2026-07-26-merge-subagent-control-service.md)。
|
|
10
|
+
Service Definition:[dsh-subagent](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/subagent/subagent)(`ctx.subagents` + 下文词汇)。Service Provider 是六个兄弟包:`dsh-subagent-spawn-in-process`、`-fork`、`-acp`、`-codex`、`-claude-code`、`-dsh-sdk`;面向模型的 Consumer 包括 [dsh-tool-subagent](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/subagent/tool-subagent)(按提供方委派)、[dsh-tool-subagent-control](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/subagent/tool-subagent-control)(可选的全局 `send_message`、`interrupt_agent` 与 `list_agents` 控制工具)和 [dsh-tool-subagent-report](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/subagent/tool-subagent-report)(可选的 child 作用域 `report` 返回通道)。同一个 `ctx.subagents` 服务通过内部激活管理器负责可继续子 agent 编排,并直接基于会话存储和可选的会话持久化提供只读的 child 与后代发现。产品提供方设计理由见 [Codex 与 Claude Code Agent Note](https://github.com/deepseek-ai/deepseek-harness/blob/master/.agents/notes/implemented/feature/2026-08-04-claude-code-and-codex-subagent-backends.zh.md);通用 seam 的设计理由见 [subagent Agent Note](https://github.com/deepseek-ai/deepseek-harness/blob/master/.agents/notes/implemented/feature/2026-06-21-subagent-capability-seam.zh.md)、[可继续 subagent Agent Note](https://github.com/deepseek-ai/deepseek-harness/blob/master/.agents/notes/implemented/feature/2026-07-28-continuable-subagent-conversations.zh.md)、[report 工具 Agent Note](https://github.com/deepseek-ai/deepseek-harness/blob/master/.agents/notes/implemented/feature/2026-07-30-continuable-subagent-report-tool.zh.md)、[持久化目录 Agent Note](https://github.com/deepseek-ai/deepseek-harness/blob/master/.agents/notes/implemented/feature/2026-07-22-durable-subagent-catalog-and-list-agents.zh.md)、[列表身份投影 Agent Note](https://github.com/deepseek-ai/deepseek-harness/blob/master/.agents/notes/implemented/architecture/2026-08-06-subagent-list-identity-projection.zh.md)和[服务合并 Agent Note](https://github.com/deepseek-ai/deepseek-harness/blob/master/.agents/notes/implemented/simplification/2026-07-26-merge-subagent-control-service.zh.md)。
|
|
11
11
|
|
|
12
12
|
源码:[`packages/subagent/subagent/src/types.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/subagent/subagent/src/types.ts)、[`packages/subagent/subagent/src/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/subagent/subagent/src/index.ts)和 [`packages/subagent/subagent/src/continuation.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/subagent/subagent/src/continuation.ts)
|
|
13
13
|
|
|
@@ -99,7 +99,7 @@ interface SubagentStartRequest {
|
|
|
99
99
|
}
|
|
100
100
|
```
|
|
101
101
|
|
|
102
|
-
`signal` 是就绪前后唯一的取消通道。[subagent 组合控制 Agent Note](https://github.com/deepseek-ai/deepseek-harness/blob/master/.agents/notes/implemented/feature/2026-07-12-subagent-persona-tool-filter-and-depth.md)规定 persona、live 全局工具过滤、绝对深度以及「可见性而非权限」的设计理由。
|
|
102
|
+
`signal` 是就绪前后唯一的取消通道。[subagent 组合控制 Agent Note](https://github.com/deepseek-ai/deepseek-harness/blob/master/.agents/notes/implemented/feature/2026-07-12-subagent-persona-tool-filter-and-depth.zh.md)规定 persona、live 全局工具过滤、绝对深度以及「可见性而非权限」的设计理由。
|
|
103
103
|
|
|
104
104
|
面向调用方的请求不携带目录格式细节或继续执行状态。`SubagentRuntime.start()` 会在能力检查后解析分离的一次性描述符,再将以下面向提供方的请求传给所选传输;可继续子 agent 绝不会到达 `SubagentProvider.start()`:
|
|
105
105
|
|
|
@@ -289,7 +289,7 @@ interface ContinuableCreateSpec {
|
|
|
289
289
|
|
|
290
290
|
## 持久化枚举:`listChildren()`、`listDescendants()` 与其条目
|
|
291
291
|
|
|
292
|
-
`SubagentRuntime.listChildren(parentSessionId)` 从 `ctx.sessions.list()` 与可选 `ctx.sessionPersistence.list()` 的实时优先合并中枚举 parent 直接且由会话支撑的 subagent——不经查询服务,也不会加载或恢复任何 Agent。候选是持久 header 携带 `origin: 'subagent'` 的直接 child;该标记只负责枚举分类与粗粒度的通用路由拒绝,不能证明描述符有效、child 可恢复或操作已获授权——身份由投影折叠负责,恢复由 Activation 约定负责。每行的 `mode`/`label` 是已注册 `subagent` projection unit 的值,经三级阶梯供值:存活 child 由注册表水位缓存供值(零日志读取);冷 child 先读可选的投影 checkpoint 缓存(`cachedSnapshot`——过 own-suffix seq 门的身份即定值,own descriptor 一经追加不可变);否则在一次 `persistence.inspect()` 读取上经注册表折叠(有界并发,每次列表重新计算)。该缓存是纯可选加速层:服务缺席、行里是 `null` 哨兵或 key 缺席、seq 门不过、读取出错,都静默落到权威重折。折叠规则是 `subagent/descriptor` last-wins 且没有失败通道:子 agent 自己的描述符覆盖 fork seed 中祖先的描述符,格式错误或版本不认识的载荷折叠为可序列化的 `null` 哨兵,视同无值。结果是按 `createdAt`、再按 id 排序的 `SubagentListEntry[]`:取到身份即生成带有 `mode: 'one-shot' | 'continuable'` 和 `activity: 'running' | 'inactive'` 的 `child` 条目;可继续条目始终携带 `label`,一次性条目则只在启动调用方提供展示元数据时携带该字段。已定局而折叠无身份的候选生成 `corrupt` diagnostic——缺失、格式错误与版本不认识的描述符有意不再细分(`unsupported` 仍保留在类型中但从不产出);运行中而无身份的候选被省略(描述符落盘前的创建窗口);冷检查失败生成一条 `unavailable` diagnostic 并在下次列表自然重试,因此一个损坏的 sibling 不会隐藏健康 child。`hasChildren` 标记存在持久 subagent origin 的直接后代,读取自同一份合并材料。活动状态只表示逻辑记录是否在 `ctx.sessions` 中存活,而不表示结果或可恢复性。缺少持久化时,枚举退化为仅存活枚举而不是报错——此时冷 child 本就无法恢复。缺少 `ctx.sessionProjections` 注册表时,`listChildren()` 抛出携带错误码 `SUBAGENT_CONTROL_PROJECTIONS_UNAVAILABLE` 的 `SubagentError`,缺少会话存储时则抛出 `SUBAGENT_CONTROL_SESSION_STORE_UNAVAILABLE`,两者都在任何读取之前检查,因此零 child 的部署同样确定失败;列表工具在插件加载时要求 `ctx.subagents` 与 `ctx.agents`。UI 等服务消费方可以展示两种模式,并为无标签的一次性 child 选择回退展示;面向模型的 `list_agents` 适配器([dsh-tool-subagent-control](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/subagent/tool-subagent-control) 中可单独加载的 `/list-agents` 插件)则只保留可继续条目,并通过在线 Agent 注册表将状态细化为自己的 `running`/`idle`/`ready` 词汇,其中 `ready` 把仅存于存储的 child 命名为可恢复而非终态。枚举不会查询继续执行管理器的 Activation map、Agent 注册表或提供方可用性;`send_message` 仍是消息送达时的权威操作,列表中的运行中可继续 child 仍可能因所有权冲突而拒绝投递。读路径的设计理由见[列表身份投影 Agent Note](https://github.com/deepseek-ai/deepseek-harness/blob/master/.agents/notes/implemented/architecture/2026-08-06-subagent-list-identity-projection.md)。
|
|
292
|
+
`SubagentRuntime.listChildren(parentSessionId)` 从 `ctx.sessions.list()` 与可选 `ctx.sessionPersistence.list()` 的实时优先合并中枚举 parent 直接且由会话支撑的 subagent——不经查询服务,也不会加载或恢复任何 Agent。候选是持久 header 携带 `origin: 'subagent'` 的直接 child;该标记只负责枚举分类与粗粒度的通用路由拒绝,不能证明描述符有效、child 可恢复或操作已获授权——身份由投影折叠负责,恢复由 Activation 约定负责。每行的 `mode`/`label` 是已注册 `subagent` projection unit 的值,经三级阶梯供值:存活 child 由注册表水位缓存供值(零日志读取);冷 child 先读可选的投影 checkpoint 缓存(`cachedSnapshot`——过 own-suffix seq 门的身份即定值,own descriptor 一经追加不可变);否则在一次 `persistence.inspect()` 读取上经注册表折叠(有界并发,每次列表重新计算)。该缓存是纯可选加速层:服务缺席、行里是 `null` 哨兵或 key 缺席、seq 门不过、读取出错,都静默落到权威重折。折叠规则是 `subagent/descriptor` last-wins 且没有失败通道:子 agent 自己的描述符覆盖 fork seed 中祖先的描述符,格式错误或版本不认识的载荷折叠为可序列化的 `null` 哨兵,视同无值。结果是按 `createdAt`、再按 id 排序的 `SubagentListEntry[]`:取到身份即生成带有 `mode: 'one-shot' | 'continuable'` 和 `activity: 'running' | 'inactive'` 的 `child` 条目;可继续条目始终携带 `label`,一次性条目则只在启动调用方提供展示元数据时携带该字段。已定局而折叠无身份的候选生成 `corrupt` diagnostic——缺失、格式错误与版本不认识的描述符有意不再细分(`unsupported` 仍保留在类型中但从不产出);运行中而无身份的候选被省略(描述符落盘前的创建窗口);冷检查失败生成一条 `unavailable` diagnostic 并在下次列表自然重试,因此一个损坏的 sibling 不会隐藏健康 child。`hasChildren` 标记存在持久 subagent origin 的直接后代,读取自同一份合并材料。活动状态只表示逻辑记录是否在 `ctx.sessions` 中存活,而不表示结果或可恢复性。缺少持久化时,枚举退化为仅存活枚举而不是报错——此时冷 child 本就无法恢复。缺少 `ctx.sessionProjections` 注册表时,`listChildren()` 抛出携带错误码 `SUBAGENT_CONTROL_PROJECTIONS_UNAVAILABLE` 的 `SubagentError`,缺少会话存储时则抛出 `SUBAGENT_CONTROL_SESSION_STORE_UNAVAILABLE`,两者都在任何读取之前检查,因此零 child 的部署同样确定失败;列表工具在插件加载时要求 `ctx.subagents` 与 `ctx.agents`。UI 等服务消费方可以展示两种模式,并为无标签的一次性 child 选择回退展示;面向模型的 `list_agents` 适配器([dsh-tool-subagent-control](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/subagent/tool-subagent-control) 中可单独加载的 `/list-agents` 插件)则只保留可继续条目,并通过在线 Agent 注册表将状态细化为自己的 `running`/`idle`/`ready` 词汇,其中 `ready` 把仅存于存储的 child 命名为可恢复而非终态。枚举不会查询继续执行管理器的 Activation map、Agent 注册表或提供方可用性;`send_message` 仍是消息送达时的权威操作,列表中的运行中可继续 child 仍可能因所有权冲突而拒绝投递。读路径的设计理由见[列表身份投影 Agent Note](https://github.com/deepseek-ai/deepseek-harness/blob/master/.agents/notes/implemented/architecture/2026-08-06-subagent-list-identity-projection.zh.md)。
|
|
293
293
|
|
|
294
294
|
`SubagentRuntime.listDescendants(rootSessionId)` 将同一份实时优先语料与基于投影的解释应用到根的完整后代树,并按稳定 pre-order 输出。普通会话和一次性 child 仍作为遍历节点,因此其下的可继续后代仍可发现;只有 `origin: 'subagent'` 的候选会生成条目。每个返回的 child 或 diagnostic 都从枚举所得的持久 header 附加树位置;冷检查在提供身份前还会重新校验完整生命周期:
|
|
295
295
|
|
|
@@ -308,6 +308,8 @@ type SubagentDescendantListEntry = SubagentListEntry & {
|
|
|
308
308
|
```
|
|
309
309
|
|
|
310
310
|
|
|
311
|
+
<a id="the-terminal-result-subagentresult"></a>
|
|
312
|
+
|
|
311
313
|
## 终态结果:`SubagentResult`
|
|
312
314
|
|
|
313
315
|
单次 run 的最终产出,由 `SubagentRun.result` resolve。`structured` 仅在请求了 `outputSchema` 且成功满足时才存在;请求 schema 不保证一定能得到它,当子 agent 失败或结束时未产出有效 capture 时,提供方可能返回 `stopReason: 'error'`。提供方可以为非 `completed` 结果附带安全且不属于 assistant 内容的 `diagnostic`;在消费方将它与 `output` 分开呈现前,提供方会排除工具输入、文件内容、环境值、凭证与原始协议载荷,并把完整值限制在 4096 个 UTF-8 字节以内。非 `completed` 的 `stopReason` 意味着 `output` 可能不完整——消费方将其映射为 `isError` 的工具结果,而非将部分输出报告为成功。
|
|
@@ -485,7 +487,7 @@ spawn 和 fork 后端通过 `parent.ctx` 创建一个普通的单次 agent,将
|
|
|
485
487
|
|
|
486
488
|
## Cordis API
|
|
487
489
|
|
|
488
|
-
Generated from source by `scripts/gen-cordis-catalog.ts` (verified fresh by `pnpm run verify-cordis-catalog` in doc-sync; regenerate with `pnpm run gen-cordis-catalog`) —
|
|
490
|
+
Generated from source by `scripts/gen-cordis-catalog.ts` (verified fresh by `pnpm run verify-cordis-catalog` in doc-sync; regenerate with `pnpm run gen-cordis-catalog`) — the language sides differ only in locale-specific paired document paths. Signature blocks use a `ts cordis-catalog` fence and keep the original source JSDoc; dispatch modes are defined in the [primer](../cordis-primer.md#dispatch-modes), and the framework-inherited `ctx` API lives in [cordis-api/inherited.md](../cordis-api/inherited.md).
|
|
489
491
|
|
|
490
492
|
<a id="ctxsubagents--subagentruntime"></a>
|
|
491
493
|
|
|
@@ -670,7 +672,7 @@ async start(name: string, request: SubagentStartRequest): Promise<SubagentRun>
|
|
|
670
672
|
|
|
671
673
|
Types: [Agent](./core.md) · [ContentBlock](./llm-streaming.md) · [MessageId](./llm-streaming.md) · [SessionId](./core.md)
|
|
672
674
|
|
|
673
|
-
Source: [`packages/subagent/subagent/src/index.ts
|
|
675
|
+
Source: [`packages/subagent/subagent/src/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/subagent/subagent/src/index.ts)
|
|
674
676
|
|
|
675
677
|
<a id="subagent-events"></a>
|
|
676
678
|
|
|
@@ -696,7 +698,7 @@ A published child settled. Scope-filtered dispatch uses the same delegating pare
|
|
|
696
698
|
|
|
697
699
|
Types: [Scoped](./scope.md)
|
|
698
700
|
|
|
699
|
-
Source: [`packages/subagent/subagent/src/index.ts
|
|
701
|
+
Source: [`packages/subagent/subagent/src/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/subagent/subagent/src/index.ts)
|
|
700
702
|
|
|
701
703
|
<a id="subagentprovider-added--emit"></a>
|
|
702
704
|
|
|
@@ -713,7 +715,7 @@ A provider became resolvable in the registry.
|
|
|
713
715
|
'subagent/provider-added'(provider: SubagentProvider): void
|
|
714
716
|
```
|
|
715
717
|
|
|
716
|
-
Source: [`packages/subagent/subagent/src/index.ts
|
|
718
|
+
Source: [`packages/subagent/subagent/src/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/subagent/subagent/src/index.ts)
|
|
717
719
|
|
|
718
720
|
<a id="subagentprovider-removed--emit"></a>
|
|
719
721
|
|
|
@@ -730,7 +732,7 @@ A provider left the registry. Accepted runs remain holder-owned.
|
|
|
730
732
|
'subagent/provider-removed'(name: string): void
|
|
731
733
|
```
|
|
732
734
|
|
|
733
|
-
Source: [`packages/subagent/subagent/src/index.ts
|
|
735
|
+
Source: [`packages/subagent/subagent/src/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/subagent/subagent/src/index.ts)
|
|
734
736
|
|
|
735
737
|
<a id="subagentstart--emit"></a>
|
|
736
738
|
|
|
@@ -754,5 +756,5 @@ A provider established a published child. For in-process providers, `ctx.agents.
|
|
|
754
756
|
|
|
755
757
|
Types: [Scoped](./scope.md)
|
|
756
758
|
|
|
757
|
-
Source: [`packages/subagent/subagent/src/index.ts
|
|
759
|
+
Source: [`packages/subagent/subagent/src/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/subagent/subagent/src/index.ts)
|
|
758
760
|
<!-- END GENERATED cordis-surface -->
|
|
@@ -249,7 +249,7 @@ interface SubprocessOutcome {
|
|
|
249
249
|
|
|
250
250
|
## 服务行为
|
|
251
251
|
|
|
252
|
-
抽象的 [`SubprocessRuntime`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/subprocess/subprocess/src/index.ts) Service Definition 规定执行世界坐标、可执行文件查找、普通 `spawn` 与 `spawnTerminal`。[`LocalSubprocessRuntime`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/subprocess/subprocess-local/src/index.ts) 以 detached 进程树、按处置方式接线、凭据清除、`node-pty`、平台进程检查,以及先终止再等待退出的资源释放提供这些能力。Service Definition 约定见 [`dsh-subprocess`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/subprocess/subprocess/README.md),本地机制见 [`dsh-subprocess-local`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/subprocess/subprocess-local/README.md)。
|
|
252
|
+
抽象的 [`SubprocessRuntime`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/subprocess/subprocess/src/index.ts) Service Definition 规定执行世界坐标、可执行文件查找、普通 `spawn` 与 `spawnTerminal`。[`LocalSubprocessRuntime`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/subprocess/subprocess-local/src/index.ts) 以 detached 进程树、按处置方式接线、凭据清除、`node-pty`、平台进程检查,以及先终止再等待退出的资源释放提供这些能力。Service Definition 约定见 [`dsh-subprocess`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/subprocess/subprocess/README.zh.md),本地机制见 [`dsh-subprocess-local`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/subprocess/subprocess-local/README.zh.md)。
|
|
253
253
|
|
|
254
254
|
<!-- BEGIN GENERATED cordis-surface (gen-cordis-catalog.ts) — do not edit between markers -->
|
|
255
255
|
|
|
@@ -257,7 +257,7 @@ interface SubprocessOutcome {
|
|
|
257
257
|
|
|
258
258
|
## Cordis API
|
|
259
259
|
|
|
260
|
-
Generated from source by `scripts/gen-cordis-catalog.ts` (verified fresh by `pnpm run verify-cordis-catalog` in doc-sync; regenerate with `pnpm run gen-cordis-catalog`) —
|
|
260
|
+
Generated from source by `scripts/gen-cordis-catalog.ts` (verified fresh by `pnpm run verify-cordis-catalog` in doc-sync; regenerate with `pnpm run gen-cordis-catalog`) — the language sides differ only in locale-specific paired document paths. Signature blocks use a `ts cordis-catalog` fence and keep the original source JSDoc; dispatch modes are defined in the [primer](../cordis-primer.md#dispatch-modes), and the framework-inherited `ctx` API lives in [cordis-api/inherited.md](../cordis-api/inherited.md).
|
|
261
261
|
|
|
262
262
|
<a id="ctxe2b--e2bruntime"></a>
|
|
263
263
|
|
|
@@ -274,7 +274,7 @@ Creates one lazily consumable E2B SDK handle and deletes the sandbox at timeout
|
|
|
274
274
|
async getSandbox(): Promise<Sandbox>
|
|
275
275
|
```
|
|
276
276
|
|
|
277
|
-
Source: [`packages/e2b/e2b/src/index.ts
|
|
277
|
+
Source: [`packages/e2b/e2b/src/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/e2b/e2b/src/index.ts)
|
|
278
278
|
|
|
279
279
|
<a id="ctxsubprocess--subprocessruntime-abstract-seam"></a>
|
|
280
280
|
|
|
@@ -323,5 +323,5 @@ abstract spawn(spec: SubprocessSpawnSpec): SubprocessHandle
|
|
|
323
323
|
abstract spawnTerminal(spec: SubprocessTerminalSpawnSpec): Promise<SubprocessTerminalHandle>
|
|
324
324
|
```
|
|
325
325
|
|
|
326
|
-
Source: [`packages/subprocess/subprocess/src/index.ts
|
|
326
|
+
Source: [`packages/subprocess/subprocess/src/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/subprocess/subprocess/src/index.ts)
|
|
327
327
|
<!-- END GENERATED cordis-surface -->
|
|
@@ -5,7 +5,7 @@ outline: [2,3]
|
|
|
5
5
|
|
|
6
6
|
# 系统提示词组装
|
|
7
7
|
|
|
8
|
-
[system-prompt 包](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/core/system-prompt)负责管理提示词贡献者与一次组装调用之间交换的数据。该包的 [README](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/core/system-prompt/README.md) 记录注册、排序、作用域与渲染行为;本页记录各插件实现或传递的确切跨包类型。
|
|
8
|
+
[system-prompt 包](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/core/system-prompt)负责管理提示词贡献者与一次组装调用之间交换的数据。该包的 [README](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/core/system-prompt/README.zh.md) 记录注册、排序、作用域与渲染行为;本页记录各插件实现或传递的确切跨包类型。
|
|
9
9
|
|
|
10
10
|
源码:[`packages/core/system-prompt/src/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/core/system-prompt/src/index.ts)。
|
|
11
11
|
|
|
@@ -93,7 +93,7 @@ interface PromptContext {
|
|
|
93
93
|
|
|
94
94
|
## Cordis API
|
|
95
95
|
|
|
96
|
-
Generated from source by `scripts/gen-cordis-catalog.ts` (verified fresh by `pnpm run verify-cordis-catalog` in doc-sync; regenerate with `pnpm run gen-cordis-catalog`) —
|
|
96
|
+
Generated from source by `scripts/gen-cordis-catalog.ts` (verified fresh by `pnpm run verify-cordis-catalog` in doc-sync; regenerate with `pnpm run gen-cordis-catalog`) — the language sides differ only in locale-specific paired document paths. Signature blocks use a `ts cordis-catalog` fence and keep the original source JSDoc; dispatch modes are defined in the [primer](../cordis-primer.md#dispatch-modes), and the framework-inherited `ctx` API lives in [cordis-api/inherited.md](../cordis-api/inherited.md).
|
|
97
97
|
|
|
98
98
|
<a id="ctxsystemprompt--systemprompt"></a>
|
|
99
99
|
|
|
@@ -159,7 +159,7 @@ variable(name: string, provider: (context: AssembleContext) => string | undefine
|
|
|
159
159
|
async assemble(context: AssembleContext = {}): Promise<PromptAssembly>
|
|
160
160
|
```
|
|
161
161
|
|
|
162
|
-
Source: [`packages/core/system-prompt/src/index.ts
|
|
162
|
+
Source: [`packages/core/system-prompt/src/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/core/system-prompt/src/index.ts)
|
|
163
163
|
|
|
164
164
|
<a id="system-prompt-events"></a>
|
|
165
165
|
|
|
@@ -189,7 +189,7 @@ Expert waterfall over the assembled sections, contexts, tools, and variables. Sc
|
|
|
189
189
|
|
|
190
190
|
Types: [Scoped](./scope.md)
|
|
191
191
|
|
|
192
|
-
Source: [`packages/core/system-prompt/src/index.ts
|
|
192
|
+
Source: [`packages/core/system-prompt/src/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/core/system-prompt/src/index.ts)
|
|
193
193
|
|
|
194
194
|
<a id="system-promptchange--emit"></a>
|
|
195
195
|
|
|
@@ -206,5 +206,5 @@ Emitted when any prompt provider changes. This registry notification is unfilter
|
|
|
206
206
|
'system-prompt/change'(): void
|
|
207
207
|
```
|
|
208
208
|
|
|
209
|
-
Source: [`packages/core/system-prompt/src/index.ts
|
|
209
|
+
Source: [`packages/core/system-prompt/src/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/core/system-prompt/src/index.ts)
|
|
210
210
|
<!-- END GENERATED cordis-surface -->
|
|
@@ -5,7 +5,7 @@ outline: [2,3]
|
|
|
5
5
|
|
|
6
6
|
# 持久 PTY 会话
|
|
7
7
|
|
|
8
|
-
PTY 后端、`ctx.terminals` 与面向模型的消费方共享的类型。[持久 PTY Agent Note](https://github.com/deepseek-ai/deepseek-harness/blob/master/.agents/notes/implemented/feature/2026-07-16-persistent-pty-sessions.md) 负责记录决策依据;本页记录来自 [`packages/terminal/terminal/src/types.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/terminal/terminal/src/types.ts) 的跨包词汇。
|
|
8
|
+
PTY 后端、`ctx.terminals` 与面向模型的消费方共享的类型。[持久 PTY Agent Note](https://github.com/deepseek-ai/deepseek-harness/blob/master/.agents/notes/implemented/feature/2026-07-16-persistent-pty-sessions.zh.md) 负责记录决策依据;本页记录来自 [`packages/terminal/terminal/src/types.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/terminal/terminal/src/types.ts) 的跨包词汇。
|
|
9
9
|
|
|
10
10
|
## 标识与就绪
|
|
11
11
|
|
|
@@ -99,7 +99,7 @@ interface TerminalSendResult {
|
|
|
99
99
|
|
|
100
100
|
## Cordis API
|
|
101
101
|
|
|
102
|
-
Generated from source by `scripts/gen-cordis-catalog.ts` (verified fresh by `pnpm run verify-cordis-catalog` in doc-sync; regenerate with `pnpm run gen-cordis-catalog`) —
|
|
102
|
+
Generated from source by `scripts/gen-cordis-catalog.ts` (verified fresh by `pnpm run verify-cordis-catalog` in doc-sync; regenerate with `pnpm run gen-cordis-catalog`) — the language sides differ only in locale-specific paired document paths. Signature blocks use a `ts cordis-catalog` fence and keep the original source JSDoc; dispatch modes are defined in the [primer](../cordis-primer.md#dispatch-modes), and the framework-inherited `ctx` API lives in [cordis-api/inherited.md](../cordis-api/inherited.md).
|
|
103
103
|
|
|
104
104
|
<a id="ctxterminals--terminalsessionservice"></a>
|
|
105
105
|
|
|
@@ -183,5 +183,5 @@ list(owner: Agent): TerminalSessionSnapshot[]
|
|
|
183
183
|
|
|
184
184
|
Types: [Agent](./core.md)
|
|
185
185
|
|
|
186
|
-
Source: [`packages/terminal/terminal/src/index.ts
|
|
186
|
+
Source: [`packages/terminal/terminal/src/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/terminal/terminal/src/index.ts)
|
|
187
187
|
<!-- END GENERATED cordis-surface -->
|
|
@@ -51,7 +51,7 @@ interface TokenSurfaceNode {
|
|
|
51
51
|
|
|
52
52
|
## Cordis API
|
|
53
53
|
|
|
54
|
-
Generated from source by `scripts/gen-cordis-catalog.ts` (verified fresh by `pnpm run verify-cordis-catalog` in doc-sync; regenerate with `pnpm run gen-cordis-catalog`) —
|
|
54
|
+
Generated from source by `scripts/gen-cordis-catalog.ts` (verified fresh by `pnpm run verify-cordis-catalog` in doc-sync; regenerate with `pnpm run gen-cordis-catalog`) — the language sides differ only in locale-specific paired document paths. Signature blocks use a `ts cordis-catalog` fence and keep the original source JSDoc; dispatch modes are defined in the [primer](../cordis-primer.md#dispatch-modes), and the framework-inherited `ctx` API lives in [cordis-api/inherited.md](../cordis-api/inherited.md).
|
|
55
55
|
|
|
56
56
|
<a id="ctxtokenmeter--tokenmeter"></a>
|
|
57
57
|
|
|
@@ -89,5 +89,5 @@ estimateMessage(message: Message): number
|
|
|
89
89
|
|
|
90
90
|
Types: [EpochHeader](./session.md) · [Message](./llm-streaming.md) · [Session](./session.md)
|
|
91
91
|
|
|
92
|
-
Source: [`packages/llm/token-meter/src/index.ts
|
|
92
|
+
Source: [`packages/llm/token-meter/src/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/llm/token-meter/src/index.ts)
|
|
93
93
|
<!-- END GENERATED cordis-surface -->
|
|
@@ -466,7 +466,7 @@ type ObjectJsonSchema = JsonSchemaNode & { type: 'object' }
|
|
|
466
466
|
- `ToolCallView`(待执行):`{ card: 'generic', title, kind?, rawInput?, content?, locations? }`(默认卡片;`locations` 是 `{ path, line? }[]`,表示调用读取/修改的文件,供编辑器跟随)、`{ card: 'terminal', title, description?, cwd? }`(shell 命令→终端卡片)、或 `{ card: 'diff', title, diffs, locations? }`(文件创建/修改→行内 diff 卡片;`diffs` 是 `{ path, oldText, newText }[]`,新文件时 `oldText: null`)。
|
|
467
467
|
- `ToolResultView`(已完成):`{ card: 'generic', title?, content? }`、`{ card: 'terminal', title?, output?, exitCode?, signal? }`(捕获的运行输出 + 退出状态;有能力的 UI 显示退出状态标签,其他 UI 可以派生围栏 ` ```console ` 回退)、`{ card: 'diff', title?, diffs }`(已完成的文件变更→要展示的变更,通常是从变更前后内容计算出带上下文行的已应用 hunk,或在没有前像时的整文件 diff)、`{ card: 'search', shape, title?, truncated, total, … }`(已完成的发现型搜索→`shape: 'matches'`(grep)为按文件分组的匹配,`shape: 'paths'`(glob)为扁平路径列表;`truncated`/`total` 报告内联结果是否被截断,使 UI 永不把部分结果当作完整结果呈现;该视图不携带结果文本——无 search 卡片的 UI 回退到原始结果内容)、`{ card: 'read', title?, path, offset, lines, totalLines, lang?, content? }`(已完成的文件读取→带行号、可选语法高亮的代码视图;`offset` 是窗口请求的 1-based 起始行,即使 `lines` 为空也保留;`lang` 是从扩展名推得的语言提示,`content` 是无读取能力的 UI 回退时使用的去信封文本)、或 `{ card: 'web', kind: 'search' | 'fetch', title?, … }`(已完成的 web 检索;`kind: 'search'` 携带结构化的 `sources`/`answer?`/`truncated`,`kind: 'fetch'` 携带 `url`/`statusCode`/`truncated`,不具备 `web` 能力的 UI 回退到原始结果内容——正文不会重复进视图)。已完成视图会替换待执行视图,因此变更工具即使与调用时的片段重复也要返回 diff 结果;搜索和 web 检索都没有 `card` 的调用时对应视图(其 pending 状态保持为 generic 卡片,因为结构化结果只在 `execute` 之后才存在)。
|
|
468
468
|
|
|
469
|
-
`ToolCallKind`(`'read' | 'edit' | 'delete' | 'move' | 'search' | 'execute' | 'fetch' | 'other'`)用于为通用卡片选择图标。`FileLocation`(`{ path, line? }`)、`FileDiff`(`{ path, oldText, newText }`)与 `ReadFileLine`(`{ number, text }`,读取窗口中一行带 1-based 行号的内容)是共享的文件卡片词汇。该设计由[渲染意图联合类型 Agent Note](https://github.com/deepseek-ai/deepseek-harness/blob/master/.agents/notes/implemented/architecture/2026-07-02-tool-render-intent-union.md)固定;host/client 运行时将这套中性词汇投影为各自的视图。
|
|
469
|
+
`ToolCallKind`(`'read' | 'edit' | 'delete' | 'move' | 'search' | 'execute' | 'fetch' | 'other'`)用于为通用卡片选择图标。`FileLocation`(`{ path, line? }`)、`FileDiff`(`{ path, oldText, newText }`)与 `ReadFileLine`(`{ number, text }`,读取窗口中一行带 1-based 行号的内容)是共享的文件卡片词汇。该设计由[渲染意图联合类型 Agent Note](https://github.com/deepseek-ai/deepseek-harness/blob/master/.agents/notes/implemented/architecture/2026-07-02-tool-render-intent-union.zh.md)固定;host/client 运行时将这套中性词汇投影为各自的视图。
|
|
470
470
|
|
|
471
471
|
完整的展示字段文档见 [`packages/core/tools/src/presentation.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/core/tools/src/presentation.ts)。`bash` schema 与执行器见 [shell.md](./shell.md);通用后台控制见 [jobs.md](./jobs.md)。
|
|
472
472
|
|
|
@@ -476,7 +476,7 @@ type ObjectJsonSchema = JsonSchemaNode & { type: 'object' }
|
|
|
476
476
|
|
|
477
477
|
## Cordis API
|
|
478
478
|
|
|
479
|
-
Generated from source by `scripts/gen-cordis-catalog.ts` (verified fresh by `pnpm run verify-cordis-catalog` in doc-sync; regenerate with `pnpm run gen-cordis-catalog`) —
|
|
479
|
+
Generated from source by `scripts/gen-cordis-catalog.ts` (verified fresh by `pnpm run verify-cordis-catalog` in doc-sync; regenerate with `pnpm run gen-cordis-catalog`) — the language sides differ only in locale-specific paired document paths. Signature blocks use a `ts cordis-catalog` fence and keep the original source JSDoc; dispatch modes are defined in the [primer](../cordis-primer.md#dispatch-modes), and the framework-inherited `ctx` API lives in [cordis-api/inherited.md](../cordis-api/inherited.md).
|
|
480
480
|
|
|
481
481
|
<a id="ctxtools--toolruntime"></a>
|
|
482
482
|
|
|
@@ -574,7 +574,7 @@ async execute(exec: ToolExecutionInput): Promise<ToolExecutionResult>
|
|
|
574
574
|
|
|
575
575
|
Types: [ScopeKey](./scope.md)
|
|
576
576
|
|
|
577
|
-
Source: [`packages/core/tools/src/index.ts
|
|
577
|
+
Source: [`packages/core/tools/src/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/core/tools/src/index.ts)
|
|
578
578
|
|
|
579
579
|
<a id="tools-events"></a>
|
|
580
580
|
|
|
@@ -599,7 +599,7 @@ A tool was registered or unregistered, or a scoped restriction changed (the avai
|
|
|
599
599
|
'tools/change'(): void
|
|
600
600
|
```
|
|
601
601
|
|
|
602
|
-
Source: [`packages/core/tools/src/index.ts
|
|
602
|
+
Source: [`packages/core/tools/src/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/core/tools/src/index.ts)
|
|
603
603
|
|
|
604
604
|
<a id="toolscode-dispatch-log--waterfall"></a>
|
|
605
605
|
|
|
@@ -626,7 +626,7 @@ Allow a listener to replace content in the DURABLE LOG COPY of one `run_code` su
|
|
|
626
626
|
|
|
627
627
|
Types: [ContentBlock](./llm-streaming.md) · [Scoped](./scope.md)
|
|
628
628
|
|
|
629
|
-
Source: [`packages/core/tools/src/index.ts
|
|
629
|
+
Source: [`packages/core/tools/src/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/core/tools/src/index.ts)
|
|
630
630
|
|
|
631
631
|
<a id="toolsexecute--waterfall"></a>
|
|
632
632
|
|
|
@@ -650,7 +650,7 @@ Around-dispatch waterfall for timeout, retry, or metrics. `next()` returns a nor
|
|
|
650
650
|
|
|
651
651
|
Types: [Scoped](./scope.md)
|
|
652
652
|
|
|
653
|
-
Source: [`packages/core/tools/src/index.ts
|
|
653
|
+
Source: [`packages/core/tools/src/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/core/tools/src/index.ts)
|
|
654
654
|
|
|
655
655
|
<a id="toolspost-execute--waterfall"></a>
|
|
656
656
|
|
|
@@ -675,7 +675,7 @@ Accept, replace, enrich, or block a normalized dispatch result. `next()` accepts
|
|
|
675
675
|
|
|
676
676
|
Types: [Scoped](./scope.md)
|
|
677
677
|
|
|
678
|
-
Source: [`packages/core/tools/src/index.ts
|
|
678
|
+
Source: [`packages/core/tools/src/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/core/tools/src/index.ts)
|
|
679
679
|
|
|
680
680
|
<a id="toolspre-execute--waterfall"></a>
|
|
681
681
|
|
|
@@ -698,7 +698,7 @@ Allow, deny, or ask before dispatch. `next()` delegates to allow; missing approv
|
|
|
698
698
|
|
|
699
699
|
Types: [Scoped](./scope.md)
|
|
700
700
|
|
|
701
|
-
Source: [`packages/core/tools/src/index.ts
|
|
701
|
+
Source: [`packages/core/tools/src/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/core/tools/src/index.ts)
|
|
702
702
|
|
|
703
703
|
<a id="toolsresult--emit"></a>
|
|
704
704
|
|
|
@@ -719,5 +719,5 @@ Observe the frozen, lossless-JSON final outcome. Listener failures are contained
|
|
|
719
719
|
|
|
720
720
|
Types: [Scoped](./scope.md)
|
|
721
721
|
|
|
722
|
-
Source: [`packages/core/tools/src/index.ts
|
|
722
|
+
Source: [`packages/core/tools/src/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/core/tools/src/index.ts)
|
|
723
723
|
<!-- END GENERATED cordis-surface -->
|
|
@@ -5,7 +5,7 @@ outline: [2,3]
|
|
|
5
5
|
|
|
6
6
|
# Typert 远程调用
|
|
7
7
|
|
|
8
|
-
以下类型由生成的 Remote 产物、Host Gateway 与消费方 API assembly 共用。[Typert Gateway Agent Note](https://github.com/deepseek-ai/deepseek-harness/blob/master/.agents/notes/implemented/architecture/2026-08-02-typert-remote-method-calls.md) 负责架构与传输决策;本页记录 [`dsh-typert-protocol`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/typert/protocol/src/types.ts) 和 [`dsh-api-gateway`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/api/gateway/src/types.ts) 中公共约定的字面定义。
|
|
8
|
+
以下类型由生成的 Remote 产物、Host Gateway 与消费方 API assembly 共用。[Typert Gateway Agent Note](https://github.com/deepseek-ai/deepseek-harness/blob/master/.agents/notes/implemented/architecture/2026-08-02-typert-remote-method-calls.zh.md) 负责架构与传输决策;本页记录 [`dsh-typert-protocol`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/typert/protocol/src/types.ts) 和 [`dsh-api-gateway`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/api/gateway/src/types.ts) 中公共约定的字面定义。
|
|
9
9
|
|
|
10
10
|
## Lookup 与上下文声明
|
|
11
11
|
|
|
@@ -234,7 +234,7 @@ interface TypertClientRemote extends TypertRemoteNamespaceMap {
|
|
|
234
234
|
|
|
235
235
|
## Cordis API
|
|
236
236
|
|
|
237
|
-
Generated from source by `scripts/gen-cordis-catalog.ts` (verified fresh by `pnpm run verify-cordis-catalog` in doc-sync; regenerate with `pnpm run gen-cordis-catalog`) —
|
|
237
|
+
Generated from source by `scripts/gen-cordis-catalog.ts` (verified fresh by `pnpm run verify-cordis-catalog` in doc-sync; regenerate with `pnpm run gen-cordis-catalog`) — the language sides differ only in locale-specific paired document paths. Signature blocks use a `ts cordis-catalog` fence and keep the original source JSDoc; dispatch modes are defined in the [primer](../cordis-primer.md#dispatch-modes), and the framework-inherited `ctx` API lives in [cordis-api/inherited.md](../cordis-api/inherited.md).
|
|
238
238
|
|
|
239
239
|
<a id="ctxapiproxy--apiproxy"></a>
|
|
240
240
|
|
|
@@ -251,7 +251,7 @@ Root interface of the unified API. New client-request domain = one new file pair
|
|
|
251
251
|
respond(message: ClientResponse): Promise<RpcReceipt>
|
|
252
252
|
```
|
|
253
253
|
|
|
254
|
-
Source: [`packages/host/apiproxy/src/api/index.ts
|
|
254
|
+
Source: [`packages/host/apiproxy/src/api/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/host/apiproxy/src/api/index.ts)
|
|
255
255
|
|
|
256
256
|
<a id="ctxtypert--typertregistry"></a>
|
|
257
257
|
|
|
@@ -317,7 +317,7 @@ toJSONSchema(key: string, params?: z.core.ToJSONSchemaParams): z.core.JSONSchema
|
|
|
317
317
|
|
|
318
318
|
Types: [TypertContribution](./invariants.md) · [TypertFace](./invariants.md) · [TypertPackageFilter](./invariants.md) · [TypertPackageRecord](./invariants.md) · [TypertSchemaFilter](./invariants.md) · [TypertSchemaRecord](./invariants.md)
|
|
319
319
|
|
|
320
|
-
Source: [`packages/typert/registry/src/service.ts
|
|
320
|
+
Source: [`packages/typert/registry/src/service.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/typert/registry/src/service.ts)
|
|
321
321
|
|
|
322
322
|
<a id="ctxtypertgateway--typertgatewayservice"></a>
|
|
323
323
|
|
|
@@ -335,5 +335,5 @@ Resolve strict generated definitions or conservative SRC markers against current
|
|
|
335
335
|
async invoke(request: InvokeRemoteRequest): Promise<unknown>
|
|
336
336
|
```
|
|
337
337
|
|
|
338
|
-
Source: [`packages/api/gateway/src/index.ts
|
|
338
|
+
Source: [`packages/api/gateway/src/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/api/gateway/src/index.ts)
|
|
339
339
|
<!-- END GENERATED cordis-surface -->
|
|
@@ -142,7 +142,7 @@ class UserQuestionError extends HarnessError {
|
|
|
142
142
|
|
|
143
143
|
## Cordis API
|
|
144
144
|
|
|
145
|
-
Generated from source by `scripts/gen-cordis-catalog.ts` (verified fresh by `pnpm run verify-cordis-catalog` in doc-sync; regenerate with `pnpm run gen-cordis-catalog`) —
|
|
145
|
+
Generated from source by `scripts/gen-cordis-catalog.ts` (verified fresh by `pnpm run verify-cordis-catalog` in doc-sync; regenerate with `pnpm run gen-cordis-catalog`) — the language sides differ only in locale-specific paired document paths. Signature blocks use a `ts cordis-catalog` fence and keep the original source JSDoc; dispatch modes are defined in the [primer](../cordis-primer.md#dispatch-modes), and the framework-inherited `ctx` API lives in [cordis-api/inherited.md](../cordis-api/inherited.md).
|
|
146
146
|
|
|
147
147
|
<a id="ctxuserquestions--userquestionservice"></a>
|
|
148
148
|
|
|
@@ -177,5 +177,5 @@ registerProvider(provider: UserQuestionProvider): () => void
|
|
|
177
177
|
async ask(request: AskUserQuestionRequest): Promise<AskUserQuestionAnswer>
|
|
178
178
|
```
|
|
179
179
|
|
|
180
|
-
Source: [`packages/interaction/user-questions/src/index.ts
|
|
180
|
+
Source: [`packages/interaction/user-questions/src/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/interaction/user-questions/src/index.ts)
|
|
181
181
|
<!-- END GENERATED cordis-surface -->
|
|
@@ -5,7 +5,7 @@ outline: [2,3]
|
|
|
5
5
|
|
|
6
6
|
# HTTP 服务器
|
|
7
7
|
|
|
8
|
-
[dsh-host-webserver](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/host/webserver) 是 GUI 宿主的浏览器 HTTP 载体:它是一个提供 `ctx.webServer` 的 `node:http` 插件,包含具名路由注册表、index.html 转换回调,以及一个可由插件认领的回退处理器。它不属于 agent loop(智能体循环),也不是能力 seam;它不了解任何 harness 概念。其他插件负责注册所有功能路由,包括 `/api` 桥接、插件 bundle 和 HMR(热模块替换)事件流([分层说明](https://github.com/deepseek-ai/deepseek-harness/blob/master/.agents/notes/implemented/architecture/2026-07-19-gui-layering-and-rpc-protocol.md))。该服务器只服务浏览器:Electron 通过 `file://` 加载已构建文件,并经 IPC 桥接发送 fetch 请求,不使用本服务器。
|
|
8
|
+
[dsh-host-webserver](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/host/webserver) 是 GUI 宿主的浏览器 HTTP 载体:它是一个提供 `ctx.webServer` 的 `node:http` 插件,包含具名路由注册表、index.html 转换回调,以及一个可由插件认领的回退处理器。它不属于 agent loop(智能体循环),也不是能力 seam;它不了解任何 harness 概念。其他插件负责注册所有功能路由,包括 `/api` 桥接、插件 bundle 和 HMR(热模块替换)事件流([分层说明](https://github.com/deepseek-ai/deepseek-harness/blob/master/.agents/notes/implemented/architecture/2026-07-19-gui-layering-and-rpc-protocol.zh.md))。该服务器只服务浏览器:Electron 通过 `file://` 加载已构建文件,并经 IPC 桥接发送 fetch 请求,不使用本服务器。
|
|
9
9
|
|
|
10
10
|
源码:[`packages/host/webserver/src/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/host/webserver/src/index.ts)
|
|
11
11
|
|
|
@@ -27,7 +27,7 @@ interface WebRoute {
|
|
|
27
27
|
}
|
|
28
28
|
```
|
|
29
29
|
|
|
30
|
-
匹配顺序固定:先查 exact 表,再取最长匹配前缀,最后落到已注册的回退。注册顺序不携带任何面向请求的语义:具名路由在组合上互不相交,任何未被具名路由认领的请求都由回退席位应答;席位只有一个所有者,第二次注册会抛出异常。发布的 Web 组合用 [`dsh-host-frontend-static`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/host/frontend-static/src/index.ts) 认领席位,即遵循固定语义的 SPA dist 服务器:非 GET/HEAD 返回 405,越出 dist 根目录的遍历返回 403
|
|
30
|
+
匹配顺序固定:先查 exact 表,再取最长匹配前缀,最后落到已注册的回退。注册顺序不携带任何面向请求的语义:具名路由在组合上互不相交,任何未被具名路由认领的请求都由回退席位应答;席位只有一个所有者,第二次注册会抛出异常。发布的 Web 组合用 [`dsh-host-frontend-static`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/host/frontend-static/src/index.ts) 认领席位,即遵循固定语义的 SPA dist 服务器:非 GET/HEAD 返回 405,越出 dist 根目录的遍历返回 403,可读的 index 在 dist 根目录和配置的 index 路径渲染,现有文件直接提供,缺失或不是文件的目标返回空的 404,未知扩展名按 octet-stream 发送。
|
|
31
31
|
|
|
32
32
|
## 配置
|
|
33
33
|
|
|
@@ -45,9 +45,9 @@ interface Config {
|
|
|
45
45
|
|
|
46
46
|
## 服务
|
|
47
47
|
|
|
48
|
-
`WebServer`(`ctx.webServer`)在激活时立即监听;监听失败(EADDRINUSE 等)会使初始化被拒绝,启动进程会报告失败的 fiber。`register(route)` 添加一条具名路由并返回其 disposer;重复的 `(kind, path)` 抛出异常,因为路由模式是组合层约定,冲突即配置错误。`
|
|
48
|
+
`WebServer`(`ctx.webServer`)在激活时立即监听;监听失败(EADDRINUSE 等)会使初始化被拒绝,启动进程会报告失败的 fiber。`register(route)` 添加一条具名路由并返回其 disposer;重复的 `(kind, path)` 抛出异常,因为路由模式是组合层约定,冲突即配置错误。`collectIndexInjections()` 经一次 `webserver/index-inject` emit 收集结构化 `IndexInjection` 行,`renderIndex(html)` 把它们渲染进成功的根路径和配置 index 响应,随后再按注册顺序应用原始的 `tapIndex(transform)` 逃生口转换;[dsh-client-modules](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/client/modules) 以启动 manifest(元数据清单)行回应该事件。`port` 读取监听端口,包括 `config.port` 为 0 时操作系统分配的端口。
|
|
49
49
|
|
|
50
|
-
处理过程中抛出异常的请求(畸形的 % 转义撞上 `decodeURIComponent`、客户端在请求体中途断开)会记录为警告并应答 400(响应头已发出时则销毁 socket),绝不导致进程退出。dispose(资源释放)把 `close()` 与 `closeAllConnections()` 配对使用,因为处理器可能像 SSE(Server-Sent Events)那样保持响应打开,而这类连接永远不会自行结束;没有强制关闭,拆卸就会挂起。该包从不打印输出:URL 行归 shell 所有。逐包运维细节(含开发模式的 bundle 监视流水线)留在 [README](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/host/webserver/README.md) 中。
|
|
50
|
+
处理过程中抛出异常的请求(畸形的 % 转义撞上 `decodeURIComponent`、客户端在请求体中途断开)会记录为警告并应答 400(响应头已发出时则销毁 socket),绝不导致进程退出。dispose(资源释放)把 `close()` 与 `closeAllConnections()` 配对使用,因为处理器可能像 SSE(Server-Sent Events)那样保持响应打开,而这类连接永远不会自行结束;没有强制关闭,拆卸就会挂起。该包从不打印输出:URL 行归 shell 所有。逐包运维细节(含开发模式的 bundle 监视流水线)留在 [README](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/host/webserver/README.zh.md) 中。
|
|
51
51
|
|
|
52
52
|
<!-- BEGIN GENERATED cordis-surface (gen-cordis-catalog.ts) — do not edit between markers -->
|
|
53
53
|
|
|
@@ -55,7 +55,7 @@ interface Config {
|
|
|
55
55
|
|
|
56
56
|
## Cordis API
|
|
57
57
|
|
|
58
|
-
Generated from source by `scripts/gen-cordis-catalog.ts` (verified fresh by `pnpm run verify-cordis-catalog` in doc-sync; regenerate with `pnpm run gen-cordis-catalog`) —
|
|
58
|
+
Generated from source by `scripts/gen-cordis-catalog.ts` (verified fresh by `pnpm run verify-cordis-catalog` in doc-sync; regenerate with `pnpm run gen-cordis-catalog`) — the language sides differ only in locale-specific paired document paths. Signature blocks use a `ts cordis-catalog` fence and keep the original source JSDoc; dispatch modes are defined in the [primer](../cordis-primer.md#dispatch-modes), and the framework-inherited `ctx` API lives in [cordis-api/inherited.md](../cordis-api/inherited.md).
|
|
59
59
|
|
|
60
60
|
<a id="ctxwebserver--webserver"></a>
|
|
61
61
|
|
|
@@ -91,8 +91,9 @@ registerUpgrade(route: WebUpgradeRoute): () => void
|
|
|
91
91
|
registerFallback(handler: WebRoute['handler']): () => void
|
|
92
92
|
|
|
93
93
|
/**
|
|
94
|
-
* Register
|
|
95
|
-
*
|
|
94
|
+
* Register a raw-HTML index transform, the escape hatch for markup no
|
|
95
|
+
* {@link IndexInjection} row expresses: {@link renderIndex} applies taps in
|
|
96
|
+
* registration order after rendering the structured rows.
|
|
96
97
|
* @param transform - pure html-to-html function.
|
|
97
98
|
* @returns the disposer removing the transform.
|
|
98
99
|
*/
|
|
@@ -105,7 +106,46 @@ tapIndex(transform: (html: string) => string): () => void
|
|
|
105
106
|
* @returns the transformed body.
|
|
106
107
|
*/
|
|
107
108
|
applyIndexTaps(html: string): string
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Gather the structured injection table: one `webserver/index-inject` emit,
|
|
112
|
+
* every subscriber pushes its current rows. Fresh per call, so subscribers
|
|
113
|
+
* read live state (module graph, theme preference) at emit time.
|
|
114
|
+
* @returns rows in subscriber activation order.
|
|
115
|
+
*/
|
|
116
|
+
collectIndexInjections(): IndexInjection[]
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Render one index.html body: the structured injection table first, then
|
|
120
|
+
* the raw `tapIndex` transforms over the result.
|
|
121
|
+
* @param html - the raw index.html body.
|
|
122
|
+
* @returns the transformed body.
|
|
123
|
+
*/
|
|
124
|
+
renderIndex(html: string): string
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
Source: [`packages/host/webserver/src/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/host/webserver/src/index.ts)
|
|
128
|
+
|
|
129
|
+
<a id="webserver-events"></a>
|
|
130
|
+
|
|
131
|
+
### `webserver/*` events
|
|
132
|
+
|
|
133
|
+
<a id="webserverindex-inject--emit"></a>
|
|
134
|
+
|
|
135
|
+
#### `webserver/index-inject` — emit
|
|
136
|
+
|
|
137
|
+
Collect the structured index injection table. Emitted on every index render and every worker boot-payload request; listeners push their current rows, so a row's data is read fresh at emit time.
|
|
138
|
+
|
|
139
|
+
```ts cordis-catalog
|
|
140
|
+
/**
|
|
141
|
+
* Collect the structured index injection table. Emitted on every index
|
|
142
|
+
* render and every worker boot-payload request; listeners push their
|
|
143
|
+
* current rows, so a row's data is read fresh at emit time.
|
|
144
|
+
* @param table - Mutable row table; listeners append in activation order.
|
|
145
|
+
* @mode emit
|
|
146
|
+
*/
|
|
147
|
+
'webserver/index-inject'(table: IndexInjection[]): void
|
|
108
148
|
```
|
|
109
149
|
|
|
110
|
-
Source: [`packages/host/webserver/src/index.ts
|
|
150
|
+
Source: [`packages/host/webserver/src/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/host/webserver/src/index.ts)
|
|
111
151
|
<!-- END GENERATED cordis-surface -->
|