o
    S۷i-                  
   @   sN  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rTd d
lmZmZmZ d dlmZ zd dlZd dlmZmZmZ W n eyo   edw d%ddZd&ddZ d'ddZ!										d(ddZ"ddd e#ddddddf
d!d"Z$G d#d$ d$eZ%dS ))    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                 C   s.   |  di }|d}|du ri }||d< |S )z,Get the metadata dictionary from the kwargs.litellm_paramsmetadataN)
setdefaultget)r   r   r    r   U/home/ubuntu/vllm_env/lib/python3.10/site-packages/sentry_sdk/integrations/litellm.py_get_metadata_dict   s   
r   messagesList[Dict[str, Any]]c                 C   s   t | } | D ]9}t|tsq|d}t|ttfr@g }|D ]}t|tr6t|}||dur2|n| q|| q||d< q| 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.
    contentN)	copydeepcopy
isinstancedictr   listtupler   append)r    messager"   transformeditemresultr   r   r   _convert_message_parts*   s   



r.   c                 C   s$  t  t}|du rdS | dd}zt|\}}}}W n ty+   |}d}Y nw | dd}|dkr9d}nd}t |dkrEt	j
jnt	j
j| d	| tjd
}|  |t| d< t|tj| t|tj| t r|jr|dkr| d}	|	rt  }
t|	tr|	n|	g}t|||
}|durt|tj|dd n#| dg }|rt  }
t|}t|||
}|durt|tj|dd tjtjtj tj!tj"tj#tj$d}|% D ]\}}| |}|durt||| q| d| d| dd}|% D ]\}}|durt|d| | qdS )zHandle the start of a request.Nmodel unknown	call_type	embedding
embeddingschat )opnameorigin_sentry_spaninputF)unpackr    )r/   stream
max_tokenspresence_penaltyfrequency_penaltytemperaturetop_papi_baseapi_versioncustom_llm_provider)rC   rD   rE   zgen_ai.litellm.)&
sentry_sdk
get_clientget_integrationLiteLLMIntegrationr   litellmget_llm_provider	Exceptionr   r   OPGEN_AI_CHATGEN_AI_EMBEDDINGSr9   	__enter__r   r   r
   GEN_AI_SYSTEMGEN_AI_OPERATION_NAMEr   include_promptsget_current_scoper%   r'   r	   GEN_AI_EMBEDDINGS_INPUTr.   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_modelr/   provider_r2   	operationspanembedding_inputscope
input_listmessages_datar    paramskey	attributevaluer   r   r   r   _input_callbackE   s   	
		

rm   completion_responser   
start_timer   end_timec           
      C   s  t | d}|du rdS t t}|du rdS zt|dr(t|tj	|j
 t r|jrt|drg }|jD ]P}t|drt|jdrN||j  q8t|jdr]||j  q8i }t|jdrk|jj|d< t|jd	rw|jj|d	< t|jd
r|jj|d
< || q8|rt|tj| t|dr|j}	t|t|	ddt|	ddt|	ddd W |ddd dS W |ddd dS |ddd w )zHandle successful completion.r:   Nr/   choicesr*   
model_dumpr&   roler"   
tool_callsusageprompt_tokenscompletion_tokenstotal_tokens)input_tokensoutput_tokensrx   )r   r   rF   rG   rH   rI   hasattrr   r
   GEN_AI_RESPONSE_MODELr/   r   rS   rq   r*   r)   rr   r&   rs   r"   rt   GEN_AI_RESPONSE_TEXTru   r   getattr__exit__)
r   rn   ro   rp   rd   r_   response_messageschoicemsgru   r   r   r   _success_callback   sX   









	"r   	exceptionc                 C   st   t | d}|du rdS z"t|t jdddd\}}tj||d W |t||d dS |t||d w )zHandle request failure.r:   NrJ   F)typehandled)client_options	mechanism)hint)	r   r   r   rF   rG   optionscapture_eventr   r   )r   r   ro   rp   rd   eventr   r   r   r   _failure_callback   s   
*r   c                   @   sD   e Zd ZdZdZde Zddd deddfd	d
ZedddZ	dS )rI   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.
    rJ   zauto.ai.TselfrS   r   Nc                 C   s
   || _ d S )N)rS   )r   rS   r   r   r   __init__5  s   
zLiteLLMIntegration.__init__c                   C   sh   t pg t_ ttj vrtj t tpg t_ttjvr tjt tp#g t_ttjvr2tjt dS dS )z(Set up LiteLLM callbacks for monitoring.N)r   rJ   rm   r)   r   r   r   r   r   r   r   r   
setup_once8  s   





zLiteLLMIntegration.setup_once)T)r   N)
__name__
__module____qualname____doc__
identifierr9   boolr   staticmethodr   r   r   r   r   rI     s    ,
rI   )r   r   r   r   )r    r!   r   r!   )r   r   r   N)
r   r   rn   r   ro   r   rp   r   r   N)&r#   typingr   rF   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   rJ   r   r   r   ImportErrorr   r.   rm   r   rL   r   rI   r   r   r   r   <module>   sZ    


h
@
