fix(otel v2): keep embedding observations typed as generation in Langfuse

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
yucheng 2026-09-19 17:38:20 +00:00
parent c5181f6178
commit c4d6c3046e
2 changed files with 3 additions and 7 deletions

View file

@ -27,7 +27,6 @@ from litellm.integrations.otel.model.payloads import (
LLMRequestParams,
LLMUsage,
)
from litellm.integrations.otel.model.semconv import GenAIOperation
from litellm.integrations.otel.model.trace_controls import TraceControls
LANGFUSE_OBSERVATION_INPUT: Final = "langfuse.observation.input"
@ -40,9 +39,7 @@ LANGFUSE_TRACE_TAGS: Final = "langfuse.trace.tags"
class LangfuseMapper:
_LLM_CALL_ATTRS: dict[str, Callable[[LLMCallSpanData], AttrValue | None]] = {
"langfuse.observation.type": lambda d: (
"embedding" if d.operation is GenAIOperation.EMBEDDINGS else "generation"
),
"langfuse.observation.type": lambda _: "generation",
"langfuse.observation.model.name": lambda d: d.request_model or None,
"langfuse.observation.metadata.provider": lambda d: d.provider or None,
"langfuse.observation.id": lambda d: d.identity.call_id or None,

View file

@ -174,7 +174,7 @@ def test_langfuse_mapper_skips_when_no_messages():
assert "langfuse.observation.output" not in attrs
def test_langfuse_mapper_renders_an_embedding_call_as_an_embedding_with_a_vector_summary():
def test_langfuse_mapper_renders_an_embedding_call_with_a_vector_summary_as_output():
data = _llm_call(
operation=GenAIOperation.EMBEDDINGS,
request_model="text-embedding-3-small",
@ -185,7 +185,7 @@ def test_langfuse_mapper_renders_an_embedding_call_as_an_embedding_with_a_vector
)
attrs = LangfuseMapper().map(data)
assert attrs["langfuse.observation.type"] == "embedding"
assert attrs["langfuse.observation.type"] == "generation"
assert json.loads(attrs["langfuse.observation.output"]) == {"count": 2, "dimensions": 1536}
assert json.loads(attrs["langfuse.observation.input"]) == [{"role": "user", "content": "hello"}]
@ -193,7 +193,6 @@ def test_langfuse_mapper_renders_an_embedding_call_as_an_embedding_with_a_vector
def test_langfuse_mapper_keeps_chat_output_when_no_embedding_summary():
attrs = LangfuseMapper().map(_llm_call(embedding_output=None))
assert attrs["langfuse.observation.type"] == "generation"
assert json.loads(attrs["langfuse.observation.output"]) == [{"role": "assistant", "content": "Sunny."}]