Files
deepseek-harness/docs/user/develop/framework/events.zh.md
imccyu ec601ca13d build(vendor): rescope the vendored Cordis packages into @deepseek-ai
Machine-produced by `pnpm run rescope-vendor --apply` plus the regeneration it
prints: `pnpm install` for the lockfile, `pnpm run gen-third-party-notices`,
`verify-translation-pairing --write` for the touched bilingual pairs,
`gen-doc-graphs`, and one typert snapshot whose ids embed character offsets.
`pnpm run rescope-vendor --check` verifies the result.

Renames nine vendored packages (cordis, cosmokit, schemastery and the six
@cordisjs plugins) and every reference that resolves them: manifest names and
dependency keys, module specifiers including declare-module merges, cordis.yml
plugin names, tsconfig paths, every Markdown fence, and `docs/` prose.
Directory names, upstream versions, and dependency ranges are unchanged, so
vendor/README.md still reads as an upstream snapshot; its manifest table gains
an upstream-name column so THIRD_PARTY_NOTICES keeps MIT attribution pointed
at each fork's origin.

The tutorial tier follows the rename end to end: its yaml fences named plugins
the Loader can no longer resolve, its `ts ignore-check` fences disagreed with
the compiled fences beside them, and its prose quoted both. The contracts that
told readers to keep upstream names — the root convention and the vendoring
cookbook's tree comment and manifest invariant — now say to rescope instead.

Two rules read `@deepseek-ai/` as "another workspace plugin": the client bundle
purity gate now names the vendored libraries a browser bundle inlines, and the
files where a bare `cordis` is an agent-preset id keep that product data.
2026-08-10 22:04:13 +08:00

144 lines
3.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 事件系统
[English](events.md) | 中文
事件是 Cordis 插件间通信的核心机制。Harness 大量使用事件来实现松耦合的扩展点。
## 基本用法
### 监听事件
```ts ignore-check
ctx.on('event-name', (payload) => {
// Handle the event.
})
```
### 触发事件
```ts ignore-check
ctx.emit('event-name', payload)
```
## 事件模式
Cordis 提供多种事件模式,适用于不同的交互约定:
### emit — 广播
所有监听器同步执行,返回值会被忽略:
```ts ignore-check
// Emit
ctx.emit('my-plugin/ready', { id: 'worker-1' })
// Listen
ctx.on('my-plugin/ready', ({ id }) => {
console.log(`${id} is ready`)
})
```
### bail — 短路
依次调用监听器,第一个非 `undefined` 的返回值将作为最终结果:
```ts ignore-check
// Dispatch
const result = ctx.bail('some-check', input)
// Listen: a returned value stops later listeners.
ctx.on('some-check', (input) => {
if (shouldBlock(input)) return 'blocked'
// Return undefined to continue to the next listener.
})
```
### serial — 顺序执行
监听器按注册顺序依次执行,并等待异步结果;第一个返回非空值的监听器会终止后续执行:
```ts ignore-check
await ctx.serial('setup-phase', context)
```
### waterfall瀑布式事件— 流水线
每个监听器可以包装下游返回值,形成处理链。**必须调用 `next()` 传递给下游**,不调用即会短路流水线:
```ts ignore-check
// Dispatch
const output = await ctx.waterfall('my-plugin/transform', input, async () => input)
// Listen: next() is mandatory.
ctx.on('my-plugin/transform', async (_input, next) => {
const downstream = await next()
return downstream.trim()
})
```
::: warning
waterfall 监听器**必须调用 `next()`**。不调用 `next` 会短路整个流水线,这是故意为之的设计——用于实现拦截/网关逻辑。
:::
## 类型安全的事件
Harness 使用 TypeScript 声明合并来为事件提供类型安全:
```ts
import '@deepseek-ai/cordis'
declare module '@deepseek-ai/cordis' {
interface Events {
'my-plugin/ready': (payload: { id: string }) => void
'my-plugin/check': (input: string) => boolean | undefined
'my-plugin/transform': (input: string, next: () => Promise<string>) => Promise<string>
}
}
// ctx.on('my-plugin/ready', ...) and ctx.emit('my-plugin/ready', ...)
// are now inferred correctly.
```
## Cordis 事件与会话记录
Harness 的 Cordis 事件遵循 `namespace/action` 命名,例如 `agent/step`、`agent/request`、`agent/request-error`、`tools/result` 和 `session/event`。完整签名与触发模式见[子系统页面](../../../subsystems/core.md)上生成的 `cordis-surface` 区块。
`turn/*`、`step/*`、`tool/call`、`tool/result` 和 `compact/*` 是持久化的会话事件类型,不是同名 Cordis 事件。需要观察它们时,监听 `session/event` 并检查 `event.type`。
## 事件监听器也是效果
通过 `ctx.on()` 注册的监听器会在插件卸载时自动移除:
```ts ignore-check
export function apply(ctx: Context) {
// This listener is removed when the plugin disposes.
ctx.on('tools/result', handler)
}
```
## 示例:日志插件
这个插件记录工具调用和工具结果:
```ts
import type { Context } from '@deepseek-ai/cordis'
import '@deepseek-ai/dsh-tools'
export const name = 'tool-logger'
export function apply(ctx: Context) {
ctx.on('tools/result', (exec, result) => {
console.log(`[tool] ${exec.name}(${JSON.stringify(exec.arguments)})`)
const text = result.content
.map(block => block.type === 'text' ? block.text : '')
.join('')
console.log(`[tool result] ${text.slice(0, 100)}`)
})
}
```
## 下一步
- [能力分层](../practice/) — 了解能力接口中的事件
- [LLM大语言模型适配器](../practice/llm-adapter.md) — 实现一个完整的 LLM 后端