dsh-plugin-dev-kb 1.0.8 → 1.1.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 +21 -0
- package/README.en.md +6 -6
- package/README.md +6 -6
- package/kb/INDEX.md +21 -5
- package/kb/README.md +11 -10
- package/kb/extra/AGENTS.md +4 -4
- package/kb/extra/cookbook/adding-a-remote-api.md +197 -0
- package/kb/extra/cookbook/adding-a-remote-api.zh.md +197 -0
- package/kb/extra/cookbook/adding-a-vendored-package.md +2 -2
- package/kb/extra/cookbook/adding-a-vendored-package.zh.md +2 -2
- package/kb/extra/deepseek-llm-api-wire-extensions.md +163 -0
- package/kb/extra/deepseek-llm-api-wire-extensions.zh.md +163 -0
- package/kb/extra/development.md +8 -14
- package/kb/extra/development.zh.md +8 -14
- package/kb/extra/event-producer-consumer.md +55 -48
- package/kb/extra/event-producer-consumer.zh.md +58 -51
- package/kb/extra/glossary.md +1 -1
- package/kb/extra/glossary.zh.md +1 -1
- package/kb/extra/graph-atlas.md +0 -2
- package/kb/extra/graph-atlas.zh.md +0 -2
- package/kb/extra/i18n/README.md +4 -4
- package/kb/extra/i18n/README.zh.md +4 -4
- package/kb/extra/i18n/style-samples.md +2 -2
- package/kb/extra/module-graph.md +646 -926
- package/kb/extra/module-graph.zh.md +648 -928
- package/kb/extra/postmortem/0001-acp-default-export-drops-inject.md +2 -2
- package/kb/extra/postmortem/0001-acp-default-export-drops-inject.zh.md +2 -2
- package/kb/extra/postmortem/0002-js-expression-disabled-filesystem-tools.md +2 -2
- package/kb/extra/postmortem/0002-js-expression-disabled-filesystem-tools.zh.md +2 -2
- package/kb/extra/postmortem/0003-web-agent-gui-feedback-loop.md +2 -2
- package/kb/extra/postmortem/0003-web-agent-gui-feedback-loop.zh.md +2 -2
- package/kb/extra/postmortem/0004-landlock-partial-notice-misclassified-child-failures.md +1 -1
- package/kb/extra/postmortem/0004-landlock-partial-notice-misclassified-child-failures.zh.md +1 -1
- package/kb/extra/rescope.md +2 -2
- package/kb/extra/rescope.zh.md +2 -2
- package/kb/extra/subsystems/agent-team.md +28 -4
- package/kb/extra/subsystems/agent-team.zh.md +28 -4
- package/kb/extra/subsystems/attachment.md +168 -7
- package/kb/extra/subsystems/attachment.zh.md +168 -7
- package/kb/extra/subsystems/extensions.md +18 -0
- package/kb/extra/subsystems/extensions.zh.md +18 -0
- package/kb/extra/subsystems/feedback.md +4 -4
- package/kb/extra/subsystems/feedback.zh.md +4 -4
- package/kb/extra/subsystems/todo.md +32 -0
- package/kb/extra/subsystems/todo.zh.md +32 -0
- package/kb/extra/subsystems/webhook.md +70 -0
- package/kb/extra/subsystems/webhook.zh.md +70 -0
- package/kb/extra/testing.md +15 -10
- package/kb/extra/testing.zh.md +13 -8
- package/kb/extra/web-styling.md +4 -0
- package/kb/extra/web-styling.zh.md +4 -0
- package/kb/meta/search-index.json +309 -177
- package/kb/meta/site-pages.txt +183 -167
- package/kb/meta/source.json +5 -5
- package/kb/meta/topics.md +14 -6
- package/kb/site/develop/basic/publish.md +2 -2
- package/kb/site/develop/basic/tool.md +1 -1
- package/kb/site/develop/cordis-tutorial/07-into-the-harness.md +5 -4
- package/kb/site/develop/framework/events.md +1 -1
- package/kb/site/develop/practice/dynamic-cordis.md +17 -0
- package/kb/site/develop/practice/llm-adapter.md +4 -3
- package/kb/site/en/develop/basic/publish.md +2 -2
- package/kb/site/en/develop/basic/tool.md +1 -1
- package/kb/site/en/develop/cordis-tutorial/07-into-the-harness.md +5 -4
- package/kb/site/en/develop/framework/events.md +1 -1
- package/kb/site/en/develop/practice/dynamic-cordis.md +17 -0
- package/kb/site/en/develop/practice/llm-adapter.md +4 -3
- package/kb/site/en/guide/github-review.md +104 -0
- package/kb/site/en/guide/mcp-memory.md +103 -0
- package/kb/site/en/guide/network-proxy.md +87 -0
- package/kb/site/en/guide/providers.md +70 -17
- package/kb/site/en/guide/python-sdk.md +80 -34
- package/kb/site/en/guide/schedule.md +23 -0
- package/kb/site/en/reference/agent-lifecycle.md +6 -4
- package/kb/{extra → site/en/reference}/api-gateway.md +12 -10
- package/kb/site/en/reference/capability-seams.md +128 -73
- package/kb/site/en/reference/config-catalog.md +481 -360
- package/kb/site/en/reference/cookbook/adding-a-package.md +3 -4
- package/kb/site/en/reference/cookbook/adding-a-settings-card.md +12 -10
- package/kb/site/en/reference/cookbook/adding-a-tool.md +11 -4
- package/kb/site/en/reference/cookbook/adding-an-llm-adapter.md +1 -1
- package/kb/site/en/reference/cookbook/extension-cookbook.md +20 -17
- package/kb/site/en/reference/cordis-api/inherited.md +1 -1
- package/kb/site/en/reference/cordis-primer.md +2 -1
- package/kb/site/en/reference/index.md +30 -11
- package/kb/site/en/reference/persistence-catalog.md +148 -80
- package/kb/site/en/reference/subsystems/approval.md +10 -10
- package/kb/site/en/reference/subsystems/client-modules.md +58 -16
- package/kb/site/en/reference/subsystems/code-runtime.md +10 -6
- package/kb/site/en/reference/subsystems/commands.md +25 -16
- package/kb/site/en/reference/subsystems/compaction.md +11 -11
- package/kb/site/en/reference/{cookbook/adding-a-conversation-node.md → subsystems/conversation.md} +50 -24
- package/kb/site/en/reference/subsystems/core.md +156 -17
- package/kb/site/en/reference/subsystems/credentials.md +44 -3
- package/kb/site/en/reference/subsystems/filesystem.md +12 -2
- package/kb/site/en/reference/subsystems/goal.md +1 -1
- package/kb/site/en/reference/subsystems/index.md +7 -2
- package/kb/site/en/reference/subsystems/jobs.md +1 -1
- package/kb/site/en/reference/subsystems/llm-streaming.md +154 -12
- package/kb/site/en/reference/subsystems/permission-presets.md +6 -6
- package/kb/site/en/reference/subsystems/persistence.md +185 -175
- package/kb/site/en/reference/subsystems/plan.md +2 -2
- package/kb/site/en/reference/subsystems/sandbox.md +2 -0
- package/kb/site/en/reference/subsystems/schedule.md +9 -3
- package/kb/site/en/reference/subsystems/session-projection.md +115 -48
- package/kb/site/en/reference/subsystems/session-query.md +28 -14
- package/kb/site/en/reference/subsystems/session-reference.md +53 -8
- package/kb/site/en/reference/subsystems/session-telemetry.md +8 -8
- package/kb/site/en/reference/subsystems/session-title.md +6 -6
- package/kb/site/en/reference/subsystems/session.md +401 -99
- package/kb/site/en/reference/subsystems/settings.md +101 -6
- package/kb/site/en/reference/subsystems/skills.md +23 -0
- package/kb/site/en/reference/subsystems/slots.md +178 -0
- package/kb/site/en/reference/subsystems/spill.md +2 -2
- package/kb/site/en/reference/subsystems/storage.md +34 -3
- package/kb/site/en/reference/subsystems/subagent.md +122 -109
- package/kb/site/en/reference/subsystems/system-prompt.md +17 -4
- package/kb/site/en/reference/subsystems/token-meter.md +27 -12
- package/kb/site/en/reference/subsystems/tools.md +39 -39
- package/kb/site/en/reference/subsystems/typert.md +62 -55
- package/kb/site/en/reference/subsystems/user-questions.md +33 -33
- package/kb/site/en/reference/subsystems/web-client.md +98 -0
- package/kb/site/en/reference/subsystems/web-server.md +11 -5
- package/kb/site/en/reference/subsystems/web.md +7 -1
- package/kb/site/en/reference/subsystems/workspace.md +102 -9
- package/kb/site/en/reference/tool-catalog.md +86 -82
- package/kb/site/en/reference/tool-execution-pipeline.md +1 -1
- package/kb/site/guide/github-review.md +104 -0
- package/kb/site/guide/mcp-memory.md +103 -0
- package/kb/site/guide/network-proxy.md +87 -0
- package/kb/site/guide/providers.md +70 -17
- package/kb/site/guide/python-sdk.md +87 -41
- package/kb/site/guide/schedule.md +23 -0
- package/kb/site/reference/agent-lifecycle.md +6 -4
- package/kb/{extra/api-gateway.zh.md → site/reference/api-gateway.md} +12 -10
- package/kb/site/reference/capability-seams.md +128 -73
- package/kb/site/reference/config-catalog.md +481 -360
- package/kb/site/reference/cookbook/adding-a-package.md +3 -4
- package/kb/site/reference/cookbook/adding-a-settings-card.md +12 -10
- package/kb/site/reference/cookbook/adding-a-tool.md +11 -4
- package/kb/site/reference/cookbook/adding-an-llm-adapter.md +1 -1
- package/kb/site/reference/cookbook/extension-cookbook.md +20 -17
- package/kb/site/reference/cordis-api/inherited.md +1 -1
- package/kb/site/reference/cordis-primer.md +2 -1
- package/kb/site/reference/index.md +30 -11
- package/kb/site/reference/persistence-catalog.md +148 -80
- package/kb/site/reference/subsystems/approval.md +10 -10
- package/kb/site/reference/subsystems/client-modules.md +58 -16
- package/kb/site/reference/subsystems/code-runtime.md +10 -6
- package/kb/site/reference/subsystems/commands.md +25 -16
- package/kb/site/reference/subsystems/compaction.md +11 -11
- package/kb/site/reference/{cookbook/adding-a-conversation-node.md → subsystems/conversation.md} +50 -24
- package/kb/site/reference/subsystems/core.md +156 -17
- package/kb/site/reference/subsystems/credentials.md +44 -3
- package/kb/site/reference/subsystems/filesystem.md +12 -2
- package/kb/site/reference/subsystems/goal.md +1 -1
- package/kb/site/reference/subsystems/index.md +7 -2
- package/kb/site/reference/subsystems/jobs.md +1 -1
- package/kb/site/reference/subsystems/llm-streaming.md +154 -12
- package/kb/site/reference/subsystems/permission-presets.md +5 -5
- package/kb/site/reference/subsystems/persistence.md +184 -174
- package/kb/site/reference/subsystems/plan.md +2 -2
- package/kb/site/reference/subsystems/schedule.md +9 -3
- package/kb/site/reference/subsystems/session-projection.md +115 -48
- package/kb/site/reference/subsystems/session-query.md +28 -14
- package/kb/site/reference/subsystems/session-reference.md +53 -8
- package/kb/site/reference/subsystems/session-telemetry.md +8 -8
- package/kb/site/reference/subsystems/session-title.md +6 -6
- package/kb/site/reference/subsystems/session.md +401 -99
- package/kb/site/reference/subsystems/settings.md +101 -6
- package/kb/site/reference/subsystems/skills.md +23 -0
- package/kb/site/reference/subsystems/slots.md +178 -0
- package/kb/site/reference/subsystems/spill.md +2 -2
- package/kb/site/reference/subsystems/storage.md +34 -3
- package/kb/site/reference/subsystems/subagent.md +122 -109
- package/kb/site/reference/subsystems/system-prompt.md +17 -4
- package/kb/site/reference/subsystems/token-meter.md +27 -12
- package/kb/site/reference/subsystems/tools.md +39 -39
- package/kb/site/reference/subsystems/typert.md +62 -55
- package/kb/site/reference/subsystems/user-questions.md +33 -33
- package/kb/site/reference/subsystems/web-client.md +98 -0
- package/kb/site/reference/subsystems/web-server.md +11 -5
- package/kb/site/reference/subsystems/web.md +7 -1
- package/kb/site/reference/subsystems/workspace.md +102 -9
- package/kb/site/reference/tool-catalog.md +85 -81
- package/kb/site/reference/tool-execution-pipeline.md +1 -1
- package/package.json +2 -2
- package/skills/dsh-plugin-dev-kb.md +8 -6
|
@@ -26,12 +26,25 @@ interface ContentBlockMap {
|
|
|
26
26
|
'text': TextBlock
|
|
27
27
|
'reasoning': ReasoningBlock
|
|
28
28
|
'image': ImageBlock
|
|
29
|
+
'file': FileBlock
|
|
29
30
|
'tool-call': ToolCallBlock
|
|
30
31
|
'tool-result': ToolResultBlock
|
|
31
32
|
}
|
|
32
33
|
```
|
|
33
34
|
|
|
34
|
-
各块接口(完整字段见源码):`TextBlock`(`text`)、`ReasoningBlock`(thinking,区别于可见文本)、`ImageBlock`(一个持久的[图片附件](https://github.com/deepseek-ai/deepseek-harness/blob/master/docs/subsystems/attachment.zh.md))、`ToolCallBlock`(`id:
|
|
35
|
+
各块接口(完整字段见源码):`TextBlock`(`text`)、`ReasoningBlock`(thinking,区别于可见文本)、`ImageBlock`(一个持久的[图片附件](https://github.com/deepseek-ai/deepseek-harness/blob/master/docs/subsystems/attachment.zh.md))、`FileBlock`(一个持久的原样[文件附件](https://github.com/deepseek-ai/deepseek-harness/blob/master/docs/subsystems/attachment.zh.md),请求组装对每条路由都把它投影为 handle 文本)、`ToolCallBlock`(`id: ToolCallId`、`name`、原始 JSON `arguments`),以及 `ToolResultBlock`(`toolCallId`、嵌套 `content: ContentBlock[]`、`isError?`)。`ContentBlock = ContentBlockMap[ContentBlockType]`。仅当适配器、UI、压缩(compaction)和持久回放路径均支持某种新模态时,才将其纳入可合并扩展的 map。
|
|
36
|
+
|
|
37
|
+
图片访问方式属于请求序列化,不属于持久附件或确定性请求图片版本。`resolveImageAttachmentAccess()` 把附件提供方可选的宿主对象路径,与消费方为当前工具执行文件系统提供的映射组合起来。结果只适用于本次请求,不参与 `variantId`。
|
|
38
|
+
|
|
39
|
+
源码:[`packages/llm/llm/src/content.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/llm/llm/src/content.ts)
|
|
40
|
+
|
|
41
|
+
```ts type-equiv
|
|
42
|
+
/** Execution-world path that model tools can use to read one normalized attachment. */
|
|
43
|
+
interface ImageAttachmentAccess {
|
|
44
|
+
/** Absolute path to immutable normalized bytes; callers must treat it as read-only. */
|
|
45
|
+
readonlyPath: string
|
|
46
|
+
}
|
|
47
|
+
```
|
|
35
48
|
|
|
36
49
|
源码:[`packages/llm/llm/src/message.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/llm/llm/src/message.ts)
|
|
37
50
|
|
|
@@ -196,7 +209,7 @@ type StreamChunk =
|
|
|
196
209
|
| { type: 'block-start'; index: number; blockType: ContentBlockType }
|
|
197
210
|
| { type: 'text-delta'; index: number; text: string }
|
|
198
211
|
| { type: 'reasoning-delta'; index: number; text: string }
|
|
199
|
-
| { type: 'tool-call-delta'; index: number; id:
|
|
212
|
+
| { type: 'tool-call-delta'; index: number; id: ToolCallId; name?: string; argumentsDelta: string }
|
|
200
213
|
| { type: 'block-end'; index: number; block: ContentBlock }
|
|
201
214
|
| { type: 'usage'; usage: TokenUsage }
|
|
202
215
|
| {
|
|
@@ -207,6 +220,16 @@ type StreamChunk =
|
|
|
207
220
|
}
|
|
208
221
|
```
|
|
209
222
|
|
|
223
|
+
<a id="compact-assistant-streams"></a>
|
|
224
|
+
|
|
225
|
+
## 紧凑 Assistant stream
|
|
226
|
+
|
|
227
|
+
`AssistantStreamAccumulator` 把每个 `StreamChunk` 与其原始安全整数时间戳配对,并生成 `AssistantStreamRecord[]`。同一 block 的连续 text、reasoning 或 tool argument delta 会变成一个 record,使用 `time0`、精确时间戳间隔和每个原始 delta 对应的一个数组成员;其他 chunk 保留为带时间戳的 raw record。该表示会移除重复 event envelope,但不会合并 token 边界,也不会丢弃 terminal、usage、block、failure 或 replay 事实。
|
|
228
|
+
|
|
229
|
+
`snapshot()` 返回分离且不可变的 stream。`expandAssistantStream()` 会严格检查 record key、成员数、index、时间戳、tool-call identity 与无损 JSON,再重建精确的带时间 chunk 序列。Session 日志会把该 stream 嵌入作为 surface result 的 `assistant/message`,或嵌入没有 surface message 的 `assistant/attempt`。
|
|
230
|
+
|
|
231
|
+
进程本地 `agent/assistant-stream` frame 承载实时呈现。持久回放、遥测、token 记账与历史 UI 组装会展开嵌入式 settlement,而不会把 live frame 当作持久事实。
|
|
232
|
+
|
|
210
233
|
<a id="llmfailure"></a>
|
|
211
234
|
|
|
212
235
|
## `LlmFailure`
|
|
@@ -229,13 +252,51 @@ interface LlmFailure {
|
|
|
229
252
|
}
|
|
230
253
|
```
|
|
231
254
|
|
|
255
|
+
## 请求图片定价
|
|
256
|
+
|
|
257
|
+
提供方对请求图片收取视觉 token 的适配器通过覆写 `LlmAdapter.imageRequestPricing` 声明按路由的定价,消费方经 `ctx.llm.imageRequestPricing(provider, model)` 同步解析。token 计量服务在每次计量时解析路由模型的定价,使 compaction 的压力、保留与选段都按路由请求实际发送的形式为图片历史计价;DeepSeek 适配器复现自身的请求投影(按模型的像素预算、最旧优先 offload),并用官方公布的 v4 视觉计量为保留图片定价,已完成请求仍以 provider usage 为权威锚点。
|
|
258
|
+
|
|
259
|
+
```ts type-equiv
|
|
260
|
+
/**
|
|
261
|
+
* Request price of one ordered image occurrence under one exact model route's
|
|
262
|
+
* request projection. Every occurrence resolves to the pair the wire actually
|
|
263
|
+
* carries: provider visual tokens for a retained image, plus the model-visible
|
|
264
|
+
* text sent with or instead of it (request-preview handle, offload placeholder,
|
|
265
|
+
* or text-only substitution). The caller prices `text` with its own text
|
|
266
|
+
* estimator so provider pricing never fixes a text tokenization.
|
|
267
|
+
*/
|
|
268
|
+
interface LlmImageRequestPrice {
|
|
269
|
+
/** Provider visual tokens for the retained request image; 0 when only text represents this occurrence. */
|
|
270
|
+
visualTokens: number
|
|
271
|
+
/** Model-visible text sent for this occurrence, to be priced by the caller's text estimator. */
|
|
272
|
+
text: string
|
|
273
|
+
}
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
```ts type-equiv
|
|
277
|
+
/**
|
|
278
|
+
* Provider-side request-image pricing for one exact model route. Implemented
|
|
279
|
+
* by adapters whose provider charges visual tokens; consumers (the token
|
|
280
|
+
* meter) resolve it synchronously per measurement, so implementations must not
|
|
281
|
+
* perform I/O.
|
|
282
|
+
*/
|
|
283
|
+
interface LlmImageRequestPricing {
|
|
284
|
+
/**
|
|
285
|
+
* Price every image occurrence of one request projection.
|
|
286
|
+
* @param images - durable image references in request order, one entry per occurrence.
|
|
287
|
+
* @returns one price per occurrence, aligned by index with `images`.
|
|
288
|
+
*/
|
|
289
|
+
priceImages(images: readonly ImageAttachmentRef[]): readonly LlmImageRequestPrice[]
|
|
290
|
+
}
|
|
291
|
+
```
|
|
292
|
+
|
|
232
293
|
## 适配器约定
|
|
233
294
|
|
|
234
295
|
每个适配器必须遵守以下规则,每个消费方可以依赖它们:
|
|
235
296
|
|
|
236
297
|
- **`usage` 在 `finish` 之前,`finish` 之后不再有任何分片。** 将两者都推迟到提供方的流结束标记,这样尾部的 usage-only 分片就不会违反顺序。
|
|
237
298
|
- **工具调用的 `arguments` 全程保持原始 JSON 字符串。** 部分片段通过 `argumentsDelta` 流式传输;如果提供方返回的是已解析的对象,适配器在 `block-end` 时重新序列化为字符串。
|
|
238
|
-
- **两条受支持的错误路径,共用一个 `LlmFailure` 类型。** 失败可以从 `stream()` 抛出(传输/协议错误),**或者**以 `finish {kind:'error'|'aborted', failure}` 结束流(无法在流中途抛异常的适配器用它表示提供方带内错误)。`LlmError.failure` 携带同一个 `LlmFailure`。调用选定适配器后,流会保留被抛出的确切 `Error` 对象,并将不可变事实以及实际服务注册所对应的不可变重试策略关联到该调用;agent loop
|
|
299
|
+
- **两条受支持的错误路径,共用一个 `LlmFailure` 类型。** 失败可以从 `stream()` 抛出(传输/协议错误),**或者**以 `finish {kind:'error'|'aborted', failure}` 结束流(无法在流中途抛异常的适配器用它表示提供方带内错误)。`LlmError.failure` 携带同一个 `LlmFailure`。调用选定适配器后,流会保留被抛出的确切 `Error` 对象,并将不可变事实以及实际服务注册所对应的不可变重试策略关联到该调用;agent loop(智能体循环)先把 attempt stream 提交为 `assistant/attempt`,再关闭失败步骤,并把错误、事实、不可变的先前已重试失败事实、实际服务策略和轮次信号提供给 `agent/request-error`。处理该错误的 listener 在其 await 的修复完成后返回 `{ kind: 'retry' }`;若未恢复,结构化失败会成为轮次错误,并且该次 attempt 不会提交 surface Assistant message 或工具副作用。
|
|
239
300
|
- **一次适配器调用就是一次提供方尝试。** 适配器禁用库重试。agent 层恢复会打开另一个持久、带编号的轮次;直接调用 `ctx.llm.stream()` 的调用方仍然只尝试一次。
|
|
240
301
|
- **提供方停顿在传输层受到时限约束。** 两个已交付的远程适配器都暴露正数且有限的 `streamIdleTimeoutMs`,默认五分钟。watchdog 只在 iterator `next()` 尚未完成时启动,整个请求使用同一个稳定 signal,把自身到期映射为 `TIMEOUT`,并把更早发生的调用方中止保留为 `ABORTED`。
|
|
241
302
|
- **上下文溢出只有一个规范 code。** 两个 DeepSeek 适配器都通过 `isContextWindowExceededError()` 对提供方的显式细节分类并暴露 `CONTEXT_WINDOW_EXCEEDED`,无论失败以抛出的 HTTP `LlmError` 还是带内 finish error 到达。消费方按 code 路由,绝不依赖提供方文本。
|
|
@@ -273,7 +334,7 @@ interface AppIdentity {
|
|
|
273
334
|
|
|
274
335
|
## `TokenUsage`
|
|
275
336
|
|
|
276
|
-
逐调用 token 记账。各计数**互不重叠**:`inputTokens` 只包含未缓存输入;缓存输入单独报告,计费输入是三者之和。若提供方把缓存命中折入单一提示词总数(如 DeepSeek 的 `prompt_tokens
|
|
337
|
+
逐调用 token 记账。各计数**互不重叠**:`inputTokens` 只包含未缓存输入;缓存输入单独报告,计费输入是三者之和。若提供方把缓存命中折入单一提示词总数(如 DeepSeek 的 `prompt_tokens`),适配器会再将其扣除。可选的 `totalTokens` 是精确的提示词与输出聚合计数,由适配器保留提供方原值或从权威聚合计数重建;不可用或不一致时省略。`reasoningTokens` 存在时只是信息性细节,已经包含在 `outputTokens` 中;汇总时不得重复相加。
|
|
277
338
|
|
|
278
339
|
```ts type-equiv
|
|
279
340
|
/**
|
|
@@ -287,6 +348,14 @@ interface AppIdentity {
|
|
|
287
348
|
interface TokenUsage {
|
|
288
349
|
inputTokens: number
|
|
289
350
|
outputTokens: number
|
|
351
|
+
/**
|
|
352
|
+
* Exact full-call total including aggregate prompt and output tokens.
|
|
353
|
+
*
|
|
354
|
+
* Adapters preserve a provider total or derive it from authoritative
|
|
355
|
+
* aggregate prompt/output counters; they omit it when unavailable or
|
|
356
|
+
* inconsistent.
|
|
357
|
+
*/
|
|
358
|
+
totalTokens?: number
|
|
290
359
|
cacheReadTokens?: number
|
|
291
360
|
cacheWriteTokens?: number
|
|
292
361
|
reasoningTokens?: number
|
|
@@ -362,7 +431,7 @@ declare class BlockAssembler {
|
|
|
362
431
|
|
|
363
432
|
源码:[`packages/llm/llm/src/types.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/llm/llm/src/types.ts)
|
|
364
433
|
|
|
365
|
-
|
|
434
|
+
提供方与模型发现使用小型、提供方无关的描述符。模型目录仅供参考:路由仍以已注册提供方为键。
|
|
366
435
|
|
|
367
436
|
注册适配器会返回一个句柄:既是释放器,也带有原子的路由替换——路由集合由用户配置决定的插件正需要它。
|
|
368
437
|
|
|
@@ -610,8 +679,6 @@ interface LlmModelDiscoveryRequest {
|
|
|
610
679
|
api?: string
|
|
611
680
|
/** Credential for this interrogation alone; the harness never stores it. */
|
|
612
681
|
apiKey?: string
|
|
613
|
-
/** Caller cancellation; implementations must settle promptly after it aborts. */
|
|
614
|
-
signal?: AbortSignal
|
|
615
682
|
}
|
|
616
683
|
```
|
|
617
684
|
|
|
@@ -671,6 +738,12 @@ interface LlmCallConfigAdapterDefaults {
|
|
|
671
738
|
}
|
|
672
739
|
```
|
|
673
740
|
|
|
741
|
+
## DeepSeek 官方请求扩展
|
|
742
|
+
|
|
743
|
+
`ctx.deepseekLlmApiExtensions` 是用于向 `deepseek-official` 请求添加顶层字段的提供方特定注册表。贡献插件通过 `register(field, provider)` 认领一个字段;适配器在序列化基础正文后调用 `prepare(request)`,并在 HTTP 前合并返回字段。已准备的 `accept()` 事务会在 2xx 后运行,因此贡献方可以提交交付状态,而不会把传输失败或提供方拒绝当作接受。准备、冲突与接受失败会使用 `REQUEST_EXTENSION`,并使模型请求失败。
|
|
744
|
+
|
|
745
|
+
[协议参考](https://github.com/deepseek-ai/deepseek-harness/blob/master/docs/deepseek-llm-api-wire-extensions.zh.md)定义确切的请求标头、扩展事务、字段版本和接收方义务。随附组合会将 [`dsh_session_log`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/session/session-log-deepseek/README.zh.md) 注册为无损增量权威日志后缀,并将 [`dsh_plugin_packages`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/llm/plugin-package-inventory-deepseek/README.zh.md) 注册为完整存活 Loader 包集合。这些字段仍位于模型消息之外,也不会进入 pi-ai 适配器路径。
|
|
746
|
+
|
|
674
747
|
## 服务与提供方约定
|
|
675
748
|
|
|
676
749
|
`LlmAdapter` 是提供方约定:创建子类、实现 `stream()`,再用 `ctx.llm.registerAdapter(providers, adapter)` 注册一个适配器实例。`GenerateOptions.provider` 选择已注册适配器;`GenerateOptions.model` 会传给该适配器,无需在生命周期启动时注册。重复提供方路由会原子失败。可选的 `providerRetryPolicy()` 会按路由捕获并填入 normal 默认值,`providerInfo()` 与异步 `listModels()` 方法则为 `LlmRuntime.listProviders()` / `listModels()` 提供分离的 selector 元数据。该目录仅供参考,不是请求白名单:适配器仍是权威,并可接受未列出的模型 id。单次异步 `resolveModel()` 查询返回确切模型身份,以及可选的对正确性敏感的上下文容量、适配器配置的 `defaultMaxTokens`、由模型持有的有序推理强度 ID 和可选的部署默认值;字段缺失表示元数据不可用或保留提供方持有的行为,而不表示目录成员关系无效。解析器会接收可选的取消信号,并且必须在信号中止后迅速完成结算。`LlmRuntime.resolveModelInfo()` 会校验聚合结果并返回分离值。在最终适配器边界,`resolveCallConfig()` 仅在 `maxTokens` 缺失时填入输出默认值,并校验和填入推理强度,因此直接调用也无法绕过任何一项已配置行为;直接分派会在等待解析前捕获一项适配器注册。agent loop 则使用 `prepareCall()`,使模型解析、请求头持久记录和分派全程使用同一项注册,保留来自同一次查询的分离上下文元数据,并报告适配器填入的配置字段。适配器查找发生在 `llm/stream` waterfall 的终端 continuation,因此 listener 可以在查找前短路调用,或路由一个可变的一次性请求。AgentLoop 在外层 waterfall 返回流句柄时观察到一次请求尝试;这个有限边界不能证明惰性终端适配器已构造完成或开始提供方 I/O。`block-start` / `block-end` 的 `index` 关联与 assembler 共同意味着适配器只需 emit 格式正确的分片——块重组不是每个适配器各自的问题。`ctx.llm.stream()` 与 `llm/stream` waterfall 在一个轮次中的位置见 [architecture.md](../index.md#turn-flow)。
|
|
@@ -719,6 +792,16 @@ declare abstract class LlmAdapter {
|
|
|
719
792
|
* @returns a resolved policy, or `undefined` to use the normal defaults.
|
|
720
793
|
*/
|
|
721
794
|
providerRetryPolicy(_provider: string): ResolvedRetryPolicy | undefined;
|
|
795
|
+
/**
|
|
796
|
+
* Resolve provider-side request-image pricing for one exact model route.
|
|
797
|
+
* The default declares none, so consumers fall back to their own neutral
|
|
798
|
+
* estimate. Implementations must answer synchronously without I/O; the
|
|
799
|
+
* token meter resolves this per measurement.
|
|
800
|
+
* @param _provider - a route passed to `registerAdapter()` for this instance.
|
|
801
|
+
* @param _model - exact model id passed to {@link GenerateOptions.model}.
|
|
802
|
+
* @returns route-owned image pricing, or `undefined` when the route declares none.
|
|
803
|
+
*/
|
|
804
|
+
imageRequestPricing(_provider: string, _model: string): LlmImageRequestPricing | undefined;
|
|
722
805
|
/**
|
|
723
806
|
* List models this adapter can currently advertise for one owned provider.
|
|
724
807
|
* The result is advisory: an adapter may accept unlisted model ids, and
|
|
@@ -770,6 +853,33 @@ declare abstract class LlmAdapter {
|
|
|
770
853
|
|
|
771
854
|
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).
|
|
772
855
|
|
|
856
|
+
<a id="ctxdeepseekllmapiextensions--deepseekllmapiextensionregistry"></a>
|
|
857
|
+
|
|
858
|
+
### `ctx.deepseekLlmApiExtensions` — `DeepSeekLlmApiExtensionRegistry`
|
|
859
|
+
|
|
860
|
+
Registry of independently owned top-level fields for official DeepSeek requests.
|
|
861
|
+
|
|
862
|
+
```ts cordis-catalog
|
|
863
|
+
/**
|
|
864
|
+
* Register the sole provider of one top-level request field. Registration is effect-scoped.
|
|
865
|
+
* @param field - declaration-merged field owned by the provider.
|
|
866
|
+
* @param provider - request-time field preparation and optional acceptance behavior.
|
|
867
|
+
* @returns disposer that releases the field.
|
|
868
|
+
*/
|
|
869
|
+
register<K extends keyof DeepSeekLlmApiExtensionMap>( field: K, provider: DeepSeekLlmApiExtensionProvider<DeepSeekLlmApiExtensionMap[K]>, ): () => Promise<void>
|
|
870
|
+
|
|
871
|
+
/**
|
|
872
|
+
* Prepare every currently registered field from one immutable base request.
|
|
873
|
+
* Preparation failures reject before HTTP dispatch. Field values are cloned and frozen;
|
|
874
|
+
* providers retain no mutable alias to the outgoing request.
|
|
875
|
+
* @param request - exact serialized request facts before extension fields.
|
|
876
|
+
* @returns detached fields and their idempotent joint acceptance transaction.
|
|
877
|
+
*/
|
|
878
|
+
async prepare(request: DeepSeekLlmApiExtensionRequest): Promise<PreparedDeepSeekLlmApiExtensions>
|
|
879
|
+
```
|
|
880
|
+
|
|
881
|
+
Source: [`packages/llm/deepseek-llm-api-extensions/src/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/llm/deepseek-llm-api-extensions/src/index.ts)
|
|
882
|
+
|
|
773
883
|
<a id="ctxllm--llmruntime"></a>
|
|
774
884
|
|
|
775
885
|
### `ctx.llm` — `LlmRuntime`
|
|
@@ -791,7 +901,7 @@ registerAdapter(providers: string[], adapter: LlmAdapter): AdapterRegistrationHa
|
|
|
791
901
|
* Describe provider routes with a registered adapter.
|
|
792
902
|
* @returns detached provider metadata in registration order.
|
|
793
903
|
*/
|
|
794
|
-
listProviders(): LlmProviderInfo[]
|
|
904
|
+
@Remote listProviders(): LlmProviderInfo[]
|
|
795
905
|
|
|
796
906
|
/**
|
|
797
907
|
* Declare provider routes an adapter plugin can activate through
|
|
@@ -807,7 +917,7 @@ registerConfigurableProviders(entries: readonly LlmConfigurableProvider[]): Dire
|
|
|
807
917
|
* List every declared configurable provider, registered or dormant.
|
|
808
918
|
* @returns detached directory entries in declaration order.
|
|
809
919
|
*/
|
|
810
|
-
listConfigurableProviders(): LlmConfigurableProvider[]
|
|
920
|
+
@Remote listConfigurableProviders(): LlmConfigurableProvider[]
|
|
811
921
|
|
|
812
922
|
/**
|
|
813
923
|
* Offer to interrogate provider endpoints on behalf of the settings
|
|
@@ -816,10 +926,10 @@ listConfigurableProviders(): LlmConfigurableProvider[]
|
|
|
816
926
|
* directory, and because a provider being *added* has no route to name yet.
|
|
817
927
|
* Disposed with the fiber.
|
|
818
928
|
* @param settingsNs - the namespace whose profiles this discovery serves.
|
|
819
|
-
* @param discover - interrogates one endpoint
|
|
929
|
+
* @param discover - interrogates one endpoint and must honor the supplied signal.
|
|
820
930
|
* @returns the disposer that withdraws the offer.
|
|
821
931
|
*/
|
|
822
|
-
registerModelDiscovery( settingsNs: string, discover: (request: LlmModelDiscoveryRequest) => Promise<readonly LlmDiscoveredModel[]>, ): () => void
|
|
932
|
+
registerModelDiscovery( settingsNs: string, discover: ( request: LlmModelDiscoveryRequest, signal?: AbortSignal, ) => Promise<readonly LlmDiscoveredModel[]>, ): () => void
|
|
823
933
|
|
|
824
934
|
/**
|
|
825
935
|
* Interrogate one provider endpoint for the models it advertises. The
|
|
@@ -828,9 +938,20 @@ registerModelDiscovery( settingsNs: string, discover: (request: LlmModelDiscover
|
|
|
828
938
|
* candidate metadata a surface may offer for adoption.
|
|
829
939
|
* @param settingsNs - namespace whose registered discovery serves this draft.
|
|
830
940
|
* @param request - the endpoint, protocol, and one-shot credential to use.
|
|
941
|
+
* @param signal - caller cancellation.
|
|
831
942
|
* @returns the advertised models, deduplicated in endpoint order.
|
|
832
943
|
*/
|
|
833
|
-
async discoverModels( settingsNs: string, request: LlmModelDiscoveryRequest, ): Promise<LlmDiscoveredModel[]>
|
|
944
|
+
async discoverModels( settingsNs: string, request: LlmModelDiscoveryRequest, signal?: AbortSignal, ): Promise<LlmDiscoveredModel[]>
|
|
945
|
+
|
|
946
|
+
/**
|
|
947
|
+
* Remote adapter for one draft provider interrogation.
|
|
948
|
+
* @param settingsNs - namespace whose registered discovery serves this draft.
|
|
949
|
+
* @param request - endpoint, protocol, and one-shot credential to use.
|
|
950
|
+
* @param signal - caller cancellation supplied by the Remote carrier.
|
|
951
|
+
* @returns advertised models in endpoint order.
|
|
952
|
+
* @throws RemoteError with `llm/model-discovery-rejected` when discovery refuses or fails.
|
|
953
|
+
*/
|
|
954
|
+
@Remote('discoverModels') async remoteDiscoverModels( settingsNs: string, request: LlmModelDiscoveryRequest, signal: AbortSignal, ): Promise<LlmDiscoveredModel[]>
|
|
834
955
|
|
|
835
956
|
/**
|
|
836
957
|
* Resolve the retry policy captured when one provider route was registered.
|
|
@@ -839,6 +960,25 @@ async discoverModels( settingsNs: string, request: LlmModelDiscoveryRequest, ):
|
|
|
839
960
|
*/
|
|
840
961
|
providerRetryPolicy(provider: string): ResolvedRetryPolicy
|
|
841
962
|
|
|
963
|
+
/**
|
|
964
|
+
* Resolve provider-side request-image pricing for one exact route, or
|
|
965
|
+
* `undefined` when the provider is unregistered or declares none. Unknown
|
|
966
|
+
* providers degrade to `undefined` rather than throwing because callers
|
|
967
|
+
* price durable history whose route may no longer be mounted.
|
|
968
|
+
* @param provider - provider route named by a request header.
|
|
969
|
+
* @param model - exact model id named by the same header.
|
|
970
|
+
* @returns the owning adapter's image pricing for the route, when declared.
|
|
971
|
+
*/
|
|
972
|
+
imageRequestPricing(provider: string, model: string): LlmImageRequestPricing | undefined
|
|
973
|
+
|
|
974
|
+
/**
|
|
975
|
+
* Resolve the exact text one durable file occurrence contributes to every
|
|
976
|
+
* provider request in the current execution environment.
|
|
977
|
+
* @param ref - durable verbatim file reference from model history.
|
|
978
|
+
* @returns the same deterministic handle text used at adapter dispatch.
|
|
979
|
+
*/
|
|
980
|
+
fileRequestText(ref: FileAttachmentRef): string
|
|
981
|
+
|
|
842
982
|
/**
|
|
843
983
|
* Discover models advertised by one registered provider. Catalog membership
|
|
844
984
|
* is advisory and never changes routing or request validation.
|
|
@@ -894,6 +1034,8 @@ async prepareCall(config: LlmCallConfig, signal?: AbortSignal): Promise<Prepared
|
|
|
894
1034
|
stream(options: GenerateOptions): AsyncIterable<StreamChunk>
|
|
895
1035
|
```
|
|
896
1036
|
|
|
1037
|
+
Types: [FileAttachmentRef](https://github.com/deepseek-ai/deepseek-harness/blob/master/docs/subsystems/attachment.zh.md)
|
|
1038
|
+
|
|
897
1039
|
Source: [`packages/llm/llm/src/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/llm/llm/src/index.ts)
|
|
898
1040
|
|
|
899
1041
|
<a id="llm-events"></a>
|
|
@@ -48,7 +48,7 @@ interface Config {
|
|
|
48
48
|
|
|
49
49
|
## 当前预设与派生的 `custom`
|
|
50
50
|
|
|
51
|
-
`current(
|
|
51
|
+
`current(session)` 从可选注册的 `permissions` 投影派生实际生效的预设。该单元折叠会话的沙箱模式、审批策略和已记录选择;状态内部的缺失值回退到执行器配置的模式与审批服务配置,最后回退到 `ask`。注册表或投影 key 缺失时会显式失败。服务优先取仍然匹配的选择,其次取声明顺序中第一个匹配的表项,否则返回 `CUSTOM_PRESET`(`'custom'`)。`custom` 只是派生值:客户端可以把它显示为当前值,但它绝不是切换目标,也绝不出现在事件 payload 中。
|
|
52
52
|
|
|
53
53
|
`names` 按预设表声明顺序列出可切换的预设;`optionOf(name)` 为某个表键(label 回退为该键)或 `custom` 构建客户端渲染的选项,传入其他任何名称都会抛出异常。
|
|
54
54
|
|
|
@@ -68,7 +68,7 @@ interface PresetOption {
|
|
|
68
68
|
|
|
69
69
|
`set(session, name)` 解析预设(未知名称抛出异常),在 `name` 尚不是生效预设时追加一条仅记日志的 `permission/preset` 事件,然后通过各旋钮自己的 setter([dsh-sandbox-policy](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/sandbox/sandbox-policy) 的 `setSandboxMode` 与 [dsh-user-approval](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/interaction/user-approval) 的 `setApprovalPolicy`)写入,且仅当该 knob的生效值发生变化时才写。同一轮次内,选择事件先于旋钮事件出现;重新选择当前生效的预设则什么都不追加。
|
|
70
70
|
|
|
71
|
-
`permission/preset` 是持久、仅记日志的用户意图:它不进入模型 transcript(文本记录),模型可见的后果由 knob 事件经各自消费方承担;它存在是为了在两个预设共享同一个旋钮组合时,让 `current()`
|
|
71
|
+
`permission/preset` 是持久、仅记日志的用户意图:它不进入模型 transcript(文本记录),模型可见的后果由 knob 事件经各自消费方承担;它存在是为了在两个预设共享同一个旋钮组合时,让 `current()` 仍能保住用户选择的究竟是哪一个预设。`permissions` 投影把该选择与两个 knob 事件一同折叠,并保留用于区分空恢复 seed 与新会话的 `session/end-seed` 边界;回放不需要任何追赶状态或原始日志重扫。完整事件声明见[持久化日志事件目录](../persistence-catalog.md);方法签名见生成的[服务目录](#ctxpermissionpresets--permissionpresetservice)。
|
|
72
72
|
|
|
73
73
|
<!-- BEGIN GENERATED cordis-surface (gen-cordis-catalog.ts) — do not edit between markers -->
|
|
74
74
|
|
|
@@ -89,10 +89,10 @@ Owns the deployment's permission presets and their write path. Requires a confin
|
|
|
89
89
|
* Resolve the preset matching the effective knob values. A still-matching
|
|
90
90
|
* last selection wins shared-bundle ties; otherwise the first table match
|
|
91
91
|
* wins, or {@link CUSTOM_PRESET} when no entry matches.
|
|
92
|
-
* @param
|
|
92
|
+
* @param session - the session whose knob state is read.
|
|
93
93
|
* @returns the effective preset name, or `custom` when nothing matches.
|
|
94
94
|
*/
|
|
95
|
-
current(
|
|
95
|
+
current(session: Session): string
|
|
96
96
|
|
|
97
97
|
/**
|
|
98
98
|
* Build the whole select value for one folded knob state: every table
|
|
@@ -128,7 +128,7 @@ optionOf(name: string): PresetOption
|
|
|
128
128
|
set(session: Session, name: string): void
|
|
129
129
|
```
|
|
130
130
|
|
|
131
|
-
Types: [Session](./session.md)
|
|
131
|
+
Types: [Session](./session.md)
|
|
132
132
|
|
|
133
133
|
Source: [`packages/interaction/permission-presets/src/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/interaction/permission-presets/src/index.ts)
|
|
134
134
|
<!-- END GENERATED cordis-surface -->
|