
    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 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 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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)DataDogLogger)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 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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                  dd       t	        d      t        j                  dd       t	        d      t        t        j                        | _        t        j                  d      | _	        t        j                  d      | _
        d| j                   d| _        t        j                  d	      }|r
| d| _        t        j                  | j                                t        j                         | _        g | _        | j%                         }|j'                  |       t)        j*                  | fi |d
| j                   i y # t        $ r(}t        j,                  dt/        |              |d }~ww xY w)Nz"DataDogLLMObs: Initializing logger
DD_API_KEYz*DD_API_KEY is not set, set 'DD_API_KEY=<>'DD_SITEzGDD_SITE is not set, set 'DD_SITE=<>', example sit = `us5.datadoghq.com`)llm_providerzhttps://api.z"/api/intake/llm-obs/v1/trace/spansDD_BASE_URL
flush_lockz$DataDogLLMObs: Error initializing - )r   debugosgetenv	Exceptionr   r   LoggingCallbackasync_clientr   r   
intake_urlasynciocreate_taskperiodic_flushLockr   	log_queue_get_datadog_llm_obs_paramsupdater   __init__	exceptionstr)selfkwargsdd_base_urldict_datadog_llm_obs_paramses        /Users/manta/Documents/Projects/TheRoad-I1/backend/.venv/lib/python3.12/site-packages/litellm/integrations/datadog/datadog_llm_obs.pyr-   zDataDogLLMObsLogger.__init__(   s]   #	  !EFyyt,4 LMMyyD)1]  !71AA!D !ii5DO99Y/DLt||n,NO O
 ))M2K%0M1S"T 3 3 56%llnDO24DN
 +/*J*J*L'MM56&&tRvR$//R 	$$'KCPQF8%TUG	s   E(E+ +	F4#FF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   )r0   r3   s     r5   r+   z/DataDogLLMObsLogger._get_datadog_llm_obs_paramsN   s     -/#33?88:Q <<GGI , +* GDDdK.E />>/*, , +*    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_payloadr*   appendlen
batch_sizeasync_send_batchr"   r.   r/   r0   r1   response_obj
start_timeend_timepayloadr4   s          r5   async_log_success_eventz+DataDogLLMObsLogger.async_log_success_eventc        	  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 r@   rA   rB   z-DataDogLLMObs: Error logging failure event - rC   rJ   s          r5   async_log_failure_eventz+DataDogLLMObsLogger.async_log_failure_events   rP   rQ   c           	        K   	 | j                   sy t        j                  dt        | j                          d       dt	        dt        | j                         | j                         g| j                               i}ddlm	} 	 t        j                  d	 ||              ||      }| j                  j                  | j                  || j                  dd       d {   }|j                   dk7  r%t        d|j                    d|j"                         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 eventsdataspan)ml_apptagsspans)type
attributesr   )
safe_dumpsz
payload %sz payload serialization failed: %szapplication/json)z
DD-API-KEYzContent-Type)urlcontentheaders   z2DataDogLLMObs: Unexpected response - status_code: z, text: z6DataDogLLMObs: Successfully sent batch - status_code: z%DataDogLLMObs: Error sending batch - )r*   r   r   rG   DDIntakePayloadDDSpanAttributes_get_datadog_service_get_datadog_tags*litellm.litellm_core_utils.safe_json_dumpsr\   r"   r/   r$   postr%   r   status_codetextclearhttpxHTTPStatusErrorr.   response)r0   rN   r\   debug_errorjson_payloadrl   r4   s          r5   rI   z$DataDogLLMObsLogger.async_send_batch   s    7	W>>  *3t~~+>*?wG /#88:"4467"nn 	G N$$\:g3FG &g.L!..33OO$"&//$6 4  H ##s*HI]I]H^^fgogtgtfuv    HI]I]H^_ NN  "1  $$6K8H $ $$ 	$$7

7HI   	W$$'LSQRVH%UVV	Ws   HF HA4F E "A F "F#A4F H	F
!F F F

F H
",GHH
!H HH

Hr1   rL   rM   c                    |j                  d      }|t        d      |d   }| j                  |      }|j                  di       j                  di       }t        t	        |            }t        | j                  ||j                  d                  }| j                  |      }	t        | j                  |j                  d            ||| j                  |      |		      }
t        t        |j                  d
d            t        |j                  dd            t        |j                  dd            t        |j                  dd            | j                  |            }t        |j                  d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| j+                  |      g
      }| j-                         }|||d<   |S )Nstandard_logging_objectz1DataDogLLMObs: standard_logging_object is not setmessages)rq   litellm_paramsmetadata	call_type)standard_logging_payloadrt   )kindinputoutputrs   errorprompt_tokensr   completion_tokenstotal_tokensresponse_cost)input_tokensoutput_tokensr|   
total_costtime_to_first_token	parent_id	undefinedtrace_idspan_idnamelitellm_llm_callg    eAry   ok)rp   )
r   r   r   r   metastart_nsdurationmetricsstatusrX   apm_id)rD   r"   _ensure_string_content	InputMetar   
OutputMeta_get_response_messages_assemble_error_infoMeta_get_datadog_span_kind _get_dd_llm_obs_payload_metadata
LLMMetricsfloat _get_time_to_first_token_secondsLLMObsPayloadr/   r   uuid4int	timestamptotal_secondsrd   _get_apm_trace_id)r0   r1   rL   rM   ru   rq   rs   
input_metaoutput_meta
error_infor   r   rN   apm_trace_ids                 r5   rE   z*DataDogLLMObsLogger.create_llm_obs_payload   sJ    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
,,-E-I-I+-VW::;ST
 7;;OQOP 8 < <=PRS TU7;;NANO599/1MN $ E E(!
 "/ll;<-11*c$**,>OPLLC

,=>f&89--/#56(Z/>>@3FG(7d&&?W&X"
 --/# ,GHr>   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   callabler/   r"   )r0   current_span_fnr   r   s       r5   r   z%DataDogLLMObsLogger._get_apm_trace_id  se    		%fndCO(.0+&|ZFH+"8},   		s   >A 	AAru   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)messagerZ   stack)rD   DDLLMObsError)r0   ru   r   r   s       r5   r   z(DataDogLLMObsLogger._assemble_error_info  s     /3
#''1Y> ),,-@A  !*-11/B '/33K@'&*..}=+//<
 r>   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        )rD   )r0   ru   rL   completion_start_timerM   s        r5   r   z4DataDogLLMObsLogger._get_time_to_first_token_seconds(  si     '?&B&B;&O
1I1M1M!2
 %=$@$@$K ,1G(:55!j&<j((r>   rt   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
        rl   Nr   choicesr   )rD   r;   r/   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_messagesdictrG   KeyError
IndexError	TypeError)r0   ru   rt   rK   r   r   s         r5   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)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                  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         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"
        r   r   r   r   r   )Er   r   r   
aembeddingr   r   r   r   r   r   r   r   r   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	responses
aresponses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)r0   rt   s     r5   r   z*DataDogLLMObsLogger._get_datadog_span_kindp  sW     ,,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  r>   rq   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 )Nr^    )r;   r/   listr   rD   )r0   rq   r   s      r5   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
        r@   rA   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_metricsrs   )rD   _get_stream_value_from_payload_get_latency_metricsr,   r   _get_spend_metrics_extract_tool_call_metadata)r0   ru   	_metadatar  r  tool_call_metadata_standard_logging_metadatas          r5   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r>   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   rD   r   )
r0   ru   r  time_to_first_token_secondsr'  litellm_overhead_msguardrail_infototal_durationinfo_guardrail_duration_secondss
             r5   r  z(DataDogLLMObsLogger._get_latency_metrics  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 <=r>   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)rD   r;   r   )r0   ru   stream_valuemodel_paramss       r5   r  z2DataDogLLMObsLogger._get_stream_value_from_payload8  s^     033H=4 0334FKlD)'++H5Lt# r>   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   rs   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: )DDLLMObsSpendMetricsrD   r   r   r   r   r   r   r:  r;   r/   replacefromisoformatr<  utc	isoformatr"   )r0   ru   r  rs   r7  r8  r9  r   r:  budget_reset_at
iso_stringr4   s               r5   r   z&DataDogLLMObsLogger._get_spend_metricsS  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   )r;   r   rD   rF   r   extend)r0   rq   	processedmsg	converteds        r5   -_process_input_messages_preserving_tool_callszADataDogLLMObsLogger._process_input_messages_preserving_tool_calls  s     	C#t$3&#''&/V*C$$S) W E 
 $$Y/ S 
   +) * r>   rE  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.idrZ   z.typefunctionr   z.function.name	argumentsz.function.argumentsr   Nz*DataDogLLMObs: Error processing tool call z: )	enumeraterD   r;   r/   r   dumpsr   r   r   r   r   )rE  kv_pairsidx	tool_calltool_id	tool_typerM  function_namefunction_argumentsr   r4   s              r5   _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.
        rq   rE  input_rl   r   r   output_z4DataDogLLMObs: Error extracting tool call metadata: N)
rD   r;   r  r   rX  itemsr"   r   r   r/   )r0   ru   r#  rq   r   rE  input_tool_calls_kvkeyr   rK   r   choiceresponse_tool_calls_kvr4   s                 r5   r!  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__r-   r   r+   rO   rS   rI   r   r   rE   r	   r/   r   r   r   r   r   r   r   r   r   r   r   r
   r   r   r*  r  boolr  r=  r   rK  staticmethodrX  r!  r8   r>   r5   r   r   '   s   $L+T +*  8WtBB(0B<DB	BH8C= (>	-	 2(>	./(>/KSTW=/	c/bc!#c	@	AcJ sDItCH~'E!FG	c,(>,	c3h,\&(>&	&P(>	6?(>?	?BS		d38n	B -T#s(^(< -c3h - -^+"(>+"	c3h+"r>   r   )$__doc__r&   r   r    litellm._uuidr   r   typingr   r   r   r   r	   r
   rj   r9   litellm._loggingr   (litellm.integrations.custom_batch_loggerr   $litellm.integrations.datadog.datadogr   %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   r8   r>   r5   <module>rq     s]      	   < <   + F > 8 9 i"-): i"r>   