Appearance
Copilot SDK 通过事件流实时反馈 Agent 的所有动作:思考过程、代码输出、工具调用、权限请求等。事件分瞬态(实时但不持久化)和持久化(可在会话恢复时重放)两种。订阅 assistant.message_delta 获取流式文字,订阅 tool.called 追踪工具使用。
GitHub Copilot SDK 流式事件系统:实时追踪 Agent 执行过程
事件统一结构
所有事件共享相同的信封格式:
typescript
interface Event {
id: string // 事件唯一 ID
type: string // 事件类型,决定 data 的结构
timestamp: string // ISO 时间戳
parentId?: string // 父事件 ID(用于关联子 Agent 事件)
data: object // 事件数据,根据 type 变化
}瞬态事件 vs 持久化事件
| 类型 | 描述 | 会话恢复时 |
|---|---|---|
| 瞬态(Ephemeral) | 实时流式推送,不写入磁盘 | 不可重放 |
| 持久化 | 写入磁盘,会话关联 | 可重放 |
assistant.message_delta(单个文字 chunk)是瞬态事件;完整的助手消息是持久化事件。
订阅所有事件
typescript
// 订阅所有事件类型
session.on('*', (event) => {
console.log(`[${event.type}] ${JSON.stringify(event.data)}`)
})核心事件类型
助手响应
typescript
// 流式文字 chunk(用于实时显示输出)
session.on('assistant.message_delta', (event) => {
process.stdout.write(event.data.delta)
})
// 完整消息完成
session.on('assistant.message_completed', (event) => {
console.log('助手消息完成:', event.data.content)
})工具调用
typescript
// 工具被调用时
session.on('tool.called', (event) => {
console.log(`调用工具: ${event.data.toolName}`)
console.log(`参数:`, event.data.arguments)
})
// 工具调用完成
session.on('tool.result', (event) => {
console.log(`工具结果:`, event.data.result)
})权限请求
typescript
// Agent 需要用户批准某个操作
session.on('permission.requested', (event) => {
console.log(`需要权限: ${event.data.action}`)
// 在 UI 中显示权限请求,等待用户确认
})子 Agent 活动
typescript
// 子 Agent 开始
session.on('subagent.started', (event) => {
console.log(`Sub-agent "${event.data.agentName}" 开始工作`)
})
// 子 Agent 完成
session.on('subagent.completed', (event) => {
console.log(`Sub-agent "${event.data.agentName}" 完成`)
})会话状态
typescript
// Agent 完成当前任务,进入空闲等待
session.on('session.idle', () => {
console.log('Agent 空闲,等待新的输入')
})
// 发生错误
session.on('session.error', (event) => {
console.error('Session 错误:', event.data.error)
})构建实时进度 UI
利用事件流构建实时反馈界面:
typescript
import { createSession } from '@github/copilot-sdk'
const session = await createSession()
// 状态追踪
let currentStatus = 'idle'
const toolsUsed: string[] = []
session.on('tool.called', (event) => {
currentStatus = `正在执行: ${event.data.toolName}`
toolsUsed.push(event.data.toolName)
updateUI({ status: currentStatus, tools: toolsUsed })
})
session.on('assistant.message_delta', (event) => {
appendToOutput(event.data.delta)
})
session.on('session.idle', () => {
currentStatus = '完成'
updateUI({ status: currentStatus })
})
// 发送任务
await session.sendPrompt({
messages: [{ role: 'user', content: '分析这个仓库的依赖安全问题' }]
})事件分类完整列表
| 类别 | 事件类型(示例) | 瞬态/持久化 |
|---|---|---|
| 助手响应 | assistant.message_delta、assistant.message_completed | delta 瞬态,completed 持久化 |
| 工具执行 | tool.called、tool.result | 持久化 |
| 权限 | permission.requested、permission.granted | 持久化 |
| 用户输入 | user.message_submitted | 持久化 |
| 子 Agent | subagent.started、subagent.completed | 持久化 |
| 会话状态 | session.idle、session.error | 瞬态 |
常见问题
Q: 会话恢复后能看到之前的工具调用记录吗?
A: 可以。持久化事件(包括工具调用)在会话恢复时可以重放,可以追溯整个任务的执行历史。
Q: 事件流会影响性能吗?
A: * 通配符订阅会捕获所有事件,高频事件场景下有小幅开销。如果只需要特定事件(如最终响应),只订阅 assistant.message_completed 而不是 assistant.message_delta。
Q: 同一事件可以有多个订阅者吗?
A: 可以。多次调用 session.on('event-type', handler) 会注册多个处理函数,所有处理函数都会被调用。