4141 LangfuseEvent ,
4242 LangfuseGeneration ,
4343 LangfuseSpan ,
44+ LangfuseAgent ,
45+ LangfuseTool ,
46+ LangfuseChain ,
47+ LangfuseRetriever ,
48+ LangfuseEmbedding ,
4449)
4550from langfuse ._utils import _get_timestamp
4651from 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 ()
0 commit comments