SessionStatus
SessionStatus 管理会话的运行状态。
概述
SessionStatus 跟踪会话的当前状态(空闲、重试中、忙碌),用于协调 UI 显示和防止并发操作。
定义位置
packages/opencode/src/session/status.ts:7-25
主要对象
Info
会话状态信息(联合类型)。
Idle 状态
{
type: "idle"
}
表示会话空闲,可以接受新输入。
Retry 状态
{
type: "retry"
attempt: number
message: string
next: number
}
表示会话正在重试失败的操作。
| 属性名 | 类型 | 必填 | 说明 |
|---|---|---|---|
type | "retry" | 是 | 类型标识 |
attempt | number | 是 | 当前尝试次数 |
message | string | 是 | 重试原因/消息 |
next | number | 是 | 下次重试延迟(毫秒) |
Busy 状态
{
type: "busy"
}
表示会话正在处理,不能接受新输入。
TypeScript 类型定义
export type Info =
| { type: "idle" }
| {
type: "retry"
attempt: number
message: string
next: number
}
| { type: "busy" }
事件
| 事件名 | 类型 | 说明 |
|---|---|---|
session.status | {sessionID, status: Info} | 会话状态更新 |
session.idle | {sessionID} (已废弃) | 会话进入空闲状态 |
典型使用场景
1. 获取会话状态
const status = SessionStatus.get(sessionStatusID)
console.log(status.type) // "idle" | "retry" | "busy"
if (status.type === "retry") {
console.log(`Attempt ${status.attempt}: ${status.message}`)
console.log(`Next retry in ${status.next}ms`)
}
2. 设置会话为忙碌
SessionStatus.set(sessionID, {
type: "busy",
})
// 发布 session.status 事件
3. 设置会话为空闲
SessionStatus.set(sessionID, {
type: "idle",
})
// 自动清除状态,发布 session.status 和 session.idle 事件
4. 设置重试状态
SessionStatus.set(sessionID, {
type: "retry",
attempt: 3,
message: "API rate limited",
next: 5000, // 5 秒后重试
})
5. 列出所有会话状态
const allStatus = SessionStatus.list()
for (const [sessionID, status] of Object.entries(allStatus)) {
console.log(`${sessionID}: ${status.type}`)
}
状态转换图
状态使用场景
防止并发操作
const' status = SessionStatus.get(sessionID)
if (status.type === "busy") {
console.log("Session is busy, please wait")
return
}
// 安全地执行操作
SessionStatus.set(sessionID, { type: "busy" })
try {
await performOperation()
} finally {
SessionStatus.set(sessionID, { type: "idle" })
}
UI 状态显示
Bus.subscribeAll(async (event) => {
if (event.type === "session.status") {
const { sessionID, status } = event.properties
switch (status.type) {
case "idle":
updateUI({ status: "ready", icon: "check" })
break
case "busy":
updateUI({ status: "processing", icon: "spinner" })
break
case "retry":
updateUI({
status: "retrying",
icon: "retry",
message: `Attempt ${status.attempt}`,
})
break
}
}
})
重试逻辑
async function withRetry<T>(sessionID: string, fn: () => Promise<T>, maxAttempts = 3): Promise<T> {
let attempt = 0
while (attempt < maxAttempts) {
attempt++
try {
return await fn()
} catch (error) {
if (attempt >= maxAttempts) {
throw error
}
// 计算重试延迟(指数退避)
const delay = Math.pow(2, attempt) * 1000
// 设置重试状态
SessionStatus.set(sessionID, {
type: "retry",
attempt,
message: error.message,
next: delay,
})
// 等待
await new Promise((resolve) => setTimeout(resolve, delay))
}
}
throw new Error("Max attempts exceeded")
}
状态管理
内存存储
const state = Instance.state(() => {
const data: Record<string, Info> = {}
return data
})
状态持久化
SessionStatus 是运行时状态,不持久化到磁盘。重启后会话默认为 idle。
自动清理
当会话设置为 idle 时:
if (status.type === "idle") {
// 清理状态
delete state()[sessionID]
// 发布已废弃的 idle 事件
Bus.publish(Event.Idle, { sessionID })
}
错误处理
无效状态转换
// 不允许从 idle 直接到 retry
if (current.type === "idle" && newStatus.type === "retry") {
throw new Error("Invalid state transition: idle -> retry")
}
对象关系
变更历史
| 版本 | 变更内容 | 日期 |
|---|---|---|
| v1 | 初始 SessionStatus 架构 | - |
| v1.1 | 添加 retry 状态支持 | - |