Skip to content

fix(ui): paginate session logs in drawer sidebar with Shift+J/K shortcuts - #28761

Open
shenshouer wants to merge 4 commits into
BerriAI:litellm_oss_staging_2from
shenshouer:fix/log-drawer-session-pagination
Open

fix(ui): paginate session logs in drawer sidebar with Shift+J/K shortcuts#28761
shenshouer wants to merge 4 commits into
BerriAI:litellm_oss_staging_2from
shenshouer:fix/log-drawer-session-pagination

Conversation

@shenshouer

@shenshouer shenshouer commented May 25, 2026

Copy link
Copy Markdown

Relevant issues

Fixes #28224 — original bug report (still OPEN, filed 2026-05-19): the session trace sidebar in the Log Details drawer silently truncates to the first 50 entries.

Re-submission of #28225 (silently closed on 2026-05-22 during dated-staging cleanup; verified the fix is NOT in main, litellm_internal_staging, or litellm_oss_staging as of 2026-05-25).

Same root cause as #21300 (open since 2026-02-16, still unresolved) — sessionSpendLogsCall in networking.tsx not passing pagination params to the backend. That PR fetches all pages eagerly; this PR keeps a single-page-at-a-time UX with explicit user-controlled paging, which is more memory-friendly for very long sessions and matches the existing main-list pagination pattern.

Pre-Submission checklist

Please complete all items before asking a LiteLLM maintainer to review your PR

  • I have Added testing in the tests/test_litellm/ directory — UI test coverage added in useKeyboardNavigation.test.ts (9 vitest specs in the dashboard test suite, since this is a UI-only change with no Python surface)
  • My PR passes all unit tests on make test-unit
  • My PR's scope is as isolated as possible, it only solves 1 specific problem (session log drawer truncation at 50 entries)
  • I have requested a Greptile review by commenting @greptileai and received a Confidence Score of at least 4/5 before requesting a maintainer review (Greptile previously confirmed 5/5 on fix(ui/log-drawer): paginate session trace list to surface logs beyond the first 50 #28225 — same diff)

Type

🐛 Bug Fix
🆕 New Feature

Changes

The session sidebar in the log details drawer fetched all logs for a session in a single call. The backend defaults to page_size=50, so long sessions silently truncated to 50 entries — anything beyond that was unreachable from the UI.

This PR forwards page / page_size to the existing /spend/logs/session/ui endpoint and surfaces page navigation directly in the drawer with Shift+J / Shift+K keyboard shortcuts.

  • networking.tsxsessionSpendLogsCall now accepts page (default 1) and page_size (default 50) and forwards them as query params.
  • LogDetailsDrawer.tsx — track sessionPage state, reset to 1 on session_id change, include page in the query key, and render a (this page) disclosure on the sidebar header when paginated.
  • DrawerHeader.tsx — render previous/next page buttons (DoubleLeft / DoubleRight icons) with ⇧K / ⇧J shortcut labels when showPageControls is true.
  • useKeyboardNavigation.ts — explicit shiftKey branch routes Shift+J/K to onNextPage / onPreviousPage. Plain J / K continue selecting next/prev log within the page (mutually exclusive — Shift+ never fires both).
  • useKeyboardNavigation.test.ts (new) — 9 vitest specs covering J/K bounds, Shift+J/K page calls and mutual exclusion with selection, optional handlers safe, Escape, isOpen=false ignored, and a regression test verifying addEventListener is not re-attached when callback identities are stable.

…tcuts

The session sidebar in the log details drawer fetched all logs for a
session in a single call, which truncated long sessions and made the
sidebar slow to render. This adds page/page_size forwarding to the
existing /spend/logs/session/ui endpoint and surfaces page navigation
in the drawer.

- networking.tsx: sessionSpendLogsCall now accepts page (default 1)
  and page_size (default 50) and forwards them as query params
- LogDetailsDrawer.tsx: track sessionPage state, reset to 1 on
  session_id change, include page in query key, render a "(this page)"
  disclosure on the sidebar header when paginated
- DrawerHeader.tsx: render previous/next page buttons with
  DoubleLeft/DoubleRight icons and Shift+J/K shortcut labels when
  showPageControls is true
- useKeyboardNavigation.ts: explicit shiftKey branch routes Shift+J/K
  to onNextPage/onPreviousPage; plain J/K continue selecting next/prev
  log within the page (mutually exclusive)
- useKeyboardNavigation.test.ts: 9 vitest specs covering J/K bounds,
  Shift+J/K page calls and mutual exclusion with selection, optional
  handlers safe, Escape, isOpen=false ignored, and a regression test
  verifying addEventListener is not re-attached when callback
  identities are stable

Re-submission of BerriAI#28225 (silently closed during dated-staging cleanup).
Same root cause as the long-open BerriAI#21300.
@codecov

codecov Bot commented May 25, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@greptile-apps

greptile-apps Bot commented May 25, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR fixes a long-standing truncation bug where the session-trace sidebar silently stopped at 50 entries by wiring page / page_size through sessionSpendLogsCall to the backend /spend/logs/session/ui endpoint, which already supports and returns total_pages / total. The UI surfaces the new capability via Shift+J / Shift+K keyboard shortcuts and optional prev/next page buttons in the drawer header.

  • networking.tsxsessionSpendLogsCall gains page/page_size params (defaulting to 1/50) and appends them as query params; no breaking changes to existing callers.
  • LogDetailsDrawer.tsx — tracks sessionPage state; resets on drawer close and sessionId change; derives totalPages from the backend response; memoizes goToPreviousPage/goToNextPage/handleSelectLog with correct useCallback deps to keep the keyboard listener stable.
  • useKeyboardNavigation.ts — replaces the switch with an explicit shiftKey branch so Shift+J/K page and plain J/K navigate rows as strictly-mutually-exclusive paths; onClose, onSelectLog, and the new page handlers are added to the effect deps.
  • useKeyboardNavigation.test.ts (new) — 9 vitest specs covering bounds, mutual exclusion, optional-handler safety, Escape, isOpen=false guard, and the addEventListener re-attachment regression.

Confidence Score: 5/5

Safe to merge — all changed paths are UI-only, the backend already supports the added pagination params and returns total_pages/total in its response, and the new logic is well-covered by tests.

The networking change forwards well-typed params to an endpoint that already handles them. State management is scoped correctly with resets on all relevant lifecycle events. The memoization strategy for the keyboard-navigation callbacks is sound and the new test suite validates all key paths including the regression guard for listener churn.

No files require special attention.

Important Files Changed

Filename Overview
ui/litellm-dashboard/src/components/networking.tsx sessionSpendLogsCall now accepts page/page_size params and appends them to the query string; backward-compatible defaults (page=1, page_size=50) preserve existing callers.
ui/litellm-dashboard/src/components/view_logs/LogDetailsDrawer/LogDetailsDrawer.tsx Adds sessionPage state with correct resets on drawer close and sessionId change; derives total/totalPages from backend response; memoizes goToPreviousPage/goToNextPage and handleSelectLog with proper useCallback deps.
ui/litellm-dashboard/src/components/view_logs/LogDetailsDrawer/DrawerHeader.tsx Adds optional DoubleLeft/DoubleRight page-navigation buttons with ⇧K/⇧J shortcut labels behind the showPageControls flag; disabled state driven by canGoPreviousPage/canGoNextPage props.
ui/litellm-dashboard/src/components/view_logs/LogDetailsDrawer/useKeyboardNavigation.ts Replaces switch/case with explicit shiftKey branch so Shift+J/K route to page handlers and plain J/K continue selecting rows; onClose/onSelectLog/onPreviousPage/onNextPage added to effect deps to close the pre-existing stale-closure gap.
ui/litellm-dashboard/src/components/view_logs/LogDetailsDrawer/useKeyboardNavigation.test.ts New vitest suite with 9 specs covering J/K bounds, Shift+J/K mutual exclusion, optional-handler safety, Escape, isOpen=false guard, and the addEventListener re-attachment regression.

Reviews (2): Last reviewed commit: "fix(ui/log-drawer): hide page controls o..." | Re-trigger Greptile

…eyboard listener

Greptile P2: the inline onSelectLog passed to useKeyboardNavigation
was recreated every render, while the effect's dependency array
omitted onSelectLog. This left the keydown listener holding a stale
closure across re-renders.

- Wrap the inline callback in useCallback so the parent passes a
  stable reference
- Add onClose and onSelectLog to the effect's deps so the listener
  re-attaches if either ever changes (the regression test still
  passes — stable refs from the parent prevent churn on no-op
  re-renders)
@shenshouer

Copy link
Copy Markdown
Author

@greptileai please re-review — the previous P2 about onSelectLog not being memoized has been addressed in 3b310fd (wrapped in useCallback and added to the effect deps in useKeyboardNavigation).

shenshouer and others added 2 commits May 25, 2026 11:19
Greptile P2: showPageControls was tied to isSessionMode, so the
Shift+K / Shift+J buttons rendered (both disabled) even when the
session had only one page. Switch to isSessionPaginated, which is
already computed and is the correct guard.
… unmount flicker

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@shenshouer

Copy link
Copy Markdown
Author

@Sameerlite 👋 friendly ping — this PR targets litellm_oss_staging_2 (per the recent merge pattern there, including #28549 and #28490) and fixes a UI truncation bug referenced in #28224 / #21300.

Current state:

  • ✅ Greptile reviewed and the two P2 findings were addressed (commits 3b310fd, 68188fa) plus an additional drawer-flicker fix (4d8e8c8) on top.
  • ✅ CodeCov / CI green.
  • 🟡 Greptile hasn't re-reviewed yet despite an explicit re-review request.

Could you let me know whether anything else is needed from me to move this forward — or whether I should be tagging someone else for the OSS staging merge flow? Happy to adjust as needed. Thank you!

@Sameerlite

Copy link
Copy Markdown
Contributor

@yuneng-berri can you review this?

@shenshouer

Copy link
Copy Markdown
Author

Adding context: another user just reported hitting this exact bug on 1.88.0-rc.1 with a 1512-message session — see #28224 (comment). This isn't an isolated case; the 50-entry truncation is actively blocking debugging workflows for users on the latest RC.

@shenshouer

shenshouer commented Jun 5, 2026

Copy link
Copy Markdown
Author

@ishaan-berri sorry to bother you directly — wanted to flag this small UI fix that's been waiting on review.

Context:

Could you either take a look or point me to whoever owns the OSS staging merge queue right now? Happy to rebase / adjust if anything is needed. Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants