From dcbc51e22dcd3d7b5a01d6c3b7b0285efa49bca4 Mon Sep 17 00:00:00 2001 From: Adam Malczewski Date: Fri, 29 May 2026 18:45:45 +0900 Subject: feat: stop generation button with abort signal plumbing - Add POST /chat/stop endpoint on API - Thread abortSignal from agent-manager through Agent.run() to streamText - Thread abortSignal option through the Agent.run() signature - Emit status:idle on stopTab() so frontend WS gets the update - Add stopGeneration() store method on frontend tabStore - Add stop button in ChatInput (btn-sm lg:btn-xs for mobile tap target) - Add tests for /chat/stop endpoint - Refactor processMessage to pass abortSignal to agent.run --- packages/api/tests/routes.test.ts | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) (limited to 'packages/api/tests') diff --git a/packages/api/tests/routes.test.ts b/packages/api/tests/routes.test.ts index 49bae49..eba2226 100644 --- a/packages/api/tests/routes.test.ts +++ b/packages/api/tests/routes.test.ts @@ -318,3 +318,25 @@ describe("POST /chat", () => { expect(typeof body.messageId).toBe("string"); }); }); + +describe("POST /chat/stop", () => { + it("returns 200 with success: true for valid tabId", async () => { + const res = await app.request("/chat/stop", { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ tabId: "tab-stop-1" }), + }); + expect(res.status).toBe(200); + const body = await res.json(); + expect(body).toEqual({ success: true }); + }); + + it("returns 400 when tabId is missing", async () => { + const res = await app.request("/chat/stop", { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({}), + }); + expect(res.status).toBe(400); + }); +}); -- cgit v1.2.3