
    BNj                       d Z ddlm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ZddlZddl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  ej@                  e!      Z"d
d
d
d
dZ#ddZ$ddZ%ddZ&ddZ'ddZ(ddZ)ddZ*ddZ+ G d d      Z,	 d	 	 	 	 	 d dZ-	 d	 	 	 	 	 d!dZ.d"dZ/	 	 	 	 	 	 	 	 	 	 d#dZ0y# e$ r dZY ~w xY w# eef$ r dZdZY w xY w)$zAModality detection, input parsing, and message format conversion.    )annotationsN)defaultdict)AnyLiteralNoReturn)urlparse)MULTIMODAL_DICT_KEYS
AudioInputMessageFormatModality	PairInputSingleInput
VideoInput)Image)AudioDecoderVideoDecoderflat)apertusdeepseek_v3gpt_ossseed_ossc                0    | j                  d      xr d| vS )zQCheck if a string looks like a valid URL (starts with http(s) and has no spaces).)zhttp://zhttps:// )
startswithtexts    t/Users/ahmed/devFolder/Ultron/claude-voice/.venv/lib/python3.12/site-packages/sentence_transformers/base/modality.py_looks_like_urlr   /   s    ??23G4G    c                    t        |       r5	 t        |       j                  j                         }|j                  |      S | j                         j                  |      xr t        j                  j                  |       S # t        $ r Y yw xY w)zOCheck if a string is a URL or local file path with one of the given extensions.F)r   r   pathlower
ValueErrorendswithosisfile)r   
extensionsr!   s      r   _is_media_url_or_pathr(   4   su    t	D>&&,,.D }}Z((::<  ,E1EE	  		s   #B 	BBc                >    | j                  d      ryt        | d      S )z:Check if a string is an image URL, file path, or data URI.zdata:image/T)z.jpgz.jpegz.pngz.gifz.bmpz.tiffz.webp)r   r(   r   s    r   is_image_url_or_pathr*   @   s    }% 'bccr   c                    t        | d      ryt        |       sy	 t        |       j                  }|dv S # t        $ r Y yw xY w)z.Check if a string is a video URL or file path.)z.mp4z.aviz.movz.wmvz.flvz.mkvTF)zwww.youtube.comzyoutube.comzyoutu.bezm.youtube.com)r(   r   r   netlocr#   )r   r,   s     r   is_video_url_or_pathr-   G   sW    T#ST4 $&&      s   4 	A A c                    t        | d      S )z/Check if a string is an audio URL or file path.)z.mp3z.wavz.oggz.flacz.aac)r(   r   s    r   is_audio_url_or_pathr/   Y   s     'PQQr   c                0   t        | t        t        f      rt        |       dk7  ryt        | d   t              rt        | d   t              ry| D ]E  }t        |t
              r
d|v rd|v r yt        |t              s.|s1t        |d   t
              sE y y)a  Check if a sample is a non-text pair (2-element tuple/list with at least one non-string element).

    Text pairs ``(str, str)`` are handled natively by tokenizers and detected as ``"text"`` modality
    by :func:`infer_modality`. This helper detects pairs that contain at least one non-string element
    (e.g. an image, audio array, or dict), which require conversion to message format.
       Fr      rolecontentT)
isinstancetuplelistlenstrdict)sampleelems     r   _is_non_text_pairr=   ^   s     fudm,Fq0@&)S!jC&@dD!fnd9JdD!dz$q'4/H	 
 r   c                   t        | t              rd| v r| d   |d   d<   | d   S t        \t        | t              rL| j                         }|j                  |d   d<   |j
                  j                  d      j                         S | S )zUnwrap dict-wrapped audio or an ``AudioDecoder`` into a raw array, collecting ``sampling_rate``.

    Passes through unchanged if ``audio_value`` is already a raw array/tensor/URL/path.
    sampling_rateaudioarrayr   )dim)r5   r:   r   get_all_samplessample_ratedatameannumpy)audio_valueextra_modality_kwargssampless      r   _unwrap_audiorK   s   s    
 +t$k)>I/>Z!'*?;7##J{L$I--/:A:M:Mg&7||  Q '--//r   c           
        t        | t              r0d| v r'|d   j                  dg       j                  | d          | d   S t        t        | t              r| j                  dt        |             }|d   j                  dg       j                  | j                  j                  | j                  j                  t        t        |j                  j                  d               d       |j                  S | S )zUnwrap dict-wrapped video or a ``VideoDecoder`` into a raw array, collecting ``video_metadata``.

    Passes through unchanged if ``video_value`` is already a raw array/tensor/URL/path.
    video_metadatavideorA   r   )fpstotal_num_framesframes_indices)r5   r:   
setdefaultappendr   get_frames_in_ranger8   metadataaverage_fps
num_framesr7   rangerE   shape)video_valuerI   frame_batchs      r   _unwrap_videor\      s    
 +t${*!'*556FKRRS^_oSpq7##J{L$I!55a[9IJg&112BBGNN"++77$/$8$8$C$C"&u[-=-=-C-CA-F'G"H	
 r   c                      e Zd ZdZ	 	 	 d	 	 	 	 	 	 	 ddZddZ	 	 	 	 ddZddZdddZ	 	 	 	 	 	 ddZ	e
dd	       Zdd
Z	 	 	 	 	 	 ddZ	 	 	 	 	 	 ddZy)InputFormattera  Handles input parsing, modality detection, and message format conversion.

    This class manages the complete input preprocessing pipeline:
    1. Parsing raw inputs to detect their modality (text, image, audio, video, message)
    2. Converting inputs to different chat template formats
    3. Normalizing mixed-modality inputs

    Different models require different message/chat template formats:
    - **Structured format**: Content is a list of dicts with type annotations
        [{"role": "user", "content": [{"type": "text", "text": "hello"}]}]

    - **Flat format**: Content is the direct value
        [{"role": "user", "content": "hello"}]

    Args:
        model_type: The model type string (e.g. from ``config.model_type``).
        message_format: Message format to use. Options:
            - ``"structured"``: Content is a list of dicts with type/modality keys
            - ``"flat"``: Content is the direct value
            - ``"auto"``: Automatically infer from processor (default)
        processor: Optional processor to infer format from when ``message_format="auto"``.
        supported_modalities: Optional list of modalities supported by the model. When provided,
            string inputs that look like media URLs/paths are only classified as non-text if the
            model actually supports that modality. This prevents text-only models from
            misclassifying text containing media URLs.
    Nc                    || _         || _        || _        |dk(  r!|r| j                  |      | _        y d| _        y || _        y )Nauto
structured)
model_type	processorsupported_modalities_infer_formatmessage_format)selfrb   rf   rc   rd   s        r   __init__zInputFormatter.__init__   sG     %"$8!V#CL$"4"4Y"?DR^D"0Dr   c                    | j                   t        v rt        | j                      S t        |dd      t        t              rsyg d}t        fd|D              ryy)a  Infer the message format expected by the processor.

        Checks known model types first, then inspects the processor's chat template
        for patterns indicating structured format. Defaults to ``"structured"`` if
        neither approach is conclusive.

        Args:
            processor: The processor/tokenizer to inspect.

        Returns:
            ``"structured"`` or ``"flat"`` message format.
        chat_templateNra   )z
content[0]z.typez'type'z"type"z	item.typezmessage.content[c              3  &   K   | ]  }|v  
 y wN ).0patterntemplates     r   	<genexpr>z/InputFormatter._infer_format.<locals>.<genexpr>   s     F2Eww("2E   r   )rb   !KNOWN_MODEL_TYPES_MESSAGE_FORMATSgetattrr5   r9   any)rg   rc   structured_patternsrp   s      @r   re   zInputFormatter._infer_format   s]     ????4T__EE9ot<(C(
 F2EFFr   c                   |sddg it        t              fS g }t        t              }d}|D ]  }t        |      r|j                  d|f       d}%t	        || j
                        }t        |t              r!|t        v r|j                         |hk(  r||   }|dk(  rt        ||      }nu|dk(  rt        ||      }nct        |t              r8t        |      }d|v rt        |d   |      |d<   d|v r.t        |d   |      |d<   n|dk(  rt        |t              r|g}n|}|j                  ||f       	 |rg }|D ]  \  }	}|	dk(  r!|j                  | j                  |             ,|	dk(  rEt        |t        t        f      r/t        |      d	k(  r!|j                  | j                  |             v|	dk(  r|j                  |       t        |	t              r|n|	|i}
|j                  | j                  |
              dd|i|fS t!        | \  }}t        |      }t#        |      }t        |      d
k(  r\|j%                         }t        |t&              r||i}n|d   j                         }|D 	ci c]  }	|	|D cg c]  }||	   	 c} }}	}nUt(        j+                  d| d       d|D cg c]*  \  }}| j                  t        |t              r|n||i      , c}}i}d}|||fS c c}w c c}}	w c c}}w )a-  Parse inputs and group by modality.

        Analyzes a list of inputs to detect their modality (text, image, audio, video, message)
        and groups them appropriately for the processor. Handles mixed modalities by converting
        to message format when necessary.

        Non-text pairs (e.g. ``(image, text)`` or ``(image, image)``) are detected and converted
        to message format with ``"query"``/``"document"`` roles via :meth:`pair_to_messages`.

        Args:
            inputs: List of inputs to parse. Can be:
                - str: Text inputs
                - tuple/list of str: Text pairs (for cross-encoders)
                - tuple/list of mixed types: Non-text pairs (e.g. image + text)
                - dict: Chat messages, audio data, or multimodal inputs
                - PIL.Image.Image: Image inputs
                - np.ndarray/torch.Tensor: Audio (1-2D) or video (3-5D) inputs

        Returns:
            Tuple of (modality, processor_inputs_dict, extra_modality_kwargs) where:
                - modality: Detected modality string (``"text"``, ``"image"``, etc.) or tuple of modalities
                - processor_inputs_dict: Dictionary mapping modality names to input lists
                - extra_modality_kwargs: Extra kwargs per modality (e.g. ``sampling_rate`` for audio)
        r   FpairTrd   r@   rN   messager1   r2   r   zMixed modalities detected: z!. Converting to 'message' format.)r   r:   r=   rS   infer_modalityrd   r5   r	   keysrK   r\   r6   pair_to_messagesr7   r8   
to_messagezipsetpopr9   loggerdebug)rg   inputstyped_inputsrI   	has_pairsitemmodalityvaluemessagesmodtyped
modalitiesprocessed_inputsunique_modalitiesordered_keysentrys                   r   parse_inputszInputFormatter.parse_inputs   s+   8 FB<T):::EG +D 1	D !&##VTN3 	%dAZAZ[H $%(6J*Jtyy{_g^hOhH~
 7"%d,ABW$%d,ABHe,T
e#%25>CX%YE'Ne#%25>CX%YE'NY&:dD+A5 12C L H*
U&=OOD$9$9%$@AF]z%%'GCPUJZ[OOOD$9$9%$@AI%OOE*%/U%;E#uEOODOOE$:; + y(35JJJ'*L'9$
$ 01
O !Q&(,,.H(C($,.>#?   02779_k#l_kX[CBR)SBR%*BR)S$S_k #lLL67H6IIjkl+7+7% OOZ%-HExY^N_`+7  !H)+@@@ *T#ls   4
K2>K-
K22/K8-K2c                    |\  }}t        |      }t        |      }| j                  dk(  r
d|dd|dgS d }d |||      dd |||      dgS )a  Convert a pair of inputs to query/document message format.

        Each element of the pair is wrapped in a message with role ``"query"`` (first element)
        or ``"document"`` (second element). The modality of each element is inferred individually
        via :func:`infer_modality`.

        Args:
            pair: A 2-element tuple or list of inputs (e.g. ``(image, text)``).

        Returns:
            List of two message dictionaries with ``"query"`` and ``"document"`` roles.
        r   queryr3   r4   documentc                    t        | t              r,t        |t              r| D cg c]  }||v sd||||   i c}S t        |t              r!| t        v r|j	                         | hk(  r||    }d| | |igS c c}w )Ntype)r5   r6   r:   r	   r|   )r   r   r   s      r   _to_contentz4InputFormatter.pair_to_messages.<locals>._to_contentm  s     (E*z$/EAIY#STX[c495YY$%(6J*Jtyy{_g^hOhH~Xx677	 Zs
   	A5A5)r{   rf   )rg   rx   
query_itemdoc_itemquery_modalitydoc_modalityr   s          r   r}   zInputFormatter.pair_to_messagesV  sy      $
H'
3%h/&( Z8#9 
	8 ^Z)PQKh,OP
 	
r   c           	        | j                   dk(  rNt        |      dk(  r+t        t        |j	                                     \  }}||dgS t
        j                  d       ||j	                         D cg c]  \  }}d|||i c}}dgS c c}}w )a  Convert a typed input dictionary to message format.

        Produces a single message with the given ``role``. For pair/multi-value inputs,
        use :meth:`pair_to_messages` instead (which is called automatically by :meth:`parse_inputs`).

        Args:
            typed_input: Dictionary mapping modality to input value (single value per modality).
            role: Role for the message (default: ``"user"``).

        Returns:
            List of message dictionaries (single message).
        r   r2   r   zbFlat message format requested but multiple modalities detected. Falling back to structured format.r   )rf   r8   nextiteritemsr   warning)rg   typed_inputr3   _r   r   s         r   r~   zInputFormatter.to_message|  s     &(;1$[%6%6%8 9:5!%%8999 WbWhWhWjkWjOHeVXx?Wjk
 	
 ls   2B	c                P   |sddg ifS t        |t              r|fn|}t        t        t	        |j                                           }g }t        |      D ]  }|D ci c]  }||v s|||   |    }}t        |      dk(  ryt        t	        |j                                     }	t        |	t        t        f      rAt        |	      dk(  r3t        d |	D              r!|j                  | j                  |	             |j                  | j                  |              dd|ifS c c}w )ac  Convert a batch of modality-specific inputs into the unified message format.

        Args:
            modality: The modality key (string) or tuple of modality keys.
            processor_inputs: Dictionary mapping modality names to lists of inputs.

        Returns:
            Tuple of ``("message", {"message": [messages_per_sample, ...]})``
        rz   r2   r1   c              3  <   K   | ]  }t        |t                y wrl   )r5   r9   )rn   vs     r   rq   z2InputFormatter.batch_to_message.<locals>.<genexpr>  s     OrlqghPZ[\^aPblqs   )r5   r9   r8   r   r   valuesrX   r6   r7   allrS   r}   r~   )
rg   r   processor_inputsr   
batch_sizer   ir   r   r   s
             r   batch_to_messagezInputFormatter.batch_to_message  s     y"o--$.x$=h[8
d#3#:#:#<=>?
z"ADTjDTSX[_iXi3 0 5a 88DTKj;1$T+"4"4"678eeT]3E
aCOrlqOrLrOOD$9$9%$@AOODOOK89 # 9h/// ks   	D#'D#c                    | D ]S  }|D ]L  }|j                  d      }t        |t              r%t        |t              rt	        d |D              sH  y  y U y)a  Check whether all messages in a batch contain only text content.

        Works with both flat format (``{"content": "hello"}``) and structured format
        (``{"content": [{"type": "text", "text": "hello"}]}``).

        Args:
            messages_batch: List of message lists, one per sample.

        Returns:
            True if every message contains only text, False if any contain non-text content.
        r4   c              3  F   K   | ]  }|j                  d d      dk7    yw)r   r   N)get)rn   r   s     r   rq   z7InputFormatter.is_text_only_messages.<locals>.<genexpr>  s!     R'$488FF3v='s   !FT)r   r5   r9   r7   ru   )messages_batchr   rz   r4   s       r   is_text_only_messagesz$InputFormatter.is_text_only_messages  sV     'H#!++i0gs+gt,R'RR$  $ ' r   c                p   g }|D ]-  }d|vsd|vrt         j                  d| d       &|d   }t        |t              xr |xr t        |d   t              }| j
                  dk(  ri|rgt        |      dk(  r%d|d   v r|j                  i |d|d   d   i       t         j                  d	t        |       d
       |j                  |       | j
                  dk(  rB|s@t        |t              r|j                  i |dd|dgi       
|j                  |       |j                  |       0 |S )a;  Normalize messages to the target format (``self.message_format``).

        Extra keys beyond ``"role"`` and ``"content"`` are preserved during conversion.

        Args:
            messages: List of message dictionaries to normalize.

        Returns:
            Normalized list of message dictionaries.
        r3   r4   zInvalid message format: z. Skipping.r   r   r2   r   z;Cannot convert structured message to flat format: contains z# content items. Keeping structured.ra   r   r   )	r   r   r5   r7   r:   rf   r8   rS   r9   )rg   r   
normalizedrz   r4   is_currently_structureds         r   normalize_messagesz!InputFormatter.normalize_messages  sN    
GW$	(@!9'+NOi(G&0$&?&lG&lPZ[bcd[egkPl#""f,1Hw<1$71:)=%%&P&P)WQZ=O&PQNN$$'L>1TV %%g.$$4=Tgs+%%&a&a)vW^>_=`&ab%%g.!!'*/  2 r   c                    | j                   dk(  r|D cg c]  }d|dg|z    c}S |D cg c]  }dd|dgdg|z    c}S c c}w c c}w )a'  Prepend a system prompt to message format inputs.

        Args:
            messages: List of message lists (each message list represents one input).
            prompt: System prompt to prepend.

        Returns:
            Messages with system prompt prepended to each message list.
        r   systemr   r   r   )rf   )rg   r   promptmessage_lists       r   prepend_prompt_to_messagesz)InputFormatter.prepend_prompt_to_messages  sy     &(_gh_g|h6:;lJ_ghh !)
 ( VV,L+MNOR^^ (
 	
 i
s
   AAc           	         g }|D ]N  }t        |t              r|j                  ||z          (|j                  ||d   z   gt        |dd       z          P |S )ab  Prepend a prompt to text format inputs.

        For single texts, prepends the prompt directly.
        For text pairs (cross-encoder inputs), prepends only to the first text.

        Args:
            texts: List of text inputs (strings or pairs)
            prompt: Prompt to prepend

        Returns:
            Texts with prompt prepended
        r   r2   N)r5   r9   rS   r7   )rg   textsr   resultr   s        r   prepend_prompt_to_textsz&InputFormatter.prepend_prompt_to_texts
  s[     D$$ftm,vQ/04QR>AB	 
 r   )r`   NN)rb   r9   rf   r   rd   list[Modality] | NonereturnNone)r   zLiteral['structured', 'flat'])r   list[SingleInput | PairInput]r   zBtuple[Modality, dict[str, list], defaultdict[str, dict[str, Any]]])rx   ztuple | listr   list[dict[str, Any]])user)r   zdict[Modality, Any]r3   r9   r   r   )r   r   r   r:   r   z*tuple[Literal['message'], dict[str, list]])r   list[list[dict[str, Any]]]r   bool)r   r   r   r   )r   r   r   r9   r   r   )r   z'list[str | tuple[str, str] | list[str]]r   r9   r   zlist[str | list[str]])__name__
__module____qualname____doc__rh   re   r   r}   r~   r   staticmethodr   r   r   r   rm   r   r   r^   r^      s    < )/6:11 &1
 41 
1 DmA-mA 
LmA^$
L
<0 0480	30:  0%N
2
<?
	#
&<FI	r   r^   c                   t         t        | t               ryt        t        | t              ryt        t        | t              ry| xt        d x\   t        |       r
 |d|vryy xt        d x\   t        |       r
 |d|vryy xt        d x\   t        |       r
 |d|vryy xxt        d x\     y x  r! dk(  r\  t        d x\   t        d x\     y  x  r! dk(  r\  t        d x\   t        d x\     y   xt        d x\   d| v rd| v r y	 xt        d x'\   | r$t        | d
   t              rd| d
   v r
d| d
   v r y	 xt        d x\   d| v rd| v r y xt        d x\   d| v rd| v r y xt        d x,\   d| v r' t        dt        | j                                       xt        d x\   | r t        | j                               t        z
  }|rt        d| dt        t                     t        |       dk(  rt!        t#        |             S t%        t        | j                                     S  xt        d x\    t        d       xt&        j(                  d x\   n xt*        j,                  d x\   n  nH | j.                  dv ry| j.                  dk(  ry| j.                  dv ryt        d| j.                   d      	 t        dt1        |       j2                   d      )ah  Infer the modality of a single input sample by inspecting its type/structure.

    Pure type-based detection, does not require a processor or tokenizer.

    Args:
        sample: A single input sample to inspect.
        supported_modalities: Optional list of modalities the model supports. When provided,
            string inputs that would be classified as image/video/audio based on URL/path
            heuristics are instead classified as ``"text"`` if that modality is not supported.
            This prevents misclassification of text that happens to contain media URLs.

    Returns:
        The detected modality string, or a tuple of modality strings for multimodal dict inputs
        with 2+ keys. A 1-key dict like ``{"image": pil}`` collapses to the bare modality string.

    Raises:
        ValueError: If the input type/structure is not recognized.
    imager@   rN   rm   r   r1   r3   r4   rz   r   rA   r?   rM   zuDict input with 'array' key must also include 'sampling_rate' (for audio) or 'video_metadata' (for video). Got keys: z;Multimodal dict input contains unrecognized modality keys: z. Expected keys from: r2   z-Empty dict input is not a valid input sample.)r2   r1      )      z#Unsupported tensor dimensionality: z<D. Expected 1-2D for audio, 3D for image, or 4-5D for video.zUnsupported input type: zG. Expected one of: str, dict, PIL.Image.Image, np.ndarray, torch.Tensor)PILImager5   r   r   r9   r*   r-   r/   r:   r7   r#   r   r|   r	   sortedr8   r   r   r6   npndarraytorchTensorndimr   r   )r;   rd   invalid_keyss      r   r{   r{   "  s   . 
68 <Jv|$DJv|$D
SU*62U#/GCW4W  SU*62U#/GCW4W  SU*62U#/GCW4W  5USU4 ^^ceSU4 $nnsuce4 '54TVv'I,?V TVv*VAY"=&FSTIBUZcgmnogpZpV TVw&(_-FV TVw&(-=-GV TVw&(V /02   TVvV v{{}-0DDL QR^Q_ `++12F+G*HJ  6{aDL)).//  TVLMM RZZ\NELLN*{{f$!& 9&++ GP Q  *4<+@+@*A BX Y r   c                    | sy| D ch c]  }t        ||       }}t        |      dk(  r|j                         S dS c c}w )a  Infer the modality of a batch of input samples.

    If all samples share the same modality, that modality is returned. If the batch contains
    mixed modalities, ``"message"`` is returned, consistent with how :class:`InputFormatter`
    handles mixed-modality batches in :meth:`~InputFormatter.parse_inputs`.

    Args:
        samples: List of input samples to inspect.
        supported_modalities: Optional list of modalities the model supports. Passed through
            to :func:`infer_modality` to prevent misclassification of text as media modalities.

    Returns:
        The detected modality, or ``"message"`` for mixed-modality batches.
    r   ry   r2   rz   )r{   r8   r   )rJ   rd   r;   r   s       r   infer_batch_modalityr     sL    $ bijbiX^.>RSbiJj":!3:>>BB ks   >c                H    t        | t              rdj                  |       S | S )zSFormat a modality for display, e.g. ``("text", "image")`` becomes ``"text+image"``.+)r5   r6   join)r   s    r   format_modalityr     s     (E"xx!!Or   c                2   dj                  d D              }|dk(  r	 | D ch c]  }t        |       }}|dhk(  rt        d| d| d      d|v rt        d| d| d      |rdj                  d	 t        |t        
      D              }|D 	ch c]  }t        |t              r|n|fD ]  }	|	   }
}}	t        fd|
D              }|r't        d| d| ddj                  |       d| d	      t        d| d| d      t        |t              r5t        fd|D              r!t        d| ddj                  |       d      t        dt        |       d| d| d      c c}w # t        t        f$ r t	               }Y Uw xY wc c}	}w )a  Raise a clear ``ValueError`` explaining why ``modality`` is not supported.

    Shared by :meth:`BaseModel.preprocess` and :meth:`Transformer.preprocess` so both raise the
    same, accurate guidance. ``source`` is a human-readable description of what rejected the input,
    e.g. ``"SentenceTransformer model"`` or ``"Transformer module"``.

    Args:
        inputs: The original batch of inputs, re-inspected per sample to distinguish explicit
            chat-style ``"message"`` inputs from inferred mixed-modality batches (both collapse to
            the ``"message"`` modality at the batch level).
        modality: The inferred (and unsupported) batch modality.
        supported_modalities: The modalities the source actually supports.
        source: Human-readable name of the rejecting component, used verbatim in the message.

    Raises:
        ValueError: Always, with a message tailored to the specific unsupported-modality scenario.
    z, c              3  2   K   | ]  }t        |        y wrl   r   rn   ms     r   rq   z3raise_unsupported_modality_error.<locals>.<genexpr>  s     O:NQoa0:N   rz   ry   zThis zy does not support chat-style 'message' inputs (dicts or lists of dicts with 'role' and 'content'). Supported modalities: .z does not support chat-style 'message' inputs (dicts or lists of dicts with 'role' and 'content'), which this batch mixes with other modalities. Supported modalities: c              3  2   K   | ]  }t        |        y wrl   r   r   s     r   rq   z3raise_unsupported_modality_error.<locals>.<genexpr>  s     #o@n1OA$6@nr   )keyc              3  ,   K   | ]  }|vs|  y wrl   rm   rn   partrd   s     r   rq   z3raise_unsupported_modality_error.<locals>.<genexpr>  s      f/$TQeEe/s   	z&This batch mixes multiple modalities (z), but this z does not support z. Supported modalities: z), which this zZ cannot encode in a single batch. Encode each modality separately (one call per modality).c              3  &   K   | ]  }|v  
 y wrl   rm   r   s     r   rq   z3raise_unsupported_modality_error.<locals>.<genexpr>  s     *]T\D43G+GT\rr   z
 supports z and zr individually, but cannot combine them in a single input. Encode each modality separately (one call per modality).z
Modality 'z' is not supported by this )
r   r{   r#   	TypeErrorr   r   r   r5   r6   r   )r   r   rd   sourcesupported_strr;   sample_modalitiespresent_strr   r   base_modalitiesunsupporteds     `         r    raise_unsupported_modality_errorr     s7   . IIO:NOOM9	&`f0`fV\v<PQ`f  0 +x  @@MaQ  )) x  ccpbqqrt  ))#oGX^m@n#ooK .?q->Q[\]_dQeAlmkoLo4tLot->Oq  f/ ffK <[MV\U] ^##'99[#9"::RS`Raabd  8^TZS[ \e f  (E"s*]T\*]']F8:gll8&<%= >g h
 	

 
_X.//J6( S!!.q	2 W0 I& 	& #	&( rs'   E3 E.E3 #F.E3 3FF)r   r9   r   r   )r   r9   r'   ztuple[str, ...]r   r   )r;   r   r   r   )rH   r
   rI   dict[str, dict[str, Any]]r   r   )rZ   r   rI   r   r   r   rl   )r;   zSingleInput | PairInput | Anyrd   r   r   r   )rJ   r   rd   r   r   r   )r   r   r   r9   )
r   r   r   r   rd   zlist[Modality]r   r9   r   r   )1r   
__future__r   loggingr%   collectionsr   typingr   r   r   urllib.parser   rG   r   r   )sentence_transformers.base.modality_typesr	   r
   r   r   r   r   r   	PIL.Imager   r   ImportErrortorchcodec.decodersr   r   OSError	getLoggerr   r   rs   r   r(   r*   r-   r/   r=   rK   r\   r^   r{   r   r   r   rm   r   r   <module>r     sj   G "  	 # ) ) !    +>
 
		8	$
 	% !H
	Fd$R
*",E ET 37\)\/\ \B 37C*C/C C0L)LL )L 	L
 LM  H
 	W LLs$   B= 	C
 =CC
CC