o
    witJ                  
   @   s  d dl Z d dlmZ d dlmZ d dlZd dl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 d d	lmZmZ d d
lmZmZ d dlmZ erdd dlmZmZmZmZmZmZ d dl m!Z! z"d dl"m#Z# d dl$m%Z% d dl&m'Z'm(Z(m)Z)m*Z* d dl+m,Z,m-Z- W n e.y   edw ej/ej0ej1ej2ej3ej4ej5ej6ej7d	Z8g dZ9G dd deZ:G dd dZ;G dd de(Z<dd Z=dS )    N)OrderedDictwraps)set_ai_pipeline_namerecord_token_usage)OPSPANDATA)set_data_normalized)should_send_default_pii)Span)DidNotEnableIntegration)loggercapture_internal_exceptions)TYPE_CHECKING)AnyListCallableDictUnionOptional)UUID)BaseMessage)	LLMResult)managerBaseCallbackHandlerBaseCallbackManager	Callbacks)AgentActionAgentFinishzlangchain not installed)	temperaturetop_ptop_kfunction_call
tool_callstoolsresponse_format
logit_biastags)zopenai-chatzanthropic-chatzcohere-chathuggingface_endpointc                   @   s6   e Zd ZdZde ZdZ	d
ddZedd	 ZdS )LangchainIntegration	langchainzauto.ai.   TNc                 C   s   || _ || _|| _d S N)include_prompts	max_spanstiktoken_encoding_name)selfr.   r/   r0    r2   ^/home/ubuntu/sommelier/.venv/lib/python3.10/site-packages/sentry_sdk/integrations/langchain.py__init__?   s   
zLangchainIntegration.__init__c                   C   s   t tjt_d S r-   )_wrap_configurer   
_configurer2   r2   r2   r3   
setup_onceG      zLangchainIntegration.setup_once)Tr,   N)	__name__
__module____qualname__
identifieroriginr/   r4   staticmethodr7   r2   r2   r2   r3   r*   8   s    

r*   c                   @   s,   e Zd ZdZdZdZdZg ZdZdd Z	dS )WatchedSpanNr   Fc                 C   s
   || _ d S r-   )span)r1   r@   r2   r2   r3   r4   U   s   
zWatchedSpan.__init__)
r9   r:   r;   r@   num_completion_tokensnum_prompt_tokensno_collect_tokenschildrenis_pipeliner4   r2   r2   r2   r3   r?   M   s    r?   c                   @   s   e Zd ZdZd,ddZdd Zdd Zd	d
 Zdd Zdd Z	dd Z
ddddddZdd Zdd Zdd Zdd Zdd Zdd Zd d! Zd"d# Zd$d% Zd&d' Zd(d) Zd*d+ ZdS )-SentryLangchainCallbackzJBase callback handler that can be used to handle callbacks from langchain.Nc                 C   s>   t  | _|| _|| _d | _|d urdd l}||| _d S d S Nr   )r   span_mapmax_span_map_sizer.   tiktoken_encodingtiktokenget_encoding)r1   rI   r.   r0   rK   r2   r2   r3   r4   ]   s   z SentryLangchainCallback.__init__c                 C   s   | j d urt| j |S dS rG   )rJ   lenencode_ordinary)r1   sr2   r2   r3   count_tokensi   s   
z$SentryLangchainCallback.count_tokensc                 C   sF   t | j| jkr!| jjdd\}}| || t | j| jksd S d S )NF)last)rM   rH   rI   popitem
_exit_span)r1   run_idwatched_spanr2   r2   r3   gc_span_mapo   s   z#SentryLangchainCallback.gc_span_mapc                 C   sP   |r|| j vr	d S | j | }|sd S t||jj |jd d d  | j |= d S r-   )rH   
sentry_sdkcapture_exceptionr@   scope__exit__)r1   rT   error	span_datar2   r2   r3   _handle_errorv   s   
z%SentryLangchainCallback._handle_errorc                 C   s   |j |jd}||j |S )N)contentrole)r^   typeupdateadditional_kwargs)r1   messageparsedr2   r2   r3   _normalize_langchain_message   s   z4SentryLangchainCallback._normalize_langchain_messagec                 K   s   d }|r| j |}|rt|jjdi |}|j| |d u r+ttjdi |}|dd	drC|dr@t
|d d|_|j  || j |< |   |S )Nop zai.pipeline.nameTr2   )rH   getr?   r@   start_childrD   appendrW   
start_span
startswithr   rE   	__enter__rV   )r1   rT   	parent_idkwargsrU   parent_spanr2   r2   r3   _create_span   s    


z$SentryLangchainCallback._create_spanc                 C   s*   |j rtd  |jd d d  | j|= d S r-   )rE   r   r@   rZ   rH   )r1   r\   rT   r2   r2   r3   rS      s   z"SentryLangchainCallback._exit_span)r(   parent_run_idmetadatac                K   s   t  \ |s	 W d   dS |di }||di  | j||dtj|dp-dtjd}	|	j}
t	 rB| j
rBt|
tj| t D ]\}}||v rVt|
|||  qFW d   dS 1 sbw   Y  dS )zRun when LLM starts running.Ninvocation_paramsrp   rs   rh   zLangchain LLM callrf   rh   r=   )r   ri   ra   rr   r   LANGCHAIN_RUNr*   r=   r@   r
   r.   r	   r   AI_INPUT_MESSAGESDATA_FIELDSitems)r1   
serializedpromptsrT   r(   rs   rt   rp   
all_paramsrU   r@   kvr2   r2   r3   on_llm_start   s,   "z$SentryLangchainCallback.on_llm_startc             
      s  t   |s	 W d   dS |di   |di  j||dtj|dp-dtjd}|j} d d	 d
}t	 fddt
D |_|sYd dv rYd}|rb|tj| t rvjrvt|tjfdd|D  t D ]\}}	| v rt||	 |  qz|js|D ]#}
|
D ]}j|  j|j|j 7  _qqW d   dS W d   dS 1 sw   Y  dS )z#Run when Chat Model starts running.Nru   rp   rs   rh   zLangchain Chat Modelrv   model
model_namemodel_idc                 3   s     | ]}|  d dv V  qdS )_typerg   N)ri   .0x)r}   r2   r3   	<genexpr>   s    
z>SentryLangchainCallback.on_chat_model_start.<locals>.<genexpr>	anthropicr   zclaude-2c                    s   g | ]} fd d|D qS )c                    s   g | ]}  |qS r2   )re   r   r1   r2   r3   
<listcomp>   s    zJSentryLangchainCallback.on_chat_model_start.<locals>.<listcomp>.<listcomp>r2   r   list_r   r2   r3   r      s    z?SentryLangchainCallback.on_chat_model_start.<locals>.<listcomp>)r   ri   ra   rr   r   !LANGCHAIN_CHAT_COMPLETIONS_CREATEr*   r=   r@   anyNO_COLLECT_TOKEN_MODELSrC   set_datar   AI_MODEL_IDr
   r.   r	   rx   ry   rz   rH   rB   rP   r^   r`   )r1   r{   messagesrT   rp   rU   r@   r   r~   r   r   rc   r2   )r}   r1   r3   on_chat_model_start   sb   



%"z+SentryLangchainCallback.on_chat_model_startc                K   s   t  6 |r|| jvr	 W d   dS | j| }|r|jr'	 W d   dS | j| |7  _W d   dS 1 s<w   Y  dS )z?Run on new LLM token. Only available when streaming is enabled.N)r   rH   rC   rA   rP   )r1   tokenrT   rp   r\   r2   r2   r3   on_llm_new_token   s   

"z(SentryLangchainCallback.on_llm_new_tokenc                K   s   t  k |s	 W d   dS |jr|jdnd}| j| }|s*	 W d   dS t r>| jr>t|jtj	dd |j
D  |js`|rVt|j|d|d|dd n
t|j|j|jd	 | || W d   dS 1 sqw   Y  dS )
zRun when LLM ends running.Ntoken_usagec                 S   s   g | ]	}d d |D qS )c                 S   s   g | ]}|j qS r2   )textr   r2   r2   r3   r     s    zASentryLangchainCallback.on_llm_end.<locals>.<listcomp>.<listcomp>r2   r   r2   r2   r3   r     s    z6SentryLangchainCallback.on_llm_end.<locals>.<listcomp>prompt_tokenscompletion_tokenstotal_tokens)input_tokensoutput_tokensr   )r   r   )r   
llm_outputri   rH   r
   r.   r	   r@   r   AI_RESPONSESgenerationsrC   r   rB   rA   rS   )r1   responserT   rp   r   r\   r2   r2   r3   
on_llm_end   s>   
"z"SentryLangchainCallback.on_llm_endc                K   s8   t   | || W d   dS 1 sw   Y  dS )zRun when LLM errors.N)r   r]   r1   r[   rT   rp   r2   r2   r3   on_llm_error'  s   "z$SentryLangchainCallback.on_llm_errorc                K   s   t  I |s	 W d   dS | j||d|ddur tjntj|dp(dtjd}|d}|rDt|j	t
j| W d   dS W d   dS 1 sOw   Y  dS )zRun when chain starts running.Nrs   rh   zChain executionrv   rt   )r   rr   ri   r   rw   LANGCHAIN_PIPELINEr*   r=   r	   r@   r   AI_METADATA)r1   r{   inputsrT   rp   rU   rt   r2   r2   r3   on_chain_start-  s&   
"z&SentryLangchainCallback.on_chain_startc                K   sx   t  / |r|| jvr	 W d   dS | j| }|s$	 W d   dS | || W d   dS 1 s5w   Y  dS )zRun when chain ends running.N)r   rH   rS   )r1   outputsrT   rp   r\   r2   r2   r3   on_chain_endB  s   
"z$SentryLangchainCallback.on_chain_endc                K      |  || dS )zRun when chain errors.Nr]   r   r2   r2   r3   on_chain_errorN  r8   z&SentryLangchainCallback.on_chain_errorc                K   s   t  P |s	 W d    d S | j||dtj|jpdtjd}|jr;t	 rC| j
rKt|jtj|j W d    d S W d    d S W d    d S W d    d S 1 sVw   Y  d S )Nrs   AI tool usagerv   )r   rr   ri   r   LANGCHAIN_AGENTtoolr*   r=   
tool_inputr
   r.   r	   r@   r   rx   )r1   actionrT   rp   rU   r2   r2   r3   on_agent_actionS  s,   


"z'SentryLangchainCallback.on_agent_actionc                K   s   t  ; |s	 W d    d S | j| }|s	 W d    d S t r0| jr0t|jtj|j	  | 
|| W d    d S 1 sAw   Y  d S r-   )r   rH   r
   r.   r	   r@   r   r   return_valuesrz   rS   )r1   finishrT   rp   r\   r2   r2   r3   on_agent_finishd  s   
"z'SentryLangchainCallback.on_agent_finishc                K   s   t  h |s	 W d   dS | j||dtj|dp#|dp#dtjd}t rS| jr[t	|j
tj|d|g |drct	|j
tj|d W d   dS W d   dS W d   dS W d   dS 1 snw   Y  dS )zRun when tool starts running.Nrs   rh   r   rv   r   rt   )r   rr   ri   r   LANGCHAIN_TOOLr*   r=   r
   r.   r	   r@   r   rx   r   )r1   r{   	input_strrT   rp   rU   r2   r2   r3   on_tool_starts  s8   


"z%SentryLangchainCallback.on_tool_startc                K   s   t  = |r|| jvr	 W d   dS | j| }|s$	 W d   dS t r2| jr2t|jtj| | || W d   dS 1 sCw   Y  dS )zRun when tool ends running.N)	r   rH   r
   r.   r	   r@   r   r   rS   )r1   outputrT   rp   r\   r2   r2   r3   on_tool_end  s   
"z#SentryLangchainCallback.on_tool_endc                O   r   )zRun when tool errors.Nr   )r1   r[   rT   argsrp   r2   r2   r3   on_tool_error  r8   z%SentryLangchainCallback.on_tool_errorr-   )r9   r:   r;   __doc__r4   rP   rV   r]   re   rr   rS   r   r   r   r   r   r   r   r   r   r   r   r   r   r2   r2   r2   r3   rF   Z   s2    
 .'rF   c                    s   t  	 	 d fdd	}|S )Nc           	         sB  t  t}|d u r | ||g|R i |S |pg }t|tr%|j}n$t|tr.|g}nt|tr6|}nt	
d|  | ||g|R i |S t|trR|j}n
t|trZ|}ng }tdd t||D st|j|j|j}t|tr| }g |j||_nt|tr||g}ng ||} | ||g|R i |S )NzUnknown callback type: %sc                 s   s    | ]}t |tV  qd S r-   )
isinstancerF   )r   cbr2   r2   r3   r     s
    
z9_wrap_configure.<locals>.new_configure.<locals>.<genexpr>)rW   
get_clientget_integrationr*   r   r   handlersr   listr   debugr   	itertoolschainrF   r/   r.   r0   copy)	callback_manager_clsinheritable_callbackslocal_callbacksr   rp   integrationcallbacks_listinheritable_callbacks_listsentry_handlerfr2   r3   new_configure  sx   




	




z&_wrap_configure.<locals>.new_configure)NNr   )r   r   r2   r   r3   r5     s
   Nr5   )>r   collectionsr   	functoolsr   rW   sentry_sdk.ai.monitoringr   r   sentry_sdk.constsr   r   sentry_sdk.ai.utilsr	   sentry_sdk.scoper
   sentry_sdk.tracingr   sentry_sdk.integrationsr   r   sentry_sdk.utilsr   r   typingr   r   r   r   r   r   r   uuidr   langchain_core.messagesr   langchain_core.outputsr   langchain_core.callbacksr   r   r   r   langchain_core.agentsr   r   ImportErrorAI_TEMPERATUREAI_TOP_PAI_TOP_KAI_FUNCTION_CALLAI_TOOL_CALLSAI_TOOLSAI_RESPONSE_FORMATAI_LOGIT_BIASAI_TAGSry   r   r*   r?   rF   r5   r2   r2   r2   r3   <module>   sP       G