
    i                        d Z ddlZddlZddlZddlmZ ddlmZ ddlmZm	Z	m
Z
mZmZmZ ddlZddlZddlmZ ddlmZ ddlmZmZ dd	lmZmZmZ dd
lmZ ddlmZ ddlm Z m!Z! ddl" ddl#m$Z$m%Z%m&Z&m'Z'  G d de      Z(y)z
Implements logging integration with Datadog's LLM Observability Service


API Reference: https://docs.datadoghq.com/llm_observability/setup/api/?tab=example#api-standards

    N)uuid)datetime)AnyDictListLiteralOptionalUnion)verbose_logger)CustomBatchLogger)should_use_datadog_mockcreate_mock_datadog_client)get_datadog_serviceget_datadog_tagsget_datadog_base_url_from_env)tracer)>handle_any_messages_to_chat_completion_str_messages_conversion)get_async_httpx_clienthttpxSpecialProvider)*)	CallTypes#StandardLoggingGuardrailInformationStandardLoggingPayload&StandardLoggingPayloadErrorInformationc                      e Zd Zd ZdefdZd ZdefdZd Z	d Z
d	 Zd
edededefdZdee   fdZdedee   fdZdedefdZdedee   dee   fdZ	 d"dee   dee   ded   fdZdeeeee   eeef   f      dee   fdZdedeeef   fdZdedefdZdede fdZ!dede"fdZ#dee   deeeef      fdZ$e%deeeef      deeef   fd        Z&dedeeef   fd!Z'y)#DataDogLLMObsLoggerc                    	 t        j                  d       t               | _        | j                  rt	                t        j                  d       t        j                  d      }t        t        j                        | _
        t        j                  d      | _        |r| j                  |       nRt        j                  dd       t        d      t        j                  dd       t        d	      | j                          t               }|r
| d
| _        t#        j$                  | j'                                t#        j(                         | _        g | _        | j/                         }|j1                  |       t3        j4                  | fi |d| j*                  i y # t        $ r(}t        j6                  dt9        |              |d }~ww xY w)Nz"DataDogLLMObs: Initializing loggerz<[DATADOG MOCK] DataDogLLMObs logger initialized in mock modeLITELLM_DD_AGENT_HOST)llm_provider
DD_API_KEY)dd_agent_host*DD_API_KEY is not set, set 'DD_API_KEY=<>'DD_SITEzGDD_SITE is not set, set 'DD_SITE=<>', example sit = `us5.datadoghq.com`"/api/intake/llm-obs/v1/trace/spans
flush_lockz$DataDogLLMObs: Error initializing - )r   debugr   is_mock_moder   osgetenvr   r   LoggingCallbackasync_clientr    _configure_dd_agent	Exception_configure_dd_direct_apir   
intake_urlasynciocreate_taskperiodic_flushLockr%   	log_queue_get_datadog_llm_obs_paramsupdater   __init__	exceptionstr)selfkwargsr!   dd_base_urldict_datadog_llm_obs_paramses         }/Users/manta/Documents/Projects/TheRoad-I1/.venv/lib/python3.12/site-packages/litellm/integrations/datadog/datadog_llm_obs.pyr7   zDataDogLLMObsLogger.__init__0   s   2	  !EF 7 9D  *,$$R II&=>M 61AA!D !ii5DO((}(E 99\408#$PQQ99Y-5#a  --/ 89K%0M1S"T 3 3 56%llnDO24DN
 +/*J*J*L'MM56&&tRvR$//R 	$$'KCPQF8%TUG	s   F"F% %	G.#GGr!   c                     t        j                  dd      }d| _        d| d| d| _        t	        j
                  d| j                          y)	zK
        Configure the Datadog logger to send traces to the Agent.
        LITELLM_DD_LLM_OBS_PORT8126	localhostzhttp://:r$   z!DataDogLLMObs: Using DD Agent at N)r(   r)   r#   r/   r   r&   )r:   r!   
agent_ports      r?   r,   z'DataDogLLMObsLogger._configure_dd_agente   sS     YY8&A
"m_Aj\1ST 	 	@@QRS    c                     | j                   st        d      t        j                  d      | _        | j                  st        d      d| j                   d| _        y)zZ
        Configure the Datadog logger to send traces directly to the Datadog API.
        r"   r#   zHDD_SITE is not set, set 'DD_SITE=<>', example site = `us5.datadoghq.com`zhttps://api.r$   N)r    r-   r(   r)   r#   r/   )r:   s    r?   r.   z,DataDogLLMObsLogger._configure_dd_direct_apit   sX     HIIyy+||Z 
 4<<.(JK 	rF   returnc                 0   i }t         j                  t        t         j                  t              r t         j                  j	                         }|S t        t         j                  t
              r't        di t         j                  j	                         }|S )z
        Get the datadog_llm_observability_params from litellm.datadog_llm_observability_params

        These are params specific to initializing the DataDogLLMObsLogger e.g. turn_off_message_logging
         )litellm datadog_llm_observability_params
isinstanceDatadogLLMObsInitParams
model_dumpr   )r:   r=   s     r?   r5   z/DataDogLLMObsLogger._get_datadog_llm_obs_params   s     -/#33?88:Q <<GGI , +* GDDdK.E />>/*, , +*rF   c                   K   	 t        j                  d|j                  dd              | j                  |||      }t        j                  d|        | j                  j                  |       t        | j                        | j                  k\  r| j                          d {    y y 7 # t        $ r+}t        j                  dt        |              Y d }~y d }~ww xY ww)Nz/DataDogLLMObs: Logging success event for model modelunknownDataDogLLMObs: Payload: z-DataDogLLMObs: Error logging success event - r   r&   getcreate_llm_obs_payloadr4   appendlen
batch_sizeasync_send_batchr-   r8   r9   r:   r;   response_obj
start_timeend_timepayloadr>   s          r?   async_log_success_eventz+DataDogLLMObsLogger.async_log_success_event        	  A&**WV_B`Aab 11&*hOG  #;G9!EFNN!!'*4>>"doo5++--- 6- 	$$?AxH 	A   C'B#B0 'B.(B0 ,C'.B0 0	C$9!CC'C$$C'c                   K   	 t        j                  d|j                  dd              | j                  |||      }t        j                  d|        | j                  j                  |       t        | j                        | j                  k\  r| j                          d {    y y 7 # t        $ r+}t        j                  dt        |              Y d }~y d }~ww xY ww)Nz/DataDogLLMObs: Logging failure event for model rQ   rR   rS   z-DataDogLLMObs: Error logging failure event - rT   r[   s          r?   async_log_failure_eventz+DataDogLLMObsLogger.async_log_failure_event   ra   rb   c           	        K   	 | j                   sy t        j                  dt        | j                          d       | j                  rt        j                  d       dt        dt        t               t               | j                               i}dd	l	m
} 	 t        j                  d
 ||              ||      }ddi}| j                  r| j                  |d<   | j                  j                  | j                   ||       d {   }|j"                  dk7  r%t        d|j"                   d|j$                         | j                  r-t        j                  dt        | j                          d       n"t        j                  d|j"                          | j                   j'                          y # t        $ r*}t        j                  dt        |             Y d }~/d }~ww xY w7 # t(        j*                  $ r6}t        j,                  d|j.                  j$                          Y d }~y d }~wt        $ r+}t        j,                  dt        |              Y d }~y d }~ww xY ww)NzDataDogLLMObs: Flushing z eventsz@[DATADOG MOCK] Mock mode enabled - API calls will be intercepteddataspan)ml_apptagsspans)type
attributesr   )
safe_dumpsz
payload %sz payload serialization failed: %szContent-Typezapplication/jsonz
DD-API-KEY)urlcontentheaders   z2DataDogLLMObs: Unexpected response - status_code: z, text: z[DATADOG MOCK] Batch of z events successfully mockedz6DataDogLLMObs: Successfully sent batch - status_code: z%DataDogLLMObs: Error sending batch - )r4   r   r&   rX   r'   DDIntakePayloadDDSpanAttributesr   r   *litellm.litellm_core_utils.safe_json_dumpsrm   r-   r9   r    r+   postr/   status_codetextclearhttpxHTTPStatusErrorr8   response)r:   r_   rm   debug_errorjson_payloadrp   r{   r>   s           r?   rZ   z$DataDogLLMObsLogger.async_send_batch   s=    B	W>>  *3t~~+>*?wG   $$V /24-/"nn 	G N$$\:g3FG &g.L%'9:G(,%!..33OO$ 4  H ##s*HI]I]H^^fgogtgtfuv    $$.s4>>/B.CC^_ $$LXMaMaLbc NN  "=  $$6K8H ( $$ 	$$7

7HI   	W$$'LSQRVH%UVV	Ws   I-G/ I-BG/ F7 6AG/ G-	B-G/ 6I-7	G* G%G/ %G**G/ /I*,H3.I-3I*?!I% I-%I**I-r;   r]   r^   c                    |j                  d      }|t        d      |d   }| j                  |      }|j                  di       j                  di       }t        t	        |            }t        | j                  ||j                  d                  }| j                  |      }	d }
t        |t              r|j                  d	      }
t        | j                  |j                  d      |
      ||| j                  |      |	
      }t        t        |j                  dd            t        |j                  dd            t        |j                  dd            t        |j                  dd            | j                  |            }t!        |
r|
nd|j                  dt#        t%        j&                                     |j                  dt#        t%        j&                                     |j                  dd      |t)        |j+                         dz        t)        ||z
  j-                         dz        ||	rdndt/        |      
      }| j1                         }|||d<   |S )Nstandard_logging_objectz1DataDogLLMObs: standard_logging_object is not setmessages)r   litellm_paramsmetadata	call_type)standard_logging_payloadr   	parent_id)kindinputoutputr   errorprompt_tokensr   completion_tokenstotal_tokensresponse_cost)input_tokensoutput_tokensr   
total_costtime_to_first_token	undefinedtrace_idspan_idnamelitellm_llm_callg    eAr   ok)r   )
r   r   r   r   metastart_nsdurationmetricsstatusri   apm_id)rU   r-   _ensure_string_content	InputMetar   
OutputMeta_get_response_messages_assemble_error_inforM   dictMeta_get_datadog_span_kind _get_dd_llm_obs_payload_metadata
LLMMetricsfloat _get_time_to_first_token_secondsLLMObsPayloadr9   r   uuid4int	timestamptotal_secondsr   _get_apm_trace_id)r:   r;   r]   r^   r   r   r   
input_metaoutput_meta
error_infometadata_parent_idr   r   r_   apm_trace_ids                  r?   rV   z*DataDogLLMObsLogger.create_llm_obs_payload   s\    FLZZ%F
  $+OPP+J7...A::.377
BGS


 !00)A266{C 1 
 ../GH
,0h%!)k!:,,(,,[9;M ::;ST
 7;;OQOP 8 < <=PRS TU7;;NANO599/1MN $ E E(!
 "/,>(K-11*c$**,>OPLLC

,=>f&89--/#56(Z/>>@3FG(7d!:RS"
 --/# ,GHrF   c                     	 t        t        dd      }t        |      r# |       }|t        |dd      }|t        |      S y# t        $ r Y yw xY w)z/Retrieve the current APM trace ID if available.current_spanNr   )getattrr   callabler9   r-   )r:   current_span_fnr   r   s       r?   r   z%DataDogLLMObsLogger._get_apm_trace_idG  se    		%fndCO(.0+&|ZFH+"8},   		s   >A 	AAr   c                     d}|j                  d      dk(  re|j                  d      }|rRt        |j                  d      xs |j                  d      xs d|j                  d      |j                  d	      
      }|S )z_
        Assemble error information for failure cases according to DD LLM Obs API spec
        Nr   failureerror_informationerror_message	error_strzUnknown errorerror_class	traceback)messagerk   stack)rU   DDLLMObsError)r:   r   r   r   s       r?   r   z(DataDogLLMObsLogger._assemble_error_infoU  s     /3
#''1Y> ),,-@A  !*-11/B '/33K@'&*..}=+//<
 rF   c                     |j                  d      }|j                  d      }|j                  d      }||||z
  S ||||z
  S y)z
        Get the time to first token in seconds

        CompletionStartTime - StartTime = Time to first token

        For non streaming calls, CompletionStartTime is time we get the response back
        	startTimecompletionStartTimeendTime        )rU   )r:   r   r]   completion_start_timer^   s        r?   r   z4DataDogLLMObsLogger._get_time_to_first_token_secondsn  si     '?&B&B;&O
1I1M1M!2
 %=$@$@$K ,1G(:55!j&<j((rF   r   c           
         |j                  d      }|g S t        |t              r	 ddl}|j	                  |      }|t        j                  j                  t        j                  j                  t        j                  j                  t        j                  j                  t        j                   j                  t        j"                  j                  t        j$                  j                  t        j&                  j                  t        j(                  j                  f	v r<	 t        |t*              r)d|v r%|d   }|rt-        |      dkD  rd|d   v r	|d   d   gS g S g S # t
        t        f$ rA 	 t        j                  t        |            }n# t        j                  $ r g cY cY S w xY wY rw xY w# t.        t0        t2        f$ r g cY S w xY w)z}
        Get the messages from the response object

        for now this handles logging /chat/completions responses
        r{   Nr   choicesr   )rU   rM   r9   astliteral_eval
ValueErrorSyntaxErrorjsonloadsJSONDecodeErrorr   
completionvalueacompletiontext_completionatext_completiongenerate_contentagenerate_contentgenerate_content_streamagenerate_content_streamanthropic_messagesr   rX   KeyError
IndexError	TypeError)r:   r   r   r\   r   r   s         r?   r   z*DataDogLLMObsLogger._get_response_messages  s    033J?I lC(	"//=   &&!!''%%++&&,,&&,,''----33..44((..

 

	lD1i<6O*95G3w<!#3	WQZ8O '
9 566	 	9 , #'::c,.?#@L++ I !2 j)4 	sM   E "8F2 F2 F//FF/F(#F/'F((F/.F/2G
GNr   )llmtooltask	embedding	retrievalc                    ||y|t         j                  j                  t         j                  j                  fv ry|t         j                  j                  t         j
                  j                  t         j                  j                  t         j                  j                  t         j                  j                  t         j                  j                  t         j                  j                  t         j                  j                  t         j                  j                  t         j                  j                  t         j                  j                  fv ry|t         j                  j                  fv ry|t         j                   j                  t         j"                  j                  t         j$                  j                  t         j&                  j                  t         j(                  j                  t         j*                  j                  t         j,                  j                  t         j.                  j                  t         j0                  j                  t         j2                  j                  t         j4                  j                  t         j6                  j                  t         j8                  j                  t         j:                  j                  t         j<                  j                  t         j>                  j                  t         j@                  j                  fv ry|g t         jB                  j                  t         jD                  j                  t         jF                  j                  t         jH                  j                  t         jJ                  j                  t         jL                  j                  t         jN                  j                  t         jP                  j                  t         jR                  j                  t         jT                  j                  t         jV                  j                  t         jX                  j                  t         jZ                  j                  t         j\                  j                  t         j^                  j                  t         j`                  j                  t         jb                  j                  t         jd                  j                  t         jf                  j                  t         jh                  j                  t         jj                  j                  t         jl                  j                  t         jn                  j                  t         jp                  j                  t         jr                  j                  t         jt                  j                  t         jv                  j                  t         jx                  j                  t         jz                  j                  t         j|                  j                  t         j~                  j                  t         j                  j                  t         j                  j                  t         j                  j                  t         j                  j                  t         j                  j                  v ryy)z
        Map liteLLM call_type to appropriate DataDog LLM Observability span kind.

        Available DataDog span kinds: "llm", "tool", "task", "embedding", "retrieval"
        see: https://docs.datadoghq.com/ja/llm_observability/terms/
        r   r   r   r   r   )Er   r   r   
aembeddingr   r   r   r   r   r   r   r   r   	responses
aresponsescall_mcp_toolget_assistantsaget_assistants
get_threadaget_threadget_messagesaget_messagesafile_retrievefile_retrieve
afile_list	file_listafile_contentfile_contentretrieve_batcharetrieve_batchretrieve_fine_tuning_jobaretrieve_fine_tuning_jobalist_input_itemscreate_batchacreate_batchcreate_fine_tuning_jobacreate_fine_tuning_jobcancel_fine_tuning_jobacancel_fine_tuning_joblist_fine_tuning_jobsalist_fine_tuning_jobscreate_assistantsacreate_assistantsdelete_assistantadelete_assistantcreate_threadacreate_threadadd_messagea_add_message
run_threadarun_threadrun_thread_streamarun_thread_streamfile_deleteafile_deletecreate_fileacreate_fileimage_generationaimage_generation
image_editaimage_edit
moderationamoderationtranscriptionatranscriptionspeechaspeechrerankarerank)r:   r   r   s      r?   r   z*DataDogLLMObsLogger._get_datadog_span_kind  s\    	 1 ,,22I4H4H4N4NOO   &&!!''%%++&&,,&&,,''----33..44((..%%  &&
 
  006677 $$**%%++  &&!!''""((##))$$**##))  &&%%##))""(($$**%%++..44//55''--#
 
&   %
""((%
##))%
 ,,22%
 --33	%

 ,,22%
 --33%
 ++11%
 ,,22%
 ''--%
 ((..%
 &&,,%
 ''--%
 ##))%
 $$**%
 !!''%
  ##))!%
"   &&#%
$ !!''%%
& ''--'%
( ((..)%
* !!''+%
, ""((-%
. !!''/%
0 ""((1%
2 &&,,3%
4 ''--5%
6   &&7%
8 !!''9%
:   &&;%
< !!''=%
> ##))?%
@ $$**A%
B ""C%
D ##E%
F ""G%
H ##I%
 %
L  rF   r   c                     |g S t        |t              r|gS t        |t              r|D cg c]  }| c}S t        |t              rt        |j	                  dd            gS g S c c}w )Nro    )rM   r9   listr   rU   )r:   r   r   s      r?   r   z*DataDogLLMObsLogger._ensure_string_content  sm     Ih$:$'+348G844$'Y3455	 5s   	A&c                    |j                  dd      |j                  dd      |j                  dd      |j                  dd      |j                  dd      |j                  dd      |j                  dd	      |j                  d
d      | j                  |      d	}| j                  |      }|j                  dt	        |      i       | j                  |      }|j                  dt	        |      i       | j                  |      }|j                  |       t	        |j                  di             xs i }|j                  |       |S )zh
        Fields to track in DD LLM Observability metadata from litellm standard logging payload
        rQ   rR   custom_llm_provideridr   	cache_hit	cache_keysaved_cache_costr   guardrail_informationN)	
model_namemodel_providerr$  r   r%  r&  r'  r(  is_streamed_requestlatency_metricsspend_metricsr   )rU   _get_stream_value_from_payload_get_latency_metricsr6   r   _get_spend_metrics_extract_tool_call_metadata)r:   r   	_metadatar,  r-  tool_call_metadata_standard_logging_metadatas          r?   r   z4DataDogLLMObsLogger._get_dd_llm_obs_payload_metadata*  s[    366w	J6::%y +..tY?044ZK155k9M155k9M 8 < <=OQR S%=%A%A'& $(#F#F($%
	* 334LM+T/-BCD
 //0HI/4+>?@ "==>VW+, )--j"=>D" 	# 	34rF   c                 @   t               }| j                  |      }|dkD  r|dz  |d<   |j                  di       }|j                  d      }|||d<   |j                  d      }|8d}|D ]$  }|j                  d      }	|	|t        |	      z  }& |dkD  r|dz  |d	<   |S )
zK
        Get the latency metrics from the standard logging payload
        r   i  time_to_first_token_mshidden_paramslitellm_overhead_time_msr(  r   r   guardrail_overhead_time_ms)DDLLMObsLatencyMetricsr   rU   r   )
r:   r   r,  time_to_first_token_secondsr7  litellm_overhead_msguardrail_infototal_durationinfo_guardrail_duration_secondss
             r?   r/  z(DataDogLLMObsLogger._get_latency_metricsX  s     3I2J '+&K&K$'
# '*+d2 45
 144_bI+//0JK*:MO67
 %(()@A 	 % N&?Cxx
?S+.:"e,G&HHN '
 !@NQU@U <=rF   c                     |j                  d      }|du ry|j                  di       }t        |t              r|j                  d      }|du ryy)as  
        Extract the stream value from standard logging payload.

        The stream field in StandardLoggingPayload is only set to True for completed streaming responses.
        For non-streaming requests, it's None. The original stream parameter is in model_parameters.

        Returns:
            bool: True if this was a streaming request, False otherwise
        streamTmodel_parametersF)rU   rM   r   )r:   r   stream_valuemodel_paramss       r?   r.  z2DataDogLLMObsLogger._get_stream_value_from_payload  s^     033H=4 0334FKlD)'++H5Lt# rF   c                 J   t               }|j                  dd      |d<   |j                  di       }|j                  d      }|t        |      |d<   |j                  d      }|	 t        |      |d<   |j                  d      }|	 d	d
lm}m} d}	t        |t              r%|j                  dd      }
 |j                  |
      }	nt        ||      r|}	|	U|	j                  |	j                  |j                        }	|	j                         }
|
|d<   t        j                  d|
        |S |S # t        t        f$ r t        j                  d|        Y w xY w# t         $ r;}t        j                  d|        t        j                  d|        Y d}~|S d}~ww xY w)zI
        Get the spend metrics from the standard logging payload
        r   r   r   user_api_key_max_budgetNuser_api_key_spendz"Invalid user_api_key_spend value: user_api_key_budget_reset_atr   )r   timezoneZz+00:00)tzinfoz)Converted budget_reset_at to ISO format: z(Error processing budget reset datetime: zOriginal value: )DDLLMObsSpendMetricsrU   r   r   r   r   r&   r   rJ  rM   r9   replacefromisoformatrL  utc	isoformatr-   )r:   r   r-  r   rG  rH  rI  r   rJ  budget_reset_at
iso_stringr>   s               r?   r0  z&DataDogLLMObsLogger._get_spend_metrics  s    /C.D *B)E)ES*
o&
 ,//
B? #+,,/H"I".7<=T7UM34 &\\*>?)6;<N6O23 (0||4R'S$'3X7"&:C@!=!E!Ec8!TJ&<h&<&<Z&HO <hG&BO".&--5*9*A*A*A*V "1!:!:!<JDNM"@A #((CJ<P }K 	* $$89K8LMB  X$$'OPQs%ST$$'78T7U%VWW	Xs+   'D1 	B$E 1'EE	F"'0FF"c                    g }|D ]w  }t        |t              rHd|v s|j                  d      dk(  r|j                  |       =t	        |g      }|j                  |       [t	        |g      }|j                  |       y |S )z
        Process input messages while preserving tool_calls and tool message types.

        This bypasses the lossy string conversion when tool calls are present,
        allowing complex nested tool_calls objects to be preserved for Datadog.
        
tool_callsroler   )rM   r   rU   rW   r   extend)r:   r   	processedmsg	converteds        r?   -_process_input_messages_preserving_tool_callszADataDogLLMObsLogger._process_input_messages_preserving_tool_calls  s     	C#t$3&#''&/V*C$$S) W E 
 $$Y/ S 
   +) * rF   rU  c           
         i }t        |       D ]  \  }}	 |j                  d      }|r	||d| d<   |j                  d      }|r	||d| d<   |j                  d      }|rf|j                  d      }|r	||d| d<   |j                  d	      }|r7t        |t              r
||d| d
<   nddl}	 |	j
                  |      |d| d
<    |S # t        t        t        f$ r.}
t        j                  d| dt        |
              Y d}
~
d}
~
ww xY w)z
        Extract tool call information into key-value pairs for Datadog metadata.

        Similar to OpenTelemetry's implementation but adapted for Datadog's format.
        r$  ztool_calls.z.idrk   z.typefunctionr   z.function.name	argumentsz.function.argumentsr   Nz*DataDogLLMObs: Error processing tool call z: )	enumeraterU   rM   r9   r   dumpsr   r   r   r   r&   )rU  kv_pairsidx	tool_calltool_id	tool_typer]  function_namefunction_argumentsr   r>   s              r?   _tool_calls_kv_pairz'DataDogLLMObsLogger._tool_calls_kv_pair  sQ    $&'
3NC##---7>H{3%s34 &MM&1	9BH{3%u56 %==4$,LL$8M$FS;se>!BC)1k)B&)%&8#> !3 %"-cU2E F ( !+

+= > %"-cU2E F; 4L  i4 $$@RAxP 	s   B1C

D$DDc                    i }	 |j                  dg       }|rrt        |t              rb|D ]]  }t        |t              sd|v s|j                  d      }|s-| j	                  |      }|j                         D ]  \  }}||d| <    _ |j                  d      }	|	rt        |	t              r|	j                  dg       }
|
D ]}  }t        |t              s|j                  d      }|s(t        |t              s9|j                  d      }|sM| j	                  |      }|j                         D ]  \  }}||d| <     |S # t        $ r,}t        j                  dt        |              Y d	}~|S d	}~ww xY w)
zk
        Extract tool call information from both input messages and response for Datadog metadata.
        r   rU  input_r{   r   r   output_z4DataDogLLMObs: Error extracting tool call metadata: N)
rU   rM   r!  r   rh  itemsr-   r   r&   r9   )r:   r   r3  r   r   rU  input_tool_calls_kvkeyr   r\   r   choiceresponse_tool_calls_kvr>   s                 r?   r1  z/DataDogLLMObsLogger._extract_tool_call_metadata-  s    .0!	/33JCHJx6'G!'40\W5L%,[[%>
%262J2J:2V/.A.G.G.I
UEJ 2VC5> B /J  ( 477
CL
< >&**9b9%F!&$/"(**Y"7"z'4'@)0\)BJ)9=9Q9Q$.:" 6 3I2N2N2PJCJO$6$G 3Q &$ "!  	  Fs1vhO  "!	sA   9E E E A=E E )E :E 3E 	E8!E33E8)N)(__name__
__module____qualname__r7   r9   r,   r.   r   r5   r`   rd   rZ   r   r   rV   r	   r   r   r   r   r   r   r   r   r   r   r   r
   r   r   r:  r/  boolr.  rM  r0  r[  staticmethodrh  r1  rJ   rF   r?   r   r   /   s   3jT T
"+T +*  CWJFF(0F<DF	FP8C= (>	-	 2(>	./(>/KSTW=/	c/d DHe!#e3;C=e	@	AeN sDItCH~'E!FG	c,(>,	c3h,\&(>&	&P(>	6?(>?	?BS		d38n	B -T#s(^(< -c3h - -^+"(>+"	c3h+"rF   r   ))__doc__r0   r   r(   litellm._uuidr   r   typingr   r   r   r   r	   r
   ry   rK   litellm._loggingr   (litellm.integrations.custom_batch_loggerr   0litellm.integrations.datadog.datadog_mock_clientr   r   ,litellm.integrations.datadog.datadog_handlerr   r   r   %litellm.litellm_core_utils.dd_tracingr   8litellm.litellm_core_utils.prompt_templates.common_utilsr   &litellm.llms.custom_httpx.http_handlerr   r   *litellm.types.integrations.datadog_llm_obslitellm.types.utilsr   r   r   r   r   rJ   rF   r?   <module>r     si      	   < <   + F 
 9 9 i"+ i"rF   