feat(agent): add AgentErrorEvent for error propagation via subscribe

Add agent_error event type to MulticaEvent union so errors from
agent runs reach subscribe() consumers (Desktop IPC + Channel).
Make emitMulticaEvent public on Runner so AsyncAgent can emit errors.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Naiyuan Qing 2026-02-06 19:35:32 +08:00
parent 9bb1fd6e12
commit 4a503ecf4c
3 changed files with 12 additions and 2 deletions

View file

@ -48,12 +48,16 @@ export class AsyncAgent {
await this.agent.flushSession();
// Normal text is delivered via message_end event; only handle errors here
if (result.error) {
console.error(`[AsyncAgent] Agent run error: ${result.error}`);
this.channel.send({ id: uuidv7(), content: `[error] ${result.error}` });
this.agent.emitMulticaEvent({ type: "agent_error", error: result.error });
}
})
.catch((err) => {
const message = err instanceof Error ? err.message : String(err);
console.error(`[AsyncAgent] Agent run exception: ${message}`);
this.channel.send({ id: uuidv7(), content: `[error] ${message}` });
this.agent.emitMulticaEvent({ type: "agent_error", error: message });
});
}

View file

@ -26,5 +26,11 @@ export type CompactionEndEvent = {
reason: "count" | "tokens" | "summary" | "pruning";
};
/** Emitted when the agent encounters an error (LLM failure, quota exceeded, etc.) */
export type AgentErrorEvent = {
type: "agent_error";
error: string;
};
/** Union of all Multica-specific events */
export type MulticaEvent = CompactionStartEvent | CompactionEndEvent;
export type MulticaEvent = CompactionStartEvent | CompactionEndEvent | AgentErrorEvent;

View file

@ -342,7 +342,7 @@ export class Agent {
};
}
private emitMulticaEvent(event: MulticaEvent): void {
emitMulticaEvent(event: MulticaEvent): void {
for (const fn of this.multicaListeners) {
try {
fn(event);