fix(otel): accept langfuse_base_url (v3 naming) for per-key langfuse host, fall back to langfuse_host

This commit is contained in:
michelligabriele 2026-06-03 21:31:24 +02:00
parent 897f4dbdfb
commit bedee5d026
No known key found for this signature in database
4 changed files with 37 additions and 3 deletions

View file

@ -409,12 +409,18 @@ class LangfuseOtelLogger(OpenTelemetry):
Per-key Langfuse credentials are only valid against the host that issued
them, so the host must travel with the credentials. Returns None when no
per-key host is set, falling back to the env-configured endpoint.
Prefers ``langfuse_base_url`` (the Langfuse v3 naming) and falls back to
the deprecated ``langfuse_host`` for backward compatibility, mirroring the
SDK's own ``base_url`` -> ``host`` resolution order.
"""
dynamic_langfuse_host = standard_callback_dynamic_params.get("langfuse_host")
if not dynamic_langfuse_host:
dynamic_langfuse_base_url = standard_callback_dynamic_params.get(
"langfuse_base_url"
) or standard_callback_dynamic_params.get("langfuse_host")
if not dynamic_langfuse_base_url:
return None
return LangfuseOtelLogger._construct_langfuse_otel_endpoint(
dynamic_langfuse_host
dynamic_langfuse_base_url
)
def create_litellm_proxy_request_started_span(

View file

@ -36,6 +36,7 @@ _supported_callback_params = [
"langfuse_secret",
"langfuse_secret_key",
"langfuse_host",
"langfuse_base_url",
"langfuse_prompt_version",
"langsmith_api_key",
"langsmith_project",

View file

@ -2994,6 +2994,8 @@ class StandardCallbackDynamicParams(TypedDict, total=False):
langfuse_secret: Optional[str]
langfuse_secret_key: Optional[str]
langfuse_host: Optional[str]
# Langfuse v3 naming for the host; preferred over langfuse_host where set
langfuse_base_url: Optional[str]
# Langfuse prompt version
langfuse_prompt_version: Optional[int]

View file

@ -419,6 +419,31 @@ class TestLangfuseOtelIntegration:
is None
)
def test_construct_dynamic_otel_endpoint_with_base_url(self):
"""Per-key langfuse_base_url (the Langfuse v3 naming) is honored."""
from litellm.types.utils import StandardCallbackDynamicParams
logger = LangfuseOtelLogger()
endpoint = logger.construct_dynamic_otel_endpoint(
StandardCallbackDynamicParams(
langfuse_base_url="https://us.cloud.langfuse.com"
)
)
assert endpoint == "https://us.cloud.langfuse.com/api/public/otel"
def test_construct_dynamic_otel_endpoint_base_url_preferred_over_host(self):
"""When both are set, langfuse_base_url wins (mirrors the SDK's resolution order)."""
from litellm.types.utils import StandardCallbackDynamicParams
logger = LangfuseOtelLogger()
endpoint = logger.construct_dynamic_otel_endpoint(
StandardCallbackDynamicParams(
langfuse_base_url="https://us.cloud.langfuse.com",
langfuse_host="https://cloud.langfuse.com",
)
)
assert endpoint == "https://us.cloud.langfuse.com/api/public/otel"
def test_get_langfuse_otel_config_with_otel_host_priority(self):
"""LANGFUSE_OTEL_HOST should take priority over LANGFUSE_HOST."""
with patch.dict(