fix(ui): keep the session view open when selecting a log inside it (#35399)

Opening a session from the logs table stored no ?session_id (row clicks
called openLog, which deletes it), so session mode was derived from the
clicked row's session_total_count. Rows fetched by the session drawer
come from /spend/logs/session/ui, which does not enrich that field, so
selecting any log inside the session view swapped in an unenriched row
and collapsed the drawer to a single-log Trace view

Row clicks on a multi-call session's row now call openSession, and
selectLog writes ?session_id when the session view is active, so session
mode is anchored in the URL instead of derived from row data
This commit is contained in:
ryan-crabbe-berri 2026-07-31 16:36:32 -07:00 committed by GitHub
parent 5df98a8f47
commit 5466402274
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 48 additions and 6 deletions

View file

@ -403,6 +403,41 @@ describe("RequestLogsPanel", () => {
expect(drawer()).toHaveAttribute("data-session-id", "sess-1");
});
});
it("clicking a multi-call session's row writes ?session_id= alongside ?log_id=", async () => {
const user = userEvent.setup();
respondWith([
logEntry({ request_id: "req-llm", call_type: "acompletion", session_id: "sess-1", session_total_count: 3 }),
logEntry({ request_id: "req-llm-2", call_type: "acompletion", session_id: "sess-1", session_total_count: 3 }),
]);
renderWithProviders(<RequestLogsPanel {...defaultProps} />);
await waitFor(() => expect(row("req-llm")).not.toBeNull());
await user.click(row("req-llm") as HTMLElement);
const params = new URLSearchParams(window.location.search);
expect(params.get("session_id")).toBe("sess-1");
expect(params.get("log_id")).toBe("req-llm");
await waitFor(() => expect(drawer()).toHaveAttribute("data-session-id", "sess-1"));
});
it("selecting another log while a session view is open keeps the session open", async () => {
const user = userEvent.setup();
window.history.replaceState(null, "", "/logs/?log_id=req-llm");
respondWith([
logEntry({ request_id: "req-llm", call_type: "acompletion", session_id: "sess-1", session_total_count: 3 }),
logEntry({ request_id: "req-unenriched" }),
]);
renderWithProviders(<RequestLogsPanel {...defaultProps} />);
await waitFor(() => expect(drawer()).toHaveAttribute("data-session-id", "sess-1"));
await user.click(screen.getByRole("button", { name: "select-next-log" }));
await waitFor(() => expect(drawer()).toHaveAttribute("data-log-id", "req-unenriched"));
expect(new URLSearchParams(window.location.search).get("session_id")).toBe("sess-1");
expect(drawer()).toHaveAttribute("data-session-id", "sess-1");
});
});
describe("live tail", () => {

View file

@ -235,9 +235,13 @@ export default function RequestLogsPanel({ accessToken, token, userRole, userID,
const handleRowClick = useCallback(
(log: LogEntry) => {
setSelectedLog(log);
openLog(log.request_id);
if (log.session_id && (log.session_total_count || 1) > 1) {
openSession(log.session_id, log.request_id);
} else {
openLog(log.request_id);
}
},
[openLog],
[openLog, openSession],
);
const handleSessionClick = useCallback(
@ -253,9 +257,9 @@ export default function RequestLogsPanel({ accessToken, token, userRole, userID,
const handleSelectLog = useCallback(
(log: LogEntry) => {
setSelectedLog(log);
selectLog(log.request_id);
selectLog(log.request_id, displaySessionId);
},
[selectLog],
[selectLog, displaySessionId],
);
const handleKeyHashClick = useCallback((keyHash: string) => {

View file

@ -11,7 +11,7 @@ export interface LogDetailRouting {
sessionId: string | null;
openLog: (requestId: string) => void;
openSession: (sessionId: string, requestId: string | null) => void;
selectLog: (requestId: string) => void;
selectLog: (requestId: string, sessionId?: string | null) => void;
close: () => void;
}
@ -36,9 +36,12 @@ export function useLogDetailRouting(): LogDetailRouting {
});
}, []);
const selectLog = useCallback((requestId: string) => {
const selectLog = useCallback((requestId: string, sessionId?: string | null) => {
navigateWithParams((params) => {
params.set(LOG_ID_QUERY_PARAM, requestId);
if (sessionId) {
params.set(SESSION_ID_QUERY_PARAM, sessionId);
}
}, "replace");
}, []);