Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions langfuse/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@
from ._client.get_client import get_client
from ._client.observe import observe
from ._client.propagation import propagate_attributes
from ._client.skills import discover_skills
from ._client.span import (
LangfuseAgent,
LangfuseChain,
Expand Down Expand Up @@ -93,6 +94,8 @@
OtelSpanData,
OtelSpanIdentifier,
OtelSpanPatch,
SkillReference,
SkillsConfig,
)

Langfuse = _client_module.Langfuse
Expand All @@ -104,6 +107,9 @@
"get_client",
"observe",
"propagate_attributes",
"discover_skills",
"SkillReference",
"SkillsConfig",
"ObservationTypeLiteral",
"LangfuseSpan",
"LangfuseGeneration",
Expand Down
17 changes: 16 additions & 1 deletion langfuse/_client/attributes.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,12 @@
ObservationTypeGenerationLike,
ObservationTypeSpanLike,
)
from langfuse._client.skills import serialize_available_skills
from langfuse._utils.serializer import EventSerializer
from langfuse.api import MapValue
from langfuse.logger import langfuse_logger
from langfuse.model import PromptClient
from langfuse.types import SpanLevel
from langfuse.types import SkillReference, SpanLevel


class LangfuseOtelSpanAttributes:
Expand All @@ -41,6 +42,7 @@ class LangfuseOtelSpanAttributes:
OBSERVATION_STATUS_MESSAGE = "langfuse.observation.status_message"
OBSERVATION_INPUT = "langfuse.observation.input"
OBSERVATION_OUTPUT = "langfuse.observation.output"
OBSERVATION_SKILLS_AVAILABLE = "langfuse.observation.skills_available"

# Langfuse-observation of type Generation attributes
OBSERVATION_COMPLETION_START_TIME = "langfuse.observation.completion_start_time"
Expand Down Expand Up @@ -87,6 +89,7 @@ def create_trace_attributes(
def create_span_attributes(
*,
metadata: Optional[Any] = None,
available_skills: Optional[list[SkillReference]] = None,
input: Optional[Any] = None,
output: Optional[Any] = None,
level: Optional[SpanLevel] = None,
Expand All @@ -103,6 +106,7 @@ def create_span_attributes(
LangfuseOtelSpanAttributes.VERSION: version,
LangfuseOtelSpanAttributes.OBSERVATION_INPUT: _serialize(input),
LangfuseOtelSpanAttributes.OBSERVATION_OUTPUT: _serialize(output),
**create_available_skills_attributes(available_skills),
**_flatten_and_serialize_metadata(metadata, "observation"),
}

Expand All @@ -114,6 +118,7 @@ def create_generation_attributes(
name: Optional[str] = None,
completion_start_time: Optional[datetime] = None,
metadata: Optional[Any] = None,
available_skills: Optional[list[SkillReference]] = None,
level: Optional[SpanLevel] = None,
status_message: Optional[str] = None,
version: Optional[str] = None,
Expand Down Expand Up @@ -148,12 +153,22 @@ def create_generation_attributes(
LangfuseOtelSpanAttributes.OBSERVATION_MODEL_PARAMETERS: _serialize(
model_parameters
),
**create_available_skills_attributes(available_skills),
**_flatten_and_serialize_metadata(metadata, "observation"),
}

return {k: v for k, v in attributes.items() if v is not None}


def create_available_skills_attributes(
available_skills: Optional[list[SkillReference]],
) -> dict[str, str]:
serialized = serialize_available_skills(available_skills)
if serialized is None:
return {}
return {LangfuseOtelSpanAttributes.OBSERVATION_SKILLS_AVAILABLE: serialized}


def _serialize(obj: Any) -> Optional[str]:
if obj is None or isinstance(obj, str):
return obj
Expand Down
Loading
Loading