import type { ChatMessage, ToolCallInfo } from "../schemas/message"; import type { McpAppData } from "../schemas/mcp-app"; import type { TurnProjection } from "../schemas/projection"; import type { SessionStatus } from "../schemas/session"; /** * AgentSession 的语义事件表。 * * 这是"底层逃生舱"(L1):React 使用者优先用 useChat() 的响应式状态(L2) * 或 的声明式入口(L3),一般不需要直接监听。 * Vue / 无框架集成者用 session.on(...) 精确订阅。 */ export interface AgentSessionEvents { /** 一条消息物化完成(turn 离开 streaming 状态)。 */ message: { message: ChatMessage; turn: TurnProjection; }; /** 智能体发起了一次工具调用(首次出现)。 */ toolCall: { toolCall: ToolCallInfo; turn: TurnProjection; }; /** 一次工具调用出结果(done / error / cancelled)。 */ toolResult: { toolCall: ToolCallInfo; turn: TurnProjection; /** 实时到达,或首次连接/断线重连时由服务端回放。 */ source: "live" | "bootstrap_replay" | "reconnect_replay"; }; /** 一轮回复结束。status: completed / paused / interrupted / failed。 */ chatEnd: { status: string; }; /** * 运行错误(system:error、发送失败等)。 * * `code` 是服务端给的机器可读原因(如 `owner_timeout` / `route_broken`), * 供调用方决定要不要重试;`message` 是可以直接展示的业务文案。 */ error: { message: string; code?: string; }; /** planning / executing 模式切换。 */ modeChange: { mode: "planning" | "executing"; }; /** * 智能体给宿主页面下发指令。 * * action 的来源:技能作者在工具实现的返回值 JSON 里写 `_meta.bridge: * { action, payload }`,后端剥离后经事件流送达前端。action 是技能作者与 * 宿主页面开发者约定的业务契约字符串(如 "map.highlight"),LLM 不参与、 * SDK 不做枚举。一般用 session.onCommand(action, fn) 消费,而不是监听本事件。 */ command: { action: string; payload: unknown; toolCallId?: string; }; /** 系统通知(技能阶段提示、后台任务启动等)。 */ notification: { type: string; title: string; detail?: string; status: "info" | "running" | "done" | "error"; loopId?: string; metadata?: Record; }; /** 工作区文件发生变化(写文件、重命名等)。 */ workspaceChanged: { filePath?: string; }; /** 智能体产出了文件成果(artifact:created / artifact:updated)。 */ artifact: { filePath: string; contentType: string; title: string; content: string; oldString?: string; newString?: string; kind: "created" | "updated"; }; /** 工具返回值带 _meta.ui 的可视化预览(resource HTML / URI)。 */ toolPreview: { /** Source file identity when the preview comes from a local HTML file. */ sourcePath?: string; toolCallId: string; type: "resource-html" | "resource-uri" | "resource-file"; content: string; title: string; mcpApp?: McpAppData; }; /** 任务清单(TaskCreate 等)更新。 */ taskListUpdated: { tasks: unknown[]; }; /** 沙盒后台命令状态更新。 */ backgroundTask: { id: string; command: string; description?: string; /** * 与 REST 一致的真实状态。不要在客户端合并这些值:把 cancelled / lost * 显示成"完成"会让订阅方拿到与 REST 相反的结论。 * lost 表示平台跟丢了这个进程,不代表它失败,也可能仍在运行。 */ status: "starting" | "running" | "cancelling" | "succeeded" | "failed" | "cancelled" | "lost"; /** failed 时说明原因,如 start_failed、log_budget_exceeded。 */ failureReason?: string | null; exitCode?: number | null; elapsedSeconds: number; output?: string; }; /** 会话被回溯到某个检查点。 */ rewind: { checkpointId: string; }; /** 会话属性(名称、状态、绑定技能等)被服务端更新。 */ sessionUpdated: { workspacePath?: string; chatGroupId?: string | null; intent?: string; status?: SessionStatus; model?: string | null; boundSkillId?: string | null; replayState?: Record | null; }; /** 回放输入不匹配,需要决定保持回放还是转自主模式。 */ replayMismatch: { actualMessage?: string; expectedMessage?: string; respond: (decision: "keep_replay" | "continue_replay") => void; }; /** 沙盒内存超限自动重启。 */ sandboxOom: { toolCallId: string; }; /** session.attach() 被调用,渲染层(ChatView/useChat)应把它显示为输入框附件。 */ attachRequested: { label: string; content: string; }; /** session.insertText() 被调用,渲染层应把文字追加到输入框。 */ insertTextRequested: { text: string; }; } export type AgentSessionEventName = keyof AgentSessionEvents; type Handler = (event: E) => void; export declare class Emitter { private handlers; on(name: K, handler: Handler): () => void; off(name: K, handler: Handler): void; emit(name: K, event: Events[K]): void; /** * 只把事件交给最先注册的处理器。用于必须由单一交互入口作答的事件, * 避免多个 UI 同时弹窗并提交相互冲突的决定。 */ emitFirst(name: K, event: Events[K]): boolean; listenerCount(name: keyof Events): number; clear(): void; } export {};