o
    iJ                     @   s  d dl Z d dlm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 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# 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/Z0G d%d& d&e#Z1dS )'    N)Any)Optional)Union)core)
get_logger)get_argument_value)format_trace_id)AGENT_MANIFEST) DISPATCH_ON_GUARDRAIL_SPAN_START)DISPATCH_ON_LLM_TOOL_CHOICE)$DISPATCH_ON_OPENAI_AGENT_SPAN_FINISH)DISPATCH_ON_TOOL_CALL)!DISPATCH_ON_TOOL_CALL_OUTPUT_USED)INPUT_MESSAGES)INPUT_VALUE)METADATA)METRICS)
MODEL_NAME)MODEL_PROVIDER)NAME)OAI_HANDOFF_TOOL_ARG)OUTPUT_MESSAGES)OUTPUT_VALUE)PARENT_ID_KEY)
SESSION_ID)	SPAN_KIND)BaseLLMIntegration)LLMObsTraceInfo)OaiSpanAdapter)OaiTraceAdapter)_get_nearest_llmobs_ancestor)_get_span_name)load_data_value)	safe_json)Spanc                       s  e Zd ZdZdeddf fddZ		d5d	ed
edef fddZ			d6dede
e deeeeeef f dee deddfddZdededdfddZdeddfddZdededdfddZdededdfddZdededdfdd Zdededdfd!d"Zdededdfd#d$Zd%eeef dee fd&d'Zd7d(d)Zdede
e deeef d*eddf
d+d,Zd-d. Zd/d0 Zd1d2 Zd3d4 Z   Z!S )8OpenAIAgentsIntegrationopenai_agentsintegration_configreturnNc                    s    t  | t | _i | _d S N)super__init__weakrefWeakValueDictionaryoai_to_llmobs_spanllmobs_traces)selfr'   	__class__ ^/home/ubuntu/.local/lib/python3.10/site-packages/ddtrace/llmobs/_integrations/openai_agents.pyr+   /   s   

z OpenAIAgentsIntegration.__init__ Foperation_idsubmit_to_llmobsc                    s   | d}| d}|r|jn|r|jnd}t j|p|||d}|r=|| j|j< tt|jt	|jd| j
t	|j< |S |rW|| j|j< | || |jdkrWtt|f |S )N	oai_traceoai_spanzopenai_agents.request)r6   r7   	span_name)span_idtrace_id	guardrail)getnamer*   tracer.   r<   r   strr;   r   r/   _llmobs_update_trace_info_input	span_typer   dispatchr
   )r0   r6   r7   kwargsr8   r9   r:   llmobs_spanr1   r3   r4   r@   7   s*   


zOpenAIAgentsIntegration.tracespanargsrE   response	operationc                 C   s\  | d}|durt|tr| || dS | d}|sdS t|ts.tdt| dS |j}|j	}	|
t|	 |jr^| }
| }d|_	 |
rQ|d|
 |r^|
r^|dt| |dkro| || | | dS |d	v r{| || dS |d
kr| || dS |dkr| || ttd dS |dkr|j}|r|
t| dS dS dS )z@Sets meta tags and metrics for span events to be sent to LLMObs.r8   Nr9   z"Expected OaiSpanAdapter but got %s   z
error.typezerror.messagerI   )functiontoolhandoffagentr3   custom)r>   
isinstancer   _llmobs_set_trace_attributesr   loggerwarningtyperC   llmobs_span_kind_set_ctx_itemr   errorget_error_messageget_error_dataset_tagjsondumps_llmobs_set_response_attributes _llmobs_update_trace_info_output_llmobs_set_tool_attributes_llmobs_set_handoff_attributes_llmobs_set_agent_attributesr   rD   r   formatted_custom_datar   )r0   rG   rH   rE   rI   rJ   r8   r9   rC   	span_kind	error_msg
error_datacustom_datar3   r3   r4   _llmobs_set_tagsV   sL   
	

z(OpenAIAgentsIntegration._llmobs_set_tagsr9   rF   c                 C   sn   |  |}|s	dS |jdkr|t|jkrt|j|_|jdkr1|js3|t|jkr5||_dS dS dS dS )a  
        Store the openai span we are using as the input to the top level trace. Since the openai trace
        itself does not have input / output data, we use the input to the first LLM call of the first
        agent invocation as the top level trace input.
        NrO   rI   )_llmobs_get_trace_inforC   _get_ctx_itemr   r;   rA   current_top_level_agent_span_idinput_oai_span)r0   r9   rF   
trace_infor3   r3   r4   rB      s   


z7OpenAIAgentsIntegration._llmobs_update_trace_info_inputc                 C   sR   |  |}|s	dS | j|j}|sdS |j}|r%|t|kr'||_dS dS dS )a  
        Store the openai span we are using as the output to the top level trace. Since the openai trace
        itself does not have input / output data, we use the output of the last LLM call of the last
        agent invocation as the top level trace output.
        N)ri   r.   r>   r;   rk   rj   r   output_oai_span)r0   r9   rm   rF   rk   r3   r3   r4   r_      s   

z8OpenAIAgentsIntegration._llmobs_update_trace_info_outputr8   c                 C   s   |  |}|s	d S |j}|r|t| |td |jr*|j }|r*|t| |jr9|jj	}|r9|t
| |j}|rF|t| d S d S )Nworkflow)ri   group_idrW   r   r   rl   llmobs_trace_inputr   rn   response_output_textr   metadatar   )r0   rG   r8   rm   rp   input_valueoutput_valuers   r3   r3   r4   rR      s&   

z4OpenAIAgentsIntegration._llmobs_set_trace_attributesc                 C   sH  |j sdS t|}| |}|r$|r$|t|jkr$|tt|d  |j	r4|t
|j	 |td |jrP| \}}|D ]
}tt||f q?|t| |j r|j jr| \}}}	|D ]#}
tt|
dd|
ddt|
di t|jt|jdf q`|t| |j}|r|t| |j}|r|t| dS dS )	z(Sets attributes for response type spans.Nz (LLM)openaitool_idr5   r?   	arguments)r<   r;   ) rI   r    ri   rj   r   rk   rW   r   r!   llmobs_model_namer   r   inputllmobs_input_messagesr   rD   r   r   outputllmobs_output_messagesr   r>   r#   r   r<   rA   r;   r   llmobs_metadatar   llmobs_metricsr   )r0   rG   r9   parentrm   messagestool_call_idstool_call_idtool_call_outputs_tool_call_outputrs   metricsr3   r3   r4   r^      sF   


z7OpenAIAgentsIntegration._llmobs_set_response_attributesc                 C   s@   | t|jpd | t|jpd tt|j|jd|f d S )Nr5   rL   )	rW   r   rz   r   r|   r   rD   r   r?   r0   rG   r9   r3   r3   r4   r`      s   z3OpenAIAgentsIntegration._llmobs_set_tool_attributesc                 C   s^   d d|jd }||_|d|jpd |d|jp!d t	t
|td|f d S )Nztransfer_to_{}r    rt   r5   ru   rN   )formatjointo_agentsplitlowerr?   rW   
from_agentr   rD   r   r   )r0   rG   r9   handoff_tool_namer3   r3   r4   ra     s   
z6OpenAIAgentsIntegration._llmobs_set_handoff_attributesc                 C   s   |j r|t|j  d S d S r)   )r~   rW   r   r   r3   r3   r4   rb     s   z4OpenAIAgentsIntegration._llmobs_set_agent_attributesoai_trace_or_spanc                 C   sR   d}t |tr|j}nt |tr|j}ndS | j|}|s dS | jt|jS )zGet trace info for a span

        Args:
            oai_trace_or_span: An openai span or trace adapter to get trace info for.

        Returns:
            The trace info if found, None otherwise.
        N)	rQ   r   r;   r   r<   r.   r>   r/   r   )r0   r   keyrF   r3   r3   r4   ri     s   

z.OpenAIAgentsIntegration._llmobs_get_trace_infoc                 C   s   | j   | j  d S r)   )r.   clearr/   )r0   r3   r3   r4   clear_state.  s   
z#OpenAIAgentsIntegration.clear_stateagent_indexc                 C   s   t |||dd}|r| jsd S i }d|d< t|dr|j|d< t|dr)|j|d< t|dr3|j|d< t|drJ|j}t|trB|nt	|dd	|d< | 
|}|rU||d
< | |}	|	r`|	|d< | |}
|
rk|
|d< | |}|rv||d< |t| d S )NrO   TOpenAI	frameworkr?   instructionshandoff_descriptionmodelr5   model_settingstoolshandoffs
guardrails)r   llmobs_enabledhasattrr?   r   r   r   rQ   rA   getattr"_extract_model_settings_from_agent_extract_tools_from_agent_extract_handoffs_from_agent_extract_guardrails_from_agentrW   r	   )r0   rG   rH   rE   r   rO   manifestr   r   r   r   r   r3   r3   r4   tag_agent_manifest2  s6   











z*OpenAIAgentsIntegration.tag_agent_manifestc                 C   s4   t |dsd S |j}t|tkrt|dd }t|S )Nr   __dict__)r   r   rU   dictr   r"   )r0   rO   r   r3   r3   r4   r   U  s   
z:OpenAIAgentsIntegration._extract_model_settings_from_agentc                 C   sp  t |dr|js
d S g }|jD ]%}i }t|dd }|r ||d< |dkr9t |dr.|j|d< t |dr8|j|d< n|dkrpt |drG|j|d< t |drQ|j|d< t |d	r[|j|d	< t |d
re|j|d
< t |dro|j	|d< n|dkrt |dr~|j
|d< t |dr|j|d< n|dkrt |dr|j|d< n|dkrt |dr|j|d< t |dr|j|d< n|dkrt |dr|j|d< np|dkrt |dr|j|d< nat |dr|j|d< t |dr|j|d< t |dr0|j}dd |dg D }i }|di  D ]*\}	}
i }d|
v r|
d |d< d|
v r|
d |d< |	|v r&d|d< |||	< q||d < || q|S )!Nr   r?   web_search_previewuser_locationsearch_context_sizefile_searchvector_store_idsmax_num_resultsinclude_search_resultsranking_optionsfilterscomputer_use_previewcomputeron_safety_checkcode_interpretertool_config
hosted_mcpon_approval_requestimage_generationlocal_shellexecutordescriptionstrict_json_schemaparams_json_schemac                 S   s   i | ]}|d qS )Tr3   ).0paramr3   r3   r4   
<dictcomp>  s    zEOpenAIAgentsIntegration._extract_tools_from_agent.<locals>.<dictcomp>required
propertiesrU   titleT
parameters)r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r>   itemsappend)r0   rO   r   rM   	tool_dict	tool_nameparameter_schemarequired_paramsr   r   schema
param_dictr3   r3   r4   r   `  s   


































z1OpenAIAgentsIntegration._extract_tools_from_agentc                 C   s   t |dr|js
d S g }|jD ]E}i }t |dst |dr+t|dd p(t|dd |d< t |ds5t |drCt|dd p@t|dd |d< t |drM|j|d< |rT|| q|S )Nr   r   tool_descriptionr?   
agent_namer   )r   r   r   r   r   )r0   rO   r   rN   handoff_dictr3   r3   r4   r     s"   



z4OpenAIAgentsIntegration._extract_handoffs_from_agentc                 C   sH   g }t |dr|dd |jD  t |dr"|dd |jD  |S )Ninput_guardrailsc                 S      g | ]}t |d dqS r?   r5   r   r   r=   r3   r3   r4   
<listcomp>      zJOpenAIAgentsIntegration._extract_guardrails_from_agent.<locals>.<listcomp>output_guardrailsc                 S   r   r   r   r   r3   r3   r4   r     r   )r   extendr   r   )r0   rO   r   r3   r3   r4   r     s   

z6OpenAIAgentsIntegration._extract_guardrails_from_agent)r5   F)Nr5   )r(   N)"__name__
__module____qualname___integration_namer   r+   rA   boolr$   r@   listr   r   r   r   r   rh   rB   r_   rR   r^   r`   ra   rb   r   ri   r   intr   r   r   r   r   __classcell__r3   r3   r1   r4   r%   ,   sZ    
$
81



*#Dr%   )2r\   typingr   r   r   r,   ddtrace.internalr   ddtrace.internal.loggerr   ddtrace.internal.utilsr   ddtrace.internal.utils.formatsr   ddtrace.llmobs._constantsr	   r
   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   !ddtrace.llmobs._integrations.baser   "ddtrace.llmobs._integrations.utilsr   r   r   ddtrace.llmobs._utilsr    r!   r"   r#   ddtrace.tracer$   r   rS   r%   r3   r3   r3   r4   <module>   sN    