diff --git a/ui/src/context/LiveUpdatesProvider.test.ts b/ui/src/context/LiveUpdatesProvider.test.ts index 3a66cec4..c24faf70 100644 --- a/ui/src/context/LiveUpdatesProvider.test.ts +++ b/ui/src/context/LiveUpdatesProvider.test.ts @@ -117,3 +117,77 @@ describe("LiveUpdatesProvider visible issue toast suppression", () => { ).toBe(true); }); }); + +describe("LiveUpdatesProvider run lifecycle toasts", () => { + it("does not build start or success toasts for agent runs", () => { + const queryClient = { + getQueryData: () => [], + }; + + expect( + __liveUpdatesTestUtils.buildAgentStatusToast( + { + agentId: "agent-1", + status: "running", + }, + () => "CodexCoder", + queryClient as never, + "company-1", + ), + ).toBeNull(); + + expect( + __liveUpdatesTestUtils.buildRunStatusToast( + { + runId: "run-1", + agentId: "agent-1", + status: "succeeded", + }, + () => "CodexCoder", + ), + ).toBeNull(); + }); + + it("still builds failure toasts for agent errors and failed runs", () => { + const queryClient = { + getQueryData: () => [ + { + id: "agent-1", + title: "Software Engineer", + }, + ], + }; + + expect( + __liveUpdatesTestUtils.buildAgentStatusToast( + { + agentId: "agent-1", + status: "error", + }, + () => "CodexCoder", + queryClient as never, + "company-1", + ), + ).toMatchObject({ + title: "CodexCoder errored", + body: "Software Engineer", + tone: "error", + }); + + expect( + __liveUpdatesTestUtils.buildRunStatusToast( + { + runId: "run-1", + agentId: "agent-1", + status: "failed", + error: "boom", + }, + () => "CodexCoder", + ), + ).toMatchObject({ + title: "CodexCoder run failed", + body: "boom", + tone: "error", + }); + }); +}); diff --git a/ui/src/context/LiveUpdatesProvider.tsx b/ui/src/context/LiveUpdatesProvider.tsx index ec593b3b..20132721 100644 --- a/ui/src/context/LiveUpdatesProvider.tsx +++ b/ui/src/context/LiveUpdatesProvider.tsx @@ -244,8 +244,8 @@ function shouldSuppressAgentStatusToastForVisibleIssue( } const ISSUE_TOAST_ACTIONS = new Set(["issue.created", "issue.updated", "issue.comment_added"]); -const AGENT_TOAST_STATUSES = new Set(["running", "error"]); -const TERMINAL_RUN_STATUSES = new Set(["succeeded", "failed", "timed_out", "cancelled"]); +const AGENT_TOAST_STATUSES = new Set(["error"]); +const RUN_TOAST_STATUSES = new Set(["failed", "timed_out", "cancelled"]); function describeIssueUpdate(details: Record | null): string | null { if (!details) return null; @@ -416,7 +416,7 @@ function buildRunStatusToast( const runId = readString(payload.runId); const agentId = readString(payload.agentId); const status = readString(payload.status); - if (!runId || !agentId || !status || !TERMINAL_RUN_STATUSES.has(status)) return null; + if (!runId || !agentId || !status || !RUN_TOAST_STATUSES.has(status)) return null; const error = readString(payload.error); const triggerDetail = readString(payload.triggerDetail); @@ -653,6 +653,8 @@ function handleLiveEvent( } export const __liveUpdatesTestUtils = { + buildAgentStatusToast, + buildRunStatusToast, invalidateActivityQueries, shouldSuppressActivityToastForVisibleIssue, shouldSuppressRunStatusToastForVisibleIssue,