mirror of
https://github.com/deepseek-ai/deepseek-harness.git
synced 2026-10-26 16:55:08 +00:00
Merge pull request #5146 from deepseek-harness/fix/producer-owned-source-doc-examples
docs: show the producer-owned message source in current-state examples
This commit is contained in:
commit
3dce1c93d0
14 files changed
+18
-18
No files matched your search
@@ -9,8 +9,8 @@
|
||||
en: 2cc80a2a79e23005
|
||||
zh: 87e43383055890ce
|
||||
/tool-authoring-reference/rules-of-the-execute-contract:
|
||||
en: 110fa68298c53f96
|
||||
zh: f5762893eb615ddf
|
||||
en: 0b85f46f6a5bd8af
|
||||
zh: 56eb8d05198333dc
|
||||
/tool-authoring-reference/long-running-work:
|
||||
en: d81167332dfd05b7
|
||||
zh: 1c878b60f70728c2
|
||||
|
||||
@@ -46,7 +46,7 @@ Registration is effect-based: disposing the plugin fiber unregisters the tool. S
|
||||
- **Throwing or returning an invalid value means `isError`.** The registry catches throws and contains schema, renderer, metadata-projector, and lossless-JSON failures before observers run. Throw for infrastructure failures. Represent a successful domain outcome in the canonical value even when its Native renderer explains a non-ideal state, such as a non-zero process exit.
|
||||
- **Honor `exec.signal`.** Cancel in-flight work when it fires.
|
||||
- **Project durable card data with `presentationMeta` (optional).** `output.presentationMeta(args, value)` derives replayable JSON from the same canonical value. The core persists it on `tool/result` and hands it to `presentResult`, so a card that needs result-time facts—such as `write`/`edit` applied hunks—survives replay without persisting the canonical value. The projector is skipped for nested Code dispatches because they have no cards.
|
||||
- **Use `exec.agent` for async notifications.** `agent.inject({ content, source: { kind: 'plugin', plugin: '<name>' } })` appends durable context the NEXT model request sees — it is not a wake-up (an idle agent stays idle). Guard against disposed agents (try/catch).
|
||||
- **Use `exec.agent` for async notifications.** `agent.inject({ content, source: { kind: 'my-plugin' } })` appends durable context the NEXT model request sees — it is not a wake-up (an idle agent stays idle). Declare that `kind` through [`MessageSourceMap`](../subsystems/llm-streaming.md#content-blocks-and-messages) in your plugin: session format V4 rejects the retired `{ kind: 'plugin', plugin: '<name>' }` wrapper at message admission. Guard against disposed agents (try/catch).
|
||||
|
||||
## Long-running work
|
||||
|
||||
|
||||
@@ -46,7 +46,7 @@ export function apply(ctx: Context) {
|
||||
- **抛出异常或返回无效值意味着 `isError`。** 注册表会捕获异常,并在观察者运行前收敛 schema、渲染器、元数据投影器和无损 JSON 失败。基础设施故障请抛异常。成功的领域结果即使表示不理想的状态,也应写入规范值;其 Native 渲染器可以解释该状态,例如进程以非零状态退出。
|
||||
- **遵守 `exec.signal`。** 信号触发时取消进行中的工作。
|
||||
- **使用 `presentationMeta` 投影持久化的卡片数据(可选)。** `output.presentationMeta(args, value)` 从同一个规范值派生可回放的 JSON。核心将其持久化在 `tool/result` 上并传给 `presentResult`,因此需要结果期事实的卡片——例如 `write`/`edit` 的已应用 hunk——无需持久化规范值也能在回放中重现。嵌套 Code 分发没有卡片,因此会跳过该投影器。
|
||||
- **使用 `exec.agent` 发送异步通知。** `agent.inject({ content, source: { kind: 'plugin', plugin: '<name>' } })` 追加持久化上下文,下一次模型请求会看到它——这不是唤醒(空闲的 agent(智能体)保持空闲)。请防范已 dispose 的 agent(try/catch)。
|
||||
- **使用 `exec.agent` 发送异步通知。** `agent.inject({ content, source: { kind: 'my-plugin' } })` 追加持久化上下文,下一次模型请求会看到它——这不是唤醒(空闲的 agent(智能体)保持空闲)。在插件里通过 [`MessageSourceMap`](../subsystems/llm-streaming.zh.md#content-blocks-and-messages) 声明该 `kind`:session format V4 在消息准入处拒绝退役的 `{ kind: 'plugin', plugin: '<name>' }` 包装。请防范已 dispose 的 agent(try/catch)。
|
||||
|
||||
## 长时间运行的工作
|
||||
|
||||
|
||||
@@ -21,5 +21,5 @@
|
||||
en: f0a28d07c0bb4d1b
|
||||
zh: 840962f512cb4031
|
||||
/cookbook-extension-plugin-shapes/the-feature-mechanism-map:
|
||||
en: 2d4511fc000afc42
|
||||
zh: d4875bf1e3f2808f
|
||||
en: 0504676a42dd1445
|
||||
zh: b33fba88ec2ace9c
|
||||
@@ -124,7 +124,7 @@ Every product feature maps to a listener on a documented extension point — the
|
||||
| MCP | one plugin per server: discover tools → `ctx.tools.register()` |
|
||||
| Skills | section + tool registration; `inject()` skill content on invocation |
|
||||
| Memory | section provider + tool |
|
||||
| Scheduled tasks (cron) | a plugin registers model-callable scheduling tools; timer fires → `followup(…, {source: {kind: 'plugin', plugin: 'schedule'}})` when idle / `inject()` notification when busy |
|
||||
| Scheduled tasks (cron) | a plugin registers model-callable scheduling tools; a due timer delivers through `followup(…, {source: {kind: 'schedule'}})` |
|
||||
| UI (GUI; CLI emits JSONL) | listen to `agent/assistant-stream` for live chunks and `session/event` for durable settlements, boundaries, and tool activity; input → `followup()` |
|
||||
| Web Client Chat business node | register a `ConversationNodeDefinition` and `conversation.chat.node` keyed renderer |
|
||||
| SessionTelemetryBackend / replayable trace | `session/event` → JSONL; replay = `sessions.create(id, { seed })` |
|
||||
|
||||
@@ -128,7 +128,7 @@ export function apply(ctx: Context) {
|
||||
| MCP | 每个服务器一个插件:发现工具 → `ctx.tools.register()` |
|
||||
| skill(技能) | section + 工具注册;调用时通过 `inject()` 注入 skill 内容 |
|
||||
| 记忆 | section 提供方 + 工具 |
|
||||
| 定时任务(cron) | 插件注册面向模型的调度工具;定时器触发 → 空闲时 `followup(…, {source: {kind: 'plugin', plugin: 'schedule'}})`/忙碌时 `inject()` 通知 |
|
||||
| 定时任务(cron) | 插件注册面向模型的调度工具;定时器到期后通过 `followup(…, {source: {kind: 'schedule'}})` 投递 |
|
||||
| UI(GUI;CLI(命令行界面)输出 JSONL) | 监听 `agent/assistant-stream` 的实时 chunk,并监听 `session/event` 的持久 settlement、边界与工具活动;输入 → `followup()` |
|
||||
| Web Client Chat 业务节点 | 注册 `ConversationNodeDefinition` 与 `conversation.chat.node` keyed renderer |
|
||||
| 遥测 / 可回放 trace | `session/event` → JSONL;回放 = `sessions.create(id, { seed })` |
|
||||
|
||||
@@ -30,8 +30,8 @@
|
||||
en: 2d21fa2aad5a729d
|
||||
zh: cfbfada0eb647435
|
||||
/deepseek-ai-dsh-time-context/understand-the-implementation/design-concept:
|
||||
en: f2c19187501f7027
|
||||
zh: 48d31d0ea9bd8b16
|
||||
en: 8887d5d7453ef8cc
|
||||
zh: a80b54028f75fbc5
|
||||
/deepseek-ai-dsh-time-context/understand-the-implementation/source-map:
|
||||
en: 05a0a4627013d3d2
|
||||
zh: 281429e6ef7f26ec
|
||||
|
||||
@@ -64,7 +64,7 @@ This section explains the design of the plugin; the observable behavior is cover
|
||||
|
||||
### Design concept
|
||||
|
||||
The plugin prepends an `agent/pre-step` listener that delegates first and appends one sourced `UserMessage` when an injection is due and the downstream decision enters the step. Each reading uses the exact snapshot source `{ kind: 'plugin', plugin: 'time-context', form: 'snapshot', sections: [{ name: 'time-context', text }] }`, and the invariant companion validates that shape, re-derives the current-turn browser policy from the original `user-rpc` messages, and checks the timestamp zone and elapsed baseline.
|
||||
The plugin prepends an `agent/pre-step` listener that delegates first and appends one sourced `UserMessage` when an injection is due and the downstream decision enters the step. Each reading uses the exact snapshot source `{ kind: 'time-context', form: 'snapshot', sections: [{ name: 'time-context', text }] }`, and the invariant companion validates that shape, re-derives the current-turn browser policy from the original `user-rpc` messages, and checks the timestamp zone and elapsed baseline.
|
||||
|
||||
### Source map
|
||||
|
||||
|
||||
@@ -64,7 +64,7 @@ kind: "package-reference"
|
||||
|
||||
### 设计理念
|
||||
|
||||
插件前置注册一个 `agent/pre-step` 监听器,先委托下游,需要注入且下游决策进入步骤时追加一条带来源的 `UserMessage`。每个读数都使用确切的快照来源 `{ kind: 'plugin', plugin: 'time-context', form: 'snapshot', sections: [{ name: 'time-context', text }] }`,不变式配套模块会校验该形状,根据原始 `user-rpc` 消息重新派生当前轮次的浏览器策略,并检查时间戳时区与经过时长基线。
|
||||
插件前置注册一个 `agent/pre-step` 监听器,先委托下游,需要注入且下游决策进入步骤时追加一条带来源的 `UserMessage`。每个读数都使用确切的快照来源 `{ kind: 'time-context', form: 'snapshot', sections: [{ name: 'time-context', text }] }`,不变式配套模块会校验该形状,根据原始 `user-rpc` 消息重新派生当前轮次的浏览器策略,并检查时间戳时区与经过时长基线。
|
||||
|
||||
### 源码地图
|
||||
|
||||
|
||||
@@ -53,7 +53,7 @@ handle.agent.followup({
|
||||
})
|
||||
handle.agent.steer({
|
||||
content: [{ type: 'text', text: 'Focus on the tests.' }],
|
||||
source: { kind: 'plugin', plugin: 'my-plugin' },
|
||||
source: { kind: 'my-plugin' },
|
||||
})
|
||||
await handle.agent.whenIdle()
|
||||
```
|
||||
|
||||
@@ -53,7 +53,7 @@ handle.agent.followup({
|
||||
})
|
||||
handle.agent.steer({
|
||||
content: [{ type: 'text', text: 'Focus on the tests.' }],
|
||||
source: { kind: 'plugin', plugin: 'my-plugin' },
|
||||
source: { kind: 'my-plugin' },
|
||||
})
|
||||
await handle.agent.whenIdle()
|
||||
```
|
||||
|
||||
@@ -36,8 +36,8 @@
|
||||
en: b76a432aad14aa90
|
||||
zh: b0cd916f7897fb42
|
||||
/deepseek-ai-dsh-repeat-tool-reminder/understand-the-implementation/reminder-delivery:
|
||||
en: ebd2a7d704e0a7be
|
||||
zh: 438213ad0412a64e
|
||||
en: a3edc5c0f98b0d1e
|
||||
zh: 173f6166ce3af779
|
||||
/deepseek-ai-dsh-repeat-tool-reminder/understand-the-implementation/source-map:
|
||||
en: 567a964105e1340b
|
||||
zh: 7a8b062b2d9b39d1
|
||||
|
||||
@@ -88,7 +88,7 @@ Each agent's chain is keyed by `(tool name, canonical arguments)` — two calls
|
||||
|
||||
### Reminder delivery
|
||||
|
||||
Reminders ride the post-execute decision's `additionalContexts` (source `{kind: 'plugin', plugin: 'repeat-tool-reminder', form: 'notice', summary: '<tool> × <count>'}`), never a `content` replacement: the `tool/result` event stays the tool's own output for audit. The loop buffers the context and appends it as an injected `user/message` after the step's tool results, which the session renders as a plain synthetic user message — model-visible, source-attributed, and reconstructable from the session log with no new session event. The guard always delegates via `next()` and prepends its reminder to the downstream decision's context array, so both decision variants (a blocked call included) still get the nudge while every entry retains its own source and metadata.
|
||||
Reminders ride the post-execute decision's `additionalContexts` (source `{kind: 'repeat-tool-reminder', form: 'notice', summary: '<tool> × <count>'}`), never a `content` replacement: the `tool/result` event stays the tool's own output for audit. The loop buffers the context and appends it as an injected `user/message` after the step's tool results, which the session renders as a plain synthetic user message — model-visible, source-attributed, and reconstructable from the session log with no new session event. The guard always delegates via `next()` and prepends its reminder to the downstream decision's context array, so both decision variants (a blocked call included) still get the nudge while every entry retains its own source and metadata.
|
||||
|
||||
### Source map
|
||||
|
||||
|
||||
@@ -88,7 +88,7 @@ guard 建立在四项承诺之上:
|
||||
|
||||
### 提醒传递
|
||||
|
||||
提醒随 post-execute 决策的 `additionalContexts`(来源为 `{kind: 'plugin', plugin: 'repeat-tool-reminder', form: 'notice', summary: '<tool> × <count>'}`)传递,绝不替换 `content`:用于审计的 `tool/result` 事件仍保留工具自己的输出。循环会缓冲这段上下文,并在该步骤的工具结果之后作为注入的 `user/message` 追加,会话将其渲染为普通的合成用户消息——模型可见、带有来源归属,且无需新会话事件即可从会话日志重建。guard 始终通过 `next()` 委派,并把提醒放在下游决策的上下文数组之前,因此两种决策变体(包括被阻止的调用)都会收到提醒,同时每个条目保留自己的来源与元数据。
|
||||
提醒随 post-execute 决策的 `additionalContexts`(来源为 `{kind: 'repeat-tool-reminder', form: 'notice', summary: '<tool> × <count>'}`)传递,绝不替换 `content`:用于审计的 `tool/result` 事件仍保留工具自己的输出。循环会缓冲这段上下文,并在该步骤的工具结果之后作为注入的 `user/message` 追加,会话将其渲染为普通的合成用户消息——模型可见、带有来源归属,且无需新会话事件即可从会话日志重建。guard 始终通过 `next()` 委派,并把提醒放在下游决策的上下文数组之前,因此两种决策变体(包括被阻止的调用)都会收到提醒,同时每个条目保留自己的来源与元数据。
|
||||
|
||||
### 源码地图
|
||||
|
||||
|
||||
Reference in new issue
Block a user