@@ -830,21 +830,31 @@ def _sample_rand_range(parent_sampled, sample_rate):
830830 return sample_rate , 1.0
831831
832832
833- def _get_span_name (template , name ):
834- # type: (Union[str, "SpanTemplate"], str) -> str
833+ def _get_span_name (template , name = None , kwargs = None ):
834+ # type: (Union[str, "SpanTemplate"], Optional[ str], Optional[dict[str, Any]] ) -> str
835835 """
836836 Get the name of the span based on the template and the name.
837837 """
838838 span_name = name
839839
840840 if template == SpanTemplate .AI_CHAT :
841- span_name = "chat [MODEL]"
841+ model = None
842+ if kwargs and "model" in kwargs and isinstance (kwargs ["model" ], str ):
843+ model = kwargs ["model" ]
844+ elif (
845+ kwargs and "model_name" in kwargs and isinstance (kwargs ["model_name" ], str )
846+ ):
847+ model = kwargs ["model_name" ]
848+
849+ span_name = f"chat { model } " if model else "chat"
850+
842851 elif template == SpanTemplate .AI_AGENT :
843852 span_name = f"invoke_agent { name } "
853+
844854 elif template == SpanTemplate .AI_TOOL :
845855 span_name = f"execute_tool { name } "
846856
847- return span_name
857+ return span_name or ""
848858
849859
850860def _get_span_op (template ):
@@ -856,18 +866,119 @@ def _get_span_op(template):
856866
857867 if template == SpanTemplate .AI_CHAT :
858868 op = OP .GEN_AI_CHAT
869+
859870 elif template == SpanTemplate .AI_AGENT :
860871 op = OP .GEN_AI_INVOKE_AGENT
872+
861873 elif template == SpanTemplate .AI_TOOL :
862874 op = OP .GEN_AI_EXECUTE_TOOL
863875
864876 return op
865877
866878
879+ def _get_input_attributes (template , kwargs ):
880+ # type: (Union[str, "SpanTemplate"], dict[str, Any]) -> dict[str, Any]
881+ """
882+ Get input attributes for the given span template.
883+ """
884+ attributes = {} # type: dict[str, Any]
885+
886+ for key , value in list (kwargs .items ()):
887+ if template in [
888+ SpanTemplate .AI_AGENT ,
889+ SpanTemplate .AI_TOOL ,
890+ SpanTemplate .AI_CHAT ,
891+ ]:
892+ if key == "model" and isinstance (value , str ):
893+ attributes [SPANDATA .GEN_AI_REQUEST_MODEL ] = value
894+ elif key == "model_name" and isinstance (value , str ):
895+ attributes [SPANDATA .GEN_AI_REQUEST_MODEL ] = value
896+
897+ elif key == "agent" and isinstance (value , str ):
898+ attributes [SPANDATA .GEN_AI_AGENT_NAME ] = value
899+ elif key == "agent_name" and isinstance (value , str ):
900+ attributes [SPANDATA .GEN_AI_AGENT_NAME ] = value
901+
902+ elif key == "prompt" and isinstance (value , str ):
903+ attributes .setdefault (SPANDATA .GEN_AI_REQUEST_MESSAGES , []).append (
904+ {"role" : "user" , "content" : value }
905+ )
906+ elif key == "system_prompt" and isinstance (value , str ):
907+ attributes .setdefault (SPANDATA .GEN_AI_REQUEST_MESSAGES , []).append (
908+ {"role" : "system" , "content" : value }
909+ )
910+
911+ elif key == "max_tokens" and isinstance (value , int ):
912+ attributes .setdefault (SPANDATA .GEN_AI_REQUEST_MAX_TOKENS , []).append (
913+ value
914+ )
915+ elif key == "frequency_penalty" and isinstance (value , float ):
916+ attributes .setdefault (
917+ SPANDATA .GEN_AI_REQUEST_FREQUENCY_PENALTY , []
918+ ).append (value )
919+ elif key == "presence_penalty" and isinstance (value , float ):
920+ attributes .setdefault (
921+ SPANDATA .GEN_AI_REQUEST_PRESENCE_PENALTY , []
922+ ).append (value )
923+ elif key == "temperature" and isinstance (value , float ):
924+ attributes .setdefault (SPANDATA .GEN_AI_REQUEST_TEMPERATURE , []).append (
925+ value
926+ )
927+ elif key == "top_p" and isinstance (value , float ):
928+ attributes .setdefault (SPANDATA .GEN_AI_REQUEST_TOP_P , []).append (value )
929+ elif key == "top_k" and isinstance (value , int ):
930+ attributes .setdefault (SPANDATA .GEN_AI_REQUEST_TOP_K , []).append (value )
931+
932+ return attributes
933+
934+
935+ def _get_output_attributes (template , result ):
936+ # type: (Union[str, "SpanTemplate"], Any) -> dict[str, Any]
937+ """
938+ Get output attributes for the given span template.
939+ """
940+ attributes = {} # type: dict[str, Any]
941+
942+ if template in [SpanTemplate .AI_AGENT , SpanTemplate .AI_TOOL , SpanTemplate .AI_CHAT ]:
943+ if hasattr (result , "usage" ):
944+ if hasattr (result .usage , "input_tokens" ) and isinstance (
945+ result .usage .input_tokens , int
946+ ):
947+ attributes [SPANDATA .GEN_AI_USAGE_INPUT_TOKENS ] = (
948+ result .usage .input_tokens
949+ )
950+ elif hasattr (result .usage , "output_tokens" ) and isinstance (
951+ result .usage .output_tokens , int
952+ ):
953+ attributes [SPANDATA .GEN_AI_USAGE_OUTPUT_TOKENS ] = (
954+ result .usage .output_tokens
955+ )
956+ elif hasattr (result .usage , "total_tokens" ) and isinstance (
957+ result .usage .total_tokens , int
958+ ):
959+ attributes [SPANDATA .GEN_AI_USAGE_TOTAL_TOKENS ] = (
960+ result .usage .total_tokens
961+ )
962+
963+ elif hasattr (result , "input_tokens" ) and isinstance (result .input_tokens , int ):
964+ attributes [SPANDATA .GEN_AI_USAGE_INPUT_TOKENS ] = result .input_tokens
965+ elif hasattr (result , "output_tokens" ) and isinstance (result .output_tokens , int ):
966+ attributes [SPANDATA .GEN_AI_USAGE_OUTPUT_TOKENS ] = result .output_tokens
967+ elif hasattr (result , "total_tokens" ) and isinstance (result .total_tokens , int ):
968+ attributes [SPANDATA .GEN_AI_USAGE_TOTAL_TOKENS ] = result .total_tokens
969+
970+ elif hasattr (result , "model" ) and isinstance (result .model , str ):
971+ attributes [SPANDATA .GEN_AI_RESPONSE_MODEL ] = result .model
972+ elif hasattr (result , "model_name" ) and isinstance (result .model_name , str ):
973+ attributes [SPANDATA .GEN_AI_RESPONSE_MODEL ] = result .model_name
974+
975+ return attributes
976+
977+
867978def _set_input_attributes (span , template , args , kwargs ):
868979 # type: (Span, Union[str, "SpanTemplate"], tuple[Any, ...], dict[str, Any]) -> None
869980 """
870- Set span input attributes based on the given template.
981+ Set span input attributes based on the given span template.
871982
872983 :param span: The span to set attributes on.
873984 :param template: The template to use to set attributes on the span.
@@ -876,8 +987,6 @@ def _set_input_attributes(span, template, args, kwargs):
876987 """
877988 attributes = {} # type: dict[str, Any]
878989
879- # TODO: Implement actual input parameters for those templates :)
880-
881990 if template == SpanTemplate .AI_AGENT :
882991 attributes = {
883992 SPANDATA .GEN_AI_OPERATION_NAME : "invoke_agent" ,
@@ -893,22 +1002,25 @@ def _set_input_attributes(span, template, args, kwargs):
8931002 SPANDATA .GEN_AI_TOOL_NAME : span .description ,
8941003 }
8951004
1005+ attributes .update (_get_input_attributes (template , kwargs ))
8961006 span .set_data (attributes )
8971007
8981008
8991009def _set_output_attributes (span , template , result ):
9001010 # type: (Span, Union[str, "SpanTemplate"], Any) -> None
9011011 """
902- Set span output attributes based on the given template.
1012+ Set span output attributes based on the given span template.
9031013
9041014 :param span: The span to set attributes on.
9051015 :param template: The template to use to set attributes on the span.
9061016 :param result: The result of the wrapped function.
9071017 """
9081018 attributes = {} # type: dict[str, Any]
9091019
910- # TODO: Implement :)
1020+ if template == SpanTemplate .AI_AGENT and isinstance (result , str ):
1021+ attributes [SPANDATA .GEN_AI_TOOL_OUTPUT ] = result
9111022
1023+ attributes .update (_get_output_attributes (template , result ))
9121024 span .set_data (attributes )
9131025
9141026
@@ -948,10 +1060,16 @@ async def async_wrapper(*args, **kwargs):
9481060
9491061 with start_span_func (
9501062 op = _get_span_op (template ),
951- name = _get_span_name (template , name or qualname_from_function (f )),
1063+ name = _get_span_name (
1064+ template , name or qualname_from_function (f ), kwargs
1065+ ),
9521066 ) as span :
9531067 _set_input_attributes (span , template , args , kwargs )
9541068
1069+ docstring = getattr (f , "__doc__" , None )
1070+ if template == SpanTemplate .AI_TOOL and docstring is not None :
1071+ span .set_data (SPANDATA .GEN_AI_TOOL_DESCRIPTION , docstring )
1072+
9551073 result = await f (* args , ** kwargs )
9561074
9571075 _set_output_attributes (span , template , result )
0 commit comments