diff --git a/src/agent/async-agent.ts b/src/agent/async-agent.ts index db22b843..910e2742 100644 --- a/src/agent/async-agent.ts +++ b/src/agent/async-agent.ts @@ -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 }); }); } diff --git a/src/agent/events.ts b/src/agent/events.ts index 8eb8b422..de46f02a 100644 --- a/src/agent/events.ts +++ b/src/agent/events.ts @@ -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; diff --git a/src/agent/runner.ts b/src/agent/runner.ts index 65fd528b..479cd473 100644 --- a/src/agent/runner.ts +++ b/src/agent/runner.ts @@ -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);