diff --git a/packages/server/src/server/session.ts b/packages/server/src/server/session.ts index 9982ae2fc..813cf0e4d 100644 --- a/packages/server/src/server/session.ts +++ b/packages/server/src/server/session.ts @@ -257,6 +257,17 @@ export function resolveCreateAgentTitles(options: { }; } +export function resolveWaitForFinishError(options: { + status: "permission" | "error" | "idle"; + final: AgentSnapshotPayload | null; +}): string | null { + if (options.status !== "error") { + return null; + } + const message = options.final?.lastError; + return typeof message === "string" && message.trim().length > 0 ? message : "Agent failed"; +} + type ProcessingPhase = "idle" | "transcribing"; type WorkspaceGitWatchTarget = { @@ -6569,9 +6580,10 @@ export class Session { : record.lastStatus === "error" ? "error" : "idle"; + const error = resolveWaitForFinishError({ status, final }); this.emit({ type: "wait_for_finish_response", - payload: { requestId, status, final, error: null, lastMessage: null }, + payload: { requestId, status, final, error, lastMessage: null }, }); return; } @@ -6598,9 +6610,11 @@ export class Session { : result.status === "error" ? "error" : "idle"; + const error = resolveWaitForFinishError({ status, final }); + this.emit({ type: "wait_for_finish_response", - payload: { requestId, status, final, error: null, lastMessage: result.lastMessage }, + payload: { requestId, status, final, error, lastMessage: result.lastMessage }, }); } catch (error) { const isAbort = diff --git a/packages/server/src/server/session.wait-for-finish.test.ts b/packages/server/src/server/session.wait-for-finish.test.ts new file mode 100644 index 000000000..d84a5c1c8 --- /dev/null +++ b/packages/server/src/server/session.wait-for-finish.test.ts @@ -0,0 +1,32 @@ +import { describe, expect, test } from "vitest"; + +import { resolveWaitForFinishError } from "./session.js"; + +describe("resolveWaitForFinishError", () => { + test("returns the agent error when the wait result is an error", () => { + expect( + resolveWaitForFinishError({ + status: "error", + final: { lastError: "invalid_json_schema" } as any, + }), + ).toBe("invalid_json_schema"); + }); + + test("returns a generic fallback when the agent ended in error without a message", () => { + expect( + resolveWaitForFinishError({ + status: "error", + final: {} as any, + }), + ).toBe("Agent failed"); + }); + + test("returns null for non-error wait results", () => { + expect( + resolveWaitForFinishError({ + status: "idle", + final: { lastError: "should not surface" } as any, + }), + ).toBeNull(); + }); +});