
    *`i8M              	       j   d dl Z d dlmZ d dlmZ d dlmZmZ d dlm	Z	m
Z
mZmZmZmZmZmZ d dlmZmZmZmZmZmZmZmZ d dlmZ d dlmZmZmZm Z  d d	l!m"Z"  G d
 de          Z# G d deeeeef                   Z$ G d de$          Z% G d de%          Z& G d de&          Z'de"de#de$fdZ(dS )    N)Enum)Generic)Draft7ValidatorSchemaError) InvalidAssistantMessageExceptionInvalidFunctionCallException InvalidMessageStructureExceptionInvalidRequestExceptionInvalidSystemPromptExceptionInvalidToolExceptionInvalidToolMessageExceptionInvalidToolSchemaException)UATSAssistantMessageAssistantMessageTypeFinetuningAssistantMessageRolesSystemMessageTypeToolMessageTypeUserMessageType)ChatCompletionRequest)FunctionFunctionCallToolToolCall)TokenizerVersionc                       e Zd ZdZdZdZdZdS )ValidationModezEnum for the validation mode.

    Attributes:
        serving: The serving mode.
        finetuning: The finetuning mode.
        test: The test mode.

    Examples:
        >>> mode = ValidationMode.serving
    serving
finetuningtestN)__name__
__module____qualname____doc__r   r    r!        ~/home/jaya/work/projects/VOICE-AGENT/VIET/agent-env/lib/python3.11/site-packages/mistral_common/protocol/instruct/validator.pyr   r   %   s)        	 	 GJDDDr'   r   c                      e Zd ZU dZdZeed<   ej        fdefdZ	de
e         dedd	fd
Zdedee         fdZdedd	fdZde
e         dd	fdZdedd	fdZdedd	fdZdedd	fdZdedd	fdZdededd	fdZd dededd	fdZde
e         dd	fdZde
e         dd	fdZ dededd	fdZ!de
e         dedd	fdZ"de
e         dd	fdZ#d	S )!MistralRequestValidatora  Validator for Mistral requests.

    This class validates the structure and content of Mistral requests.

    Examples:
        >>> from mistral_common.protocol.instruct.messages import UserMessage, AssistantMessage
        >>> validator = MistralRequestValidator()
        >>> messages = [UserMessage(content="Hello how are you ?")]
        >>> validator.validate_messages(messages, False)
    F_allow_tool_call_and_contentmodec                     || _         dS )zInitializes the `MistralRequestValidator`.

        Args:
            mode: The validation mode. Defaults to ValidationMode.test.
        N)_mode)selfr,   s     r(   __init__z MistralRequestValidator.__init__D   s     


r'   messagescontinue_final_messagereturnNc                 ^    |                      ||           |                     |           dS )a  Validates the list of messages.

        Args:
            messages: The list of messages to validate.
            continue_final_message: Whether to continue the final message.

        Examples:
            >>> from mistral_common.protocol.instruct.messages import UserMessage, AssistantMessage
            >>> validator = MistralRequestValidator()
            >>> messages = [AssistantMessage(content="Hi"), UserMessage(content="Hello")]
            >>> validator.validate_messages(messages, False)
        r2   N) _validate_message_list_structure_validate_message_list_contentr/   r1   r2   s      r(   validate_messagesz)MistralRequestValidator.validate_messagesL   s8     	--hOe-fff++H55555r'   requestc                     | j         t          j        k    r|j        t	          d          |                     |j        |j                   |                     |j	        pg            |S )a  Validates the request

        Args:
            request: The request to validate.

        Returns:
            The validated request.

        Examples:
            >>> from mistral_common.protocol.instruct.messages import UserMessage
            >>> validator = MistralRequestValidator()
            >>> request = ChatCompletionRequest(messages=[UserMessage(content="Hello")])
            >>> validated_request = validator.validate_request(request)
        Nz1Model name parameter is required for serving moder5   )
r.   r   r   modelr
   r9   r1   r2   _validate_toolstools)r/   r:   s     r(   validate_requestz(MistralRequestValidator.validate_request\   sn      :///}$-.abbb 	w/Hfggg 	W]0b111r'   functionc                     	 t          j        |j                   n)# t          $ r}t	          d|j                   d}~ww xY wt          j        d|j                  st          d|j         d          dS )zE
        Checks:
        - That the function schema is valid
        zInvalid tool schema: N^[a-zA-Z0-9_-]{1,64}$Function name was [ but must be a-z, A-Z, 0-9, or contain underscores and dashes, with a maximum length of 64.)
r   check_schema
parametersr   r   messagerematchnamer   )r/   r@   es      r(   _validate_functionz*MistralRequestValidator._validate_functionx   s    
	R()<==== 	R 	R 	R,-PQY-P-PQQQ	R x0(-@@ 	&RX] R R R  	 	s    
A=Ar>   c                 D    |D ]}|                      |j                   dS )zC
        Checks:
        - That the tool schemas are valid
        N)rL   r@   )r/   r>   tools      r(   r=   z'MistralRequestValidator._validate_tools   s6      	3 	3D##DM2222	3 	3r'   rG   c                     d S )Nr&   r/   rG   s     r(   _validate_user_messagez.MistralRequestValidator._validate_user_message   s    r'   c                 |    |j         2t          j        d|j                   st          d|j          d          dS dS )z:
        Checks:
        - The tool name is valid
        NrB   rC   rD   )rJ   rH   rI   r   rP   s     r(   _validate_tool_messagez.MistralRequestValidator._validate_tool_message   sc    
 <#84glCC 1V V V V   $# r'   c                 2    |j         t          d          dS )zF
        Checks:
        - That the system prompt has content
        NzSystem prompt must have content)contentr   rP   s     r(   _validate_system_messagez0MistralRequestValidator._validate_system_message   s#    
 ?"./PQQQ #"r'   function_callc                 j    t          j        d|j                  st          d|j         d          dS )zK
        Checks:
        - That the function call has a valid name
        rB   rC   rD   N)rH   rI   rJ   r   )r/   rW   s     r(   _validate_function_callz/MistralRequestValidator._validate_function_call   sU    
 x0-2DEE 	.R]%7 R R R  	 	r'   	tool_callis_last_messagec                 :    |                      |j                   dS )zK
        Checks:
        - That the tool call has a valid function
        N)rY   r@   )r/   rZ   r[   s      r(   _validate_tool_callz+MistralRequestValidator._validate_tool_call   s!     	$$Y%788888r'   c                    | j         s9t          |j                  t          |j                  k    rt	          d          |j        !|j        D ]}|                     ||           | j        t          j        k    r4t          |t                    r|j        |j        dvrt	          d          |j        r|st	          d          dS dS )z
        Checks:
        - That the assistant message has either text or tool_calls, but not both
        - That the tool calls are valid
        zGAssistant message must have either content or tool_calls, but not both.Nr[   )r      z.Assistant message weight must be either 0 or 1z7Assistant message with prefix True must be last message)r+   boolrU   
tool_callsr   r]   r.   r   r    
isinstancer   weightprefix)r/   rG   r[   rZ   s       r(   _validate_assistant_messagez3MistralRequestValidator._validate_assistant_message   s     1 	W_8M8MQUV]VhQiQi8i8i2Y  
 )$/ U U	((O(TTTT:222z'Ke7f7f2~)gnF.J.J67ghhh> 	r" r67pqqq	r 	rr rr'   c                    d}d}|D ]s}||j         }|j         t          j        k    r|dz  }nE|j         t          j        k    r0|dk    rt	          d          |j        t          |j                  }|j         }t|dk    r$| j        t          j	        k    rt	          d          |dk     r$| j        t          j
        k    rt	          d          dS dS )z
        Checks:
        - That the number of tool calls and tool messages are the same
        - That the tool calls are followed by tool messages
        Nr   r`   3Not the same number of function calls and responses#More tool responses than tool calls)roler   rN   	assistantr	   rb   lenr.   r   r   r    )r/   r1   	prev_roleexpected_tool_messagesrG   s        r(   ._validate_tool_calls_followed_by_tool_messageszFMistralRequestValidator._validate_tool_calls_followed_by_tool_messages   s     	!" 	% 	%G #L	|uz))&!+&&00 *Q..:;pqqq%1-01C-D-D*II!Q&&4:9O+O+O23hiii#a''DJ.:S,S,S23XYYY (',S,Sr'   c                    d}|D ]}|j         }||t          j        k    r$t          j        t          j        t          j        h}n|t          j        k    r$t          j        t          j        t          j        h}n\|t          j        k    r$t          j        t          j        t          j        h}n(|t          j        k    rt          j        t          j        h}||vrt          d| d| d          |}dS )zp
        Validates the order of the messages, for example user -> assistant -> user -> assistant -> ...
        NzUnexpected role 'z' after role '')rj   r   systemuserrk   rN   r	   )r/   r1   previous_rolerG   current_roleexpected_roless         r(   _validate_message_orderz/MistralRequestValidator._validate_message_order   s      	) 	)G"<L( EL00&+j%/5<%PNN"ej00&+ou|UZ%PNN"eo55&+ouz5:%NNN"ej00&+ouz%BN~55:XLXXXXX   )MM%	) 	)r'   c                    |j         }| j        t          j        k    r5|t          j        k    rt          d|           |rt          d          d S t          |t                    o
|j	         o| }|j         t          j
        t          j        hv}|r|rt          d|           |r)|t          j        k    s|j	        rt          d|           d S d S )Nz4Expected last role Assistant for finetuning but got z0Cannot continue final message in finetuning modezuExpected last role User or Tool (or Assistant with prefix or continue_final_message set to True) for serving but got zkExpected last role Assistant with prefix False for serving with continue_final_message set to True but got )rj   r.   r   r    r   rk   r	   rc   r   re   rs   rN   )r/   rG   r2   last_message_rolebad_assistantbad_roles         r(   _validate_last_messagez.MistralRequestValidator._validate_last_message  s,   #L:222 EO336^K\^^   & k67ijjjk k 'w0@AAw'.FXwaw]wM|EJ
+CCH 	 	6?+<? ?   ( ->%/-Q-QU\Uc-Q68$58 8   -Q-Qr'   c                    t          |          dk    rt          d          t          |          dk    r4|d         j        t          j        t          j        hvrt          d          | j        t          j        k    st          |          dk    r| 	                    |d         |           | 
                    |           |                     |           dS )z
        Validates the structure of the list of messages

        For example the messages must be in the correct order of user/assistant/tool
        r   z+Conversation must have at least one messager`   z=Conversation must start with a user message or system messager5   N)rl   r	   rj   r   rs   rr   r.   r   r    r|   rw   ro   r8   s      r(   r6   z8MistralRequestValidator._validate_message_list_structure)  s     x==A23`aaa x==A{
EL'AAA67vwww :222c(mma6G6G''Mc'ddd$$X...;;HEEEEEr'   c                    t          |          D ]\  }}|j        t          j        k    r|                     |           0|j        t          j        k    r,|                     ||t          |          dz
  k               q|j        t          j        k    r| 	                    |           |j        t          j
        k    r|                     |           t          dt          |                     dS )z7
        Validates the content of the messages
        r`   r_   zUnsupported message type N)	enumeraterj   r   rs   rQ   rk   rf   rl   rN   rS   rr   rV   r
   type)r/   r1   idxrG   s       r(   r7   z6MistralRequestValidator._validate_message_list_content?  s    
 &h// 
	[ 
	[LC|uz))++G44440000#QTU]Q^Q^abQbJb0cccc++++G4444----g6666-.Y$w--.Y.YZZZ
	[ 
	[r'   )F)$r"   r#   r$   r%   r+   ra   __annotations__r   r!   r0   listr   r9   r   r?   r   rL   r   r=   r   rQ   r   rS   r   rV   r   rY   r   r]   r   rf   ro   rw   r|   r6   r7   r&   r'   r(   r*   r*   6   s        	 	 */ $....<.A  ^    6$t* 6d 6W[ 6 6 6 6 (= BWX\B]    88      3T$Z 3D 3 3 3 3o $    
o 
$ 
 
 
 
R0A Rd R R R R	\ 	d 	 	 	 	9X 9 9QU 9 9 9 9r r3G rZ^ rko r r r r:ZtDz ZVZ Z Z Z Z@)T
 )t ) ) ) )2d D UY    0Fd F]a Ffj F F F F,[tDz [d [ [ [ [ [ [r'   r*   c                   T     e Zd ZdZdeddfdZdededdfdZde	d	eddf fd
Z
 xZS )MistralRequestValidatorV3zValidator for v3 Mistral requests.

    This validator adds additional validation for tool call IDs.

    Examples:
        >>> validator = MistralRequestValidatorV3()
    rG   r3   Nc                    |j         2t          j        d|j                   st          d|j          d          |j        t          d          t          j        d|j                  st          d|j         d          dS )	zZ
        Checks:
        - The tool name is valid
        - Tool call id is valid
        NrB   rC   rD   zTool call id has to be defined.^[a-zA-Z0-9]{9}$Tool call id was / but must be a-z, A-Z, 0-9, with a length of 9.)rJ   rH   rI   r   tool_call_idr
   rP   s     r(   rS   z0MistralRequestValidatorV3._validate_tool_messageZ  s     <#84glCC 1V V V V  
 ')*KLLLx+W-ABB 	-iG$8iii  	 	r'   rZ   r[   c                 x   |j         dk    r2t          j        d|j                   st          d|j          d          | j        t
          j        k    r|s|j         dk    rd}t          |          | j        t
          j        k    r|j         dk    rt          d          |                     |j	                   dS )z<
        Validate that the tool call has a valid ID
        nullr   r   r   zXTool call id of assistant message that is not last has to be defined in finetuning mode.z/Tool call id has to be defined in serving mode.N)
idrH   rI   r   r.   r   r    r   rY   r@   )r/   rZ   r[   err_messages       r(   r]   z-MistralRequestValidatorV3._validate_tool_callo  s     <6!!8/>> 2e	eee   :222?2y|_eOeOetK.{;;;:///ILF4J4J./`aaa$$Y%788888r'   r2   c                     t                                          ||           | j        t          j        k    r(|j        #|j        D ]}|                     |d           d S d S d S )NTr_   )superr|   r.   r   r    rb   r]   )r/   rG   r2   rZ   	__class__s       r(   r|   z0MistralRequestValidatorV3._validate_last_message  s    &&w0FGGG:222 !-!(!3 N NI,,Y,MMMM 32 .-N Nr'   )r"   r#   r$   r%   r   rS   r   ra   r]   r   r|   __classcell__)r   s   @r(   r   r   Q  s         o $    *9X 9 9QU 9 9 9 9$Nd ND NUY N N N N N N N N N Nr'   r   c                   "    e Zd ZU dZdZeed<   dS )MistralRequestValidatorV5zValidator for v5 Mistral requests.

    This validator allows for both tool calls and content in the assistant message.

    Examples:
        >>> validator = MistralRequestValidatorV5()
    Tr+   N)r"   r#   r$   r%   r+   ra   r   r&   r'   r(   r   r     s/           *. $-----r'   r   c                   *    e Zd Zdee         ddfdZdS )MistralRequestValidatorV13r1   r3   Nc                    d}t                      }t                      }|D ],}||j        }|j        t          j        k    rK|j        }||v rt          d| d          ||vrt          d| d          |                    |           n|j        t          j        k    rt          |          t          |          k    rt          d          |	                                 |	                                 |j
        E|j
        D ]=}|j        |v rt          d|j         d          |                    |j                   >|j        }.t          |          t          |          k    r$| j        t          j        k    rt          d          t          |          t          |          k     r$| j        t          j        k    rt          d          dS dS )z
        Checks:
        - That the number and ids of tool calls and tool messages are the same
        - That the tool calls are followed by tool messages
        - That tool calls have distinct ids for a given assistant message
        NzDuplicate tool call id z in tool resultszUnexpected tool call id rh   z in assistant messageri   )setrj   r   rN   r   r	   addrk   rl   clearrb   r   r.   r   r   r    )r/   r1   rm   expected_tool_idsobserved_tool_idsrG   r   rZ   s           r(   ro   zIMistralRequestValidatorV13._validate_tool_calls_followed_by_tool_messages  s    	&)ee&)ee 	% 	%G #L	|uz))&3#444:;sUa;s;s;sttt'888:;tVb;t;t;tuuu!%%l333300 ())S1B-C-CCC:;pqqq!'')))!'')))%1%,%7 < <	$<+<<<"B ]), ] ] ]# #  *--il;;;;II !!S):%;%;;;
nNd@d@d23hiii"##c*;&<&<<<~OhAhAh23XYYY =<AhAhr'   )r"   r#   r$   r   r   ro   r&   r'   r(   r   r     sC        -ZtDz -ZVZ -Z -Z -Z -Z -Z -Zr'   r   versionr,   r3   c                 2   | t           j        k    rt          |          }nu| t           j        k    rt	          |          }nT| t           j        k    rt          |          }n3| t           j        k    rt          |          }nt          d|            |S )N)r,   zUnsupported tokenizer version: )
r   v2r*   v3r   v7r   v13r   
ValueError)r   r,   	validators      r(   get_validatorr     s    "%%%+666			$'	'	'-4888			$'	'	'-4888			$(	(	(.D999		D7DDEEEr'   ))rH   enumr   typingr   
jsonschemar   r   mistral_common.exceptionsr   r   r	   r
   r   r   r   r   )mistral_common.protocol.instruct.messagesr   r   r   r   r   r   r   r   (mistral_common.protocol.instruct.requestr   +mistral_common.protocol.instruct.tool_callsr   r   r   r   %mistral_common.tokens.tokenizers.baser   r   r*   r   r   r   r   r&   r'   r(   <module>r      s   				             3 3 3 3 3 3 3 3	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 		 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 K J J J J J            C B B B B B    T   "X[ X[ X[ X[ X[go7K_^o&op X[ X[ X[v8N 8N 8N 8N 8N 7 8N 8N 8Nv	. 	. 	. 	. 	. 9 	. 	. 	..Z .Z .Z .Z .Z!: .Z .Z .Zb+ > F]      r'   