Repository navigation
fix(proxy): keep SpendLogs and callback session ids in sync when the request has none - #39450
Conversation
…request has none Add general_settings.missing_session_id (generate | reject). In generate mode one id is stamped into litellm_session_id, litellm_trace_id and metadata.session_id before callbacks run, so LiteLLM_SpendLogs.session_id and the Langfuse session id match. In reject mode such requests get a 400. Unset keeps the legacy behavior. MCP routes are not affected Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
🤖 Devin AI EngineerI'll be helping with this pull request! Here's what you should know: ✅ I will automatically:
Note: I can only respond to comments from users who have write access to this repository. ⚙️ Control Options:
|
|
|
|
PR #39450 labeled |
Greptile SummaryThis PR adds configurable handling for missing session IDs and keeps generated request IDs out of affinity decisions
Confidence Score: 5/5The PR appears safe to merge No blocking failure remains
|
| Filename | Overview |
|---|---|
| litellm/proxy/litellm_pre_call_utils.py | Adds route-aware generation or rejection of missing session IDs before callback processing |
| litellm/llms/fireworks_ai/common_utils.py | Prevents proxy-generated session IDs from becoming Fireworks affinity headers |
| litellm/router_utils/pre_call_checks/deployment_affinity_check.py | Excludes generated request IDs from deployment-affinity cache keys |
| litellm/router_strategy/complexity_router/complexity_router.py | Excludes generated request IDs from complexity-router session pins |
| litellm/proxy/_types.py | Adds the typed missing_session_id general setting |
| litellm/constants.py | Defines the shared metadata marker for generated session IDs |
Reviews (2): Last reviewed commit: "fix(proxy): mark generated session ids s..." | Re-trigger Greptile
Codecov Report❌ Patch coverage is
📢 Thoughts on this report? Let us know! |
…or ruff format Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
…in on them Fireworks x-session-affinity, the router session_affinity pre-call check and the complexity router session pin all read metadata.session_id as a caller-chosen stable key. A missing_session_id: generate id is fresh per request, so it now carries metadata.litellm_session_id_generated and those consumers skip it Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
|
@greptileai please re-review. Generated session ids are now marked so Fireworks, router and complexity router affinity ignore them; test params are typed |
|
Fixed in 4bc7887: generated ids carry a metadata marker and get_fireworks_session_id, router affinity and complexity router skip them |
|
Both parameters are typed on the current tip: dict[str, object] for the helper and pytest.MonkeyPatch for the fixture |
TLDR
Problem this solves:
How it solves it:
general_settings.missing_session_id: generate | rejectgeneratestamps one id into the request before callbacks runrejectreturns 400 when the request has no session idx-session-affinity, router session affinity, complexity routerUser Flow
Before: a platform team correlating a request between the Logs page and Langfuse by session id finds nothing on the Langfuse side
x-litellm-session-idheader"id": "chatcmpl-..."85603c20-c2d3-4483-9729-f4d4a9b733a4After: the same lookup lands on the same session in both places
general_settings.missing_session_id: generateand restarts the proxyx-litellm-session-idheader"id": "chatcmpl-..."1c58430d-d8f3-4020-9f34-3a04267883cax-litellm-session-id: my-client-session-42still works as before: both sides showmy-client-session-42missing_session_id: rejectinstead, step 2 returns 400 withRequest has no session id. Send an x-litellm-session-id header or metadata.session_idRelevant issues
Linear ticket
Resolves LIT-6694
Pre-Submission checklist
Please complete all items before asking a LiteLLM maintainer to review your PR
uv run pytest tests/test_litellm/<your_test_file>.py -v. Leave the suites (make test-unit-*,make test-unit) to CI: it finishes in ~15 minutes where a laptop takes an hour or more@greptileaito re-request a review after pushing changes)Delays in PR merge?
If you're seeing a delay in your PR being merged, ping the LiteLLM Team on Slack (#pr-review).
Screenshots / Proof of Fix
Setup shared by both runs. Langfuse is a local receiver on
127.0.0.1:3010that prints theidandsessionIdof every trace it gets (no Langfuse credentials on this box), the LLM call is a real OpenAI call, and SpendLogs is a local PostgresBefore (708c396)
Request with no session header
SpendLogs has a session id
Langfuse got the trace with no session
After (4bc7887)
generate, no session header
Same curl as Before
SpendLogs
Langfuse, same id on both sides
generate, client sends x-litellm-session-id
Same curl plus
-H "x-litellm-session-id: my-client-session-44"SpendLogs
Langfuse
reject, no session header
Proxy restarted with
missing_session_id: reject, same curl as Before with-w "\nHTTP %{http_code}\n"reject, client sends x-litellm-session-id
Same curl plus
-H "x-litellm-session-id: my-client-session-45"Type
🐛 Bug Fix
Caveats (if any)
Low
config_settings.mdFinal Attestation
Link to Devin session: https://app.devin.ai/sessions/08e66d54121744149f600a9ebf31022e
Open in Devin Desktop: https://app.devin.ai/desktop/session/08e66d54121744149f600a9ebf31022e?variant=devin
Requested by: @yassin-berriai