o
    ˜à·i«  ã                   @   s|   d dl mZ d dlmZ d dlmZ d dlmZ d dlm	Z	 d dl
mZ d dlmZ d dlmZ e	eƒZG d	d
„ d
eƒZdS )é    )ÚSequence)Úcached_property)ÚChatCompletionRequest)ÚResponsesRequest)Úinit_logger)ÚReasoningParser)ÚBaseThinkingReasoningParser)ÚMistralTokenizerc                	   @   sœ   e Zd ZdZdefdd„Zedefdd„ƒZedefdd	„ƒZ	d
e
e defdd„Zd
ee dee fdd„ZdedeeB deedB edB f fdd„ZdS )ÚMistralReasoningParsera‡  
    Reasoning parser for Mistral models.

    The Mistral models uses `[THINK]`...`[/THINK]` tokens to denote reasoning
    text. This parser extracts the reasoning content from the model output.

    A valid reasoning trace should always start with a `[THINK]` token and end with
    a `[/THINK]` token.

    If `[THINK]` token is not generated, then this parser only returns content.
    Ú	tokenizerc                 O   sz   t |tƒs	tdƒ‚tj| |g|¢R i |¤Ž | jstdƒ‚|j | j¡| _	|j | j
¡| _| j	d u s7| jd u r;tdƒ‚d S )Nz6The tokenizer must be an instance of MistralTokenizer.zZThe model tokenizer must be passed to the ReasoningParser constructor during construction.zRMistral reasoning parser could not locate think start/end tokens in the tokenizer!)Ú
isinstancer	   Ú
ValueErrorr   Ú__init__Úmodel_tokenizerr   Úget_control_tokenÚstart_tokenÚstart_token_idÚ	end_tokenÚend_token_idÚRuntimeError)Úselfr   ÚargsÚkwargs© r   ú]/home/ubuntu/vllm_env/lib/python3.10/site-packages/vllm/reasoning/mistral_reasoning_parser.pyr   "   s   
ÿÿÿzMistralReasoningParser.__init__Úreturnc                 C   ó   ddl m} |jS )z(The token that starts reasoning content.r   ©ÚSpecialTokens)Ú%mistral_common.tokens.tokenizers.baser   Úbegin_think©r   r   r   r   r   r   7   ó   z"MistralReasoningParser.start_tokenc                 C   r   )z&The token that ends reasoning content.r   r   )r   r   Ú	end_thinkr!   r   r   r   r   >   r"   z MistralReasoningParser.end_tokenÚ	input_idsc                 C   s<   d}|d d d… D ]}|| j kr|  S || jkrd}q	dS )NFéÿÿÿÿT)r   r   )r   r$   Úhas_eot_tokenÚidr   r   r   Úis_reasoning_endE   s   

€z'MistralReasoningParser.is_reasoning_endc                 C   s°   d}d}d}d}t |ƒD ]\}}|| jkr|sd}|}q|| jkr'd}|} nq|r2|s2|d|… S |s8|s8|S |rJ|rJ|d|… ||d d…  S |d|… ||d d…  S )z%
        Extract the content
        Fr%   TNé   )Ú	enumerater   r   )r   r$   Úhas_bot_tokenr&   Úbot_token_indexÚeot_token_indexÚiÚtoken_idr   r   r   Úextract_content_idsP   s(   
ýz*MistralReasoningParser.extract_content_idsÚmodel_outputÚrequestNc                 C   s®   |sdS |  | j¡\}}}t|ƒ}|o| j|v }|r2|r2|  | j¡\}}	}
||
 }||r/|fS dfS |r=||r:|fS dfS | j|v }|rS|  | j¡\}}	}
d||
 fS d|fS )zB
        Extract reasoning content from the model output.
        )NÚ N)Ú	partitionr   Úboolr   )r   r1   r2   Úprev_bot_tokenÚ	bot_tokenÚpost_bot_tokenr+   Úhas_valid_eot_tokenÚprev_eot_tokenÚ_Úpost_eot_tokenÚcontentÚhas_non_valid_eot_tokenr   r   r   Úextract_reasonings   s(   
ÿ

ÿz(MistralReasoningParser.extract_reasoning)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r	   r   r   Ústrr   r   r   Úintr5   r(   Úlistr0   r   r   Útupler?   r   r   r   r   r
      s     #ÿÿþr
   N)Úcollections.abcr   Ú	functoolsr   Ú0vllm.entrypoints.openai.chat_completion.protocolr   Ú*vllm.entrypoints.openai.responses.protocolr   Úvllm.loggerr   Úvllm.reasoningr   Úvllm.reasoning.basic_parsersr   Úvllm.tokenizers.mistralr	   r@   Úloggerr
   r   r   r   r   Ú<module>   s   