
    j#                     ^    d dl mZmZmZ d dlmZ ddlmZmZ  G d dej                        Z
y)    )AnyListOptionalN   )	validatorresultc                      e Zd ZdZh dZh dZdefdZdej                  fdZ
dee   defd	Zd
ededee   ddfdZd
ededee   defdZd
ededee   ddfdZd
ededee   ddfdZd
ededee   ddfdZdededee   ddfdZdedededee   ddf
dZd
ededededee   ddfdZd
ededededee   ddfdZddZy)ChatPromptMessagesValidatora$  
    Validator for ChatPrompt messages list.

    Validates that messages is a list of dicts with:
    - "role" key with value "system", "user", or "assistant"
    - "content" key with value either string or list of dicts
    - If content is list of dicts, each dict must have "type" key
    >   usersystem	assistant>   	audio_url	image_url	video_urlmessagesc                      || _         d | _        y )N)r   validation_result)selfr   s     }/Users/manta/Documents/Projects/TheRoad-I1/backend/.venv/lib/python3.12/site-packages/opik/validation/chat_prompt_messages.py__init__z$ChatPromptMessagesValidator.__init__   s     DH    returnc                    g }| j                  |      s(t        j                  d|      | _        | j                  S t	        | j
                        D ]  \  }}d| d}| j                  |||         t        |      dkD  r(t        j                  d|      | _        | j                  S t        j                  d      | _        | j                  S )NT)failedfailure_reasonsz	messages[]r   F)r   )_validate_messages_is_listr   ValidationResultr   	enumerater   _validate_messagelen)r   r   idxmessageprefixs        r   validatez$ChatPromptMessagesValidator.validate   s    %' ..?%+%<%<_&D" ))) &dmm4LC Q'F""67OD 5
 !#%+%<%<_&D" %%% &,%<%<E%JD"%%%r   r   c                     t        | j                  t              s5dt        | j                        j                   d}|j                  |       yy)zDValidate that messages is a list. Returns False if validation fails.zmessages must be a list but 
 was givenFT)
isinstancer   listtype__name__append)r   r   msgs      r   r   z6ChatPromptMessagesValidator._validate_messages_is_list1   sG    $--..tDMM/B/K/K.LJW  ""3'r   r$   r#   Nc                 x    | j                  |||      sy| j                  |||       | j                  |||       y)z7Validate a single message structure, role, and content.N)_validate_message_structure_validate_role_validate_content)r   r$   r#   r   s       r   r    z-ChatPromptMessagesValidator._validate_message;   s=     //QFG_=vw@r   c                    t        |t              s-| dt        |      j                   d}|j	                  |       yt        |j                               }ddh}||k7  r{|j                  |      s&||z
  }| dt        |       }|j	                  |       |j                  |      s2||z
  }| dt        |       dt        |       }|j	                  |       yy	)
zjValidate that message is a dict with exactly 'role' and 'content' keys. Returns False if validation fails.: must be a dict but r'   Frolecontentz: missing required keys: z: unexpected keys: z. Expected only: T)	r(   dictr*   r+   r,   setkeysissubsetsorted)	r   r$   r#   r   r-   message_keysexpected_keysmissing_keys
extra_keyss	            r   r/   z7ChatPromptMessagesValidator._validate_message_structureE   s    
 '4(H1$w-2H2H1ITC""3' 7<<>*+=(((7,|; 9&:N9OP&&s+ )),7)M9
h1&2D1E F&&,]&;%<>   &&s+r   c                    |j                  d      }|| j                  vr\dj                  t        | j                        D cg c]  }d| d
 c}      }| d| dt	        |       d}|j                  |       yyc c}w )z%Validate the role field of a message.r4   z, 'z.role: must be one of [z] but r'   N)getVALID_ROLESjoinr:   reprr,   )r   r$   r#   r   r4   rvalid_roles_strr-   s           r   r0   z*ChatPromptMessagesValidator._validate_rolec   s     {{6"t'''"ii6$BRBR;S(T;Sa1QCq;S(TUO(1/1B CDzl*.  ""3' ((Ts   A=c                 &   |j                  d      }|| d}|j                  |       yt        |t        t        f      s-| dt        |      j                   d}|j                  |       yt        |t              r| j                  |||       yy)z(Validate the content field of a message.r5   Nz.content: must not be Nonez2.content: must be either str or list of dicts but r'   )rA   r,   r(   strr)   r*   r+   _validate_content_list)r   r$   r#   r   r5   r-   s         r   r1   z-ChatPromptMessagesValidator._validate_contentp   s     ++i(?H67C""3'Gc4[1( G}--.j:  ""3'&''I 'r   r5   c                 `    t        |      D ]   \  }}| d| d}| j                  |||       " y)z4Validate content when it is a list of content parts.z	.content[r   N)r   _validate_content_part)r   r$   r5   r   content_idxcontent_partcontent_prefixs          r   rI   z2ChatPromptMessagesValidator._validate_content_list   s<     *37);%K &xyQ?N''oV *<r   rN   rM   c                     t        |t              s-| dt        |      j                   d}|j	                  |       yd|vr| d}|j	                  |       y|j                  d      }| j                  ||||       y)z3Validate a single content part in the content list.r3   r'   Nr*   z: must have 'type' key)r(   r6   r*   r+   r,   rA   _validate_content_type_specific)r   rN   rM   r   r-   content_types         r   rK   z2ChatPromptMessagesValidator._validate_content_part   s     ,-!" #L)223:?  ""3'%#$$:;C""3' $''/,,L,	
r   rQ   c                     || j                   v r| j                  |||||       y|dk(  r| j                  ||dd|       yy)z6Validate type-specific requirements for content parts.textN)URL_BASED_CONTENT_TYPES_validate_required_url_object_validate_required_string_key)r   rN   rQ   rM   r   s        r   rP   z;ChatPromptMessagesValidator._validate_content_type_specific   sW     4777.. V#..ffo $r   key_name	type_namec           	         ||vr| d| d| d}|j                  |       yt        |j                  |      t              s?| d| dt	        |j                  |            j
                   d}|j                  |       yy)z4Validate that a required key exists and is a string.: must have '' key when type is 'r@   .z: must be a string but r'   N)r,   r(   rA   rH   r*   r+   )r   r$   rM   rW   rX   r   r-   s          r   rV   z9ChatPromptMessagesValidator._validate_required_string_key   s     <'HM(3G	{RSTC""3'L,,X6<(!H: &L,,X67@@AM  ""3' =r   c           	         ||vr| d| d| d}|j                  |       y|j                  |      }t        |t              s0| d| dt	        |      j
                   d}|j                  |       yd|vr| d| d	}|j                  |       yt        |j                  d      t              s?| d| d
t	        |j                  d            j
                   d}|j                  |       yy)zTValidate that a required key exists and is a dict with a 'url' key that is a string.rZ   r[   r@   Nr\   r3   r'   urlz: must have 'url' keyz.url: must be a string but )r,   rA   r(   r6   r*   r+   rH   )r   r$   rM   rW   rX   r   r-   
url_objects           r   rU   z9ChatPromptMessagesValidator._validate_required_url_object   s    <'HM(3G	{RSTC""3'!%%h/
*d+(!H: &J'001=  ""3'
"HAhZ'<=C""3'JNN5137(!H: &JNN512;;<JH  ""3' 8r   c                     | j                   Nt        | j                   j                        dkD  r+t        j                  d| j                   j                        y y )Nr   zChatPrompt.__init__)r$   r   )r   r!   r   
exceptionsValidationError)r   s    r   raise_if_validation_failedz6ChatPromptMessagesValidator.raise_if_validation_failed   sW    "".D**::;a?,,, $ 6 6 F F  @ /r   )r   N)r+   
__module____qualname____doc__rB   rT   r   r   r   r   r%   r   rH   boolr   r    r/   r6   r0   r1   r)   rI   rK   rP   rV   rU   rc    r   r   r
   r
      s    2KEI I&&11 &2$s)  AA$'A:>s)A	A$':>s)	<(($((;?9(	(JJ$(J;?9J	J"WW$(W;?9W	W
!
14
GKCy
	
.  	
 c 
*(( ( 	(
 ( c( 
(&(( ( 	(
 ( c( 
(Br   r
   )typingr   r   r   opik.exceptionsra    r   r   RaisableValidatorr
   rh   r   r   <module>rm      s%    & & $ j)"="= jr   