o
    i8                     @   s4  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Z dZ!G dd deZ"dS )    )Any)Optional)
get_logger)get_argument_value)AGENT_MANIFEST)"CACHE_READ_INPUT_TOKENS_METRIC_KEY)#CACHE_WRITE_INPUT_TOKENS_METRIC_KEY)INPUT_TOKENS_METRIC_KEY)INPUT_VALUE)METADATA)METRICS)
MODEL_NAME)OUTPUT_TOKENS_METRIC_KEY)OUTPUT_VALUE)	SPAN_KIND)TOTAL_TOKENS_METRIC_KEY)BaseLLMIntegration)	_get_attr)	safe_json)Message)ToolCall)
ToolResult)Span)	max_turnsmax_thinking_tokensmax_budget_usdc                   @   s  e Zd ZdZ		d(dedee deeef de	e ded	dfd
dZ
dedeeef d	dfddZ	d)dedee deeef de	e d	df
ddZdedeeef deeef d	eeef fddZdeeef d	eeef fddZdee d	eeef fddZdeeef deeef d	dfddZdeded	ee fddZded ed	ee fd!d"Zded	eee eeef eeef f fd#d$Zd%ed	eeef fd&d'ZdS )*ClaudeAgentSdkIntegrationclaude_agent_sdkN spanargskwargsresponse	operationreturnc                 C   s,   |dkr|  || d S | |||| d S )Ntool)_llmobs_set_tool_tags_llmobs_set_agent_tags)selfr   r    r!   r"   r#    r)   a/home/ubuntu/.local/lib/python3.10/site-packages/ddtrace/llmobs/_integrations/claude_agent_sdk.py_llmobs_set_tags#   s   z*ClaudeAgentSdkIntegration._llmobs_set_tagsc                 C   sF   | di }| dd}| dd}|tdt|t|td|ii d S )N
tool_inputtool_outputr   tool_idr%   )get_set_ctx_itemsr   r
   r   r   )r(   r   r!   r,   r-   r.   r)   r)   r*   r&   0   s   z/ClaudeAgentSdkIntegration._llmobs_set_tool_tagsc                 C   s   t ||ddddp
d}|dpd}| |}| ||}tddg}	i }
i }|js6|d ur6| |\}	}
}| |||}|t	dt
|pEdt|t|t|	t|
t|i d S )	Nr   promptT)optionalr   zclaude_agent_sdk.request.modelcontentagent)r   get_tag_extract_metadata_extract_input_messagesr   error_extract_output_data_build_agent_manifestr0   r   r   r
   r   r   r   r   )r(   r   r    r!   r"   r1   modelmetadatainput_messagesoutput_messagesmetricsinit_system_messageagent_manifestr)   r)   r*   r'   >   s(   
z0ClaudeAgentSdkIntegration._llmobs_set_agent_tagsr<   r=   rA   c                 C   sv   i }d|d< |r||d< |r| dg pg }dd |D |d< |r/| dg p(g }d|i|d< d	|v r9|d	 |d
< |S )NzClaude Agent SDK	frameworkr<   toolsc                 S   s   g | ]}d |iqS )namer)   ).0r%   r)   r)   r*   
<listcomp>i       zCClaudeAgentSdkIntegration._build_agent_manifest.<locals>.<listcomp>mcp_serversdependenciesr   max_iterations)r/   )r(   r<   r=   rA   manifestrD   rI   r)   r)   r*   r;   `   s   z/ClaudeAgentSdkIntegration._build_agent_manifestc                 C   sJ   i }| d}tD ]}t||rt||rt||||< q	| || |S )Noptions)r/   CLAUDE_OPTIONS_KEYShasattrgetattr_format_context)r(   r!   r=   rM   keyr)   r)   r*   r7   q   s   
z+ClaudeAgentSdkIntegration._extract_metadatacontext_messagesc                 C   s  i ddd}|rt |ts|S z|D ]}t|j}|dkrt|dd}|r*t |ts+q|d}d}t|D ]\}}	d|	v rrz(|	dd	 d
d  }
d|
v redd |
dD \}}||d< ||d< W n t	t
fyq   Y nw d|	v ryd}q6|r|	dr nF|rd|	v r|	 dddd dkrq6dd |	dD }t|dkr|d	 r|d r|d	 }|d }|dkr|dkr||d |< q6 W |S qW |S  ty   tjddd Y |S w )a  Parse category percentages and token counts from context UserMessage.

        Args:
            context_messages: List of messages from /context query

        Returns:
            Dictionary with:
                - "categories": Dict mapping category names to percentage strings
                - "used_tokens": Token count string (e.g., "16.3k") or None
                - "total_tokens": Token count string (e.g., "200.0k") or None
        N)
categoriesused_tokenstotal_tokensUserMessager4   r   
Fz**Tokens:**   (r   /c                 S      g | ]}|  qS r)   strip)rF   tr)   r)   r*   rG      rH   zGClaudeAgentSdkIntegration._parse_context_categories.<locals>.<listcomp>rU   rV   z### Estimated usage by categoryTz###|-c                 S   r\   r)   r]   )rF   pr)   r)   r*   rG      rH         Category
PercentagerT   z Error parsing context categories)exc_info)
isinstancelisttype__name__r   strsplit	enumerater^   
IndexError
ValueError
startswithreplacelen	Exceptionlogwarning)r(   rS   resultmsgmsg_typer4   linesin_category_tableilinetokens_partused_str	total_strpartscategory
percentager)   r)   r*   _parse_context_categoriesz   s`   

 3z3ClaudeAgentSdkIntegration._parse_context_categoriesc                 C   sf   | d}| d}d|vst|d tsi |d< |r$| ||d d< |r1| ||d d< d S d S )N_dd_context_dd_before_context_ddafter_contextbefore_context)r/   rh   dictr   )r(   r=   r!   r   r   r)   r)   r*   rQ      s   

z)ClaudeAgentSdkIntegration._format_contextr1   c           	      C   s   |r| dnd }|rRt|drRg }|jD ]:}t|trBd|v rB|di p'i }|ddp/d}|ddp7d}|t||d q|tt|pJddd q|S t|t	r^t|ddgS tdddgS )	N_dd_prompt_wrappercaptured_valuesmessager4   r   roleuserr4   r   )
_get_ctx_itemrO   r   rh   r   r/   appendr   r   rl   )	r(   r1   r   prompt_wrappermessagescaptured_msgr   r4   r   r)   r)   r*   r8      s   

z1ClaudeAgentSdkIntegration._extract_input_messagesr4   r   c                 C   s|  g }t |tr|t||d |S t |ts|S |D ]}t|j}|dkr:t|ddp-d}|tt||d q|dkrRt|ddpEd}|tt||d q|dkrt|dd	}t|d
d}	t|di }
tt|t |
t	rs|
ni t|	dd}|td||gd q|dkrt|dd}t|dd}t |tr|}nt
|pt|}t|t|dd}|td||gd q|S )zParses content which can be a string or a list of content blocks
        (TextBlock, ToolUseBlock, etc.) into a list of messages.
        r   	TextBlocktextr   ThinkingBlockthinkingToolUseBlockrE   unknown_toolidinputtool_use)rE   	argumentsr.   rj   )r4   r   
tool_callsToolResultBlocktool_use_idr4   tool_result)rw   r.   rj   )r4   r   tool_results)rh   rl   r   r   ri   rj   rk   r   r   r   r   r   )r(   r4   r   r   block
block_typer   r   	tool_namer.   r,   	tool_callr   result_contentformatted_resultr   r)   r)   r*   _parse_content_blocks   sN   



z/ClaudeAgentSdkIntegration._parse_content_blocksc           
      C   s<  g }i }i }|rt |tstddg||fS |D ]z}t|j}|dkr5t|dg p*g }|| |d q|dkr\t|di p@i }|r[t |trJ|ni }t	|pQd}|
t|dd	 q|d
krrt|ddpgd}|| |d q|dkr|s}| |}t|ddpd}	|	r|
tt|	dd	 q|ptddg||fS )zeExtract output data from response, including output messages, usage metrics, and init system message.r   r3   AssistantMessager4   	assistantSystemMessagedatasystemr   rW   r   ResultMessagerw   )rh   ri   r   rj   rk   r   extendr   r   r   r   _extract_result_messagerl   )
r(   r"   r?   r@   rA   rx   ry   r4   r   rw   r)   r)   r*   r:     s8   

z.ClaudeAgentSdkIntegration._extract_output_datar   c                 C   s   i }t |dd p	i }|rWt|trW|dpd}|dpd}|dp%d}|dp,d}|r7|| | |t< |r=||t< |rK|rK|t |t  |t< |rQ||t< |rW||t< |S )Nusageinput_tokensr   output_tokenscache_creation_input_tokenscache_read_input_tokens)	r   rh   r   r/   r	   r   r   r   r   )r(   r   r@   r   r   r   cache_creation
cache_readr)   r)   r*   r   1  s$   z1ClaudeAgentSdkIntegration._extract_result_message)Nr   )N)rk   
__module____qualname___integration_namer   ri   r   r   rl   r   r+   r&   r'   r;   r7   r   rQ   r   r8   r   tupleintr:   r   r)   r)   r)   r*   r       s\    



"



"	&H00 r   N)#typingr   r   ddtrace.internal.loggerr   ddtrace.internal.utilsr   ddtrace.llmobs._constantsr   r   r   r	   r
   r   r   r   r   r   r   r   !ddtrace.llmobs._integrations.baser   ddtrace.llmobs._utilsr   r   ddtrace.llmobs.typesr   r   r   ddtrace.tracer   rk   ru   rN   r   r)   r)   r)   r*   <module>   s4    