mirror of
https://github.com/BerriAI/litellm.git
synced 2026-09-19 00:01:29 +00:00
fix(langfuse): propagate trace_metadata as trace-level attributes in v4
v2 wrote trace(metadata=...) onto the trace object. In v4 the trace only carries what the observations propagate, so a continuation request with update_trace_keys=["trace_metadata"] updated the generation's metadata while the trace kept its stale values. Coerce each entry to the SDK's string limit and hand it to propagate_attributes(metadata=...). Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
parent
093edce970
commit
e6646863de
3 changed files with 44 additions and 3 deletions
|
|
@ -210,6 +210,14 @@ def _coerce_propagated_value(value: object) -> str | Sequence[str]:
|
|||
return str(value)[:_PROPAGATED_VALUE_MAX_CHARS]
|
||||
|
||||
|
||||
def _propagated_trace_metadata(value: object) -> Mapping[str, str] | None:
|
||||
"""v2's ``trace(metadata=...)`` took any JSON; v4 propagates one flat string per key."""
|
||||
entries: Final = _object_mapping(value)
|
||||
if not entries:
|
||||
return None
|
||||
return MappingProxyType({str(key): str(item)[:_PROPAGATED_VALUE_MAX_CHARS] for key, item in entries.items()})
|
||||
|
||||
|
||||
def _trace_attributes_for_propagation(trace_params: Mapping[str, object]) -> Mapping[str, object]:
|
||||
"""Trace-level fields in v4 are propagated onto the observations, not set on a trace object.
|
||||
|
||||
|
|
@ -217,11 +225,15 @@ def _trace_attributes_for_propagation(trace_params: Mapping[str, object]) -> Map
|
|||
warning, and a dropped ``version`` would vanish from the generation too,
|
||||
because ``_generation_attributes`` already stripped it as propagated.
|
||||
"""
|
||||
trace_metadata: Final = _propagated_trace_metadata(trace_params.get("metadata"))
|
||||
return MappingProxyType(
|
||||
{
|
||||
propagated: _coerce_propagated_value(trace_params[key])
|
||||
for key, propagated in _PROPAGATED_TRACE_KEYS.items()
|
||||
if trace_params.get(key) is not None
|
||||
**{
|
||||
propagated: _coerce_propagated_value(trace_params[key])
|
||||
for key, propagated in _PROPAGATED_TRACE_KEYS.items()
|
||||
if trace_params.get(key) is not None
|
||||
},
|
||||
**({"metadata": trace_metadata} if trace_metadata is not None else {}),
|
||||
}
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@
|
|||
"cache_read_input_tokens": 0
|
||||
},
|
||||
"langfuse.release": "test_trace_release",
|
||||
"langfuse.trace.metadata.test_key": "test_value",
|
||||
"langfuse.trace.name": "test_trace_name",
|
||||
"langfuse.trace.tags": [
|
||||
"test_tag",
|
||||
|
|
|
|||
|
|
@ -1879,6 +1879,34 @@ def test_update_trace_keys_from_the_request_body_list_applies_when_enabled():
|
|||
assert span.attributes["langfuse.release"] == "v1.2.3"
|
||||
|
||||
|
||||
def test_update_trace_keys_trace_metadata_reaches_the_trace_not_just_the_generation():
|
||||
"""v2 updated the trace object's metadata; v4 has to propagate it as a trace attribute."""
|
||||
rig = _steering_logger()
|
||||
|
||||
with patch.object(litellm, "langfuse_enable_update_trace_keys", True):
|
||||
_, _, span = _emit(
|
||||
rig,
|
||||
metadata={
|
||||
"existing_trace_id": "trace-1",
|
||||
"parent_observation_id": "b" * 16,
|
||||
"update_trace_keys": ["trace_metadata"],
|
||||
"trace_metadata": {"step": 2, "note": "x" * 300},
|
||||
},
|
||||
)
|
||||
|
||||
assert span.attributes["langfuse.trace.metadata.step"] == "2"
|
||||
assert span.attributes["langfuse.trace.metadata.note"] == "x" * 200
|
||||
assert span.attributes["langfuse.observation.metadata.step"] == 2
|
||||
|
||||
|
||||
def test_trace_metadata_is_not_propagated_when_absent():
|
||||
rig = _steering_logger()
|
||||
|
||||
_, _, span = _emit(rig, metadata={"trace_name": "plain"})
|
||||
|
||||
assert not any(key.startswith("langfuse.trace.metadata.") for key in span.attributes or {})
|
||||
|
||||
|
||||
def test_update_trace_keys_matches_whole_keys_not_substrings():
|
||||
rig = _steering_logger()
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue