Ë
    tPêj`…  ã                   óø   — d Z ddlZddlZddlZddlmZ ddl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 ddlmZmZmZ dd	l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)Údatetime)ÚAnyÚFinalÚLiteral)Úverbose_logger)Úuuid)ÚCustomBatchLogger)Úget_datadog_base_url_from_envÚget_datadog_serviceÚget_datadog_tags)Úcreate_mock_datadog_clientÚshould_use_datadog_mock)Ú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dz  fd„Zdededz  fd„Zdedefd„Zdededz  dee   fd„Z	 d"dedz  dedz  ded   fd„Zdeee   z  eeef   z  dz  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|«       |‚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 - %s)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)ÚselfÚkwargsr   Údd_base_urlÚdict_datadog_llm_obs_paramsÚes         úq/home/oem/CyberBrain26-unified/.venv/lib/python3.12/site-packages/litellm/integrations/datadog/datadog_llm_obs.pyr4   zDataDogLLMObsLogger.__init__0   sw  € ð,	Ü× Ñ Ð!EÔFä 7Ó 9ˆDÔà× Ò Ü*Ô,Ü×$Ñ$Ð%cÔdô
 $&§9¡9Ð-DÓ#EˆMä 6ÔDX×DhÑDhÔ iˆDÔÜ Ÿi™i¨Ó5ˆDŒOáØ×(Ñ(°}Ð(ÕEô —9‘9˜\¨4Ó0Ð8Ü#Ð$PÓQÐQÜ—9‘9˜Y¨Ó-Ð5Ü#Ð$mÓnÐnØ×-Ñ-Ô/ô "?Ó!@ˆKÙØ%0 MÐ1SÐ"T�”ä×Ñ × 3Ñ 3Ó 5Ô6Ü%Ÿl™l›nˆDŒOØ24ˆDŒNð
 26×1QÑ1QÓ1SÐ'Ø�M‰MÐ5Ô6Ü×&Ñ& tÑR¨vÑRÀ$Ç/Á/ÔRøÜò 	Ü×$Ñ$Ð%MÈqÔQØˆ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 %sN)r%   r&   r    r,   r   r#   )r6   r   Ú
agent_ports      r;   r)   z'DataDogLLMObsLogger._configure_dd_agent_   sH   € ô ŸI™IÐ&?ÀÓHˆ
Ø"ˆŒØ# M ?°!°J°<Ð?aÐbˆŒÜ×ÑÐBÀDÇOÁOÕTó    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,   )r6   s    r;   r+   z,DataDogLLMObsLogger._configure_dd_direct_apil   sO   € ð �ŠÜÐHÓIÐIä—y‘y Ó+ˆŒØ�|Š|ÜÐfÓgÐgà(¨¯©¨Ð6XÐYˆ�rB   Ú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_dumpÚdict)r6   r9   s     r;   r2   z/DataDogLLMObsLogger._get_datadog_llm_obs_paramsy   s€   € ð -/Ð#Ü×3Ñ3Ð?Üœ'×BÑBÔD[Ô\Ü.5×.VÑ.V×.aÑ.aÓ.cÐ+ð +Ð*ô œG×DÑDÄdÔKä.Eñ /Ü×>Ñ>ñ/ç‘*“,ð ,ð +Ð*rB   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|«       Y d }~y d }~ww xY w­w)Nz1DataDogLLMObs: Logging success event for model %sÚmodelÚunknownúDataDogLLMObs: Payload: %sz/DataDogLLMObs: Error logging success event - %s©r   r#   ÚgetÚcreate_llm_obs_payloadr1   ÚappendÚlenÚ
batch_sizeÚasync_send_batchr*   r5   ©r6   r7   Úresponse_objÚ
start_timeÚend_timeÚpayloadr:   s          r;   Úasync_log_success_eventz+DataDogLLMObsLogger.async_log_success_eventŠ   ó¹   è ø€ ð		[Ü× Ñ Ð!TÐV\×V`ÑV`ÐahÐjsÓVtÔuØ!×8Ñ8¸ÀÈXÓVˆGÜ× Ñ Ð!=¸wÔGØ�N‰N×!Ñ! 'Ô*ä�4—>‘>Ó" d§o¡oÒ5Ø×+Ñ+Ó-×-Ñ-ð 6Ø-ùÜò 	[Ü×$Ñ$Ð%VÐXY×ZÑZûð	[üóA   ‚C„BB, Â#B*Â$B, Â(CÂ*B, Â,	CÂ5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|«       Y d }~y d }~ww xY w­w)Nz1DataDogLLMObs: Logging failure event for model %srN   rO   rP   z/DataDogLLMObs: Error logging failure event - %srQ   rX   s          r;   Úasync_log_failure_eventz+DataDogLLMObsLogger.async_log_failure_event–   r^   r_   c           	   ƒ   ó´  K  — 	 | j                   sy t        j                  dt        | j                   «      «       | 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                   «      «       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*                  $ r4}t        j,                  d|j.                  j$                  «       Y d }~y d }~wt        $ r }t        j,                  d|«       Y d }~y d }~ww xY w­w)Nz!DataDogLLMObs: Flushing %s 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: z5[DATADOG MOCK] Batch of %s events successfully mockedz8DataDogLLMObs: Successfully sent batch - status_code: %sz'DataDogLLMObs: Error sending batch - %s)r1   r   r#   rU   r$   ÚDDIntakePayloadÚDDSpanAttributesr   r   Ú*litellm.litellm_core_utils.safe_json_dumpsrj   r*   Ústrr   r(   Úpostr,   Ústatus_codeÚtextÚclearÚhttpxÚHTTPStatusErrorr5   Úresponse)r6   r\   rj   Údebug_errorÚjson_payloadrm   ry   r:   s           r;   rW   z$DataDogLLMObsLogger.async_send_batch¢   s  è ø€ ð6	SØ—>’>Øä× Ñ Ð!DÄcÈ$Ï.É.ÓFYÔZà× Ò Ü×$Ñ$Ð%gÔhð œØÜ/Ü2Ó4Ü-Ó/Ø"Ÿn™nô ôð	ˆGõ Nð[Ü×$Ñ$ \±:¸gÓ3FÔGñ #-¨WÓ"5ˆLà,Ð.@ÐAˆGØ�ŠØ(,¯©�˜Ñ%à$(×$5Ñ$5×$:Ñ$:Ø—O‘OØ$Øð %;ó %÷ ˆHð ×#Ñ# sÒ*ÜØHÈ×I]ÑI]ÐH^Ð^fÐgo×gtÑgtÐfuÐvóð ð × Ò Ü×$Ñ$Ð%\Ô^aÐbf×bpÑbpÓ^qÕrä×$Ñ$Ð%_Ðai×auÑauÔvØ�N‰N× Ñ Õ"øô1 ò [Ü×$Ñ$Ð%GÌÈ[ÓIY×ZÒZûð[úðùô  ×$Ñ$ò 	aÜ×$Ñ$Ð%NÐPQ×PZÑPZ×P_ÑP_×`Ñ`ûÜò 	SÜ×$Ñ$Ð%NÐPQ×RÑRûð	Süsƒ   ‚I„G' �I‘BG' ÂF/ Â3AG' ÄG%ÄB(G' Æ.IÆ/	G"Æ8GÇG' ÇG"Ç"G' Ç'IÇ:*H)È$IÈ)IÈ5IÉIÉIÉIr7   rZ   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    eÍÍAr‡   Úok)r}   )
rƒ   r‘   r’   r“   ÚmetaÚstart_nsÚdurationÚmetricsÚstatusrf   Úapm_id)rR   r*   Ú_ensure_string_contentÚ	InputMetar   Ú
OutputMetaÚ_get_response_messagesÚ_assemble_error_inforI   rL   ÚMetaÚ_get_datadog_span_kindÚ _get_dd_llm_obs_payload_metadataÚ
LLMMetricsÚfloatÚ _get_time_to_first_token_secondsÚLLMObsPayloadrr   r   Úuuid4ÚintÚ	timestampÚtotal_secondsr   Ú_get_apm_trace_id)r6   r7   rZ   r[   r‚   r~   r€   Ú
input_metaÚoutput_metaÚ
error_infoÚmetadata_parent_idr–   r™   r\   Úapm_trace_ids                  r;   rS   z*DataDogLLMObsLogger.create_llm_obs_payloadÛ   sG  € ØIOÏÉÐTmÓInÐ Ø#Ð+ÜÐOÓPÐPà+¨JÑ7ˆØ×.Ñ.¸Ð.ÓAˆà Ÿ*™*Ð%5°rÓ:×>Ñ>¸zÈ2ÓNˆä%Ô/mÐnvÓ/wÔxˆ
Ü'Ø×0Ñ0Ø)AØ2×6Ñ6°{ÓCð 1ó ô
ˆð !×5Ñ5Ð6NÓOˆ
à)-ÐÜ�h¤Ô%Ø!)§¡¨kÓ!:ÐäØ×,Ñ,Ð-E×-IÑ-IÈ+Ó-VÐXjÓkØØØ×:Ñ:Ð;SÓTØô
ˆô $ÜÐ7×;Ñ;¸OÈQÓOÓPÜÐ 8× <Ñ <Ð=PÐRSÓ TÓUÜÐ7×;Ñ;¸NÈAÓNÓOÜÐ5×9Ñ9¸/È1ÓMÓNØ $× EÑ EÐF^Ó _ô
ˆô )6Ù,>Ñ(ÀKØ-×1Ñ1°*¼cÄ$Ç*Á*Ã,Ó>OÓPØ—L‘L ¬C´·
±
³Ó,=Ó>Ø—‘˜fÐ&8Ó9ØÜ˜×-Ñ-Ó/°#Ñ5Ó6Ü˜( ZÑ/×>Ñ>Ó@À3ÑFÓGØÙ(‘7¨dÜ!Ð:RÔSô)
ˆð #×4Ñ4Ó6ˆØÐ#Ø ,ˆG�HÑàˆrB   Nc                 ó¢   — 	 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   Úcallablerr   r*   )r6   Úcurrent_span_fnr³   r‘   s       r;   r¬   z%DataDogLLMObsLogger._get_apm_trace_id  se   € ð		Ü%,¬V°^ÀTÓ%JˆOÜ˜Ô(Ù&5Ó&7�ØÐ+Ü&-¨l¸JÈÓ&M�HØÐ+Ü" 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)Úmessagerh   Ústack)rR   ÚDDLLMObsError)r6   r‚   r¯   r¹   s       r;   r    z(DataDogLLMObsLogger._assemble_error_info%  s�   € ð
 ,0ˆ
à#×'Ñ'¨Ó1°YÒ>àVn×VrÑVrØ#óWÐñ !Ü*Ø-×1Ñ1°/ÓBò 'Ø/×3Ñ3°KÓ@ò'à&Ø*×.Ñ.¨}Ó=Ø+×/Ñ/°Ó<ô�
ð ÐrB   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ç        )rR   )r6   r‚   rZ   Úcompletion_start_timer[   s        r;   r¦   z4DataDogLLMObsLogger._get_time_to_first_token_seconds<  sf   € ð +C×*FÑ*FÀ{Ó*Sˆ
Ø5M×5QÑ5QÐRgÓ5hÐØ(@×(DÑ(DÀYÓ(Oˆà Ð,°Ð1GØ(¨:Ñ5Ð5ØÐ! jÐ&<Ø˜jÑ(Ð(àrB   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
        ry   Nr   Úchoicesr¾   )rR   rI   rr   Ú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_messagesrL   rU   ÚKeyErrorÚ
IndexErrorÚ	TypeError)r6   r‚   r�   rY   rÉ   rÈ   s         r;   rŸ   z*DataDogLLMObsLogger._get_response_messagesO  s™  € ð 0×3Ñ3°JÓ?ˆØÐØˆIô �l¤CÔ(ð	Ûà"×/Ñ/°Ó=�ð Ü× Ñ ×&Ñ&Ü×!Ñ!×'Ñ'Ü×%Ñ%×+Ñ+Ü×&Ñ&×,Ñ,Ü×&Ñ&×,Ñ,Ü×'Ñ'×-Ñ-Ü×-Ñ-×3Ñ3Ü×.Ñ.×4Ñ4Ü×(Ñ(×.Ñ.ð

ñ 

ð	ä˜l¬DÔ1°iÀ<Ñ6OØ%1°)Ñ%<�GÙ¤3 w£<°!Ò#3¸	ÀWÈQÁZÑ8OØ '¨¡
¨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rƒ   )Ú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)r6   r�   rƒ   s      r;   r¢   z*DataDogLLMObsLogger._get_datadog_span_kind€  s\  € ð Ð 	Ð 1Øð œ×,Ñ,×2Ñ2´I×4HÑ4H×4NÑ4NÐ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 ð rB   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 )Nrl   Ú )rI   rr   ÚlistrL   rR   )r6   r~   r¾   s      r;   rœ   z*DataDogLLMObsLogger._ensure_string_contentç  sg   € ØÐØˆIÜ�h¤Ô$Ø�:ÐÜ˜¤$Ô'Ø+3Ö4 ’GÒ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
        rN   rO   Ú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€   )rR   Ú_get_stream_value_from_payloadÚ_get_latency_metricsr3   rL   Ú_get_spend_metricsÚ_extract_tool_call_metadata)r6   r‚   Ú	_metadatar)  r*  Útool_call_metadataÚ_standard_logging_metadatas          r;   r£   z4DataDogLLMObsLogger._get_dd_llm_obs_payload_metadataò  sP  € ð
 3×6Ñ6°wÀ	ÓJØ6×:Ñ:Ð;PÐR[Ó\Ø*×.Ñ.¨t°YÓ?Ø0×4Ñ4°ZÀÓKØ1×5Ñ5°kÀ9ÓMØ1×5Ñ5°kÀ9ÓMØ 8× <Ñ <Ð=OÐQRÓ SØ%=×%AÑ%AÐBYÐ[_Ó%`Ø#'×#FÑ#FÐG_Ó#`ñ
,
ˆ	ð "&×!:Ñ!:Ð;SÓ!TˆØ×ÑÐ+¬T°/Ó-BÐCÔDð
  $×6Ñ6Ð7OÓPˆØ×Ñ˜/¬4°Ó+>Ð?Ô@ð %)×$DÑ$DÐE]Ó$^ÐØ×ÑÐ+Ô,ä26Ð7O×7SÑ7SÐT^Ð`bÓ7cÓ2dÒ2jÐhjÐ"Ø×ÑÐ3Ô4ØÐrB   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¦   rR   r¥   )
r6   r‚   r)  Útime_to_first_token_secondsr4  Úlitellm_overhead_msÚguardrail_infoÚtotal_durationÚinfoÚ_guardrail_duration_secondss
             r;   r,  z(DataDogLLMObsLogger._get_latency_metrics  sí   € ô :PÓ9Qˆð .2×-RÑ-RÐSkÓ-lÐ#Ø&¨Ò*Ø8SÐVZÑ8ZˆOÐ4Ñ5ð  8×;Ñ;¸OÈRÓPˆØ%2×%6Ñ%6Ð7QÓ%RÐØÐ*Ø:MˆOÐ6Ñ7ð Sk×RnÑRnØ#óS
ˆð Ð%Ø ˆNØ&ò I�Ø<@¿H¹HÀZÓ<PÐ+Ø.Ñ:Ø"¤eÐ,GÓ&HÑH‘NðIð
  Ò!à@NÐQUÑ@U�Ð <Ñ=àÐrB   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)rR   rI   rL   )r6   r‚   Ústream_valueÚmodel_paramss       r;   r+  z2DataDogLLMObsLogger._get_stream_value_from_payload8  s^   € ð 0×3Ñ3°HÓ=ˆØ˜4ÑØð 7×:Ñ:Ð;MÈrÓRˆÜ�l¤DÔ)Ø'×+Ñ+¨HÓ5ˆLØ˜tÑ#Øð rB   c                 ó:  — 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|}	|	�S|	j                  €|	j                  |j                  ¬«      }	|	j                  «       }
|
|d<   t        j                  d|
«       |S |S # t        t        f$ r t        j                  d|«       Y Œáw xY w# t         $ r7}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: %sÚuser_api_key_budget_reset_atr   )r   ÚtimezoneÚZz+00:00)Útzinfoz+Converted budget_reset_at to ISO format: %sz*Error processing budget reset datetime: %szOriginal value: %s)ÚDDLLMObsSpendMetricsrR   r¥   rË   rÜ   r   r#   r   rG  rI   rr   ÚreplaceÚfromisoformatrI  ÚutcÚ	isoformatr*   )r6   r‚   r*  r€   rD  rE  rF  r   rG  Úbudget_reset_atÚ
iso_stringr:   s               r;   r-  z&DataDogLLMObsLogger._get_spend_metricsQ  sÉ  € ô 6JÓ5Kˆð *B×)EÑ)EÀoÐWZÓ)[ˆ�oÑ&ð 3×6Ñ6°zÀ2ÓFˆð *2¯©Ð6OÓ)PÐØ"Ð.Ü7<Ð=TÓ7UˆMÐ3Ñ4ð %-§L¡LÐ1EÓ$FÐØÐ)ðaÜ6;Ð<NÓ6O�Ð2Ñ3ð
 /7¯l©lÐ;YÓ.ZÐ$Ø'Ð3ðYß7à"&�ÜÐ:¼CÔ@à!=×!EÑ!EÀcÈ8Ó!T�JØ&< h×&<Ñ&<¸ZÓ&H‘OÜÐ <¸hÔGØ&B�Oà"Ð.à&×-Ñ-Ð5Ø*9×*AÑ*AÈÏÉÐ*AÓ*V˜ð "1×!:Ñ!:Ó!<�JØDN�MÐ"@ÑAô #×(Ñ(Ð)VÐXbÔcð
 Ðˆ}ÐøôC ¤	Ð*ò aÜ×$Ñ$Ð%KÐM_Ö`ðaûô: ò YÜ×$Ñ$Ð%QÐSTÔUÜ×$Ñ$Ð%9Ð;W×XÐXàÐûð	Yús+   Á'D/ Â	B"E Ä/%EÅEÅ	FÅ#,FÆ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Þ   )rI   rL   rR   rT   r   Úextend)r6   r~   Ú	processedÚmsgÚ	converteds        r;   Ú-_process_input_messages_preserving_tool_callszADataDogLLMObsLogger._process_input_messages_preserving_tool_callsŠ  s�   € ð ˆ	Øò 	,ˆCÜ˜#œtÔ$à 3Ñ&¨#¯'©'°&«/¸VÒ*CØ×$Ñ$ SÕ)ô !_Ð`cÐ_dÓ e�IØ×$Ñ$ YÕ/ô [Ð\_Ð[`Óa�	Ø× Ñ  Õ+ð	,ð ÐrB   rR  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||
«       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.idrh   z.typeÚfunctionr“   z.function.nameÚ	argumentsz.function.argumentsr   Nz0DataDogLLMObs: Error processing tool call %s: %s)Ú	enumeraterR   rI   rr   rÍ   ÚdumpsrÚ   rÜ   rË   r   r#   )rR  Úkv_pairsÚidxÚ	tool_callÚtool_idÚ	tool_typerZ  Úfunction_nameÚfunction_argumentsrÍ   r:   s              r;   Ú_tool_calls_kv_pairz'DataDogLLMObsLogger._tool_calls_kv_pair¡  s5  € ð +-ˆÜ'¨
Ó3ò 	‰NˆC�ðà#Ÿ-™-¨Ó-�ÙØ7>�H˜{¨3¨%¨sÐ3Ñ4ð &ŸM™M¨&Ó1�	ÙØ9B�H˜{¨3¨%¨uÐ5Ñ6ð %Ÿ=™=¨Ó4�ÙØ$,§L¡L°Ó$8�MÙ$ØFS˜ ;¨s¨e°>Ð!BÑCà)1¯©°kÓ)BÐ&Ù)ä%Ð&8¼#Ô>ØOa˜H {°3°%Ð7JÐ%KÒLã'àOYÈtÏzÉzÐZlÓOm˜H {°3°%Ð7JÐ%KÑLøð7	ð@ ˆøô	 œi¬Ð4ò Ü×$Ñ$Ð%WÐY\Ð^_Ô`Üûðús   •B1C
Ã
C?ÃC:Ã:C?c                 óà  — i }	 |j                  dg «      }|rrt        |t        «      rb|D ]]  }t        |t        «      sŒd|v sŒ|j                  d«      }|sŒ-| j	                  |«      }|j                  «       D ]  \  }}||d|› �<   Œ Œ_ |j                  d«      }	|	r¤t        |	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|«       Y d	}~|S d	}~ww xY w)
zk
        Extract tool call information from both input messages and response for Datadog metadata.
        r~   rR  Úinput_ry   rÈ   r¾   Úoutput_z6DataDogLLMObs: Error extracting tool call metadata: %sN)	rR   rI   r  rL   re  Úitemsr*   r   r#   )r6   r‚   r0  r~   r¾   rR  Úinput_tool_calls_kvÚkeyrÑ   rY   rÈ   ÚchoiceÚresponse_tool_calls_kvr:   s                 r;   r.  z/DataDogLLMObsLogger._extract_tool_call_metadataË  s�  € ð 57Ðð	^à6×:Ñ:¸:ÀrÓJˆHÙœJ x´Ô6Ø'ò K�GÜ! '¬4Õ0°\ÀWÒ5LØ%,§[¡[°Ó%>˜
Ú%Ø26×2JÑ2JÈ:Ó2VÐ/à.A×.GÑ.GÓ.Iò K¡
  UØEJÐ 2°V¸C¸5°>Ò BñKðKð #;×">Ñ">¸zÓ"JˆLÙ¤
¨<¼Ô >Ø!-×!1Ñ!1°)¸RÓ!@�Ø%ò 	P�FÜ! &¬$Õ/Ø"(§*¡*¨YÓ"7˜Ú"¤z°'¼4Õ'@Ø)0¯©°\Ó)B˜JÚ)Ø9=×9QÑ9QÐR\Ó9]Ð 6à2H×2NÑ2NÓ2Pò !P¡J C¨ØJOÐ$6¸ÀÀ°Ò$Gñ!Pð	Pð "Ð!øô ò 	^Ü× Ñ Ð!YÐ[\×]Ð]à!Ð!ûð	^úsA   „9E ¾E ÁE ÁA=E ÃE Ã)E Ã:E Ä3E Å	E-ÅE(Å(E-)N)&Ú__name__Ú
__module__Ú__qualname__r4   rr   r)   r+   rL   r2   r]   ra   rW   r   r§   rS   r¬   r   rÀ   r    r¥   r¦   r  r   rŸ   r   r¢   rœ   r£   r7  r,  Úboolr+  rJ  r-  rX  Ústaticmethodre  r.  rF   rB   r;   r   r   /   s  „ ò-ð^U°ó UòZð+¨Tó +ò"
[ò
[ò7Sðr:¨Tð :¸xð :ÐS[ð :Ð`mó :ðx 3¨¡:ó ðÐ=Sð ÐXeÐhlÑXló ð.ÐI_ð Ðdió ð&/Ø(>ð/ØKNÐQUÉ:ð/à	ˆc‰ó/ðd >BñeØ˜t™ðeØ03°d±
ðeà	Ð@Ñ	AóeðN	¨s°T¸#±Y©ÀÀcÈ3ÀhÁÑ/OÐRVÑ/Vð 	Ð[_Ð`cÑ[dó 	ð"ÐI_ð "ÐdhÐilÐnqÐiqÑdró "ðH Ð=Sð  ÐXnó  ðDÐG]ð Ðbfó ð27Ð;Qð 7ÐVjó 7ðrÀdÈ3Áið ÐTXÐY]Ð^aÐcfÐ^fÑYgÑThó ð. ð'¨¨T°#°s°(©^Ñ(<ð 'ÀÀcÈ3ÀhÁò 'ó ð'ðR%"ÐDZð %"Ð_cÐdgÐilÐdlÑ_mô %"rB   r   )&Ú__doc__r-   rÍ   r%   r   Útypingr   r   r   rw   rG   Úlitellm._loggingr   Úlitellm._uuidr   Ú(litellm.integrations.custom_batch_loggerr	   Ú,litellm.integrations.datadog.datadog_handlerr
   r   r   Ú0litellm.integrations.datadog.datadog_mock_clientr   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   rF   rB   r;   ú<module>r     si   ðñó Û Û 	Ý ß &Ñ &ã ã Ý +Ý Ý F÷ñ ÷
õ 9õ÷ô 9÷ó ôA"Ð+õ A"rB   