Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -1143,6 +1143,7 @@ describe("ProviderCommandReactor", () => {
await waitFor(() => harness.interruptTurn.mock.calls.length === 1);
expect(harness.interruptTurn.mock.calls[0]?.[0]).toEqual({
threadId: "thread-1",
turnId: "turn-1",
});
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -715,7 +715,10 @@ const make = Effect.gen(function* () {
}

// Orchestration turn ids are not provider turn ids, so interrupt by session.
yield* providerService.interruptTurn({ threadId: event.payload.threadId });
yield* providerService.interruptTurn({
threadId: event.payload.threadId,
...(event.payload.turnId !== undefined ? { turnId: event.payload.turnId } : {}),
});
});

const processApprovalResponseRequested = Effect.fnUntraced(function* (
Expand Down
36 changes: 36 additions & 0 deletions apps/web/src/components/ChatView.browser.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -1598,6 +1598,42 @@ describe("ChatView timeline estimator parity (full app)", () => {
}
});

it("includes the active turn id when stopping a running turn", async () => {
wsRequests.length = 0;

const mounted = await mountChatView({
viewport: DEFAULT_VIEWPORT,
snapshot: createSnapshotForTargetUser({
targetMessageId: "msg-user-stop-button-turn-id" as MessageId,
targetText: "stop button turn id target",
sessionStatus: "running",
activeTurnId: "turn-stop-button-turn-id" as TurnId,
}),
});

try {
const stopButton = await waitForElement(
() => document.querySelector<HTMLButtonElement>('button[aria-label="Stop generation"]'),
"Unable to find stop generation button.",
);

stopButton.click();

await vi.waitFor(
() =>
wsRequests.some(
(request) =>
request._tag === ORCHESTRATION_WS_METHODS.dispatchCommand &&
request.type === "thread.turn.interrupt" &&
request.turnId === "turn-stop-button-turn-id",
),
{ timeout: 8_000, interval: 16 },
);
} finally {
await mounted.cleanup();
}
});

it("keeps the new thread selected after clicking the new-thread button", async () => {
const mounted = await mountChatView({
viewport: DEFAULT_VIEWPORT,
Expand Down
4 changes: 4 additions & 0 deletions apps/web/src/components/ChatView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3867,6 +3867,10 @@ export default function ChatView({
type: "thread.turn.interrupt",
commandId: newCommandId(),
threadId: activeThread.id,
...(activeThread.session?.activeTurnId !== undefined &&
activeThread.session?.activeTurnId !== null
? { turnId: activeThread.session.activeTurnId }
: {}),
createdAt: new Date().toISOString(),
});
};
Expand Down
Loading