o
    aiX                     @   s  d dl Z d dlZd dlZd dlmZ ddlmZmZmZ d dl	m
Z
 d dlmZmZmZmZmZmZmZmZmZ d dlZd dlmZmZmZmZmZ d dlmZmZ d d	lm Z  d d
l!m"Z"m#Z#m$Z$ d dl%m&Z&m'Z'm(Z( d dl)m*Z* erd dl+m,Z, d dl	m-Z- d dl%m.Z.m/Z/m0Z0m1Z1m2Z2m3Z3m4Z4 G dd deZ5				djddZ6dkddZ7ddde8fddZ9dld"d#Z:dmd&d'Z;dmd(d)Z<dnd+d,Z=dod.d/Z>	0	1		2dpd3d4Z?		5		2dqd6d7Z@	8	9	:	;	<	=		;drd>d?ZAd@e8dAd-ddBfdCdDZBdsdFdGZC	H	I		IdtdJdKZD		5		LdudMdNZE		5		LdudOdPZFdQdRdSeGddTfdUdVZH	Q	R		TdvdWdXZIdYdBdZdde8dd d:d;ddfd[d\ZJ	Y	B	Z			5		dwd]d^ZK	8	9	:	;		_dxd`daZL	8	9	:	;		bdydcddZM	Y	B	Z				:	;		dzdedfZN	Y	B	Z			g		d{dhdiZOdS )|    N)wraps   )ORIGINTOOL_ATTRIBUTES_MAPGEN_AI_SYSTEM)BLOB_DATA_SUBSTITUTE)	TYPE_CHECKINGIterableAnyCallableListOptionalUnion	TypedDictDict)set_data_normalizedtruncate_and_annotate_messagesnormalize_message_rolestransform_google_content_partget_modality_from_mime_type)OPSPANDATA)should_send_default_pii)capture_internal_exceptionsevent_from_exceptionsafe_serialize)GenerateContentConfigPartContent)chain)Span)TextPart)GenerateContentResponseContentListUnionContentUnionDictToolModelEmbedContentResponseContentUnionc                   @   s:   e Zd ZU dZeed< eed< eed< eed< eed< dS )	UsageDatazStructure for token usage data.input_tokensinput_tokens_cachedoutput_tokensoutput_tokens_reasoningtotal_tokensN)__name__
__module____qualname____doc__int__annotations__ r5   r5   h/home/ubuntu/SoloSpeech/.venv/lib/python3.10/site-packages/sentry_sdk/integrations/google_genai/utils.pyr)   3   s   
 r)   response.Union[GenerateContentResponse, dict[str, Any]]returnc           	      C   sl  t dddddd}t| trb| di }|s|S |ddpd}|ddp'd}|| |d< |ddp5d}||d< |d	dpAd}||d
< |ddpMd}|| |d< |ddp[d}||d< |S t| dsi|S | j}t|ddpsd}t|ddp{d}|| |d< t|ddpd}||d< t|d	dpd}||d
< t|ddpd}|| |d< t|ddpd}||d< |S )a@  Extract usage data from response into a structured format.

    Args:
        response: The GenerateContentResponse object or dictionary containing usage metadata

    Returns:
        UsageData: Dictionary with input_tokens, input_tokens_cached,
                   output_tokens, and output_tokens_reasoning fields
    r   )r*   r+   r,   r-   r.   usage_metadataprompt_token_counttool_use_prompt_token_countr*   cached_content_token_countr+   thoughts_token_countr-   candidates_token_countr,   total_token_countr.   )r)   
isinstancedictgethasattrr:   getattr)	r7   
usage_datausageprompt_tokenstool_use_prompt_tokenscached_tokensreasoning_tokenscandidates_tokensr.   r5   r5   r6   extract_usage_data=   sL   
	
rM   excr
   c                 C   s0   t | t jdddd\}}tj||d dS )z.Capture exception with Google GenAI mechanism.google_genaiF)typehandled)client_options	mechanism)hintN)r   
sentry_sdk
get_clientoptionscapture_event)rN   eventrT   r5   r5   r6   _capture_exception   s   
rZ   modelzUnion[str, Model]c                 C   s*   t | tr| S t| drt| jS t| S )z(Extract model name from model parameter.name)rA   strrD   r\   )r[   r5   r5   r6   get_model_name   s
   


r^   contentsr#   List[Dict[str, Any]]c                 C   s  | du rg S g }t | trd| dgS t | tr(| D ]}t|}|| q|S t | tr| dd}| d}|r~g }g }|D ]"}t|}	|	du rKq@t |	tr]|	ddkr]||	 q@||	 q@|rw|dkrkdn|pnd}
||
|d || |S d	| v r||pd| d	 d	d
gd |S t	| dr| j
rt| ddpd}g }g }| j
D ]"}t|}	|	du rqt |	tr|	ddkr||	 q||	 q|r|dkrdn|}
||
|d || |S t| }	|	rt |	tr|	ddkr|	gS d|	gdgS zddlm} t | |jr!t| }|r!d|gdgW S W n
 ty,   Y nw t	| drat	| drat| dd}t| dd}|dura|du rQd}dt|||d}d|gdgS t	| d	rx| jrxdt| jd	d
gdgS g S )a$  Extract messages from contents parameter which can have various formats.

    Returns a list of message dictionaries in the format:
    - System: {"role": "system", "content": "string"}
    - User/Assistant: {"role": "user"|"assistant", "content": [{"text": "...", "type": "text"}, ...]}
    Nuserrolecontentrc   partstoolr[   	assistanttextrh   rP   r   Imageuri	mime_type rP   modalityrm   rl   )rA   r]   listextract_contents_messagesextendrB   rC   _extract_part_contentappendrD   re   rE   PILrk   _extract_pil_imageImportErrorr   rh   )r_   messagesitemitem_messagesrc   re   content_partstool_messagespartpart_resultnormalized_rolePILImage	blob_partfile_urirm   r5   r5   r6   rr      s   









rr   r~   Optional[dict[str, Any]]c                 C   s|  | du rdS t | trDd| v rt| S | dr| d ddS t| }|durBd| v r@| d }t |tr@t |dtr@t|d< |S dS t| drP| jrPt| S t| dr^| j	r^| j	ddS t| dr| j
r| j
}t|d	d}t|d
d}|dur|du rd}dt|||dS t| dr| jr| j}t|dd}t|d
d}|dur|du rd}t |trt}n|}dt|||dS dS )zExtract content from a Part object or dict.

    Returns:
        - dict for content part (text/blob) or tool message
        - None if part should be skipped
    Nfunction_responserh   ri   inline_datadatard   	file_datar   rm   rn   rl   ro   blobrP   rp   rm   rd   )rA   rB   _extract_tool_message_from_partrC   r   bytesr   rD   r   rh   r   rE   r   r   )r~   resultr   r   r   rm   r   rd   r5   r5   r6   rt   !  sb   



rt   c                 C   s   d}t | tr| d}nt| dr| j}|sdS d}d}d}t |tr;|d}|d}|di }|d|}n&t|dd}t|dd}t|dd}|du rSi }t |tr_|d|}n|}|sedS d|rlt|ndt||durxt|nddd	S )
zExtract tool message from a Part with function_response.

    Returns:
        {"role": "tool", "content": {"toolCallId": "...", "toolName": "...", "output": "..."}}
        or None if not a valid tool message
    Nr   idr\   r7   outputrf   )
toolCallIdtoolNamer   rb   )rA   rB   rC   rD   r   rE   r]   r   )r~   r   tool_call_id	tool_namer   response_dictresponse_objr5   r5   r6   r   y  s>   





r   imagec                 C   sd   z'ddl m} t| |jsW dS | jpd}| }d| }dt||tdW S  ty1   Y dS w )z'Extract blob part from PIL.Image.Image.r   rj   NJPEGzimage/r   r   )rv   rk   rA   formatlowerr   r   	Exception)r   r   
format_strsuffixrm   r5   r5   r6   rw     s   

rw   Optional[str]c                 C   s   t | }|sdS g }|D ]1}|d}t|tr|| qt|tr=|D ]}t|tr<|ddkr<||dd q%q|rEd|S dS )zExtract text from contents parameter which can have various formats.

    This is a compatibility function that extracts text from messages.
    For new code, use extract_contents_messages instead.
    Nrd   rP   rh   rn    )rr   rC   rA   r]   ru   rq   rB   join)r_   ry   textsmessagerd   r~   r5   r5   r6   extract_contents_text  s   


r   tools#Iterable[Tool | Callable[..., Any]]Optional[List[dict[str, Any]]]c              	   C   s   g }| D ]Q}t |r|t|ddt|ddd qt|dr<|jdur<|jD ]}|t|ddt|ddd q(qt D ]\}}t||drT|||d  nq@q|rZ|S dS )	z%Format tools parameter for span data.r/   unknownr2   N)r\   descriptionfunction_declarationsr\   r   )callableru   rE   rD   r   r   items)r   formatted_toolsrf   	func_decl	attr_namer   r5   r5   r6   _format_tools_for_span  s:   






	r   r"   c                 C   s  g }t | dg rF| jD ]:}t|drt |jdg sq|jjD ]&}t |ddrD|j}t |dddd}t |ddr?t|j|d	< || qqt | d
dr| j	D ]5}t |ddsXqOt |dg D ]%}t |ddr|j}t |dddd}t|dr~t|j|d	< || q^qO|r|S dS )z\Extract tool/function calls from response candidates and automatic function calling history.
candidatesrd   re   function_callNr\   )r\   rP   args	arguments"automatic_function_calling_history)
rE   r   rD   rd   re   r   r   r   ru   r   )r7   
tool_calls	candidater~   r   	tool_callrd   r5   r5   r6   extract_tool_calls  sD   






r   r   tuple[Any, ...]kwargsdict[str, Any]rf   r%   c                 C   s~   |r|  ni }| r=z$t|}t|j }t| D ]\}}|t|k r+|||| < qW |S  ty<   | |d< Y |S w |S )z(Capture tool input from args and kwargs.r   )	copyinspect	signaturerq   
parameterskeys	enumeratelenr   )r   r   rf   
tool_inputsigparam_namesiargr5   r5   r6   _capture_tool_input;  s    

r   r   tool_docr    c                 C   sJ   t jtjd|  td}|tj|  |tjd |r#|tj	| |S )z!Create a span for tool execution.zexecute_tool )opr\   originfunction)
rU   
start_spanr   GEN_AI_EXECUTE_TOOLr   set_datar   GEN_AI_TOOL_NAMEGEN_AI_TOOL_TYPEGEN_AI_TOOL_DESCRIPTION)r   r   spanr5   r5   r6   _create_tool_spanP  s   r   Tool | Callable[..., Any]c                    sd   t  s S t dd jt r#t d fdd}|S t d fd	d
}|S )z3Wrap a tool to emit execute_tool spans when called.r/   r   r   r
   r   r9   c                     s   t e}t| | }t  |tjt| W d    n1 s$w   Y  z0 | i |I d H }t  |tjt| W d    n1 sKw   Y  |W W  d    S  tyj } zt	|  d }~ww 1 snw   Y  d S N
r   r   r   r   r   GEN_AI_TOOL_INPUTr   GEN_AI_TOOL_OUTPUTr   rZ   r   r   r   r   r   rN   rf   r   r   r5   r6   async_wrappedi  s.   

z#wrapped_tool.<locals>.async_wrappedc                     s   t b}t| | }t  |tjt| W d    n1 s#w   Y  z- | i |}t  |tjt| W d    n1 sGw   Y  |W W  d    S  tyf } zt	|  d }~ww 1 sjw   Y  d S r   r   r   r   r5   r6   sync_wrapped  s,   

z"wrapped_tool.<locals>.sync_wrappedN)r   r
   r   r
   r9   r
   )r   rE   r2   r   iscoroutinefunctionr   )rf   r   r   r5   r   r6   wrapped_tool^  s   
r   configr   c                 C   s4   | rt | dds
| S t| }dd | jD |_|S )zWrap tools in config to emit execute_tool spans. Tools are sometimes passed directly as
    callable functions as a part of the config object.r   Nc                 S   s   g | ]}t |qS r5   )r   ).0rf   r5   r5   r6   
<listcomp>  s    z-wrapped_config_with_tools.<locals>.<listcomp>)rE   r   r   )r   r   r5   r5   r6   wrapped_config_with_tools  s
   
r   Optional[List[str]]c                 C   s   | rt | dg s
dS g }| jD ]-}t|drt|jdsq|jdu s(|jjdu r)q|jjD ]}t |ddr;||j q-q|rA|S dS )z&Extract text from response candidates.r   Nrd   re   rh   )rE   r   rD   rd   re   ru   rh   )r7   r   r   r~   r5   r5   r6   _extract_response_text  s   
r   c                 C   sf   | rt | dg s
dS g }| jD ]}t |ddr,t|j}d|v r'|dd }|| q|r1|S dS )z0Extract finish reasons from response candidates.r   Nfinish_reason.)rE   r   r]   r   splitru   )r7   finish_reasonsr   reasonr5   r5   r6   extract_finish_reasons  s   


r   system_instructions%Union[ContentUnionDict, ContentUnion]can_be_contentlist[TextPart]c                 C   s(  g }t | trd| dgS t | tr| jrd| jdgS |r@t | tr@t | jtr>| jD ]}t |jtr=|d|jd q,|S t | trR| 	drRd| d dgS |rt | tr| 	dg }|D ].}t |trxt |jtrx|d|jd qat |trt |	dtr|d|d d qa|S |S )Nrh   )rP   rd   re   )
rA   r]   r   rh   r   re   rq   ru   rB   rC   )r   r   
text_partsr~   re   r5   r5   r6   '_transform_system_instruction_one_level  s0   

r   c                 C   s6   g }t | trttdd | D }|S t| ddS )Nc                 s   s    | ]	}t |d dV  qdS )Fr   N)r   )r   instructionsr5   r5   r6   	<genexpr>  s    
z1_transform_system_instructions.<locals>.<genexpr>Tr   )rA   rq   r   from_iterabler   )r   r   r5   r5   r6   _transform_system_instructions  s   

	r   r   integrationc                 C   s  |  tjt |  tj| |ddr|  tjd |d}t ry|jryg }d}|r5t|dr5|j	}nt
|trCd|v rC|d}|durS|  tjtt| t|}|| |ryt|}	t }
t|	| |
}|duryt| tj|dd dtjfd	tjfd
tjfdtjfdtjfdtjfdtjffD ]\}}t||rt||}|dur|  || q|durt|dr|j }|rt!|}|rt| tj"|dd dS dS dS dS dS )zSet span data for the request.streamFTr   Nsystem_instructionunpacktemperaturetop_ptop_kmax_output_tokenspresence_penaltyfrequency_penaltyseedr   )#r   r   r   GEN_AI_REQUEST_MODELrC   GEN_AI_RESPONSE_STREAMINGr   include_promptsrD   r   rA   rB   GEN_AI_SYSTEM_INSTRUCTIONSjsondumpsr   rr   rs   r   rU   get_current_scoper   r   GEN_AI_REQUEST_MESSAGESGEN_AI_REQUEST_TEMPERATUREGEN_AI_REQUEST_TOP_PGEN_AI_REQUEST_TOP_KGEN_AI_REQUEST_MAX_TOKENSGEN_AI_REQUEST_PRESENCE_PENALTY GEN_AI_REQUEST_FREQUENCY_PENALTYGEN_AI_REQUEST_SEEDrE   r   r   GEN_AI_REQUEST_AVAILABLE_TOOLS)r   r   r[   r_   r   r   ry   r   contents_messagesnormalized_messagesscopemessages_dataparamspan_keyvaluer   r   r5   r5   r6   set_span_data_for_request  sv   


	
	

r  c                 C   s4  |sdS t  r|jrt|}|r| tjt| t|}|r(| tjt| t	|}|r5t
| tj| t|ddrC| tj|j t|ddrQ| tj|j t|}|d rb| tj|d  |d ro| tj|d  |d r|| tj|d  |d r| tj|d  |d r| tj|d  dS dS )	zSet span data for the response.Nresponse_idmodel_versionr*   r+   r,   r-   r.   )r   r  r   r   r   GEN_AI_RESPONSE_TEXTr   r   GEN_AI_RESPONSE_TOOL_CALLSr   r   GEN_AI_RESPONSE_FINISH_REASONSrE   GEN_AI_RESPONSE_IDr  GEN_AI_RESPONSE_MODELr  rM   GEN_AI_USAGE_INPUT_TOKENS GEN_AI_USAGE_INPUT_TOKENS_CACHEDGEN_AI_USAGE_OUTPUT_TOKENS$GEN_AI_USAGE_OUTPUT_TOKENS_REASONINGGEN_AI_USAGE_TOTAL_TOKENS)r   r   r7   response_textsr   r   rF   r5   r5   r6   set_span_data_for_responsea  sH   r(  tuple[Any, Any, str]c                 C   sj   | r| d n| dd}t| dkr| d n| d}t|}| d}t|}||ur0||d< |||fS )zBExtract and prepare common arguments for generate_content methods.r   r[   r   r   r_   r   )rC   r   r^   r   )r   r   r[   r_   
model_namer   wrapped_configr5   r5   r6   prepare_generate_content_args  s   

r,  tuple[str, Any]c                 C   s&   | dd}| d}t|}||fS )zxExtract and prepare common arguments for embed_content methods.

    Returns:
        tuple: (model_name, contents)
    r[   r   r_   )rC   r^   )r   r   r[   r_   r*  r5   r5   r6   prepare_embed_content_args  s   
r.  c                 C   s   t  r?|jrA|rCg }t|tr|g}nt|tr)|D ]}t|}|r'|| qn	t|}|r2|g}|rEt| tj	|dd dS dS dS dS dS )z$Set span data for embedding request.Fr   N)
r   r  rA   r]   rq   r   ru   r   r   GEN_AI_EMBEDDINGS_INPUT)r   r   r_   r   input_textsrz   rh   r5   r5   r6   set_span_data_for_embed_request  s2   



r1  r'   c                 C   s   |sdS t |dr:|jr<d}|jD ]}t |dr,|jr,t|jdd}|dur,|t|7 }q|dkr>| tj| dS dS dS dS )z%Set span data for embedding response.N
embeddingsr   
statisticstoken_count)rD   r2  r3  rE   r3   r   r   r"  )r   r   r7   r.   	embeddingr4  r5   r5   r6    set_span_data_for_embed_response  s   

r6  )r7   r8   r9   r)   )rN   r
   r9   N)r_   r#   r9   r`   )r~   r
   r9   r   )r   r
   r9   r   )r_   r#   r9   r   )r   r   r9   r   )r7   r"   r9   r   )r   r   r   r   rf   r%   r9   r   )rf   r   r9   r   )r   r   r9   r   )r7   r"   r9   r   )r   r   r9   r   )r   r    r   r
   r7   r"   r9   N)r   r   r   r   r9   r)  )r   r   r   r   r9   r-  )
r   r    r   r
   r_   r
   r   r   r9   N)r   r    r   r
   r7   r'   r9   N)Pr   r  r   	functoolsr   constsr   r   r   sentry_sdk._typesr   typingr   r	   r
   r   r   r   r   r   r   rU   sentry_sdk.ai.utilsr   r   r   r   r   sentry_sdk.constsr   r   sentry_sdk.scoper   sentry_sdk.utilsr   r   r   google.genai.typesr   r   r   	itertoolsr   sentry_sdk.tracingr    r!   r"   r#   r$   r%   r&   r'   r(   r)   rM   rZ   r]   r^   rr   rt   r   rw   r   r   r   r   r   r   r   r   r   boolr   r   r  r(  r,  r.  r1  r6  r5   r5   r5   r6   <module>   s   ,$


K


 

X
5

*
5

A



"

P
6


 