diff --git a/ui/litellm-dashboard/src/components/lens/traces/detail/conversation/TraceConversation.integration.test.tsx b/ui/litellm-dashboard/src/components/lens/traces/detail/conversation/TraceConversation.integration.test.tsx index a552f5b1285..a77b443ac9e 100644 --- a/ui/litellm-dashboard/src/components/lens/traces/detail/conversation/TraceConversation.integration.test.tsx +++ b/ui/litellm-dashboard/src/components/lens/traces/detail/conversation/TraceConversation.integration.test.tsx @@ -70,6 +70,33 @@ describe("TraceConversation", () => { expect(screen.getByRole("heading", { name: "read_file" })).toBeVisible(); }); + it("waits for an in-flight refresh before requesting another conversation page", async () => { + const user = userEvent.setup(); + const first = { ...trace, spans: [root], next_cursor: "old-page" }; + const refreshed = { ...first, next_cursor: "fresh-page" }; + const second = { ...trace, spans: [tool], next_cursor: null }; + const pending = Promise.withResolvers(); + vi.mocked(agentTraceCall) + .mockResolvedValueOnce(first) + .mockReturnValueOnce(pending.promise) + .mockResolvedValue(second); + renderWithProviders( + , + ); + await user.click(await screen.findByRole("tab", { name: "Conversation" })); + expect(await screen.findByText("Read the release notes")).toBeVisible(); + await user.click(screen.getByRole("button", { name: "Refresh run" })); + const more = screen.getByRole("button", { name: "Load next 20 entries" }); + expect(more).toBeDisabled(); + await user.click(more); + expect(agentTraceCall).toHaveBeenCalledTimes(2); + await act(async () => pending.resolve(refreshed)); + await waitFor(() => expect(more).toBeEnabled()); + await user.click(more); + expect(await screen.findByRole("button", { name: "Expand read_file tool call" })).toBeVisible(); + expect(vi.mocked(agentTraceCall).mock.calls.map((call) => call[3])).toEqual([null, null, "fresh-page"]); + }); + it("can load the next conversation page after a refresh fails", async () => { const user = userEvent.setup(); const first = { ...trace, spans: [root], next_cursor: "next-page" }; diff --git a/ui/litellm-dashboard/src/components/lens/traces/detail/run/RunView.tsx b/ui/litellm-dashboard/src/components/lens/traces/detail/run/RunView.tsx index cd4c90dbf1e..feaa9ba2c8c 100644 --- a/ui/litellm-dashboard/src/components/lens/traces/detail/run/RunView.tsx +++ b/ui/litellm-dashboard/src/components/lens/traces/detail/run/RunView.tsx @@ -186,7 +186,7 @@ function LoadedRun({ embedded={embedded} stale={switching} conversationPaging={{ - loading: traceQuery.isFetchingNextPage, + loading: traceQuery.isFetching, failed: isFetchNextPageError, loadMore: fetchNextPage, }}