
    tni                        d dl 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	 e	rd dlm
Z
mZmZmZmZmZ d dlmZ d dlZd dlmZ d	Zd
Z G d d          Zej        dgej        ddgej        ddgej        ddgiZi Ze                                D ]\  ZZ e D ]Z!eee!<   d3ddde"ddfdZ#	 d3ddde$ddde"ddf
dZ%de$de$fd Z&d4d#Z'd5d%Z(d&d'd(e)dd'fd)Z*d!d*d+e)de)fd,Z+eefd!d*d+e)d-e)dd.fd/Z,efd!d0ddd1dd+e)dd0f
d2Z-dS )6    N)deque)deepcopy)	getsizeof)TYPE_CHECKING)AnyCallableDictListOptionalTuple)Span)loggeri N  i'  c                       e Zd ZdZdZdZdZdS )GEN_AI_ALLOWED_MESSAGE_ROLESsystemuser	assistanttoolN)__name__
__module____qualname__SYSTEMUSER	ASSISTANTTOOL     P/var/www/html/gpu-tools/venv/lib/python3.11/site-packages/sentry_sdk/ai/utils.pyr   r      s"        FDIDDDr   r   r   r   humanr   air   	tool_callTdatar   unpackreturnc                    t          | d          rt          j        |           rd| j         dS 	 t	          |                                           S # t          $ rX}t          j        d|           t          | t          t          t          t          f          r| nt          |           cY d }~S d }~ww xY wt          | t                    rGr*t          |           dk    rt	          | d                   S t          fd| D                       S t          | t                     r fd	|                                 D             S t          | t          t          t          t          f          r| nt          |           S )
N
model_dumpz<ClassType: >r#   z+Could not convert pydantic data to JSON: %s   r   c              3   :   K   | ]}t          |           V  dS )r(   N_normalize_data).0xr#   s     r   	<genexpr>z"_normalize_data.<locals>.<genexpr>:   s0      DD!OAf555DDDDDDr   c                 :    i | ]\  }}|t          |           S )r(   r+   )r-   kvr#   s      r   
<dictcomp>z#_normalize_data.<locals>.<dictcomp>=   s,    PPP!Q?1V444PPPr   )hasattrinspectisclassr   r,   r&   	Exceptionr   warning
isinstanceintfloatboolstrlistlendictitems)r"   r#   es    ` r   r,   r,   )   s   t\"" 
T ?4   	32$-2222	T"4??#4#4VDDDD 	T 	T 	TNH!LLL%dS%s,CDDS44#d))SSSSSS	T $ E 	;c$ii1nn"476::::DDDDtDDDDDD$ QPPPP4::<<PPPPdS%s$;<<K44#d))Ks   "A 
B7AB2,B72B7spanr   keyvaluec                     t          ||          }t          |t          t          t          t
          f          r|                     ||           d S |                     |t          j        |                     d S )Nr(   )	r,   r9   r:   r;   r<   r=   set_datajsondumps)rC   rD   rE   r#   
normalizeds        r   set_data_normalizedrK   B   so     !v666J*sE4566 3c:&&&&&c4:j1122222r   rolec                 8    t                               | |           S )z
    Normalize a message role to one of the 4 allowed gen_ai role values.
    Maps "ai" -> "assistant" and keeps other standard roles unchanged.
    )GEN_AI_MESSAGE_ROLE_MAPPINGget)rL   s    r   normalize_message_rolerP   L   s    
 '**4666r   messageslist[dict[str, Any]]c                     g }| D ]r}t          |t                    s|                    |           -|                                }d|v rt	          |d                   |d<   |                    |           s|S )z
    Normalize roles in a list of messages to use standard gen_ai role values.
    Creates a deep copy to avoid modifying the original messages.
    rL   )r9   r@   appendcopyrP   )rQ   normalized_messagesmessagenormalized_messages       r   normalize_message_rolesrY   T   s    
  7 7'4(( 	&&w///$\\^^W)?)P)Pv&""#56666r   Callable[..., Any]c                  v    t          j                    } | d uo| j        d u}|rt           j        nt           j        S )N)
sentry_sdkget_current_spancontaining_transaction
start_spanstart_transaction)current_spantransaction_existss     r   get_start_span_functionrc   f   sC    .00LD T\%HPT%T  %7X:  J<XXr   rW   zDict[str, Any]	max_charsc                     t          | t                    rd| vr| S | d         }t          |t                    rt          |          |k    r| S |d|         dz   | d<   | S )zy
    Truncate a message's content to at most `max_chars` characters and append an
    ellipsis if truncation occurs.
    contentNz...)r9   r@   r=   r?   )rW   rd   rf   s      r   +_truncate_single_message_content_if_presentrg   n   ss     gt$$ 	(@(@i Ggs## s7||y'@'@ ),u4GINr   zList[Dict[str, Any]]	max_bytesc                     d}t          t          |           dz
  dd          D ]P}t          t          j        | |         d                              d                    }||z  }||k    r|dz   c S QdS )z
    Find the index of the first message that would exceed the max bytes limit.
    Compute the individual message sizes, and return the index of the first message from the back
    of the list that would exceed the max bytes limit.
    r   r)   ,:
separatorsutf-8)ranger?   rH   rI   encode)rQ   rh   running_sumidxsizes        r   _find_truncation_indexrv      s     KS]]Q&B//  4:hsm
CCCJJ7SSTTt""7NNN # 1r   max_single_message_charsz Tuple[List[Dict[str, Any]], int]c                    t          j        | d          }t          |                    d                    }||k    r| dfS t	          | |          }|t          |           k     r| |d         }nt          |           dz
  }| dd         }t          |          dk    r't          t          |d                   |          |d<   ||fS )	a  
    Returns a truncated messages list, consisting of
    - the last message, with its content truncated to `max_single_message_chars` characters,
      if the last message's size exceeds `max_bytes` bytes; otherwise,
    - the maximum number of messages, starting from the end of the `messages` list, whose total
      serialized size does not exceed `max_bytes` bytes.

    In the single message case, the serialized message size may exceed `max_bytes`, because
    truncation is based only on character count in that case.
    rk   rn   rp   r   Nr)   rj   )rd   )rH   rI   r?   rr   rv   rg   r   )rQ   rh   rw   serialized_jsoncurrent_sizetruncation_indextruncated_messagess          r   truncate_messages_by_sizer}      s     jjAAAO--g6677Ly  {-h	BB#h--''%&6&7&78x==1,%bcc]
!## K'*++7O!
 !
 !
1 ///r   zOptional[List[Dict[str, Any]]]scopec                 x    | sd S t          | |          \  }}|dk    rt          |           |j        |j        <   |S )Nr   )r}   r?   _gen_ai_original_message_countspan_id)rQ   rC   r~   rh   r|   removed_counts         r   truncate_and_annotate_messagesr      sL      t(A(I(V(V%q=@]],T\:r   )T)rQ   rR   r$   rR   )r$   rZ   ).r5   rH   collectionsr   rU   r   sysr   typingr   r   r   r	   r
   r   r   sentry_sdk.tracingr   r\   sentry_sdk.utilsr   MAX_GEN_AI_MESSAGE_BYTES MAX_SINGLE_MESSAGE_CONTENT_CHARSr   r   r   r   r   #GEN_AI_MESSAGE_ROLE_REVERSE_MAPPINGrN   rA   target_rolesource_rolessource_roler<   r,   r=   rK   rP   rY   rc   r:   rg   rv   r}   r   r   r   r   <module>r      s=                                   (AAAAAAAAAAAAAAAA''''''     # # # # # #! #)          !'( %'8 *[$,? %'<	' # ! !D!J!J!L!L ? ?K# ? ?3>#K00?L L% L L L L L L4 :>3 3
33#(3263	3 3 3 37 7 7 7 7 7   $Y Y Y Y*-   $%;  PS    $ .$D!0 !0$!0!0 "!0 (	!0 !0 !0 !0P .	 .
  	
 &     r   