
    :i8M              	       F   S SK r S SKJr  S SKJr  S SKJrJr  S SKJ	r	J
r
JrJrJrJrJrJr  S SKJrJrJrJrJrJrJrJr  S SKJr  S SKJrJrJrJ r   S S	K!J"r"   " S
 S\5      r# " S S\\\\\4   5      r$ " S S\$5      r% " S S\%5      r& " S S\&5      r'S\"S\#S\$4S jr(g)    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                   $    \ rS rSrSrSrSrSrSrg)ValidationMode%   zEnum for the validation mode.

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

Examples:
    >>> mode = ValidationMode.serving
serving
finetuningtest N)	__name__
__module____qualname____firstlineno____doc__r    r!   r"   __static_attributes__r#       d/home/james-whalen/.local/lib/python3.13/site-packages/mistral_common/protocol/instruct/validator.pyr   r   %   s    	 GJDr*   r   c                      \ rS rSr% SrSr\\S'   \R                  4S\4S jjr
S\\   S\S	S
4S jrS\S	\\   4S jrS\S	S
4S jrS\\   S	S
4S jrS\S	S
4S jrS\S	S
4S jrS\S	S
4S jrS\S	S
4S jrS\S\S	S
4S jrS"S\S\S	S
4S jjrS\\   S	S
4S jr S\\   S	S
4S jr!S\S\S	S
4S jr"S\\   S\S	S
4S jr#S\\   S	S
4S  jr$S!r%g
)#MistralRequestValidator6   ao  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                     Xl         g)zrInitializes the `MistralRequestValidator`.

Args:
    mode: The validation mode. Defaults to ValidationMode.test.
N_mode)selfr0   s     r+   __init__ MistralRequestValidator.__init__D   s	     
r*   messagescontinue_final_messagereturnNc                 D    U R                  XS9  U R                  U5        g)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)
r8   N) _validate_message_list_structure_validate_message_list_contentr4   r7   r8   s      r+   validate_messages)MistralRequestValidator.validate_messagesL   s#     	--h-f++H5r*   requestc                    U R                   [        R                  :X  a  UR                  c  [	        S5      eU R                  UR                  UR                  S9  U R                  UR                  =(       d    / 5        U$ )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)
z1Model name parameter is required for serving moder;   )
r3   r   r    modelr
   r?   r7   r8   _validate_toolstools)r4   rA   s     r+   validate_request(MistralRequestValidator.validate_request\   sk      ::///}}$-.abb 	w//HfHfg 	W]]0b1r*   functionc                     [         R                  " UR                  5        [        R                  " SUR                  5      (       d  [        SUR                   S35      eg! [         a  n[	        SUR
                   35      eSnAff = f)z-
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   )r4   rH   es      r+   _validate_function*MistralRequestValidator._validate_functionx   s    
	R(()<)<= xx0(--@@&$X]]O 4R R  A  	R,/DQYYK-PQQ	Rs    A" "
B	,BB	rE   c                 L    U H  nU R                  UR                  5        M      g)z+
Checks:
- That the tool schemas are valid
N)rT   rH   )r4   rE   tools      r+   rD   'MistralRequestValidator._validate_tools   s      D##DMM2 r*   rO   c                     g )Nr#   r4   rO   s     r+   _validate_user_message.MistralRequestValidator._validate_user_message   s    r*   c                     UR                   b@  [        R                  " SUR                   5      (       d  [        SUR                    S35      egg)z"
Checks:
- The tool name is valid
NrJ   rK   rL   )rR   rP   rQ   r   rZ   s     r+   _validate_tool_message.MistralRequestValidator._validate_tool_message   sS    
 <<#884gllCC1( 7V V  D $r*   c                 4    UR                   c  [        S5      eg)z.
Checks:
- That the system prompt has content
NzSystem prompt must have content)contentr   rZ   s     r+   _validate_system_message0MistralRequestValidator._validate_system_message   s    
 ??"./PQQ #r*   function_callc                     [         R                  " SUR                  5      (       d  [        SUR                   S35      eg)z3
Checks:
- That the function call has a valid name
rJ   rK   rL   N)rP   rQ   rR   r   )r4   rd   s     r+   _validate_function_call/MistralRequestValidator._validate_function_call   sI    
 xx0-2D2DEE.$]%7%7$8 9R R  Fr*   	tool_callis_last_messagec                 :    U R                  UR                  5        g)z3
Checks:
- That the tool call has a valid function
N)rf   rH   )r4   rh   ri   s      r+   _validate_tool_call+MistralRequestValidator._validate_tool_call   s     	$$Y%7%78r*   c                    U R                   (       d7  [        UR                  5      [        UR                  5      :X  a  [	        S5      eUR                  b"  UR                   H  nU R                  X2S9  M     U R                  [        R                  :X  a=  [        U[        5      (       a(  UR                  b  UR                  S;  a  [	        S5      eUR                  (       a  U(       d  [	        S5      egg)zr
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ri   )r      z.Assistant message weight must be either 0 or 1z7Assistant message with prefix True must be last message)r/   boolra   
tool_callsr   rk   r3   r   r!   
isinstancer   weightprefix)r4   rO   ri   rh   s       r+   _validate_assistant_message3MistralRequestValidator._validate_assistant_message   s     11W__8MQUV]VhVhQi8i2Y 
 )$//	(((T 0 ::222z'Ke7f7f~~)gnnF.J67ghh>>"67pqq # r*   c                     SnSnU H  nUc  UR                   nM  UR                   [        R                  :X  a  US-  nOQUR                   [        R                  :X  a3  US:w  a  [	        S5      eUR
                  b  [        UR
                  5      nUR                   nM     US:w  a)  U R                  [        R                  :X  a  [	        S5      eUS:  a*  U R                  [        R                  :X  a  [	        S5      egg)z|
Checks:
- That the number of tool calls and tool messages are the same
- That the tool calls are followed by tool messages
Nr   ro   3Not the same number of function calls and responses#More tool responses than tool calls)roler   rW   	assistantr	   rq   lenr3   r   r    r!   )r4   r7   	prev_roleexpected_tool_messagesrO   s        r+   ._validate_tool_calls_followed_by_tool_messagesFMistralRequestValidator._validate_tool_calls_followed_by_tool_messages   s     	!"G #LL	||uzz)&!+&0 *Q.:;pqq%%1-01C1C-D*I#  & "Q&4::9O9O+O23hii#a'DJJ.:S:S,S23XYY -T'r*   c                 r   SnU GH.  nUR                   nUGb  U[        R                  :X  a0  [        R                  [        R                  [        R                  1nOU[        R                  :X  a0  [        R                  [        R                  [        R                  1nOxU[        R                  :X  a0  [        R                  [        R                  [        R
                  1nO4U[        R
                  :X  a   [        R                  [        R
                  1nUW;  a  [        SU SU S35      eUnGM1     g)z`
Validates the order of the messages, for example user -> assistant -> user -> assistant -> ...
NzUnexpected role 'z' after role '')rz   r   systemuserr{   rW   r	   )r4   r7   previous_rolerO   current_roleexpected_roless         r+   _validate_message_order/MistralRequestValidator._validate_message_order   s     G"<<L( ELL0&+jj%//5<<%PN"ejj0&+oou||UZZ%PN"eoo5&+oouzz5::%NN"ejj0&+oouzz%BN~5:+L>VWX  )M%  r*   c                 6   UR                   nU R                  [        R                  :X  a5  U[        R
                  :w  a  [        SU 35      eU(       a  [        S5      eg [        U[        5      =(       a    UR                  (       + =(       a    U(       + nUR                   [        R                  [        R                  1;  nU(       a  U(       a  [        SU 35      eU(       a4  U[        R
                  :w  d  UR                  (       a  [        SU 35      eg g )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 )rz   r3   r   r!   r   r{   r	   rr   r   rt   r   rW   )r4   rO   r8   last_message_rolebad_assistantbad_roles         r+   _validate_last_message.MistralRequestValidator._validate_last_message  s    #LL::222 EOO36JK\J]^  &67ijj & 'w0@Aw'..FXwaw]wM||EJJ

+CCH6++<*=?  (->%//-QU\UcUc6$$5#68  Vd'r*   c                    [        U5      S:X  a  [        S5      e[        U5      S:X  a<  US   R                  [        R                  [        R
                  1;  a  [        S5      eU R                  [        R                  :X  d  [        U5      S:  a  U R                  US   US9  U R                  U5        U R                  U5        g)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 messagero   z=Conversation must start with a user message or system messager;   N)r|   r	   rz   r   r   r   r3   r   r!   r   r   r   r>   s      r+   r<   8MistralRequestValidator._validate_message_list_structure)  s     x=A23`aa x=A{

ELL'AA67vww ::222c(ma6G''Mc'd$$X.;;HEr*   c                    [        U5       H  u  p#UR                  [        R                  :X  a  U R	                  U5        M6  UR                  [        R
                  :X  a   U R                  X2[        U5      S-
  :H  S9  Mt  UR                  [        R                  :X  a  U R                  U5        M  UR                  [        R                  :X  a  U R                  U5        M  [        S[        U5       35      e   g)z'
Validates the content of the messages
ro   rn   zUnsupported message type N)	enumeraterz   r   r   r[   r{   ru   r|   rW   r^   r   rb   r
   type)r4   r7   idxrO   s       r+   r=   6MistralRequestValidator._validate_message_list_content?  s    
 &h/LC||uzz)++G4000QTU]Q^abQbJb0c+++G4---g6-0I$w-.YZZ 0r*   r2   )F)&r$   r%   r&   r'   r(   r/   rp   __annotations__r   r"   r5   listr   r?   r   rF   r   rT   r   rD   r   r[   r   r^   r   rb   r   rf   r   rk   r   ru   r   r   r   r<   r=   r)   r#   r*   r+   r-   r-   6   s   	 */ $..<.A.A ^ 6$t* 6d 6W[ 6 (= BWX\B] 88   3T$Z 3D 3o $ 
o 
$ 
R0A Rd R	\ 	d 	9X 9 9QU 9r3G rZ^ rko r:ZtDz ZVZ Z@)T
 )t )2d D UY 0Fd F]a Ffj F,[tDz [d [r*   r-   c                   d   ^  \ rS rSrSrS\SS4S jrS\S\SS4S	 jr	S\
S
\SS4U 4S jjrSrU =r$ )MistralRequestValidatorV3iQ  zValidator for v3 Mistral requests.

This validator adds additional validation for tool call IDs.

Examples:
    >>> validator = MistralRequestValidatorV3()
rO   r9   Nc                 J   UR                   b?  [        R                  " SUR                   5      (       d  [        SUR                    S35      eUR                  c  [        S5      e[        R                  " SUR                  5      (       d  [        SUR                   S35      eg)	z:
Checks:
- The tool name is valid
- Tool call id is valid
NrJ   rK   rL   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.)rR   rP   rQ   r   tool_call_idr
   rZ   s     r+   r^   0MistralRequestValidatorV3._validate_tool_messageZ  s     <<#884gllCC1( 7V V 
 ')*KLLxx+W-A-ABB-#G$8$8#99hi  Cr*   rh   ri   c                    UR                   S:w  a?  [        R                  " SUR                   5      (       d  [        SUR                    S35      eU R                  [
        R                  :X  a$  U(       d  UR                   S:X  a  Sn[        U5      eU R                  [
        R                  :X  a  UR                   S:X  a  [        S5      eU R                  UR                  5        g)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)
idrP   rQ   r   r3   r   r!   r    rf   rH   )r4   rh   ri   err_messages       r+   rk   -MistralRequestValidatorV3._validate_tool_callo  s     <<6!88/>>2'	~5de  ::222?y||_eOetK.{;;::///ILLF4J./`aa$$Y%7%78r*   r8   c                    > [         TU ]  X5        U R                  [        R                  :X  a2  UR
                  b$  UR
                   H  nU R                  USS9  M     g g g )NTrn   )superr   r3   r   r!   rq   rk   )r4   rO   r8   rh   	__class__s       r+   r   0MistralRequestValidatorV3._validate_last_message  s]    &wG::222 !!-!(!3!3I,,Y,M "4 . 3r*   r#   )r$   r%   r&   r'   r(   r   r^   r   rp   rk   r   r   r)   __classcell__)r   s   @r+   r   r   Q  s[    o $ *9X 9 9QU 9$Nd ND NUY N Nr*   r   c                   (    \ rS rSr% SrSr\\S'   Srg)MistralRequestValidatorV5i  zValidator for v5 Mistral requests.

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

Examples:
    >>> validator = MistralRequestValidatorV5()
Tr/   r#   N)	r$   r%   r&   r'   r(   r/   rp   r   r)   r#   r*   r+   r   r     s     *. $-r*   r   c                   ,    \ rS rSrS\\   SS4S jrSrg)MistralRequestValidatorV13i  r7   r9   Nc                    Sn[        5       n[        5       nU GHJ  nUc  UR                  nM  UR                  [        R                  :X  aF  UR                  nXd;   a  [        SU S35      eXc;  a  [        SU S35      eUR                  U5        OUR                  [        R                  :X  a  [        U5      [        U5      :w  a  [        S5      eUR                  5         UR                  5         UR                  bW  UR                   HG  nUR                  U;   a  [        SUR                   S35      eUR                  UR                  5        MI     UR                  nGMM     [        U5      [        U5      :w  a)  U R                  [        R                  :X  a  [        S5      e[        U5      [        U5      :  a*  U R                  [        R                  :X  a  [        S5      egg)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 rx   z in assistant messagery   )setrz   r   rW   r   r	   addr{   r|   clearrq   r   r3   r   r    r!   )r4   r7   r}   expected_tool_idsobserved_tool_idsrO   r   rh   s           r+   r   IMistralRequestValidatorV13._validate_tool_calls_followed_by_tool_messages  s    	&)e&)eG #LL	||uzz)&334:=TUaTbbr;stt8:=UVbUccs;tuu!%%l30 ()S1B-CC:;pqq!'')!'')%%1%,%7%7	$<<+<<"B"9),,G\ ]#  *--ill; &8  I=  @  !S):%;;

nNdNd@d23hii"#c*;&<<~OhOhAh23XYY Bi<r*   r#   )r$   r%   r&   r'   r   r   r   r)   r#   r*   r+   r   r     s    -ZtDz -ZVZ -Zr*   r   versionr0   r9   c                    U [         R                  ::  a  [        US9nU$ U [         R                  ::  a  [	        US9nU$ U [         R
                  ::  a  [        US9nU$ U [         R                  ::  a  [        US9nU$ [        SU  35      e)N)r0   zUnsupported tokenizer version: )
r   v2r-   v3r   v7r   v13r   
ValueError)r   r0   	validators      r+   get_validatorr     s    "%%%+6	  
$''	'-48	  
$''	'-48	  
$((	(.D9	  :7)DEEr*   ))rP   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	 	 		 	 	 K  CT "X[go7K_^o&op X[v8N 7 8Nv	. 9 	..Z!: .Zb+ > F] r*   