fix(webui): finalize turn-ending slash commands

maintainer edit: keep /new and manually submitted /stop from leaving stale WebUI streaming state after they cancel or reset the active turn.
This commit is contained in:
chengyongru
2026-07-07 15:42:04 +08:00
committed by Xubin Ren
parent ef5318ebdc
commit 8a231b6e4d
4 changed files with 152 additions and 7 deletions
+41
View File
@@ -1345,6 +1345,47 @@ describe("ThreadComposer", () => {
expect(onSend).toHaveBeenCalledWith("/status", undefined, { sideChannel: true });
});
it("marks new chat commands as side-channel sends that finalize the active turn", () => {
const onSend = vi.fn();
render(
<ThreadComposer
onSend={onSend}
placeholder="Type your message..."
/>,
);
const input = screen.getByLabelText("Message input");
fireEvent.change(input, { target: { value: "/new" } });
fireEvent.click(screen.getByRole("button", { name: "Send message" }));
expect(onSend).toHaveBeenCalledWith(
"/new",
undefined,
{ sideChannel: true, finalizeActiveTurn: true },
);
});
it("routes a manually submitted stop command through the stop handler", () => {
const onSend = vi.fn();
const onStop = vi.fn();
render(
<ThreadComposer
onSend={onSend}
onStop={onStop}
isStreaming
placeholder="Type your message..."
/>,
);
const input = screen.getByLabelText("Message input");
fireEvent.change(input, { target: { value: "/stop" } });
fireEvent.keyDown(input, { key: "Escape" });
fireEvent.keyDown(input, { key: "Enter" });
expect(onStop).toHaveBeenCalledTimes(1);
expect(onSend).not.toHaveBeenCalled();
});
it("keeps goal task commands on the normal agent turn path", () => {
const onSend = vi.fn();
render(