fix(responses): propagate metadata to callbacks on Responses API path

`responses()` accepts `metadata` as a named parameter, consuming it
from `**kwargs`. Downstream handlers read `kwargs.get("litellm_metadata")`
which never contains the caller-provided metadata. This causes custom
callback fields (e.g. caller_service for cost attribution) to be null
in success/failure callbacks for all Responses API calls.

When the Router is involved, it creates its own `litellm_metadata` dict
with `model_group` before calling `litellm.aresponses()`. The fix merges
caller-provided `metadata` into the existing `litellm_metadata` via
`setdefault` so Router keys are preserved while caller fields are added.

Fixes #15466
This commit is contained in:
Taruj Goyal 2026-04-16 16:39:53 -07:00
parent d120ddf678
commit 6d1c183a12

View file

@ -940,6 +940,17 @@ def responses(
local_vars = locals()
try:
# metadata is consumed by the function signature and is not in **kwargs.
# Merge it into litellm_metadata so downstream handlers and callbacks
# can access caller-provided fields (e.g. Langfuse tags, session IDs).
if metadata is not None:
existing = kwargs.get("litellm_metadata")
if existing is None:
kwargs["litellm_metadata"] = metadata
elif isinstance(existing, dict):
for k, v in metadata.items():
existing.setdefault(k, v)
litellm_logging_obj: LiteLLMLoggingObj = kwargs.get("litellm_logging_obj") # type: ignore
litellm_call_id: Optional[str] = kwargs.get("litellm_call_id", None)
_is_async = kwargs.pop("aresponses", False) is True