refactor(agent): align delivery method names

This commit is contained in:
Turtle
2026-07-24 15:08:36 +08:00
parent 9848a9542b
commit b02b438667
113 changed files with 462 additions and 405 deletions

View File

@@ -2,5 +2,5 @@
# side as of the last confirmed-consistent state. Both languages carry equal authority;
# after editing either side, bring the other along and re-record with:
# pnpm run verify-translation-pairing --write
extension-cookbook.md: 056be4298ed2bec2b78ed777d58f1f8a60a34b78
extension-cookbook.zh.md: 41cdd4a7d14f32494d1dd5ae4a63c098d5640bdc
extension-cookbook.md: c13b46e06a3b34512cd371e6a4868a6e932a575f
extension-cookbook.zh.md: aeb5f905278c07344c68d80da05dc5daf299b4f6

View File

@@ -36,7 +36,7 @@ This waterfall is the reorderable policy layer. Use `ctx.tools.guard()` when an
## A UI plugin
A UI plugin renders from the `session/event` feed (the assistant token stream as `assistant/chunk`, plus turn/step boundaries and tool activity), and drives input back in via `agent.send()` / `agent.steer()`.
A UI plugin renders from the `session/event` feed (the assistant token stream as `assistant/chunk`, plus turn/step boundaries and tool activity), and drives input back in via `agent.followup()` / `agent.steer()`.
```ts
import type { Context } from 'cordis'
@@ -54,13 +54,13 @@ export function apply(ctx: Context) {
render(event.data.chunk.text)
}
})
onUserInput(text => ctx.agents.get(SessionId('client-session'))?.send([{ type: 'text', text }]))
onUserInput(text => ctx.agents.get(SessionId('client-session'))?.followup([{ type: 'text', text }]))
}
```
## A client-driver plugin (external protocol bridge)
A *client driver* is a UI plugin for a wire-protocol peer. It owns stdio, so stdout logging must be disabled, creates or resumes agents through the factory, maps harness events to protocol messages, and maps requests to `send()` or `cancel()`. Settle each request exactly once from durable `turn/end`, even if rendering fails, and tear agents down with `AgentHandle.dispose()` so disposal reaches quiescence.
A *client driver* is a UI plugin for a wire-protocol peer. It owns stdio, so stdout logging must be disabled, creates or resumes agents through the factory, maps harness events to protocol messages, and maps requests to `followup()` or `cancel()`. Settle each request exactly once from durable `turn/end`, even if rendering fails, and tear agents down with `AgentHandle.dispose()` so disposal reaches quiescence.
`packages/ui/acp` is the worked example: it bridges the agent to the Agent Client Protocol (JSON-RPC over stdio) so Zed and other ACP editors can drive it. See its README for the full method surface and the permission-prompt answerer it registers on the approval seam.
@@ -99,9 +99,9 @@ Every product feature maps to a listener on a documented extension seam — the
|---|---|
| Hook system (user + project level) | listeners on `agent/session-start`, `agent/prompt-submit`, `agent/request`, `agent/step-result`, `tools/pre-execute`, `tools/post-execute`, `agent/turn-continuation` — each interception waterfall returns a typed Decision; the `dsh-hooks-claude` / `dsh-hooks-codex` bridges map hook config files onto these seams |
| `/goal` | `ctx.goals` owns durable state, `dsh-goal-session` schedules same-session rounds through the public `Agent`, and separate command/tool producers expose human/model control |
| `/loop` | on the `turn/end` session event, `send()` the next iteration; or force-continue |
| `/loop` | on the `turn/end` session event, `followup()` the next iteration; or force-continue |
| Dynamic workflow | `ctx.workflows` + the worker-thread engine + the `workflow` tool; structured in-process children enforce output with scoped prompt/tool registrations, a monotonic tool guard, final `tools/result` commit (including enclosing `run_code`), and terminal `agent/turn-stop` |
| Queued + steering messages | core `Agent.send()` / `Agent.steer()` |
| Queued + steering messages | core `Agent.followup()` / `Agent.steer()` |
| Context compaction (auto + manual) | the `ctx.compact` seam + `dsh-compact-basic`; automatic pressure runs on serial `agent/post-step`, canonical overflow recovery runs on `agent/request-error`, and manual callers use the same compact service ([compaction Agent Note](../../.agents/notes/implemented/feature/2026-06-18-compaction-capability-seam.md) — the model-facing `/compact` consumer tool is deferred) |
| System prompt configurability | `ctx.systemPrompt.section()` with ordering and scope-local shadowing |
| AGENTS.md (root) | a section provider reading the file |
@@ -118,8 +118,8 @@ Every product feature maps to a listener on a documented extension seam — 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 → `send(…, {source: {kind: 'cron', …}})` when idle / `inject()` notification when busy |
| UI (GUI; CLI emits JSONL) | listen `session/event` (assistant chunks, boundaries, tool activity); input → `send()` |
| Scheduled tasks (cron) | a plugin registers model-callable scheduling tools; timer fires → `followup(…, {source: {kind: 'cron', …}})` when idle / `inject()` notification when busy |
| UI (GUI; CLI emits JSONL) | listen `session/event` (assistant chunks, boundaries, tool activity); input → `followup()` |
| Telemetry / replayable trace | `session/event` → JSONL; replay = `sessions.create(id, { seed })` |
| Model adapters | `LlmAdapter` subclass via `registerAdapter` (`dsh-llm-deepseek`, `dsh-llm-pi-ai`) |
| Plugin hot-reload | every registration is a `ctx.effect` → vendored HMR just works |

View File

@@ -36,7 +36,7 @@ export function apply(ctx: Context) {
## UI 插件
UI 插件从 `session/event` 事件流渲染(助手 token 流以 `assistant/chunk` 形式到达,加上轮次/步骤边界与工具活动),并通过 `agent.send()` / `agent.steer()` 将输入驱动回去。
UI 插件从 `session/event` 事件流渲染(助手 token 流以 `assistant/chunk` 形式到达,加上轮次/步骤边界与工具活动),并通过 `agent.followup()` / `agent.steer()` 将输入驱动回去。
```ts
import type { Context } from 'cordis'
@@ -54,13 +54,13 @@ export function apply(ctx: Context) {
render(event.data.chunk.text)
}
})
onUserInput(text => ctx.agents.get(SessionId('client-session'))?.send([{ type: 'text', text }]))
onUserInput(text => ctx.agents.get(SessionId('client-session'))?.followup([{ type: 'text', text }]))
}
```
## 客户端驱动插件(外部协议桥接)
*客户端驱动*是面向协议格式wire format对端的 UI 插件。它拥有 stdio因此必须禁用 stdout 日志;通过工厂创建或恢复 agent智能体将 harness 事件映射为协议消息;将请求映射为 `send()``cancel()`。每个请求从持久的 `turn/end` 恰好结算一次(即使渲染失败),并通过 `AgentHandle.dispose()` 拆除 agent 以使 dispose资源释放达到静止状态。
*客户端驱动*是面向协议格式wire format对端的 UI 插件。它拥有 stdio因此必须禁用 stdout 日志;通过工厂创建或恢复 agent智能体将 harness 事件映射为协议消息;将请求映射为 `followup()``cancel()`。每个请求从持久的 `turn/end` 恰好结算一次(即使渲染失败),并通过 `AgentHandle.dispose()` 拆除 agent 以使 dispose资源释放达到静止状态。
`packages/ui/acp` 是完整的工作示例:它将 agent 桥接到 ACPAgent Client Protocol基于 stdio 的 JSON-RPC使 Zed 及其他 ACP 编辑器能够驱动它。其 README 描述了完整的方法接口以及它在审批 seam 上注册的权限提示应答器。
@@ -99,9 +99,9 @@ export function apply(ctx: Context) {
|---|---|
| 钩子系统(用户级 + 项目级) | `agent/session-start``agent/prompt-submit``agent/request``agent/step-result``tools/pre-execute``tools/post-execute``agent/turn-continuation` 上的监听器——每个拦截 waterfall 返回一个类型化 Decision`dsh-hooks-claude` / `dsh-hooks-codex` 桥接器将钩子配置文件映射到这些 seam 上 |
| `/goal` | `ctx.goals` 管理持久状态,`dsh-goal-session` 通过公共 `Agent` 调度同会话回合,独立的命令/工具生产方分别提供人类/模型控制 |
| `/loop` | 在 `turn/end` 会话事件上 `send()` 下一次迭代;或强制继续 |
| `/loop` | 在 `turn/end` 会话事件上 `followup()` 下一次迭代;或强制继续 |
| 动态工作流 | `ctx.workflows` + worker-thread 引擎 + `workflow` 工具;结构化的进程内子任务通过作用域化的 prompt/工具注册、单调工具守卫、最终 `tools/result` 提交(包括外层 `run_code`)和终端 `agent/turn-stop` 来强制输出 |
| 排队消息 + steering中途引导 | 核心 `Agent.send()` / `Agent.steer()` |
| 排队消息 + steering中途引导 | 核心 `Agent.followup()` / `Agent.steer()` |
| 上下文压缩context compaction自动 + 手动) | `ctx.compact` seam + `dsh-compact-basic`;自动压力检查运行在串行 `agent/post-step`,规范化溢出恢复运行在 `agent/request-error`,手动调用方使用同一个压缩服务([压缩 Agent Note](../../.agents/notes/implemented/feature/2026-06-18-compaction-capability-seam.md)——面向模型的 `/compact` 消费方工具已推迟) |
| 系统提示词可配置性 | `ctx.systemPrompt.section()`,支持排序与作用域局部覆盖 |
| AGENTS.md根目录 | 一个读取该文件的 section provider |
@@ -118,8 +118,8 @@ export function apply(ctx: Context) {
| MCP | 每个服务器一个插件:发现工具 → `ctx.tools.register()` |
| Skill技能 | section + 工具注册;调用时通过 `inject()` 注入 skill 内容 |
| 记忆 | section provider + 工具 |
| 定时任务cron | 插件注册面向模型的调度工具;定时器触发 → 空闲时 `send(…, {source: {kind: 'cron', …}})`/忙碌时 `inject()` 通知 |
| UIGUICLI 输出 JSONL | 监听 `session/event`(助手分片、边界、工具活动);输入 → `send()` |
| 定时任务cron | 插件注册面向模型的调度工具;定时器触发 → 空闲时 `followup(…, {source: {kind: 'cron', …}})`/忙碌时 `inject()` 通知 |
| UIGUICLI 输出 JSONL | 监听 `session/event`(助手分片、边界、工具活动);输入 → `followup()` |
| 遥测 / 可回放 trace | `session/event` → JSONL回放 = `sessions.create(id, { seed })` |
| 模型适配器 | 通过 `registerAdapter` 注册 `LlmAdapter` 子类(`dsh-llm-deepseek``dsh-llm-pi-ai` |
| 插件热重载 | 每个注册都是一个 `ctx.effect` → vendor 的 HMR热模块替换直接生效 |