o
    i?I                     @   s  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+ d d!l,m-Z- d d"l.m/Z/ d d#l.m0Z0 d d$l1m2Z2 ee3Z4G d%d& d&eZ5d'S )(    )Any)	Generator)Optional)core)
get_logger)get_argument_value)LLMObs)"CACHE_READ_INPUT_TOKENS_METRIC_KEY)#CACHE_WRITE_INPUT_TOKENS_METRIC_KEY)INPUT_MESSAGES)INPUT_VALUE)INTEGRATION)METADATA)METRICS)
MODEL_NAME)MODEL_PROVIDER)OUTPUT_MESSAGES)OUTPUT_VALUE)PROXY_REQUEST)	SPAN_KIND)TAGS)TOOL_DEFINITIONS)BaseLLMIntegration))_create_or_update_bedrock_trace_step_span)_extract_trace_step_id)translate_bedrock_trace)normalize_input_tokens))get_final_message_converse_stream_message)"get_messages_from_converse_content)(update_proxy_workflow_input_output_value)'record_bedrock_agent_span_event_created)	_get_attr)LLMObsSpanEvent)Message)ToolDefinition)Spanc                   @   s  e Zd ZU dZi Zeeef ed< i Z	eeef ed< 		d%de
dee deeef d	ee d
eddfddZdd Zd&ddZedeeeef  dee fddZed	eeef fddZededeeef eee eeef eeef f f fddZedee fddZedee fddZdeeef dee fddZdejddfd d!Zd"eeef dee fd#d$Z dS )'BedrockIntegrationbedrock_spans_active_span_by_step_idN spanargskwargsresponse	operationreturnc                 C   sx  |dkr|  ||||S i }i }|d }|trdnd}	|dp#i }
|dr/|d |d< |dr8|d }t| d	|vrVd
|v sHd|v rV|d
d|dd |d	< d|
v rl|
ddkrlt|
dphd|d< d|
v r|
ddkrt|
dp~d|d< |
dd}|
di }| |}|r|t	| |d dv }|r| 
|n| |}tddg}|js|dur|d dkr| |}nD|d dkr	 z&z|d W n ty } z|j\}}}W Y d}~nd}~ww W |  n|  w || || n| |}|t|	t|dpdt|dp dt|t|t|	dkr,|ni t|t| ji t||	 dS )a  Extract prompt/response attributes from an execution context.

        ctx is a required argument of the shape:
        {
            "resource": str, # oneof("Converse", "ConverseStream", "InvokeModel")
            "model_name": str,
            "model_provider": str,
            "llmobs.request_params": {"prompt": str | list[dict],
                                "temperature": Optional[float],
                                "max_tokens": Optional[int]
                                "top_p": Optional[int]}
            "llmobs.usage": Optional[dict],
            "llmobs.stop_reason": Optional[str],
            "llmobs.proxy_request": Optional[bool],
        }
        agentr   workflowllmzllmobs.request_paramszllmobs.stop_reasonstop_reasonzllmobs.usagetotal_tokensinput_tokensoutput_tokenstemperaturer*   g        
max_tokensprompttool_configresource)ConverseConverseStreamcontentNr=   r>   
model_namemodel_provider) _llmobs_set_tags_agentget_itemr   r   getfloatint_extract_tool_definitions_set_ctx_itemr   #_extract_input_message_for_converse_extract_input_messager#   error$_extract_output_message_for_conversesendStopIterationvaluecloseupdate_extract_output_message_set_ctx_itemsr   r   r   r   r   r   r   r   _integration_namer   )selfr+   r,   r-   r.   r/   metadatausage_metricsctx	span_kindrequest_paramsr:   r;   tool_definitionsis_converseinput_messagesoutput_messageseadditional_metadatastreamed_usage_metrics rc   X/home/ubuntu/.local/lib/python3.10/site-packages/ddtrace/llmobs/_integrations/bedrock.py_llmobs_set_tags0   sp   




z#BedrockIntegration._llmobs_set_tagsc           
      C   s   | j r|sd S t||ddddpi }|dd}|dd}|dd}|d	d}	|td
tt|td|	it||dt	di |sDd S |
tt| d S )N   	inputArgsT)optional	inputTextr*   agentIdagentAliasId	sessionIdr1   
session_id)agent_idagent_alias_idbedrock_agents)llmobs_enabledr   rE   rT   r   r   strr   r   r   rI   r   )
rV   r+   r,   r-   r.   
input_argsinput_valuern   ro   rm   rc   rc   rd   rC      s$   

	z)BedrockIntegration._llmobs_set_tags_agentc           
      C   s   |r| j sdS |D ]/}t|}| j|d}t||||\}}|r/|| j|d < |s/|| j|< t||||| j q	| j D ]\}}	tj	j
|	 t|	 q>| j  | j  dS )z5Translate bedrock agent traces to LLMObs span events.Nspan_id)rq   r   r)   popr   r(   r   itemsr   	_instance_llmobs_span_writerenqueuer    clear)
rV   traces	root_spantracetrace_step_idcurrent_active_span_eventtranslated_span_eventfinished_
span_eventrc   rc   rd   translate_bedrock_traces   s(   



z+BedrockIntegration.translate_bedrock_tracesr:   c                 C   sx   t | tstd tddgS g }| D ]%}t |tsqt|dd}|dd}|r1t |ts2q|t||7 }q|S )a  Extract input messages from the stored prompt for converse

        `prompt` is an array of `message` objects. Each `message` has a role and content field.

        The content field stores a list of `ContentBlock` objects.

        For more info, see bedrock converse request syntax:
        https://docs.aws.amazon.com/bedrock/latest/APIReference/API_runtime_Converse.html#API_runtime_Converse_RequestSyntax
        4Bedrock input is not a list of messages or a string.r*   r?   roler@   N)	
isinstancelistlogwarningr#   dictrr   rE   r   )r:   r^   messager   r@   rc   rc   rd   rJ      s   


z6BedrockIntegration._extract_input_message_for_conversec                 C   s\   t ddg}| di di }|s|S |dd}|dd}|r't|ts)|S t||S )	a  Extract output messages from the stored prompt for converse

        `response` contains an `output` field that stores a nested `message` field.

        `message` has a `content` field that `ContentBlock` objects.

        For more info, see bedrock converse response syntax:
        https://docs.aws.amazon.com/bedrock/latest/APIReference/API_runtime_Converse.html#API_runtime_Converse_ResponseSyntax
        r*   r?   outputr   r   	assistantr@   N)r#   rE   r   r   r   )r.   default_contentr   r   r@   rc   rc   rd   rM      s   
z7BedrockIntegration._extract_output_message_for_conversec                  c   s   i } i }g }i }i }d}dV }|durd|v red|d v re|d d }dD ]}d ||v r<|d | | d |< q'|ddpH|dd}	|d	dpT|d
d}
|	dur]|	| t< |
dure|
| t< d|v rv|d }|ddg d}|du rdg d}d|v r|d }|d}|dur|d | d|v rd|d v r|d d ||< d|v r|d }|d}|durd|v r||dg vr|d | |d }||d|dd ||< |di dr||i ||< || dd|d d  || d< d|v r|t||| d}dV }|dus|dur1|dr1|t||| |s=|tddd t|  ||| fS )a  
        Listens for output chunks from a converse streamed response and builds a
        list of output messages, usage metrics, and metadata.

        Converse stream response comes in chunks. The chunks we care about are:
        - a message start/stop event, or
        - a content block start/stop event (for tool calls only currently)
        - a content block delta event (for chunks of text in a message or tool call arg)
        - usage metric information

        For more info, see bedrock converse response stream response syntax:
        https://docs.aws.amazon.com/bedrock/latest/APIReference/API_runtime_ConverseStream.html#API_runtime_ConverseStream_ResponseSyntax
        NrW   usage)inputr   totalz{}Tokensz	{}_tokenscacheReadInputTokenCountcacheReadInputTokenscacheWriteInputTokenCountcacheWriteInputTokensmessageStartr   r   )r   content_block_indiciescontentBlockStartcontentBlockIndexr   starttoolUsecontentBlockDeltadeltar*   textr   messageStopr@   r   )formatrE   r	   r
   appendr   r#   r   )rX   rW   messagestext_content_blockstool_content_blockscurrent_messagechunkr   
token_typecache_read_tokenscache_write_tokensmessage_datablock_startindexcontent_block_deltadelta_contentrc   rc   rd   !_converse_output_stream_processor   s   







>

z4BedrockIntegration._converse_output_stream_processorc                 C   s   t | trt| dgS t | tstd tddgS g }| D ]\}|dd}t |trjt |d trj|D ]3}|ddkrR|t|ddt|ddd	 q5|dd
krh|tdt|ddd	 q5q|tt|t|ddd	 q|S )zExtract input messages from the stored prompt.
        Anthropic allows for messages and multiple texts in a message, which requires some special casing.
        r?   r   r*   r@   r   typer   r   r   imagez([IMAGE DETECTED]))	r   rr   r#   r   r   r   rE   r   r   )r:   r^   pr@   entryrc   rc   rd   rK   U  s$   


($z)BedrockIntegration._extract_input_messagec                 C   sv   |  dd}t|trt|dgS |r9t|tr9t|d tr&dd |D S t|d tr9t|d  dddgS g S )zExtract output messages from the stored response.
        Anthropic allows for chat messages, which requires some special casing.
        r   r*   r?   r   c                 S   s   g | ]	}t t|d qS )r?   )r#   rr   ).0r@   rc   rc   rd   
<listcomp>w  s    z>BedrockIntegration._extract_output_message.<locals>.<listcomp>)rE   r   rr   r#   r   r   )r.   	resp_textrc   rc   rd   rS   m  s   
z*BedrockIntegration._extract_output_messagec                 K   s:   | d}t|dd }|rt|dd nd }|rt|S d S )Ninstance	_endpointhost)rE   getattrrr   )rV   r-   r   endpointendpoint_hostrc   rc   rd   _get_base_url|  s   
z BedrockIntegration._get_base_urlrY   c                 C   s0   | j |dd}| |r|td d S d S )Nr   )r   T)r   	find_item_is_instrumented_proxy_urlset_itemr   )rV   rY   base_urlrc   rc   rd   _tag_proxy_request  s   
z%BedrockIntegration._tag_proxy_requestr;   c                 C   sb   t |dg }g }|D ]$}t |di }ttt |ddtt |ddt |di d}|| q
|S )z5Extract tool definitions from the stored tool config.toolstoolSpecnamer*   descriptioninputSchema)r   r   schema)r!   r$   rr   r   )rV   r;   r   r\   tool	tool_spectool_definition_inforc   rc   rd   rH     s   
z,BedrockIntegration._extract_tool_definitions)Nr*   )r0   N)!__name__
__module____qualname__rU   r(   r   rr   r"   __annotations__r)   r%   r   r   r   re   rC   r   staticmethodr#   rJ   rM   r   tuplerG   r   rK   rS   r   r   ExecutionContextr   r$   rH   rc   rc   rc   rd   r&   +   sN   
 

d
$
 f"r&   N)6typingr   r   r   ddtrace.internalr   ddtrace.internal.loggerr   ddtrace.internal.utilsr   ddtrace.llmobsr   ddtrace.llmobs._constantsr	   r
   r   r   r   r   r   r   r   r   r   r   r   r   r   ddtrace.llmobs._integrationsr   +ddtrace.llmobs._integrations.bedrock_agentsr   r   r   *ddtrace.llmobs._integrations.bedrock_utilsr   "ddtrace.llmobs._integrations.utilsr   r   r   ddtrace.llmobs._telemetryr    ddtrace.llmobs._utilsr!   ddtrace.llmobs._writerr"   ddtrace.llmobs.typesr#   r$   ddtrace.tracer%   r   r   r&   rc   rc   rc   rd   <module>   sL    