Skip to content

Commit 9ddc018

Browse files
committed
init commit
1 parent 3d3f334 commit 9ddc018

6 files changed

Lines changed: 240 additions & 148 deletions

File tree

langfuse/_client/attributes.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,9 +93,11 @@ def create_span_attributes(
9393
level: Optional[SpanLevel] = None,
9494
status_message: Optional[str] = None,
9595
version: Optional[str] = None,
96+
observation_type: Optional[str] = None,
9697
) -> dict:
98+
final_observation_type = observation_type or "span"
9799
attributes = {
98-
LangfuseOtelSpanAttributes.OBSERVATION_TYPE: "span",
100+
LangfuseOtelSpanAttributes.OBSERVATION_TYPE: final_observation_type,
99101
LangfuseOtelSpanAttributes.OBSERVATION_LEVEL: level,
100102
LangfuseOtelSpanAttributes.OBSERVATION_STATUS_MESSAGE: status_message,
101103
LangfuseOtelSpanAttributes.VERSION: version,

langfuse/_client/client.py

Lines changed: 63 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,11 @@
4141
LangfuseEvent,
4242
LangfuseGeneration,
4343
LangfuseSpan,
44+
LangfuseAgent,
45+
LangfuseTool,
46+
LangfuseChain,
47+
LangfuseRetriever,
48+
LangfuseEmbedding,
4449
)
4550
from langfuse._utils import _get_timestamp
4651
from langfuse._utils.parse_error import handle_fern_exception
@@ -345,6 +350,7 @@ def start_as_current_span(
345350
level: Optional[SpanLevel] = None,
346351
status_message: Optional[str] = None,
347352
end_on_exit: Optional[bool] = None,
353+
observation_type: Optional[str] = None,
348354
) -> _AgnosticContextManager[LangfuseSpan]:
349355
"""Create a new span and set it as the current span in a context manager.
350356
@@ -404,6 +410,7 @@ def start_as_current_span(
404410
version=version,
405411
level=level,
406412
status_message=status_message,
413+
observation_type=observation_type,
407414
),
408415
)
409416

@@ -419,6 +426,7 @@ def start_as_current_span(
419426
version=version,
420427
level=level,
421428
status_message=status_message,
429+
observation_type=observation_type,
422430
),
423431
)
424432

@@ -661,6 +669,29 @@ def start_as_current_generation(
661669
),
662670
)
663671

672+
def _get_span_class(self, as_type: str, observation_type: Optional[str] = None):
673+
"""Get the appropriate span class based on as_type and observation_type."""
674+
if observation_type == "AGENT":
675+
return LangfuseAgent
676+
elif observation_type == "TOOL":
677+
return LangfuseTool
678+
elif observation_type == "CHAIN":
679+
return LangfuseChain
680+
elif observation_type == "RETRIEVER":
681+
return LangfuseRetriever
682+
elif observation_type == "EMBEDDING":
683+
return LangfuseEmbedding
684+
if as_type == "generation" or observation_type == "GENERATION":
685+
return LangfuseGeneration
686+
elif as_type == "event" or observation_type == "EVENT":
687+
return LangfuseEvent
688+
elif as_type == "span" or observation_type == "SPAN":
689+
return LangfuseSpan
690+
else:
691+
# TODO: this should never happen -> error out?
692+
# for now default to LangfuseSpan for unknown types or "span" as_type
693+
return LangfuseSpan
694+
664695
@_agnosticcontextmanager
665696
def _create_span_with_parent_context(
666697
self,
@@ -682,6 +713,7 @@ def _create_span_with_parent_context(
682713
usage_details: Optional[Dict[str, int]] = None,
683714
cost_details: Optional[Dict[str, float]] = None,
684715
prompt: Optional[PromptClient] = None,
716+
observation_type: Optional[str] = None,
685717
) -> Any:
686718
parent_span = parent or cast(otel_trace_api.Span, remote_parent_span)
687719

@@ -702,6 +734,7 @@ def _create_span_with_parent_context(
702734
usage_details=usage_details,
703735
cost_details=cost_details,
704736
prompt=prompt,
737+
observation_type=observation_type,
705738
) as langfuse_span:
706739
if remote_parent_span is not None:
707740
langfuse_span._otel_span.set_attribute(
@@ -729,42 +762,42 @@ def _start_as_current_otel_span_with_processed_media(
729762
usage_details: Optional[Dict[str, int]] = None,
730763
cost_details: Optional[Dict[str, float]] = None,
731764
prompt: Optional[PromptClient] = None,
765+
observation_type: Optional[str] = None,
732766
) -> Any:
733767
with self._otel_tracer.start_as_current_span(
734768
name=name,
735769
end_on_exit=end_on_exit if end_on_exit is not None else True,
736770
) as otel_span:
737-
yield (
738-
LangfuseSpan(
739-
otel_span=otel_span,
740-
langfuse_client=self,
741-
environment=self._environment,
742-
input=input,
743-
output=output,
744-
metadata=metadata,
745-
version=version,
746-
level=level,
747-
status_message=status_message,
748-
)
749-
if as_type == "span"
750-
else LangfuseGeneration(
751-
otel_span=otel_span,
752-
langfuse_client=self,
753-
environment=self._environment,
754-
input=input,
755-
output=output,
756-
metadata=metadata,
757-
version=version,
758-
level=level,
759-
status_message=status_message,
760-
completion_start_time=completion_start_time,
761-
model=model,
762-
model_parameters=model_parameters,
763-
usage_details=usage_details,
764-
cost_details=cost_details,
765-
prompt=prompt,
771+
span_class = self._get_span_class(as_type, observation_type)
772+
common_args = {
773+
"otel_span": otel_span,
774+
"langfuse_client": self,
775+
"environment": self._environment,
776+
"input": input,
777+
"output": output,
778+
"metadata": metadata,
779+
"version": version,
780+
"level": level,
781+
"status_message": status_message,
782+
}
783+
784+
if span_class == LangfuseGeneration:
785+
common_args.update(
786+
{
787+
"completion_start_time": completion_start_time,
788+
"model": model,
789+
"model_parameters": model_parameters,
790+
"usage_details": usage_details,
791+
"cost_details": cost_details,
792+
"prompt": prompt,
793+
"observation_type": observation_type,
794+
}
766795
)
767-
)
796+
else:
797+
if observation_type is not None:
798+
common_args["observation_type"] = observation_type
799+
800+
yield span_class(**common_args)
768801

769802
def _get_current_otel_span(self) -> Optional[otel_trace_api.Span]:
770803
current_span = otel_trace_api.get_current_span()

langfuse/_client/constants.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,15 @@
44
"""
55

66
LANGFUSE_TRACER_NAME = "langfuse-sdk"
7+
8+
# Valid observation types for the @observe decorator
9+
VALID_OBSERVATION_TYPES = {
10+
"SPAN",
11+
"EVENT",
12+
"GENERATION",
13+
"AGENT",
14+
"TOOL",
15+
"CHAIN",
16+
"RETRIEVER",
17+
"EMBEDDING",
18+
}

0 commit comments

Comments
 (0)