Skip to content

Litellm apikey trace#22294

Draft
Harshit28j wants to merge 4 commits intomainfrom
litellm_apikey_trace
Draft

Litellm apikey trace#22294
Harshit28j wants to merge 4 commits intomainfrom
litellm_apikey_trace

Conversation

@Harshit28j
Copy link
Collaborator

@Harshit28j Harshit28j commented Feb 27, 2026

Claude code trace issues

github-actions bot and others added 2 commits February 27, 2026 10:50
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
@CLAassistant
Copy link

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you all sign our Contributor License Agreement before we can accept your contribution.
1 out of 2 committers have signed the CLA.

✅ Harshit28j
❌ github-actions[bot]
You have signed the CLA already but the status is still pending? Let us recheck it.

@Harshit28j
Copy link
Collaborator Author

@greptile can you please review this PR?

@vercel
Copy link

vercel bot commented Feb 27, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
litellm Ready Ready Preview, Comment Feb 27, 2026 4:42pm

Request Review

@greptile-apps
Copy link
Contributor

greptile-apps bot commented Feb 27, 2026

Greptile Summary

This PR threads the kwargs dict (containing litellm_params with API key metadata, passthrough_logging_payload, call_type, and litellm_call_id) from pass_through_request through the streaming handler chain to the provider-specific logging handlers. It also updates async_success_handler in litellm_logging.py to merge response_cost and model from kwargs into model_call_details. This fixes API key attribution in Langfuse traces for streaming pass-through requests.

  • kwargs propagation: pass_through_endpoints.pystreaming_handler.py → Anthropic/OpenAI/Vertex handlers now carry the full kwargs containing API key metadata
  • Cost merging in litellm_logging.py: async_success_handler now picks up response_cost and model from kwargs when model_call_details doesn't already have them
  • Bug: Anthropic handler overwrites proxy_server_request: The .update() call in _create_anthropic_response_logging_payload (line 144) replaces the entire proxy_server_request key with just {"body": {"user": user}}, losing URL, method, body, and headers from the incoming kwargs. The OpenAI handler uses .setdefault() which is correct.
  • Bug: Missing asyncio import in test: test_unit_test_streaming.py uses await asyncio.sleep(0.5) but never imports asyncio, causing a NameError at runtime

Confidence Score: 2/5

  • PR has a data-loss bug in the Anthropic handler and a broken test that needs fixing before merge
  • The core plumbing of kwargs through the streaming pipeline is well-structured, but the Anthropic handler's .update() call now overwrites the incoming proxy_server_request metadata (a regression introduced by this PR), and the new streaming test will fail at runtime due to a missing asyncio import.
  • Pay close attention to litellm/proxy/pass_through_endpoints/llm_provider_handlers/anthropic_passthrough_logging_handler.py (proxy_server_request overwrite) and tests/pass_through_unit_tests/test_unit_test_streaming.py (missing import)

Important Files Changed

Filename Overview
litellm/litellm_core_utils/litellm_logging.py Correctly merges response_cost and model from kwargs into model_call_details for pass-through endpoints, enabling proper cost tracking in standard logging payloads.
litellm/proxy/pass_through_endpoints/llm_provider_handlers/anthropic_passthrough_logging_handler.py Accepts kwargs parameter to thread API key metadata, but the .update() call on litellm_params overwrites the incoming proxy_server_request with just the user field, losing URL/method/body/headers.
litellm/proxy/pass_through_endpoints/llm_provider_handlers/openai_passthrough_logging_handler.py Correctly preserves incoming litellm_params from kwargs and uses safe .setdefault() pattern for proxy_server_request. Adds call_type and litellm_call_id propagation.
litellm/proxy/pass_through_endpoints/llm_provider_handlers/vertex_passthrough_logging_handler.py Cleanly threads kwargs through to vertex logging payload builder by renaming local variable to _kwargs to avoid shadowing the parameter.
litellm/proxy/pass_through_endpoints/pass_through_endpoints.py Passes the kwargs dict (containing litellm_params, passthrough_logging_payload, etc.) to chunk_processor for both streaming code paths.
litellm/proxy/pass_through_endpoints/streaming_handler.py Propagates kwargs through chunk_processor to _route_streaming_logging_to_handler and renames local variable to handler_kwargs to avoid shadowing. Clean refactor.
tests/pass_through_unit_tests/test_unit_test_streaming.py New test for kwargs propagation is missing import asyncio, causing a NameError at runtime. The test will always fail as-is.
tests/test_litellm/litellm_core_utils/test_litellm_logging.py Good test verifying that response_cost from kwargs is merged into model_call_details and that API key metadata appears in the standard logging object.
poetry.lock Bumps litellm-proxy-extras from 0.4.48 to 0.4.49. Routine dependency update.

Sequence Diagram

sequenceDiagram
    participant PT as pass_through_request
    participant CP as chunk_processor
    participant RH as _route_streaming_logging_to_handler
    participant AH as AnthropicHandler
    participant OH as OpenAIHandler
    participant VH as VertexHandler
    participant ASH as async_success_handler

    PT->>CP: kwargs (litellm_params, passthrough_logging_payload, call_type, litellm_call_id)
    CP->>CP: Yield raw bytes to client
    CP->>RH: kwargs forwarded via asyncio.create_task
    alt Anthropic endpoint
        RH->>AH: _handle_logging_anthropic_collected_chunks(kwargs)
        AH->>AH: _create_anthropic_response_logging_payload(kwargs)
        AH-->>RH: handler_kwargs (response_cost, model, litellm_params)
    else OpenAI endpoint
        RH->>OH: _handle_logging_openai_collected_chunks(kwargs)
        OH-->>RH: handler_kwargs (response_cost, model, litellm_params)
    else Vertex endpoint
        RH->>VH: _handle_logging_vertex_collected_chunks(kwargs)
        VH-->>RH: handler_kwargs (response_cost, model)
    end
    RH->>ASH: result + **handler_kwargs
    ASH->>ASH: Merge response_cost & model from kwargs into model_call_details
    ASH->>ASH: Build standard_logging_object with API key metadata
Loading

Last reviewed commit: f67cb1a

Copy link
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

9 files reviewed, 4 comments

Edit Code Review Agent Settings | Greptile

Harshit28j and others added 2 commits February 27, 2026 22:10
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
@Harshit28j
Copy link
Collaborator Author

@greptile can you please review this PR?

pass

# Allow the asyncio.create_task to run
await asyncio.sleep(0.5)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing asyncio import causes NameError

asyncio is used here (await asyncio.sleep(0.5)) but is never imported in this file. This will cause a NameError at runtime, meaning this test will always fail. Add import asyncio at the top of the file with the other module-level imports.

Suggested change
await asyncio.sleep(0.5)
await asyncio.sleep(0.5)

The import needs to be added at the top of the file:

import asyncio
import json
import os
...

Context Used: Context from dashboard - CLAUDE.md (source)

@greptile-apps
Copy link
Contributor

greptile-apps bot commented Feb 27, 2026

Additional Comments (1)

litellm/proxy/pass_through_endpoints/llm_provider_handlers/anthropic_passthrough_logging_handler.py
.update() overwrites incoming proxy_server_request

Now that kwargs carries the full litellm_params from _init_kwargs_for_pass_through_endpoint (which includes proxy_server_request with url, method, body, and headers), this .update() call replaces the entire proxy_server_request with just {"body": {"user": user}}, losing all the original request metadata.

Before this PR, kwargs was always {} so there was nothing to overwrite. With the new plumbing, this becomes a data-loss bug.

The OpenAI handler correctly uses .setdefault() at its equivalent code path (line 570 of openai_passthrough_logging_handler.py). The same approach should be used here:

                    kwargs["litellm_params"].setdefault("proxy_server_request", {}).setdefault("body", {})["user"] = user

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