dsh-plugin-dev-kb 1.1.0 → 1.3.0
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 +16 -0
- package/README.en.md +14 -8
- package/README.md +14 -8
- package/docs/banner.svg +25 -0
- package/kb/INDEX.md +6 -2
- package/kb/README.md +4 -4
- package/kb/extra/AGENTS.md +2 -2
- package/kb/extra/cookbook/adding-a-session-format-version.md +109 -0
- package/kb/extra/cookbook/adding-a-session-format-version.zh.md +109 -0
- package/kb/extra/cookbook/adding-a-vendored-package.md +1 -1
- package/kb/extra/cookbook/adding-a-vendored-package.zh.md +1 -1
- package/kb/extra/cookbook/responding-to-pr-review-on-a-stack.md +1 -1
- package/kb/extra/cookbook/responding-to-pr-review-on-a-stack.zh.md +1 -1
- package/kb/extra/deepseek-llm-api-wire-extensions.md +2 -2
- package/kb/extra/deepseek-llm-api-wire-extensions.zh.md +2 -2
- package/kb/extra/development.md +13 -3
- package/kb/extra/development.zh.md +13 -3
- package/kb/extra/event-producer-consumer.md +33 -31
- package/kb/extra/event-producer-consumer.zh.md +34 -32
- package/kb/extra/i18n/README.md +2 -1
- package/kb/extra/i18n/README.zh.md +3 -2
- package/kb/extra/i18n/translation-prompt.md +1 -1
- package/kb/extra/module-graph.md +62 -24
- package/kb/extra/module-graph.zh.md +62 -24
- package/kb/extra/rescope.md +1 -1
- package/kb/extra/rescope.zh.md +1 -1
- package/kb/extra/session-format-status.md +47 -0
- package/kb/extra/session-format-status.zh.md +47 -0
- package/kb/extra/subsystems/agent-team.md +1 -1
- package/kb/extra/subsystems/agent-team.zh.md +1 -1
- package/kb/extra/subsystems/feedback.md +164 -30
- package/kb/extra/subsystems/feedback.zh.md +164 -30
- package/kb/extra/testing.md +4 -3
- package/kb/extra/testing.zh.md +4 -3
- package/kb/extra/web-styling.md +1 -0
- package/kb/extra/web-styling.zh.md +1 -0
- package/kb/meta/search-index.json +151 -103
- package/kb/meta/site-pages.txt +188 -184
- package/kb/meta/source.json +5 -5
- package/kb/meta/topics.md +2 -2
- package/kb/site/develop/basic/publish.md +1 -1
- package/kb/site/en/develop/basic/publish.md +1 -1
- package/kb/site/en/guide/providers.md +1 -1
- package/kb/site/en/guide/python-sdk.md +19 -3
- package/kb/site/en/reference/agent-lifecycle.md +12 -5
- package/kb/site/en/reference/capability-seams.md +10 -3
- package/kb/site/en/reference/config-catalog.md +173 -42
- package/kb/site/en/reference/cookbook/adding-a-tool.md +1 -1
- package/kb/site/en/reference/cookbook/extension-cookbook.md +1 -1
- package/kb/site/en/reference/index.md +18 -8
- package/kb/site/en/reference/persistence-catalog.md +121 -48
- package/kb/site/en/reference/subsystems/approval.md +1 -1
- package/kb/site/en/reference/subsystems/client-modules.md +9 -0
- package/kb/site/en/reference/subsystems/client-resources.md +94 -0
- package/kb/site/en/reference/subsystems/compaction.md +1 -1
- package/kb/site/en/reference/subsystems/core.md +79 -16
- package/kb/site/en/reference/subsystems/filesystem.md +15 -0
- package/kb/site/en/reference/subsystems/goal.md +37 -1
- package/kb/site/en/reference/subsystems/index.md +2 -0
- package/kb/site/en/reference/subsystems/invariants.md +1 -1
- package/kb/site/en/reference/subsystems/llm-streaming.md +20 -10
- package/kb/site/en/reference/subsystems/lsp.md +1 -1
- package/kb/site/en/reference/subsystems/persistence.md +36 -15
- package/kb/site/en/reference/subsystems/schedule.md +1 -1
- package/kb/site/en/reference/subsystems/scope.md +1 -1
- package/kb/site/en/reference/subsystems/session-reference.md +4 -0
- package/kb/site/en/reference/subsystems/session-telemetry.md +22 -6
- package/kb/site/en/reference/subsystems/session.md +64 -42
- package/kb/site/en/reference/subsystems/shell.md +9 -6
- package/kb/site/en/reference/subsystems/sidebar-right.md +151 -0
- package/kb/site/en/reference/subsystems/slots.md +41 -33
- package/kb/site/en/reference/subsystems/spill.md +13 -6
- package/kb/site/en/reference/subsystems/subagent.md +20 -13
- package/kb/site/en/reference/subsystems/subprocess.md +25 -26
- package/kb/site/en/reference/subsystems/system-prompt.md +3 -1
- package/kb/site/en/reference/subsystems/token-meter.md +2 -1
- package/kb/site/en/reference/subsystems/tools.md +5 -5
- package/kb/site/en/reference/subsystems/workspace.md +80 -1
- package/kb/site/en/reference/tool-catalog.md +46 -2
- package/kb/site/en/reference/tool-execution-pipeline.md +2 -2
- package/kb/site/guide/providers.md +1 -1
- package/kb/site/guide/python-sdk.md +19 -3
- package/kb/site/reference/agent-lifecycle.md +12 -5
- package/kb/site/reference/capability-seams.md +10 -3
- package/kb/site/reference/config-catalog.md +173 -42
- package/kb/site/reference/cookbook/adding-a-tool.md +1 -1
- package/kb/site/reference/cookbook/extension-cookbook.md +1 -1
- package/kb/site/reference/index.md +18 -8
- package/kb/site/reference/persistence-catalog.md +127 -54
- package/kb/site/reference/subsystems/approval.md +1 -1
- package/kb/site/reference/subsystems/client-modules.md +9 -0
- package/kb/site/reference/subsystems/client-resources.md +94 -0
- package/kb/site/reference/subsystems/compaction.md +1 -1
- package/kb/site/reference/subsystems/core.md +79 -16
- package/kb/site/reference/subsystems/filesystem.md +15 -0
- package/kb/site/reference/subsystems/goal.md +37 -1
- package/kb/site/reference/subsystems/index.md +14 -12
- package/kb/site/reference/subsystems/invariants.md +1 -1
- package/kb/site/reference/subsystems/llm-streaming.md +20 -10
- package/kb/site/reference/subsystems/lsp.md +1 -1
- package/kb/site/reference/subsystems/persistence.md +36 -15
- package/kb/site/reference/subsystems/schedule.md +1 -1
- package/kb/site/reference/subsystems/scope.md +1 -1
- package/kb/site/reference/subsystems/session-reference.md +4 -0
- package/kb/site/reference/subsystems/session-telemetry.md +22 -6
- package/kb/site/reference/subsystems/session.md +64 -42
- package/kb/site/reference/subsystems/shell.md +9 -6
- package/kb/site/reference/subsystems/sidebar-right.md +151 -0
- package/kb/site/reference/subsystems/slots.md +41 -33
- package/kb/site/reference/subsystems/spill.md +13 -6
- package/kb/site/reference/subsystems/subagent.md +20 -13
- package/kb/site/reference/subsystems/subprocess.md +25 -26
- package/kb/site/reference/subsystems/system-prompt.md +3 -1
- package/kb/site/reference/subsystems/token-meter.md +2 -1
- package/kb/site/reference/subsystems/tools.md +5 -5
- package/kb/site/reference/subsystems/workspace.md +80 -1
- package/kb/site/reference/tool-catalog.md +46 -2
- package/kb/site/reference/tool-execution-pipeline.md +2 -2
- package/lib/index.js +25 -44
- package/package.json +3 -2
- package/skills/dsh-plugin-dev-kb.md +3 -3
|
@@ -42,7 +42,9 @@ interface ToolProviderResult {
|
|
|
42
42
|
|
|
43
43
|
## 提示词段落
|
|
44
44
|
|
|
45
|
-
`
|
|
45
|
+
导出的 `PERSONA_PREFIX_SECTION`(`deployment:persona-prefix`)与 `PERSONA_SUFFIX_SECTION`(`deployment:persona-suffix`)为全局配置和带作用域贡献所共享的段落命名。它们对应的 `PromptSectionOrderName` 项为 `DEPLOYMENT_PERSONA_PREFIX` 与 `DEPLOYMENT_PERSONA_SUFFIX`;[包 README](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/core/system-prompt/README.zh.md#configure-the-prompt)规定其位置与模板配置。
|
|
46
|
+
|
|
47
|
+
`PromptSection` 是一份只读的同进程注册约定。其文本可以是静态的,也可以从当前组装上下文动态解析。各段先按 order 升序排列,再按名称的代码单元顺序排列;仓库贡献方通过 `getSectionOrder()` 解析服务持有的具名分配。Runtime-context 贡献方通过 `getContextOrder()` 解析独立分配。协作式组装完成后,一个有效的 `complete` 段会成为唯一的提示词段落。agent loop(智能体循环)用 `renderPrompt` 渲染组装后的各段,并把文本作为 `system/message` surface 节点提交——首个步骤作为 surface 第 0 号节点追加,之后在渲染文本变化时原地替换,或者当已准备调用声明 `systemPromptUpdate: 'in-history'` 时,在序列延续期间把非空更新追加到已缓存历史之后——因此提示词作为派生历史中的消息而不是请求字段到达模型([决策](https://github.com/deepseek-ai/deepseek-harness/blob/master/.agents/notes/implemented/architecture/2026-09-02-system-prompt-as-surface-node.zh.md);[决策规则](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/core/agent-loop/README.zh.md#understand-the-implementation))。
|
|
46
48
|
|
|
47
49
|
```ts type-equiv
|
|
48
50
|
/** One contributed section of the system prompt (registry input). */
|
|
@@ -81,7 +81,8 @@ Replay owner for one service-wide estimator and isolated per-session folds.
|
|
|
81
81
|
* usage is reused only when the latest successful call's canonical request
|
|
82
82
|
* envelope matches `requestHeader` and its total is no lower than that
|
|
83
83
|
* call's full route-priced anchor; otherwise the complete envelope and
|
|
84
|
-
* surface are repriced.
|
|
84
|
+
* surface are repriced. The anchor includes all surface nodes immediately
|
|
85
|
+
* before the assistant message, including inputs admitted after step/start.
|
|
85
86
|
*
|
|
86
87
|
* `requestHeader` replaces the latest logged envelope for pressure and node
|
|
87
88
|
* pricing; the node set always describes the current session surface. Every
|
|
@@ -265,14 +265,14 @@ PTC mode 的桥接层还会把每个已结算的子分派暴露给 `tools/ptc-di
|
|
|
265
265
|
* copy a listener may reshape. `content` is the RENDERED result projection
|
|
266
266
|
* (what a native `tool/result` would carry) — the program itself received
|
|
267
267
|
* the structured `value` (or just the error message on failure); only the
|
|
268
|
-
* `tool/
|
|
268
|
+
* `tool/ptc-dispatch` event's copy changes.
|
|
269
269
|
*/
|
|
270
270
|
interface PtcDispatchLog {
|
|
271
271
|
/** The outer `run_code` execution. */
|
|
272
272
|
readonly exec: ToolExecution
|
|
273
273
|
/** The calling agent (the scope routing key and the spill owner), when the outer call has one. */
|
|
274
274
|
readonly agent?: Agent
|
|
275
|
-
/**
|
|
275
|
+
/** Opaque sub-call id; new calls use `<parent>:ptc:<n>`. */
|
|
276
276
|
readonly subCallId: ToolCallId
|
|
277
277
|
/** The dispatched sub-tool name. */
|
|
278
278
|
readonly name: string
|
|
@@ -370,7 +370,7 @@ interface ToolExecutionFailure {
|
|
|
370
370
|
type ToolExecutionResult = ToolExecutionSuccess | ToolExecutionFailure
|
|
371
371
|
```
|
|
372
372
|
|
|
373
|
-
结果仅承载产出。调用身份保留在不可变的 `ToolExecution` 上,后者伴随结果经过每个钩子,并出现在持久化的 `tool/call` / `tool/result` 会话事件上,因此包装层无法创建第二个相互矛盾的身份。规范的 `value` 仅存在于执行期间:循环只持久化 `content`、`error` 和 `meta`,`tool/
|
|
373
|
+
结果仅承载产出。调用身份保留在不可变的 `ToolExecution` 上,后者伴随结果经过每个钩子,并出现在持久化的 `tool/call` / `tool/result` 会话事件上,因此包装层无法创建第二个相互矛盾的身份。规范的 `value` 仅存在于执行期间:循环只持久化 `content`、`error` 和 `meta`,`tool/ptc-dispatch` 则原样存储子调用渲染后的 `content` 与 `isError`。回放可以重现展示,却无法重建规范的中间值。
|
|
374
374
|
|
|
375
375
|
成功时,注册表会快照并校验函数体返回值,将其冻结,然后调用纯渲染器;对于直接的外层调用,还会调用可选的元数据投影器。注册表会在 `tools/result` 之前另行物化持久展示字段;无效值、渲染器/投影器失败或非 JSON 展示都会转为 JSON 安全的 `isError`。因此,最终实时观察者能看到精确的执行期值,以及可安全用于后续持久追加的字段。
|
|
376
376
|
|
|
@@ -677,13 +677,13 @@ Source: [`packages/core/tools/src/index.ts`](https://github.com/deepseek-ai/deep
|
|
|
677
677
|
|
|
678
678
|
#### `tools/ptc-dispatch-log` — waterfall
|
|
679
679
|
|
|
680
|
-
Allow a listener to replace content in the DURABLE LOG COPY of one `run_code` sub-dispatch outcome before the bridge appends its `tool/
|
|
680
|
+
Allow a listener to replace content in the DURABLE LOG COPY of one `run_code` sub-dispatch outcome before the bridge appends its `tool/ptc-dispatch` event. `next()` keeps the content unchanged; a listener may return replacement blocks (e.g. the spill policy's preview + locator for an oversized text result). Only the logged copy is affected — the program already received the complete value, and the model sees neither. A throwing listener is contained: the bridge falls back to logging the original settled content. Scope-filtered dispatch (`@deepseek-ai/dsh-scope`): agent-scoped listeners receive only that agent's dispatches.
|
|
681
681
|
|
|
682
682
|
```ts cordis-catalog
|
|
683
683
|
/**
|
|
684
684
|
* Allow a listener to replace content in the DURABLE LOG COPY of one
|
|
685
685
|
* `run_code` sub-dispatch outcome before the bridge appends its
|
|
686
|
-
* `tool/
|
|
686
|
+
* `tool/ptc-dispatch` event. `next()` keeps the
|
|
687
687
|
* content unchanged; a listener may return replacement blocks (e.g. the
|
|
688
688
|
* spill policy's preview + locator for an oversized text result). Only the
|
|
689
689
|
* logged copy is affected — the program already received the complete
|
|
@@ -5,7 +5,7 @@ outline: [2,3]
|
|
|
5
5
|
|
|
6
6
|
# 工作区
|
|
7
7
|
|
|
8
|
-
工作区(workspace)是用户工作目录的持久记录:一个建立在规范路径之上的稳定 id、一个显示标题,以及归属于它的会话的有序账本。该子系统是单个包(package)([dsh-workspace](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/workspace/workspace),`ctx.workspaceRegistry`)——一项宿主侧可选能力,不属于 agent loop(智能体循环)主干,并且对模型不可见(没有工具、没有提示词文本、没有会话事件)。它通过[存储领域数据形式](./storage.md)存储自己的记录,并对照 [`SessionHeader.cwd`](./persistence.md#sessionheader--metadata-beside-the-log) 校验会话成员资格,因此 `storageDomain` 与 `sessionPersistence` 是必需的启动依赖:持久化这一依赖不可用时,插件保持 pending,而不是把这种不可用误当作空历史。设计记录:[领域 KV 存储 Agent Note(agent 决策记录)](https://github.com/deepseek-ai/deepseek-harness/blob/master/.agents/notes/proposed/architecture/2026-07-24-domain-kv-storage-and-workspace.zh.md);引导与 GUI 顺序:[Workspace UI 产品流程 Agent Note](https://github.com/deepseek-ai/deepseek-harness/blob/master/.agents/notes/
|
|
8
|
+
工作区(workspace)是用户工作目录的持久记录:一个建立在规范路径之上的稳定 id、一个显示标题,以及归属于它的会话的有序账本。该子系统是单个包(package)([dsh-workspace](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/workspace/workspace),`ctx.workspaceRegistry`)——一项宿主侧可选能力,不属于 agent loop(智能体循环)主干,并且对模型不可见(没有工具、没有提示词文本、没有会话事件)。它通过[存储领域数据形式](./storage.md)存储自己的记录,并对照 [`SessionHeader.cwd`](./persistence.md#sessionheader--metadata-beside-the-log) 校验会话成员资格,因此 `storageDomain` 与 `sessionPersistence` 是必需的启动依赖:持久化这一依赖不可用时,插件保持 pending,而不是把这种不可用误当作空历史。设计记录:[领域 KV 存储 Agent Note(agent 决策记录)](https://github.com/deepseek-ai/deepseek-harness/blob/master/.agents/notes/proposed/architecture/2026-07-24-domain-kv-storage-and-workspace.zh.md);引导与 GUI 顺序:[Workspace UI 产品流程 Agent Note](https://github.com/deepseek-ai/deepseek-harness/blob/master/.agents/notes/archived/feature/2026-07-25-workspace-ui-product-flow.md)。
|
|
9
9
|
|
|
10
10
|
源码:[`packages/workspace/workspace/src/types.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/workspace/workspace/src/types.ts)
|
|
11
11
|
|
|
@@ -245,6 +245,85 @@ Host service backing the generated `ctx.remote.workspace` namespace.
|
|
|
245
245
|
|
|
246
246
|
Source: [`packages/api/workspace-controller/src/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/api/workspace-controller/src/index.ts)
|
|
247
247
|
|
|
248
|
+
<a id="ctxworkspacefiles--workspacefiles"></a>
|
|
249
|
+
|
|
250
|
+
### `ctx.workspaceFiles` — `WorkspaceFiles`
|
|
251
|
+
|
|
252
|
+
Host Remote file reads and workspace directory observations over the composed filesystem.
|
|
253
|
+
|
|
254
|
+
```ts cordis-catalog
|
|
255
|
+
/**
|
|
256
|
+
* Read one page of lines from a UTF-8 file readable by the filesystem backend.
|
|
257
|
+
* @param workspaceFileScope - header-derived workspace root for the Session identity on the wire.
|
|
258
|
+
* @param path - absolute path or path relative to the workspace root; files outside it are allowed.
|
|
259
|
+
* @param range - the line window; omitted fields take the page defaults.
|
|
260
|
+
* @param signal - caller cancellation.
|
|
261
|
+
* @returns the page, the file's version at the stat before it, and whether it reaches the last line.
|
|
262
|
+
*/
|
|
263
|
+
@Remote async read( workspaceFileScope: WorkspaceFileScope, path: string, range: WorkspaceFileRange, signal: AbortSignal, ): Promise<WorkspaceFileText>
|
|
264
|
+
|
|
265
|
+
/**
|
|
266
|
+
* Read one byte window of a regular file readable by the filesystem backend: raw
|
|
267
|
+
* bytes, no text decoding and no binary rejection.
|
|
268
|
+
* @param workspaceFileScope - header-derived workspace root for the Session identity on the wire.
|
|
269
|
+
* @param path - absolute path or path relative to the workspace root; files outside it are allowed.
|
|
270
|
+
* @param range - the byte window; omitted fields take the window defaults.
|
|
271
|
+
* @param signal - caller cancellation.
|
|
272
|
+
* @returns the window in base64, the file's version and size at the stat before it, and whether it reaches the last byte.
|
|
273
|
+
*/
|
|
274
|
+
@Remote async readBytes( workspaceFileScope: WorkspaceFileScope, path: string, range: WorkspaceByteRange, signal: AbortSignal, ): Promise<WorkspaceFileBytes>
|
|
275
|
+
|
|
276
|
+
/**
|
|
277
|
+
* Read a complete regular file as bytes, subject to the configured full-file cap.
|
|
278
|
+
* @param workspaceFileScope - header-derived workspace root for the Session identity on the wire.
|
|
279
|
+
* @param path - absolute or workspace-relative file path.
|
|
280
|
+
* @param signal - caller cancellation.
|
|
281
|
+
* @returns one complete base64 window with offset zero and eof true; oversized files fail with too-large.
|
|
282
|
+
*/
|
|
283
|
+
@Remote async readAll(workspaceFileScope: WorkspaceFileScope, path: string, signal: AbortSignal): Promise<WorkspaceFileBytes>
|
|
284
|
+
|
|
285
|
+
/**
|
|
286
|
+
* Read a complete file relative to another file's directory, including outside the workspace.
|
|
287
|
+
* @param workspaceFileScope - header-derived workspace root for the Session identity on the wire.
|
|
288
|
+
* @param path - base file, absolute or workspace-relative.
|
|
289
|
+
* @param relativePath - relative filesystem path, not a URL or absolute path.
|
|
290
|
+
* @param signal - caller cancellation.
|
|
291
|
+
* @returns the complete related file using the ordinary file-size and access checks.
|
|
292
|
+
*/
|
|
293
|
+
@Remote async readRelated( workspaceFileScope: WorkspaceFileScope, path: string, relativePath: string, signal: AbortSignal, ): Promise<WorkspaceFileBytes>
|
|
294
|
+
|
|
295
|
+
/**
|
|
296
|
+
* Report one regular file's identity, version, and size without its content.
|
|
297
|
+
* @param workspaceFileScope - header-derived workspace root for the Session identity on the wire.
|
|
298
|
+
* @param path - absolute path or path relative to the workspace root; files outside it are allowed.
|
|
299
|
+
* @param signal - caller cancellation.
|
|
300
|
+
* @returns the file's absolute path, current version, and byte size.
|
|
301
|
+
*/
|
|
302
|
+
@Remote async stat(workspaceFileScope: WorkspaceFileScope, path: string, signal: AbortSignal): Promise<WorkspaceFileStat>
|
|
303
|
+
|
|
304
|
+
/**
|
|
305
|
+
* List the direct children of one directory inside the Session's workspace.
|
|
306
|
+
* @param workspaceFileScope - header-derived workspace root for the Session identity on the wire.
|
|
307
|
+
* @param path - workspace path, absolute or relative to the workspace root.
|
|
308
|
+
* @param signal - caller cancellation.
|
|
309
|
+
* @returns the directory's children in the backend's stable name order, bounded by the entry cap.
|
|
310
|
+
*/
|
|
311
|
+
@Remote async list(workspaceFileScope: WorkspaceFileScope, path: string, signal: AbortSignal): Promise<WorkspaceDirectoryListing>
|
|
312
|
+
|
|
313
|
+
/**
|
|
314
|
+
* Stream every `fs/observed` observation of a file inside the Session's
|
|
315
|
+
* workspace. Only instrumented filesystem operations report here; the OS is
|
|
316
|
+
* not watched.
|
|
317
|
+
* @param workspaceFileScope - header-derived workspace root for the Session identity on the wire.
|
|
318
|
+
* @param signal - generation cancellation.
|
|
319
|
+
* @returns `ready` once the Host observation queue is active and the workspace
|
|
320
|
+
* root is resolved, then queued and live observations in emission order.
|
|
321
|
+
*/
|
|
322
|
+
@Remote({ mode: 'stream' }) changes(workspaceFileScope: WorkspaceFileScope, signal: AbortSignal): AsyncIterable<WorkspaceFileWatchFrame>
|
|
323
|
+
```
|
|
324
|
+
|
|
325
|
+
Source: [`packages/api/workspace-files/src/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/api/workspace-files/src/index.ts)
|
|
326
|
+
|
|
248
327
|
<a id="ctxworkspaceregistry--workspaceregistry"></a>
|
|
249
328
|
|
|
250
329
|
### `ctx.workspaceRegistry` — `WorkspaceRegistry`
|
|
@@ -9,7 +9,7 @@ editSource: "docs/tool-catalog.zh.md"
|
|
|
9
9
|
|
|
10
10
|
已发布插件向 `ctx.tools` 提供的所有面向模型的工具:模型通过系统提示词组装获得的 `name`、`description` 和 JSON Schema `parameters`。本目录是[子系统页面](./subsystems/core.md)(类型及每页生成的 `cordis-surface` 接线区域)的补充;本页列出的是向 agent(智能体)提供的*工具*。
|
|
11
11
|
|
|
12
|
-
英文源文件由系统**生成**,并通过 `pnpm run verify-tool-catalog`(`doc-sync`(文档同步门禁)的一部分)验证新鲜度;本中文文件作为经评审对侧通过双语配对维护。与 Cordis 目录(纯源码 AST 处理)不同,英文生成器会在真实上下文中**启动**每个工具插件并读取 `ctx.tools.schemas()`,因为工具 schema 无法通过静态分析完全确定,例如运行时展开的枚举、拼接的描述、由配置决定的名称以及使用原始 JSON Schema 的 MCP 工具。完整性守卫会 glob 匹配 `packages/*/tool-*`;如果生成器的启动 manifest
|
|
12
|
+
英文源文件由系统**生成**,并通过 `pnpm run verify-tool-catalog`(`doc-sync`(文档同步门禁)的一部分)验证新鲜度;本中文文件作为经评审对侧通过双语配对维护。与 Cordis 目录(纯源码 AST 处理)不同,英文生成器会在真实上下文中**启动**每个工具插件并读取 `ctx.tools.schemas()`,因为工具 schema 无法通过静态分析完全确定,例如运行时展开的枚举、拼接的描述、由配置决定的名称以及使用原始 JSON Schema 的 MCP 工具。完整性守卫会 glob 匹配 `packages/*/tool-*`;如果生成器的启动 manifest(元数据清单)遗漏任何包,检查就会失败,因此新工具不会在无人察觉的情况下缺少文档。
|
|
13
13
|
|
|
14
14
|
范围:`packages/*/tool-*` 下已发布的产品工具,每个工具均使用其**默认**配置启动;但如果某个 Config 字段是**必填项**且没有默认值,生成器就必须作出选择,对应包的说明会记录本页展示的是哪个分支。注册的工具**名称**可以是加载时配置,例如 `tool-subagent` 的 `toolName`,因此部署可能以不同名称或额外名称提供某个包;如果存在随产品发布的别名,对应包的说明会予以记录。`examples/` 中的演示工具(例如 `echo`)不在范围内,这与 Cordis 目录仅涵盖包的范围一致。
|
|
15
15
|
|
|
@@ -22,9 +22,10 @@ editSource: "docs/tool-catalog.zh.md"
|
|
|
22
22
|
| 工具包 | 模型可见名称 | 依赖 | 写入/影响 | 随产品发布的别名 | 部署说明 |
|
|
23
23
|
| --- | --- | --- | --- | --- | --- |
|
|
24
24
|
| `@deepseek-ai/dsh-tool-ask-user` | `ask_user_question` | `ctx.tools`、`ctx.userQuestions` | `tool/call`、`tool/result after a UI/provider answers the question` | - | ask_user_question 会暂停工具调用,直到当前 UI 提供方返回人类答案。 |
|
|
25
|
-
| `@deepseek-ai/dsh-tools` | `run_code` | `ctx.tools`、`ctx.codeRuntime (execution time)`、`ctx.systemPrompt` | `tool/call`、`one tool/
|
|
25
|
+
| `@deepseek-ai/dsh-tools` | `run_code` | `ctx.tools`、`ctx.codeRuntime (execution time)`、`ctx.systemPrompt` | `tool/call`、`one tool/ptc-dispatch-start + tool/ptc-dispatch pair per bridged sub-call`、`tool/result` | - | 在 `mode: ptc`/`mode: both` 下,它由工具注册表所有,作为可过滤能力层之外的保留传输机制(参见 PTC mode Agent Note)。在 `ptc` 下,它是注册表对协议格式(wire format)的唯一贡献;其他可见能力在使用已加载运行时语言生成的 SDK 章节中声明。程序通过 binding 调用这些能力,调用按照原生并发约定调度:启动顺序和策略遵循提交顺序,并发安全的函数体最多重叠执行 `maxParallelSubCalls` 个。调用会重新进入完整且受守卫保护的工具流水线,并将每个嵌套执行关联到此外层结果。 |
|
|
26
26
|
| `@deepseek-ai/dsh-plan-mode` | `exit_plan_mode` | `ctx.tools`、`ctx.systemPrompt`、`ctx.userQuestions (execution time, opportunistic)` | `tool/call`、`plan/mode inactive on an approved review`、`tool/result` | - | 规划未激活时,exit_plan_mode 仍保留在面向模型的 schema 中,这样状态转换不会在规划策略变更之外额外造成工具目录变动。其执行路径会拒绝规划模式之外的调用;在规划模式下,它通过用户交互 seam 提交计划(批准/根据反馈继续规划),批准后会在步骤边界记录规划模式已停用。 |
|
|
27
27
|
| `@deepseek-ai/dsh-tool-bash` | `bash` | `ctx.tools`、`ctx.shell`、`ctx.systemPrompt`、`ctx.shellEnv`、`ctx.jobs at call time for run_in_background` | `tool/call`、`tool/result` | - | bash 工具是 bash 执行器 seam 面向模型的消费方。使用 `run_in_background` 的运行会注册到通用 `ctx.jobs` 运行时,并通过 `job_*` 工具(来自 `@deepseek-ai/dsh-tool-jobs`)收集/停止;禁用 `enableRunInBackground` 配置(默认为 true)后,该参数会被完全移除。 |
|
|
28
|
+
| `@deepseek-ai/dsh-tool-present` | `present` | `ctx.tools`, `ctx.fs`, `ctx.sessionProjections` | `tool/call`, `deliverables/presented 在成功的最终结果之后`, `tool/result` | - | 交付归调用方 Session 所有;Web ui-deliverables 提供源文件打开与卡片。 |
|
|
28
29
|
| `@deepseek-ai/dsh-tool-pwsh` | `pwsh` | `ctx.tools`、`ctx.shell`、`ctx.systemPrompt`、`ctx.shellEnv`、`ctx.jobs at call time for run_in_background` | `tool/call`、`tool/result` | - | pwsh 工具是 Windows 组合中 bash 执行器 seam 的 PowerShell 方言消费方(由 `@deepseek-ai/dsh-pwsh-local` 等 PowerShell 执行器为 `ctx.shell` 提供后端);除沙箱接口外,它逐项对应 bash 工具调用。使用 `run_in_background` 的运行会注册到通用 `ctx.jobs` 运行时,并通过 `job_*` 工具收集/停止;托管的 `DSH_*` 环境来自 `@deepseek-ai/dsh-shell-env`。每次调用都在新进程中运行,不使用持久 PTY 会话。路径采用原生 `C:\...` 形式,变量采用 `$env:NAME`。 |
|
|
29
30
|
| `@deepseek-ai/dsh-tool-cordis` | `cordis_define`、`cordis_inspect_list`、`cordis_inspect_query`、`cordis_inspect_self`、`cordis_run`、`cordis_stop`、`cordis_undefine` | `ctx.tools`、`ctx.dynamicCordisRunner` | `tool/call`、`tool/result`、`process-local dynamic package lifecycle` | - | 不在任何随产品发布的树中,需要显式选择启用;动态 Package 代码可以访问真实运行时,见 .agents/notes/implemented/feature/2026-07-08-self-referential-cordis-toolset.md。该工具集注入 `@deepseek-ai/dsh-cordis-host-runner` 提供的 `ctx.dynamicCordisRunner`,后者拥有定义注册表和 vm 沙箱;组合缺少它时这些工具不会激活。运行中的 Package 在停止、undefine 或 DSH 重启前可以注册**额外的**模型可见工具;发生这类工具集变化时,系统会记录完整且有变动的请求头。 |
|
|
30
31
|
| `@deepseek-ai/dsh-tool-bash-persistent` | `bash` | `ctx.tools`、`ctx.terminals`、`an owning Agent at execution time` | `tool/call`、`PTY shell state`、`tool/result` | - | 一个按所有者隔离的持久 bash 工具;部署组合提供 PTY 后端,并可覆盖面向模型的环境描述。 |
|
|
@@ -224,6 +225,49 @@ ask_user_question 会暂停工具调用,直到当前 UI 提供方返回人类
|
|
|
224
225
|
|
|
225
226
|
bash 工具是 bash 执行器 seam 面向模型的消费方。使用 `run_in_background` 的运行会注册到通用 `ctx.jobs` 运行时,并通过 `job_*` 工具(来自 `@deepseek-ai/dsh-tool-jobs`)收集/停止;禁用 `enableRunInBackground` 配置(默认为 true)后,该参数会被完全移除。
|
|
226
227
|
|
|
228
|
+
<a id="deepseek-aidsh-tool-present"></a>
|
|
229
|
+
|
|
230
|
+
## `@deepseek-ai/dsh-tool-present`
|
|
231
|
+
|
|
232
|
+
### `present`
|
|
233
|
+
|
|
234
|
+
声明交付 Session 文件系统可访问的已有文件。如果你创建或更新的文件是用户要求接收的成果,则必须在写入完成后、最终回复前调用 present,包括通过 Bash 或代码执行创建的文件。在回复中提到文件路径不能替代这次调用。文件必须已存在。用户打开当前源文件;不复制或保存其内容。
|
|
235
|
+
|
|
236
|
+
```json
|
|
237
|
+
{
|
|
238
|
+
"type": "object",
|
|
239
|
+
"properties": {
|
|
240
|
+
"files": {
|
|
241
|
+
"type": "array",
|
|
242
|
+
"items": {
|
|
243
|
+
"type": "object",
|
|
244
|
+
"additionalProperties": false,
|
|
245
|
+
"properties": {
|
|
246
|
+
"path": {
|
|
247
|
+
"type": "string",
|
|
248
|
+
"description": "Path of an existing regular file. Relative paths use the Session working directory."
|
|
249
|
+
},
|
|
250
|
+
"description": {
|
|
251
|
+
"type": "string",
|
|
252
|
+
"description": "Brief description for the user."
|
|
253
|
+
}
|
|
254
|
+
},
|
|
255
|
+
"required": [
|
|
256
|
+
"path"
|
|
257
|
+
]
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
},
|
|
261
|
+
"required": [
|
|
262
|
+
"files"
|
|
263
|
+
]
|
|
264
|
+
}
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
来源: [`packages/fs/tool-present/src/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/fs/tool-present/src/index.ts)
|
|
268
|
+
|
|
269
|
+
交付归调用方 Session 所有;Web ui-deliverables 提供源文件打开与卡片。
|
|
270
|
+
|
|
227
271
|
<a id="deepseek-aidsh-tool-pwsh"></a>
|
|
228
272
|
|
|
229
273
|
## `@deepseek-ai/dsh-tool-pwsh`
|
|
@@ -21,7 +21,7 @@ flowchart TD
|
|
|
21
21
|
around["<code>tools/execute</code> waterfall<br/>timeout, retry, metrics (around dispatch)"]
|
|
22
22
|
toolBody["Registered tool execute() body"]
|
|
23
23
|
fsGate["<code>fs/write-intent</code> or <code>fs/edit-intent</code><br/>tool-fs mutations only"]
|
|
24
|
-
owned["Tool-owned session events<br/><code>todo/write</code>, <code>fs/observed</code>, <code>hook/invoked</code>, <code>hook/result</code>, <code>tool/
|
|
24
|
+
owned["Tool-owned session events<br/><code>todo/write</code>, <code>fs/observed</code>, <code>hook/invoked</code>, <code>hook/result</code>, <code>tool/ptc-dispatch</code>"]
|
|
25
25
|
post["<code>tools/post-execute</code> waterfall<br/>accept, block, replace, add context"]
|
|
26
26
|
normalized["Registry outer normalization<br/>pipeline/result snapshot throws become isError"]
|
|
27
27
|
finalize["ToolDefinition.finalizeContent<br/>last content-only invariant"]
|
|
@@ -61,6 +61,6 @@ flowchart TD
|
|
|
61
61
|
allResults --> context
|
|
62
62
|
```
|
|
63
63
|
|
|
64
|
-
文件系统的先读后编辑检查位于 `tool-fs` 之下,通过 `fs/*` 事件实现。通用的前置/后置 waterfall 承载钩子与审批策略;`ctx.approval` 在单调守卫之前处理询问,而不得重新排序的所有者策略仍作为已注册的守卫。超时等环绕分发关注点对 `tools/execute` 进行包装。注册表会对候选结果进行无损快照;如果快照失败,则会先将失败规范化,之后再由可见定义中已随快照固定的 `finalizeContent` 回调强制执行其同步且仅限内容的不变式。随后,`tools/result` 会观察不可变、可由 JSON 无损表示的结果。这样一来,钩子便可跨越不同工具系列,而无需让工具与某个策略服务耦合。PTC mode 会将保留的 `run_code` 传输及其序列化子调用都送入流水线;子调用携带父级 token、记录 `tool/
|
|
64
|
+
文件系统的先读后编辑检查位于 `tool-fs` 之下,通过 `fs/*` 事件实现。通用的前置/后置 waterfall 承载钩子与审批策略;`ctx.approval` 在单调守卫之前处理询问,而不得重新排序的所有者策略仍作为已注册的守卫。超时等环绕分发关注点对 `tools/execute` 进行包装。注册表会对候选结果进行无损快照;如果快照失败,则会先将失败规范化,之后再由可见定义中已随快照固定的 `finalizeContent` 回调强制执行其同步且仅限内容的不变式。随后,`tools/result` 会观察不可变、可由 JSON 无损表示的结果。这样一来,钩子便可跨越不同工具系列,而无需让工具与某个策略服务耦合。PTC mode 会将保留的 `run_code` 传输及其序列化子调用都送入流水线;子调用携带父级 token、记录 `tool/ptc-dispatch`、将拒绝呈现为具有约束力的驳回,并省略 `additionalContexts`,以保持调用与结果相邻。
|
|
65
65
|
|
|
66
66
|
维护模式:英文源文件包含人工维护的 Mermaid 流程图,并由生成器写出;本中文文件作为经评审对侧通过双语配对维护。确切的工具 schema 与事件签名位于生成的目录中。
|
package/lib/index.js
CHANGED
|
@@ -14,8 +14,7 @@
|
|
|
14
14
|
* 从插件目录解析不到;这里本来也不需要)。
|
|
15
15
|
*/
|
|
16
16
|
|
|
17
|
-
import { existsSync, readdirSync, readFileSync
|
|
18
|
-
import { homedir } from 'node:os'
|
|
17
|
+
import { existsSync, readdirSync, readFileSync } from 'node:fs'
|
|
19
18
|
import { dirname, join } from 'node:path'
|
|
20
19
|
import { fileURLToPath } from 'node:url'
|
|
21
20
|
|
|
@@ -26,6 +25,14 @@ const PKG_DIR = dirname(fileURLToPath(import.meta.url))
|
|
|
26
25
|
const SKILLS_DIR = join(PKG_DIR, '..', 'skills')
|
|
27
26
|
const KB_DIR = join(PKG_DIR, '..', 'kb')
|
|
28
27
|
|
|
28
|
+
/** logger 拿不到时降级 console。 */
|
|
29
|
+
function makeLogger(ctx, tag) {
|
|
30
|
+
return {
|
|
31
|
+
info: (...args) => (ctx.logger?.info ? ctx.logger.info(...args) : console.log(tag, ...args)),
|
|
32
|
+
warn: (...args) => (ctx.logger?.warn ? ctx.logger.warn(...args) : console.warn(tag, ...args))
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
29
36
|
/** 极简 frontmatter 解析(name/description/whenToUse)。 */
|
|
30
37
|
function parseFrontmatter(md) {
|
|
31
38
|
const match = /^---\r?\n([\s\S]*?)\r?\n---\r?\n?/.exec(md)
|
|
@@ -41,10 +48,10 @@ function parseFrontmatter(md) {
|
|
|
41
48
|
}
|
|
42
49
|
|
|
43
50
|
/** 从 skills/ 目录加载技能定义(文件缺失/无 frontmatter 时跳过并警告,绝不让插件挂载失败)。 */
|
|
44
|
-
function loadSkills() {
|
|
51
|
+
function loadSkills(log) {
|
|
45
52
|
const out = []
|
|
46
53
|
if (!existsSync(SKILLS_DIR)) {
|
|
47
|
-
|
|
54
|
+
log.warn('skills 目录缺失,技能未加载:' + SKILLS_DIR)
|
|
48
55
|
return out
|
|
49
56
|
}
|
|
50
57
|
for (const file of readdirSync(SKILLS_DIR)) {
|
|
@@ -52,7 +59,7 @@ function loadSkills() {
|
|
|
52
59
|
try {
|
|
53
60
|
const fm = parseFrontmatter(readFileSync(join(SKILLS_DIR, file), 'utf8'))
|
|
54
61
|
if (!fm.name || !fm.description) {
|
|
55
|
-
|
|
62
|
+
log.warn(`技能文件缺少 name/description frontmatter,已跳过:${file}`)
|
|
56
63
|
continue
|
|
57
64
|
}
|
|
58
65
|
out.push({
|
|
@@ -62,20 +69,14 @@ function loadSkills() {
|
|
|
62
69
|
body: fm.body
|
|
63
70
|
})
|
|
64
71
|
} catch (err) {
|
|
65
|
-
|
|
72
|
+
log.warn(`技能文件读取失败,已跳过:${file}(${err?.message ?? err})`)
|
|
66
73
|
}
|
|
67
74
|
}
|
|
68
75
|
return out
|
|
69
76
|
}
|
|
70
77
|
|
|
71
|
-
/** 挂载状态文件(自诊断:$DSH_HOME/dsh-plugin-dev-kb.state.json)。 */
|
|
72
|
-
function dshHome() {
|
|
73
|
-
return process.env.DSH_HOME || join(homedir(), '.dsh')
|
|
74
|
-
}
|
|
75
|
-
|
|
76
78
|
export function apply(ctx, config) {
|
|
77
|
-
const
|
|
78
|
-
const state = { skills: [] }
|
|
79
|
+
const log = makeLogger(ctx, '[dsh-plugin-dev-kb]')
|
|
79
80
|
|
|
80
81
|
// 契约(dsh-skill validateDefinition):定义必须含 name/description/
|
|
81
82
|
// source/content 四个字符串;provider 缺省为 'runtime'。
|
|
@@ -85,37 +86,17 @@ export function apply(ctx, config) {
|
|
|
85
86
|
// resourceBase 让 skill 工具渲染相对资源引导——知识库位置随插件安装
|
|
86
87
|
// 位置动态解析,不依赖任何写死的机器路径。
|
|
87
88
|
const kbRoot = KB_DIR.replaceAll('\\', '/')
|
|
88
|
-
for (const skill of loadSkills()) {
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
state.skills.push(skill.name)
|
|
99
|
-
console.log(`[dsh-plugin-dev-kb] 技能已注册:${skill.name}`)
|
|
100
|
-
} catch (err) {
|
|
101
|
-
console.warn(`[dsh-plugin-dev-kb] 技能注册失败:${skill.name}(${err?.message ?? err})`)
|
|
102
|
-
}
|
|
89
|
+
for (const skill of loadSkills(log)) {
|
|
90
|
+
ctx.effect(() => ctx.skills.register({
|
|
91
|
+
name: skill.name,
|
|
92
|
+
description: skill.description,
|
|
93
|
+
...(skill.whenToUse ? { whenToUse: skill.whenToUse } : {}),
|
|
94
|
+
source: 'runtime',
|
|
95
|
+
content: skill.body.replaceAll('{{KB_ROOT}}', kbRoot),
|
|
96
|
+
resourceBase: { kind: 'directory', path: KB_DIR }
|
|
97
|
+
}), `dsh-plugin-dev-kb: register skill ${skill.name}`)
|
|
98
|
+
log.info(`技能已注册:${skill.name}`)
|
|
103
99
|
}
|
|
104
100
|
|
|
105
|
-
|
|
106
|
-
writeFileSync(join(dshHome(), 'dsh-plugin-dev-kb.state.json'), JSON.stringify({
|
|
107
|
-
plugin: 'dsh-plugin-dev-kb',
|
|
108
|
-
mountedAt: new Date().toISOString(),
|
|
109
|
-
skills: state.skills
|
|
110
|
-
}, null, 2), 'utf8')
|
|
111
|
-
} catch { /* 状态文件写入失败不影响挂载 */ }
|
|
112
|
-
|
|
113
|
-
console.log(`[dsh-plugin-dev-kb] 已挂载:${state.skills.length} 技能(知识库在 kb/ 目录)`)
|
|
114
|
-
|
|
115
|
-
// 卸载清理(HMR 重载时避免重复注册)。
|
|
116
|
-
return () => {
|
|
117
|
-
for (const dispose of disposers) {
|
|
118
|
-
try { dispose() } catch { /* ignore */ }
|
|
119
|
-
}
|
|
120
|
-
}
|
|
101
|
+
log.info(`已挂载(知识库在 kb/ 目录)`)
|
|
121
102
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-plugin-dev-kb",
|
|
3
|
-
"description": "dsh 插件开发知识库:DeepSeek Harness 官方文档站完整 Markdown 镜像(中英双语
|
|
4
|
-
"version": "1.
|
|
3
|
+
"description": "dsh 插件开发知识库:DeepSeek Harness 官方文档站完整 Markdown 镜像(中英双语 188 页)+ 62 篇仓库补充开发参考 + 主题导航与 253 文件全量搜索索引;以 dsh-plugin-dev-kb 技能让 agent 在插件开发任务中自动加载定位文档。纯数据插件,零运行时依赖。",
|
|
4
|
+
"version": "1.3.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "lib/index.js",
|
|
7
7
|
"exports": {
|
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
},
|
|
11
11
|
"files": [
|
|
12
12
|
"lib",
|
|
13
|
+
"docs",
|
|
13
14
|
"kb",
|
|
14
15
|
"skills",
|
|
15
16
|
"scripts",
|
|
@@ -16,18 +16,18 @@ whenToUse: 开发 dsh 插件、查询 dsh 能力与 API、写 Tool、配置 cord
|
|
|
16
16
|
|
|
17
17
|
```
|
|
18
18
|
kb/
|
|
19
|
-
├── site/ 线上站点完整镜像(中英双语
|
|
19
|
+
├── site/ 线上站点完整镜像(中英双语 188 页,优先读这里)
|
|
20
20
|
│ ├── guide/ 入门:quickstart / providers / python-sdk / github-review / schedule / mcp-memory / network-proxy
|
|
21
21
|
│ ├── develop/ basic(第一个插件/tool/config/publish)、framework(生命周期/服务/事件)、
|
|
22
22
|
│ │ practice(能力分层/LLM适配器/动态装配)、cordis-tutorial(7章)
|
|
23
23
|
│ ├── reference/ index(架构)、cordis-primer、capability-seams、agent-lifecycle、
|
|
24
24
|
│ │ config-catalog、tool-catalog、api-gateway、cordis-api/(6)、cookbook/(5)、subsystems/(46)
|
|
25
25
|
│ └── en/ 英文站镜像(结构与中文站一致)
|
|
26
|
-
├── extra/ 仓库内未发布到站点的补充文档(
|
|
26
|
+
├── extra/ 仓库内未发布到站点的补充文档(62 篇):glossary、defensive-patterns、
|
|
27
27
|
│ module-graph、testing、postmortem/(4)、i18n/、cookbook 与 subsystems 扩展
|
|
28
28
|
├── meta/
|
|
29
29
|
│ ├── topics.md ★ 主题导航:任务场景 → 要读的文件(先用这个)
|
|
30
|
-
│ ├── search-index.json 全量检索索引(
|
|
30
|
+
│ ├── search-index.json 全量检索索引(253 文件:path/url/title/字符数)
|
|
31
31
|
│ ├── source.json 来源信息(commit/时间/统计)
|
|
32
32
|
│ └── site-pages.txt 线上站点页面清单
|
|
33
33
|
├── INDEX.md 全部 站点 URL ↔ 本地文件 对照
|