feat(ui): add session id filter to request logs - #32647
Conversation
Greptile SummaryThis PR adds a Session ID filter to the request logs UI, letting users narrow the logs table to a single conversation without clicking through rows manually. The feature is implemented end-to-end: a new
Confidence Score: 5/5Safe to merge — additive feature with no changes to existing filters or auth logic. The change is purely additive: a new optional query parameter that is wired through parameterized SQL (no interpolation), LIKE metacharacters are properly escaped, and the condition is always ANDed with the existing access-control WHERE clauses. The backend and frontend are both fully exercised by new tests. No existing behavior is altered. No files require special attention.
|
| Filename | Overview |
|---|---|
| litellm/proxy/spend_tracking/spend_management_endpoints.py | Adds session_id LIKE filter to the shared /spend/logs/v2 + /spend/logs/ui handler; correctly parameterized and escapes LIKE metacharacters before wrapping in %…% |
| tests/test_litellm/proxy/spend_tracking/test_spend_management_endpoints.py | Adds parametrized test covering full-id, prefix, common-substring, and no-match cases; extends mock prisma with group_by and an early-return for mcp_tool_call_count queries so session-carrying rows work in all test paths |
| ui/litellm-dashboard/src/components/view_logs/log_filter_logic.tsx | Adds SESSION_ID to FILTER_KEYS, TEXT_FILTER_KEYS (debounced), defaultFilters, and the uiSpendLogsCall params mapping — fully wired end-to-end |
| ui/litellm-dashboard/src/components/view_logs/filter_options.ts | Adds Session ID as a non-searchable filter option, consistent with the existing Key Hash and Request ID entries |
| ui/litellm-dashboard/src/components/networking.tsx | Extends UiSpendLogsParams with session_id?: string; picked up automatically by the existing generic query-param loop — no other changes needed |
| ui/litellm-dashboard/src/lib/http/schema.d.ts | Auto-generated schema updated for both /spend/logs/v2 and /spend/logs/ui to include the new session_id query parameter |
| ui/litellm-dashboard/src/components/view_logs/log_filter_logic.test.tsx | Adds the Session ID → session_id case to the frontend filter-mapping table test |
| ui/litellm-dashboard/eslint-metrics.json | ESLint inline-object count bumped by 7 to account for the new filter option objects added in this PR |
Reviews (3): Last reviewed commit: "chore(ui): refresh eslint metrics for re..." | Re-trigger Greptile
Greptile SummaryAdds an end-to-end session ID filter to the request logs view. Users can now type a session ID (or a prefix/substring) into the Logs filter panel and the
Confidence Score: 5/5Safe to merge — the change is additive (new optional query parameter), all filtering goes through parameterized SQL, and authorization is respected. The session_id filter follows the exact same patterns already used for key_alias and error_message (LIKE with proper metachar escaping, appended to sql_conditions after auth). No existing behaviour is changed, the new parameter is optional, and the test additions cover full-match, prefix, and no-match cases without weakening any prior assertions. No files require special attention. The shared mock helper in the test file was extended, but the additions are straightforward stubs for code paths that were previously unreachable in tests.
|
| Filename | Overview |
|---|---|
| litellm/proxy/spend_tracking/spend_management_endpoints.py | Adds session_id query parameter to ui_view_spend_logs, applying a LIKE %…% condition directly to sql_conditions after the authorization phase — consistent with existing partial-match filters (key_alias, error_message). LIKE metacharacters (\, %, _) are escaped in the correct order. |
| tests/test_litellm/proxy/spend_tracking/test_spend_management_endpoints.py | Adds parametrized session-id filter test and extends the shared mock prisma helper with a group_by method and an early-return for the MCP enrichment query_raw. Both mock additions are legitimate: existing tests had no session-id data so group_by was never reached; the mcp_tool_call_count short-circuit avoids a query-shape mismatch without hiding any prior regression. |
| ui/litellm-dashboard/src/components/networking.tsx | Adds session_id?: string to UiSpendLogsParams; the generic Object.entries loop that appends params already forwards it correctly. |
| ui/litellm-dashboard/src/components/view_logs/filter_options.ts | Registers the new Session ID filter option with isSearchable: false, consistent with similar text-input filters (Key Hash, Request ID). |
| ui/litellm-dashboard/src/components/view_logs/log_filter_logic.tsx | Adds SESSION_ID to FILTER_KEYS, TEXT_FILTER_KEYS, defaultFilters, and the uiSpendLogsCall params object — all exactly parallel to the existing REQUEST_ID additions. |
| ui/litellm-dashboard/src/components/view_logs/log_filter_logic.test.tsx | Adds a { filterKey: 'Session ID', paramName: 'session_id', value: 'sess-42' } row to the filter-mapping table test, completing the round-trip coverage. |
| ui/litellm-dashboard/src/lib/http/schema.d.ts | Regenerated OpenAPI schema adds `session_id?: string |
Reviews (2): Last reviewed commit: "chore(ui): refresh eslint metrics for re..." | Re-trigger Greptile
|
bugbot run |
131aa05
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 8a44fdd. Configure here.
| if session_id is not None and isinstance(session_id, str): | ||
| like_escaped_session_id = session_id.replace("\\", "\\\\").replace("%", "\\%").replace("_", "\\_") | ||
| sql_conditions.append(f"session_id LIKE ${p}") | ||
| sql_params.append(f"%{like_escaped_session_id}%") |
There was a problem hiding this comment.
LIKE escape clause missing
Medium Severity
The session_id filter escapes \, %, and _ in the search text but uses session_id LIKE $p without an ESCAPE clause. In PostgreSQL, % and _ stay wildcard metacharacters in that form, so filters containing those characters (or a lone %) can return far more rows than a substring match should.
Reviewed by Cursor Bugbot for commit 8a44fdd. Configure here.


Note
Copy of #32568 by @thibault-linktree, pushed to a
litellm_-prefixed branch so the full CircleCI suite (which doesn't run on fork PRs) executes. Commit authorship is preserved — all commits remain authored by the original author. Full credit to @thibault-linktree.Relevant issues
Fixes #32585
Original PR: #32568
Pre-Submission checklist
Type
🆕 New Feature
Changes
The Requests logs tab lets you filter by request id but not by session id, so tracking a full conversation means clicking through rows manually. This adds a Session ID filter end to end.
On the backend,
/spend/logs/v2and/spend/logs/uigain asession_idquery parameter that does a partial (substring) match on thesession_idcolumn ofLiteLLM_SpendLogs(already indexed), following the same pattern as the existingrequest_idfilter. The pattern value has\,%, and_escaped before being wrapped in%…%, so pasting a session-id prefix matches every request in that conversation.On the dashboard, the Logs filter panel gains a Session ID text input wired through
FILTER_KEYS, the debounced text filter list, anduiSpendLogsCall, which forwards it as thesession_idquery param.schema.d.tsis regenerated for the new parameter.Tests: a new endpoint test asserts that filtering by session id (full id and substring prefixes) returns only that session's rows (the shared mock prisma helper now also supports the session-count enrichment queries, so endpoint tests can use rows that carry a
session_id), and the frontend filter mapping test table gains the Session ID →session_idcase.Screenshots / Proof of Fix
The following live-proxy reproduction was captured by the original author (@thibault-linktree) at
9a4652ebdcagainst a live proxy (python litellm/proxy/proxy_cli.py --config litellm/proxy/dev_config.yaml --detailed_debug --use_v2_migration_resolveron localhost:4000 with a local Postgres), hitting the real OpenAI API with real spend.Three real chat completions across two sessions, using the
x-litellm-session-idheader:Then the logs endpoint with the new
session_idfilter:Note
Low Risk
Additive filter on existing spend-log list endpoints and UI; no auth or spend-calculation changes, with LIKE escaping for wildcard safety.
Overview
Adds Session ID filtering for the Requests logs flow so you can narrow paginated spend logs to a conversation instead of hunting by individual request IDs.
Backend:
/spend/logs/uiand/spend/logs/v2accept a newsession_idquery parameter. When set, the raw SQL path appliessession_id LIKE %…%with\,%, and_escaped in the user input (substring match, not exact equality likerequest_id).Dashboard: The logs filter panel gets a debounced Session ID text field, wired through
FILTER_KEYS,uiSpendLogsCall, and regenerated OpenAPI types inschema.d.ts.Tests: Backend coverage for full/partial session filters on
/spend/logs/ui, plus mock Prisma helpers forgroup_byand MCP enrichment queries; frontend filter-param mapping includes Session ID →session_id.Reviewed by Cursor Bugbot for commit 8a44fdd. Bugbot is set up for automated code reviews on this repo. Configure here.