From 07c335f6f23da9fa4f4dfd01ec6702115d477d00 Mon Sep 17 00:00:00 2001 From: Charles Vien Date: Tue, 30 Jun 2026 22:07:08 -0700 Subject: [PATCH] emit completed agent-step progress on run start --- .../agent/src/server/agent-server.test.ts | 32 +++++++++++++++++++ packages/agent/src/server/agent-server.ts | 22 +++++++++++++ 2 files changed, 54 insertions(+) diff --git a/packages/agent/src/server/agent-server.test.ts b/packages/agent/src/server/agent-server.test.ts index a2d6ad3d2..798ceef93 100644 --- a/packages/agent/src/server/agent-server.test.ts +++ b/packages/agent/src/server/agent-server.test.ts @@ -1234,6 +1234,38 @@ describe("AgentServer HTTP Mode", () => { { timeout: 15000, interval: 100 }, ); }, 30000); + + it("emits a completed _posthog/progress for the agent step after session initialization", async () => { + await createServer().start(); + + // Resolves the setup card's "agent" step on the agent-proxy read leg, + // where the orchestrator's Django-only progress event never arrives. + await vi.waitFor( + () => { + const allEntries = appendLogCalls.flat() as Array<{ + notification?: { + method?: string; + params?: Record; + }; + }>; + const agentProgress = allEntries.find( + (e) => + e?.notification?.method === "_posthog/progress" && + e?.notification?.params?.step === "agent", + ); + expect(agentProgress).toBeDefined(); + expect(agentProgress?.notification?.params).toMatchObject({ + group: "setup:test-run-id", + step: "agent", + status: "completed", + }); + expect(typeof agentProgress?.notification?.params?.label).toBe( + "string", + ); + }, + { timeout: 15000, interval: 100 }, + ); + }, 30000); }); describe("getInitialPromptOverride", () => { diff --git a/packages/agent/src/server/agent-server.ts b/packages/agent/src/server/agent-server.ts index aa5777f0a..a044efc7f 100644 --- a/packages/agent/src/server/agent-server.ts +++ b/packages/agent/src/server/agent-server.ts @@ -1336,6 +1336,28 @@ export class AgentServer { JSON.stringify(runStartedNotification), ); + // Mirror the "agent" setup step onto the ingest leg the client is reading; + // the orchestrator's completed progress only lands in Django. + const agentStartedProgress = { + jsonrpc: "2.0" as const, + method: POSTHOG_NOTIFICATIONS.PROGRESS, + params: { + group: `setup:${payload.run_id}`, + step: "agent", + status: "completed", + label: "Started agent", + }, + }; + this.broadcastEvent({ + type: "notification", + timestamp: new Date().toISOString(), + notification: agentStartedProgress, + }); + this.session.logWriter.appendRawLine( + payload.run_id, + JSON.stringify(agentStartedProgress), + ); + // Signal in_progress so the UI can start polling for updates this.posthogAPI .updateTaskRun(payload.task_id, payload.run_id, {