
    \jd0              
       v   d dl Z d dlm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 d dlmZ d dlmZmZ d dlmZ d d	lmZ erd d
lmZmZmZ d dlmZ 	 d dlZd dlmZmZmZ ddZddZ d dZ!d dZ"	 	 	 	 	 	 	 	 	 	 d!dZ#	 	 	 	 	 	 	 	 	 	 d!dZ$ddde%ddddddf
dZ& G d de      Z'y# e$ r	  ed      w xY w)"    N)TYPE_CHECKING)consts)record_token_usage)get_start_span_functionset_data_normalizedtruncate_and_annotate_messagestransform_openai_content_part&truncate_and_annotate_embedding_inputs)SPANDATA)DidNotEnableIntegration)should_send_default_pii)event_from_exception)AnyDictList)datetime)input_callbacksuccess_callbackfailure_callbackzLiteLLM not installedkwargsDict[str, Any]returnc                 ^    | j                  di       }|j                  d      }|i }||d<   |S )z,Get the metadata dictionary from the kwargs.litellm_paramsmetadata)
setdefaultget)r   r   r   s      I/root/env/lib/python3.12/site-packages/sentry_sdk/integrations/litellm.py_get_metadata_dictr       sA    &&'7<N !!*-H%-z"O    c                 P   t        j                  |       } | D ]  }t        |t              s|j	                  d      }t        |t
        t        f      s<g }|D ]D  }t        |t              r!t        |      }|j                  ||n|       4|j                  |       F ||d<    | S )z
    Convert the message parts from OpenAI format to the `gen_ai.request.messages` format
    using the OpenAI-specific transformer (LiteLLM uses OpenAI's message format).

    Deep copies messages to avoid mutating original kwargs.
    content)	copydeepcopy
isinstancedictr   listtupler	   append)messagesmessager#   transformeditemresults         r   _convert_message_partsr0   *   s     }}X&H -'4(++i(ge}-K -dD):4@F&&1CvN&&t,- "-GI- Or!   c                    t        j                         j                  t              }|y| j	                  dd      }	 t        j                  |      \  }}}}| j	                  dd      }|dk(  s|dk(  rd}nd	} t               |d	k(  rt        j                  j                  nt        j                  j                  | d
| t        j                        }|j                          |t        |       d<   t!        |t"        j$                  |       t!        |t"        j&                  |       t)               r|j*                  r|dk(  ri| j	                  d      }	|	rt        j,                         }
t/        |	t0              r|	n|	g}t3        |||
      }|}t!        |t"        j4                  |d       n_| j	                  dg       }|rKt        j,                         }
t7        |      }t9        |||
      }|t!        |t"        j:                  |d       t"        j<                  t"        j>                  t"        j@                  t"        jB                  t"        jD                  t"        jF                  t"        jH                  d}|jK                         D ]&  \  }}| j	                  |      }|t!        |||       ( y# t        $ r |}d}Y kw xY w)zHandle the start of a request.Nmodel unknown	call_type	embedding
aembedding
embeddingschat )opnameorigin_sentry_spaninputF)unpackr+   )r2   stream
max_tokenspresence_penaltyfrequency_penaltytemperaturetop_p)&
sentry_sdk
get_clientget_integrationLiteLLMIntegrationr   litellmget_llm_provider	Exceptionr   r   OPGEN_AI_CHATGEN_AI_EMBEDDINGSr=   	__enter__r    r   r   GEN_AI_SYSTEMGEN_AI_OPERATION_NAMEr   include_promptsget_current_scoper&   r(   r
   GEN_AI_EMBEDDINGS_INPUTr0   r   GEN_AI_REQUEST_MESSAGESGEN_AI_REQUEST_MODELGEN_AI_RESPONSE_STREAMINGGEN_AI_REQUEST_MAX_TOKENSGEN_AI_REQUEST_PRESENCE_PENALTY GEN_AI_REQUEST_FREQUENCY_PENALTYGEN_AI_REQUEST_TEMPERATUREGEN_AI_REQUEST_TOP_Pitems)r   integration
full_modelr2   provider_r5   	operationspanembedding_inputscope
input_listmessages_datar+   paramskey	attributevalues                     r   _input_callbackrn   E   s   '')99:LMK GR(J ' 8 8 DxA
 

;-IK9#< 		 %"$ F" II!!,,{!E7#!((D 	NN 26v~. h44h?h<<iH  [%@%@$$jj1O"446 "/48 $)* 
 !Ge! !,' 88%$	 zz*b1H"4461(; >xu U ,' 88%$	 ..4488$DD%FF::..F !,,. 8Y

3i78[  s   J3 3KKc                     K   t        |       S wN)rn   )r   s    r   _async_input_callbackrq      s     6""s   
start_timer   end_timec           
         t        |       }|j                  d      }|yt        j                         j	                  t
              }|y	 t        |d      r%t        |t        j                  |j                         t               ry|j                  rlt        |d      r_g }|j                  D ]0  }t        |d      st        |j                  d      r*|j                  |j                  j!                                Qt        |j                  d      r*|j                  |j                  j#                                i }	t        |j                  d      r|j                  j$                  |	d<   t        |j                  d	      r|j                  j&                  |	d	<   t        |j                  d
      r|j                  j(                  |	d
<   |j                  |	       3 |rt        |t        j*                  |       t        |d      r<|j,                  }
t/        |t1        |
dd      t1        |
dd      t1        |
dd             | j                  d      }|dusd| v sd| v r)|j3                  dd      }||j5                  ddd       yyy# | j                  d      }|dusd| v sd| v r)|j3                  dd      }||j5                  ddd       w w w xY w)zHandle successful completion.r>   Nr2   choicesr,   
model_dumpr'   roler#   
tool_callsusageprompt_tokenscompletion_tokenstotal_tokens)input_tokensoutput_tokensr|   rA   Tcomplete_streaming_response!async_complete_streaming_response)r    r   rG   rH   rI   rJ   hasattrr   r   GEN_AI_RESPONSE_MODELr2   r   rT   ru   r,   r*   rv   r'   rw   r#   rx   GEN_AI_RESPONSE_TEXTry   r   getattrpop__exit__)r   completion_responserr   rs   r   re   r`   response_messageschoicemsgry   is_streamings               r   _success_callbackr      s    "&)H<<'D|'')99:LMK60&0h446I6O6O
 #$)D)D*I6$&!199 :Fvy1"6>><@-44V^^5N5N5PQ$V^^V<-44V^^5H5H5JK #%C&v~~v>.4nn.A.AF&v~~yA171G1GI&v~~|D4:NN4M4ML 1-44S9:" %'h;;=N
 &0'--E$UOTB%e-@$G$UNDA	 zz(+ $,62f<<<5DdD$/   = zz(+ $,62f<<<5DdD$/   =s   A4J  FJ AKc                 &   K   t        | |||      S wrp   )r   )r   r   rr   rs   s       r   _async_success_callbackr      s!      	 s   	exceptionc                 H   t        |       j                  d      }|y	 t        |t        j                         j
                  ddd      \  }}t        j                  ||       |j                  t        |      |d       y# |j                  t        |      |d       w xY w)zHandle request failure.r>   NrK   F)typehandled)client_options	mechanism)hint)	r    r   r   rG   rH   optionscapture_eventr   r   )r   r   rr   rs   re   eventr   s          r   _failure_callbackr      s     f%)).9D|
8*%002::(U;
t
 	  T2 	d9oy$7d9oy$7s   AB B!c                   F    e Zd ZdZdZde Zd
dd deddfdZedd	       Z	y)rJ   a"  
    LiteLLM integration for Sentry.

    This integration automatically captures LiteLLM API calls and sends them to Sentry
    for monitoring and error tracking. It supports all 100+ LLM providers that LiteLLM
    supports, including OpenAI, Anthropic, Google, Cohere, and many others.

    Features:
    - Automatic exception capture for all LiteLLM calls
    - Token usage tracking across all providers
    - Provider detection and attribution
    - Input/output message capture (configurable)
    - Streaming response support
    - Cost tracking integration

    Usage:

    ```python
    import litellm
    import sentry_sdk

    # Initialize Sentry with the LiteLLM integration
    sentry_sdk.init(
        dsn="your-dsn",
        send_default_pii=True
        integrations=[
            sentry_sdk.integrations.LiteLLMIntegration(
                include_prompts=True  # Set to False to exclude message content
            )
        ]
    )

    # All LiteLLM calls will now be monitored
    response = litellm.completion(
        model="gpt-3.5-turbo",
        messages=[{"role": "user", "content": "Hello!"}]
    )
    ```

    Configuration:
    - include_prompts (bool): Whether to include prompts and responses in spans.
      Defaults to True. Set to False to exclude potentially sensitive data.
    rK   zauto.ai.selfrT   r   Nc                     || _         y rp   )rT   )r   rT   s     r   __init__zLiteLLMIntegration.__init__G  s
    .r!   c                     t         xs g t        _         t        t        j                   vr#t        j                   j                  t               t        t        j                   vr#t        j                   j                  t               t
        xs g t        _        t        t        j
                  vr#t        j
                  j                  t               t        t        j
                  vr#t        j
                  j                  t               t        xs g t        _        t        t        j                  vr$t        j                  j                  t               yy)z(Set up LiteLLM callbacks for monitoring.N)
r   rK   rn   r*   rq   r   r   r   r   r    r!   r   
setup_oncezLiteLLMIntegration.setup_onceJ  s     "0!52'"8"88""))/: (>(>>""))*?@#3#9r G$<$<<$$++,=>"'*B*BB$$++,CD#3#9r G$<$<<$$++,=> =r!   )T)r   N)
__name__
__module____qualname____doc__
identifierr=   boolr   staticmethodr   r   r!   r   rJ   rJ     sJ    *X J
|$F/+ /d /d / ? ?r!   rJ   )r   r   r   r   )r+   List[Dict[str, Any]]r   r   )r   r   r   N)
r   r   r   r   rr   r   rs   r   r   N)(r$   typingr   rG   r   sentry_sdk.ai.monitoringr   sentry_sdk.ai.utilsr   r   r   r	   r
   sentry_sdk.constsr   sentry_sdk.integrationsr   r   sentry_sdk.scoper   sentry_sdk.utilsr   r   r   r   r   rK   r   r   r   ImportErrorr    r0   rn   rq   r   r   rM   r   rJ   r   r!   r   <module>r      s(        7  ' = 4 1&&!0JJ
	6[8|#G0G0G0 G0 	G0
 
G0T  	
 
888 8 	8
 
80D? D?{  0
.
//0s   B* *B8