o
    ik                     @   s  d dl Z d dlm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
 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 d dlmZ d dlmZ d dlmZ eeZdefddZdeeef fddZ e!di  dedee fddZ"dOdede#edf f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/d0 Z-d1d2 Z.d3d4 Z/d5d6 Z0d7d8 Z1d9d: Z2d;d< Z3d=d> Z4d?d@ Z5dAdB Z6dCdD Z7dPdFe8fdGdHZ9dPdFe8fdIdJZ:dKdL Z;dMdN Z<dS )Q    N)Any)Optional)config)shared_stream)unwrap)wrap)core)
is_wrapted)
get_logger)ArgumentError)get_argument_value)LangChainIntegration)	safe_json)Spanreturnc                   C   s   t tddS )N__version__ )getattrlangchain_core r   r   \/home/ubuntu/.local/lib/python3.10/site-packages/ddtrace/contrib/internal/langchain/patch.pyget_version   s   r   c                   C   s   ddiS )Nr   z>=0.1r   r   r   r   r   _supported_versions   s   r   	langchaininstancec                 C   s&   dD ]}t | |rt| |  S qdS )z+Extract model name or ID from llm instance.)model
model_namemodel_id	model_keyrepo_idN)hasattrr   )r   attrr   r   r   _extract_model_name#   s
   
r"   r   event_idargs.c                 C   s@   t | |}t|dkr| D ]}t|jtr|jqd S d S )Nr   )r   dispatch_with_resultslenvalues
isinstancevalue	Exception)r#   r$   resulteventr   r   r   _raising_dispatch+   s   r-   c           
      C   s  |j }tj}t|}t||dd}|jd|j|jjf dd|||d}d }	|	|| |
|| z=ztd|f | |i |}	td||	f W n tyX   |jt    w W |j|d	< |j||||	dd
 |  |	S |j|d	< |j||||	dd
 |  w )Nr   prompts%s.%sTllmsubmit_to_llmobsinterface_typeproviderr   r   zlangchain.llm.generate.beforezlangchain.llm.generate.after_dd.identifying_paramsr$   kwargsresponse	operation)	_llm_typer   _datadog_integrationr"   r   trace
__module__	__class____name__record_instancellmobs_set_prompt_tagr-   r   dispatchr*   set_exc_infosysexc_info_identifying_paramsllmobs_set_tagsfinish)
funcr   r$   r7   llm_providerintegrationr   r.   spancompletionsr   r   r   traced_llm_generate4   s>   


rN   c           
         s  |j }t||dd}tj}t|}|jd|j|jjf dd|||d}|	|| |
|| d }	z@ztd|f | |i |I d H }	td||	f W n ty\   |jt    w W |j|d	< |j||||	dd
 |  |	S |j|d	< |j||||	dd
 |  w )Nr   r.   r/   Tr0   r1   zlangchain.llm.agenerate.beforezlangchain.llm.agenerate.afterr5   r6   )r:   r   r   r;   r"   r<   r=   r>   r?   r@   rA   r-   r   rB   r*   rC   rD   rE   rF   rG   rH   )
rI   r   r$   r7   rJ   r.   rK   r   rL   rM   r   r   r   traced_llm_agenerateT   s@   	


rO   c           	      C   s  |j dd }t||dd}tj}|jd|j|jjf dd|t	||d}|
|| ||| d }z=ztd|f | |i |}td	||f W n ty[   |jt    w W |j|d
< |j||||dd |  |S |j|d
< |j||||dd |  w )N-r   messagesr/   T
chat_modelr1   z#langchain.chatmodel.generate.beforez"langchain.chatmodel.generate.afterr5   chatr6   r:   splitr   r   r;   r<   r=   r>   r?   r"   r@   rA   r-   r   rB   r*   rC   rD   rE   rF   rG   rH   	rI   r   r$   r7   rJ   chat_messagesrK   rL   chat_completionsr   r   r   traced_chat_model_generatet   s<   	


rY   c           	         s  |j dd }t||dd}tj}|jd|j|jjf dd|t	||d}|
|| ||| d }z@ztd|f | |i |I d H }td	||f W n ty_   |jt    w W |j|d
< |j||||dd |  |S |j|d
< |j||||dd |  w )NrP   r   rQ   r/   TrR   r1   z$langchain.chatmodel.agenerate.beforez#langchain.chatmodel.agenerate.afterr5   rS   r6   rT   rV   r   r   r   traced_chat_model_agenerate   s>   	


rZ   c                 C   s   t j}|jd|j|jjdd|d}d}d}||| zLz+z	t||dd}W n t	y8   t||dd}Y nw t
|tsA|g}| |i |}W n tyX   |jt    w W |j|g ||dd	 |  |S |j|g ||dd	 |  w )
a  
    Traces the top level call of a LangChain Expression Language (LCEL) chain.

    LCEL is a new way of chaining in LangChain. It works by piping the output of one step of a chain into the next.
    This is similar in concept to the legacy LLMChain class, but instead relies internally on the idea of a
    RunnableSequence. It uses the operator `|` to create an implicit chain of `Runnable` steps.

    It works with a set of useful tools that distill legacy ways of creating chains,
    and various tasks and tooling within, making it preferable to LLMChain and related classes.

    This method captures the initial inputs to the chain, as well as the final outputs, and tags them appropriately.
    {}.{}Tchainr2   r3   r   Nr   inputinputsr6   r   r;   r<   formatr=   r>   r?   r@   r   r   r(   listr*   rC   rD   rE   rG   rH   rI   r   r$   r7   rK   rL   r_   final_outputr   r   r   traced_lcel_runnable_sequence   s:   

re   c                    s   t j}|jd|j|jjdd|d}d}d}||| zOz.z	t||dd}W n t	y9   t||dd}Y nw t
|tsB|g}| |i |I dH }W n ty\   |jt    w W |j|g ||dd	 |  |S |j|g ||dd	 |  w )
zS
    Similar to `traced_lcel_runnable_sequence`, but for async chaining calls.
    r[   Tr\   r]   Nr   r^   r_   r6   r`   rc   r   r   r   #traced_lcel_runnable_sequence_async   s<   

rf   c              
      sJ   t jdtffdd}dtf fdd}t|  d||dS )NrL   c                         |  d S Nr@   rL   r   rK   r   r   _on_span_started      z-traced_chain_stream.<locals>._on_span_startedc                    s~   j rj d nd }|r)tr)t|tjjr)|d }|jjdkr$t|}nt|}n
d	dd |D }j
|  |dd d S )NJsonOutputParserr   c                 S      g | ]}t |qS r   str.0chunkr   r   r   
<listcomp>      zBtraced_chain_stream.<locals>._on_span_finished.<locals>.<listcomp>r\   r6   )stepsr   r(   output_parsersro   r>   r?   r   rr   joinrG   )rL   streamed_chunksmaybe_parserr+   contentr$   r   rK   r7   r   r   _on_span_finished  s   


z.traced_chain_stream.<locals>._on_span_finishedr\   )rK   rI   r   r$   r7   r3   on_span_startedon_span_finished)r   r;   r   r   )rI   r   r$   r7   rl   r   r   r~   r   traced_chain_stream   s   r   c                    l   t jj}t}td f dtffdd}dtf fdd}t|  d||||d
S )	Nz!langchain.chatmodel.stream.beforerL   c                    rg   rh   ri   rj   rk   r   r   rl   ,  rm   z,traced_chat_stream.<locals>._on_span_startedc                    sR   j d< t|r|d }|dd  D ]}||7 }qng }j|  |dd d S )Nr5   r      rS   r6   )rF   r&   rG   )rL   r{   joined_chunksru   r~   r   r   r   /  s   

z-traced_chat_stream.<locals>._on_span_finishedrR   
rK   rI   r   r$   r7   r3   r   r   r4   r   r   r;   r:   r"   r-   r   r   )rI   r   r$   r7   rJ   r   rl   r   r   r~   r   traced_chat_stream%  s$   
r   c                    r   )	Nzlangchain.llm.stream.beforerL   c                    rg   rh   ri   rj   rk   r   r   _on_span_startU  rm   z)traced_llm_stream.<locals>._on_span_startc                    s6   d dd |D }jd< j|  |dd d S )Nr   c                 S   rp   r   rq   rs   r   r   r   rv   Y  rw   z@traced_llm_stream.<locals>._on_span_finished.<locals>.<listcomp>r5   r0   r6   )rz   rF   rG   )rL   r{   r}   r~   r   r   r   X  s   
z,traced_llm_stream.<locals>._on_span_finishedr0   r   r   )rI   r   r$   r7   rJ   r   r   r   r   r~   r   traced_llm_streamG  s0   	r   c                 C   s>  t j}t||dd}t||dddd}|jd| jj dd|d	}||| d }i }	z[z0d
D ]}
t||
d }||	|
< q.t|di }|rG||	d< t|dg }|rS||	d< | |i |}W n tyj   |j	t
    w W ||ppi |	psi d}|j|g ||dd |  |S ||pi |	pi d}|j|g ||dd |  w Nr   r^   r   r   T)optionalz%stool)r3   r2   r   )namedescriptionmetadatatags)r^   r   infor6   r   r;   r   r<   __self__r   r@   r   r*   rC   rD   rE   rG   rH   rI   r   r$   r7   rK   
tool_inputr   rL   tool_output	tool_info	attributer)   r   r   tool_inputsr   r   r   traced_base_tool_invokek  sF   


r   c                    sF  t j}t||dd}t||dddd}|jd| jj dd|d	}||| d }i }	z^z3d
D ]}
t||
d }||	|
< q/t|di }|rH||	d< t|dg }|rT||	d< | |i |I d H }W n tyn   |j	t
    w W ||pti |	pwi d}|j|g ||dd |  |S ||pi |	pi d}|j|g ||dd |  w r   r   r   r   r   r   traced_base_tool_ainvoke  sH   


r   c                 C   s@   t j}|jdu r| |i |S | |i |}||||| |S )zy
    No actual tracing happens here--we just need to move the prompt template to somewhere it can be accessed later.
    Fr   r;   llmobs_enabledhandle_prompt_template_invokerI   r   r$   r7   rK   promptr   r   r   #patched_base_prompt_template_invoke  s   
r   c                    sN   t j}|jdu r| |i |I dH S | |i |I dH }||||| |S )zD
    async version of above patched_base_prompt_template_invoke
    FNr   r   r   r   r   $patched_base_prompt_template_ainvoke  s   
r   c                 C   s>   t j}|jdu r| |i |S |||| | |i |}|S )a  
    Wrapper for BaseLLM.invoke() and BaseChatModel.invoke() methods to handle prompt template metadata transfer.

    BaseLLM.invoke() wraps BaseLLM.generate(), converting .invoke()'s input (often a PromptValue
    with templating information) into a string.
    While most tagging happens in the .generate() wrapper, we need to enter here to capture
    that templating information before it is consumed.
    Since child spans may need to read the tagged data, we must tag before calling the wrapped function.
    Fr   r;   r   handle_llm_invokerI   r   r$   r7   rK   r8   r   r   r   patched_language_model_invoke  s   

r   c                    sL   t j}|jdu r| |i |I dH S |||| | |i |I dH }|S )z>
    async version of above patched_language_model_invoke
    FNr   r   r   r   r   patched_language_model_ainvoke  s   
r   c                 C   s   |j jdd  }|dkr| jdkr| |i |S tj}|jd|j|j jf dd|t||d}|	|| d }z*z	| |i |}W n t
yS   |jt    w W |j||||dd	 |  |S |j||||dd	 |  w )
N
Embeddingsr   openaiembed_queryr/   T	embeddingr1   r6   )r>   r?   rU   lowerr   r;   r<   r=   r"   r@   r*   rC   rD   rE   rG   rH   )rI   r   r$   r7   r4   rK   rL   
embeddingsr   r   r   traced_embedding  s4   	
r   c                 C   s   t j}|jj }|jd|j|jjf dd||d}||| g }z*z	| |i |}W n ty;   |j	t
    w W |j||||dd |  |S |j||||dd |  w )Nr/   Tsimilarity_search)r2   r3   r4   r   	retrievalr6   )r   r;   r>   r?   r   r<   r=   r@   r*   rC   rD   rE   rG   rH   )rI   r   r$   r7   rK   r4   rL   	documentsr   r   r   traced_similarity_search  s.   
r   c                 C   s   | |i | | j }z-t|dd }|rt|st|dt t|dd }|r2t|s5t|dt W d S W d S W d S  tyI   tdt| Y d S w )Nembed_documentsr   z-Unable to patch LangChain Embeddings class %s)	r   r   r	   r   r   r*   logwarningrr   )rI   r   r$   r7   clsr   r   r   r   r    patched_embeddings_init_subclass)  s   r   c                 C   sp   | |i | | j }zt|dd }|r t|s#t|dt W d S W d S W d S  ty7   tdt| Y d S w )Nr   z.Unable to patch LangChain VectorStore class %s)	r   r   r	   r   r   r*   r   r   rr   )rI   r   r$   r7   r   methodr   r   r   !patched_vectorstore_init_subclass9  s   r   Fis_batchc                        fdd}|S )Nc           
         s   t j}t|dd }|jj d| j } r|r| dn|}n|p"|}|j|d|d}||| d }	z)z| |i |}	|	W W |j||||	dd |  S  t	y\   |j
t    w |j||||	dd |  w Nr   ._batchT)r2   r   runnable_lambdar6   r   r;   r   r>   r?   r<   r@   rG   rH   r*   rC   rD   rE   
rI   r   r$   r7   rK   instance_namedefault_name	span_namerL   r+   r   r   r   _traced_runnable_lambda_implF  s0   

zFtraced_runnable_lambda_operation.<locals>._traced_runnable_lambda_implr   r   r   r   r   r    traced_runnable_lambda_operationE     r   c                    r   )Nc           
         s   t j}t|dd }|jj d| j } r |r| dn|}n|p#|}|j|d|d}||| d }	z,z| |i |I d H }	|	W W |j||||	dd |  S  t	y`   |j
t    w |j||||	dd |  w r   r   r   r   r   r   r   h  s2   

zLtraced_runnable_lambda_operation_async.<locals>._traced_runnable_lambda_implr   r   r   r   r   &traced_runnable_lambda_operation_asyncg  r   r   c            	      C   s  t tddrd S dt_ttjd} | t_ddlm} ddl	m
} ddlm} dd	lm} dd
lm} ddlm} ddlm} ddlm} t|dt t|dt t|dt t|dt t|dt t|dt t|dt t|dt t|dt t|dt t|dt t|dt t|dt t|dt  t|dt t|dt  t|dt! t|dt! t|dt"dd t|dt#dd t|dt"dd t|dt#dd t|dt$ t|dt% t|dt& t|dt' t|dt( t|dt) t*+dt,  d S )N_datadog_patchFT)integration_configr   )r   )BaseChatModel)BaseLLM)BasePromptTemplate)RunnableLambda)RunnableSequence)BaseTool)VectorStoregenerate	agenerateinvokeainvokestreamastreambatchabatchr   __init_subclass__zlangchain.patch)-r   r   r   r   r   r   r;   langchain_core.embeddingsr   *langchain_core.language_models.chat_modelsr   #langchain_core.language_models.llmsr   langchain_core.prompts.baser   langchain_core.runnables.baser   r   langchain_core.toolsr   langchain_core.vectorstoresr   r   rN   rO   r   r   r   rY   rZ   r   re   rf   r   r   r   r   r   r   r   r   r   r   rB   tuple)	rK   r   r   r   r   r   r   r   r   r   r   r   patch  sT   r   c                   C   s  t tddsd S dt_ttjjjd ttjjjd ttjjjd ttjjjd ttjjjd ttjjjd ttjjjd ttjjjd ttj	j
jd ttj	j
jd ttj	j
jd ttj	j
jd ttj	j
jd	 ttj	j
jd
 ttj	j
jd ttj	j
jd ttj	j
jd ttj	j
jd ttjjjd	 ttjjjd
 ttjjjd	 ttjjjd
 ttjjd ttjjd ttjj
jd ttjj
jd ttjjd ttjjd tdt  d S )Nr   Fr   r   r   r   r   r   r   r   r   zlangchain.unpatch)r   r   r   r   language_modelsllmsr   chat_modelsr   	runnablesbaser   r   toolsr   r.   r   r   r   vectorstoresr   r   rB   r   r   r   r   r   unpatch  s@   r   )r   )F)=rD   typingr   r   r   ddtracer   (ddtrace.contrib.internal.langchain.utilsr   $ddtrace.contrib.internal.trace_utilsr   r   ddtrace.internalr   ddtrace.internal.compatr	   ddtrace.internal.loggerr
   ddtrace.internal.utilsr   r   ddtrace.llmobs._integrationsr   ddtrace.llmobs._utilsr   ddtrace.tracer   r?   r   rr   r   dictr   _addr"   r   r-   rN   rO   rY   rZ   re   rf   r   r   r   r   r   r   r   r   r   r   r   r   r   boolr   r   r   r   r   r   r   r   <module>   sZ    	  *!("$''""7