o
    iS                     @   s   d dl Z d dlmZ d dlZd dlZd dlmZ d dlm	Z	 d dl
mZ d dlmZmZmZmZmZ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 )    N)Sequence)Allow)make_tool_call_id)ChatCompletionRequest)DeltaFunctionCallDeltaMessageDeltaToolCallExtractedToolCallInformationFunctionCallToolCall)init_logger)TokenizerLike)MistralTokenizer)
ToolParserc                       s   e Zd Zdef fddZdefddZdedef fd	d
Zdedede	fddZ
dedededee dee dee dededB fddZ  ZS )Hermes2ProToolParser	tokenizerc                    s   t  | t|trtd |j _d _g  _	d _
g  _d _d _tdtj _tdtj _ js=td jj jdd	 _ jj jdd	 _ fd
d jD  _ fdd jD  _d _d S )Nz4Detected Mistral tokenizer when using a Hermes modelFz<tool_call>z</tool_call>z,<tool_call>(.*?)</tool_call>|<tool_call>(.*)z <scratch_pad>(.*?)</scratch_pad>zUThe model tokenizer must be passed to the ToolParser constructor during construction.)add_special_tokensc                       g | ]	} j |gqS  model_tokenizerdecode.0token_idselfr   Z/home/ubuntu/vllm_env/lib/python3.10/site-packages/vllm/tool_parsers/hermes_tool_parser.py
<listcomp>F       z1Hermes2ProToolParser.__init__.<locals>.<listcomp>c                    r   r   r   r   r   r   r   r   K   r     )super__init__
isinstancer   loggererrorr   r   current_tool_name_sentprev_tool_call_arrcurrent_tool_idstreamed_args_for_tooltool_call_start_tokentool_call_end_tokenrecompileDOTALLtool_call_regexscratch_pad_regex
ValueErrorencodetool_call_start_token_idstool_call_end_token_idstool_call_start_token_arraytool_call_end_token_arraybuffered_delta_text)r   r   	__class__r   r   r#   "   sD   




zHermes2ProToolParser.__init__
delta_textc                 C   sr   || j v s
|| jv r*|| j d ks|| jd kr"| j}d| _|| S | j| | _dS | jr7| j}d| _|| S |S )Nr   r!   )r6   r7   r8   )r   r;   buffered_textr   r   r   tool_call_delta_bufferW   s   

z+Hermes2ProToolParser.tool_call_delta_bufferrequestreturnc                    s&   t  |}|jr|jdkrd|_|S )NnoneF)r"   adjust_requesttoolstool_choiceskip_special_tokens)r   r>   r9   r   r   rA   s   s   z#Hermes2ProToolParser.adjust_requestmodel_outputc                 C   s   | j |vrtdg |dS z-| j|}dd |D }dd |D }|d || j  }td||r5|dW S d dW S  tyN   td tdg |d Y S w )NF)tools_called
tool_callscontentc                 S   s*   g | ]}t |d  r|d  n|d qS )r      )jsonloads)r   matchr   r   r   r      s    z;Hermes2ProToolParser.extract_tool_calls.<locals>.<listcomp>c              
   S   s2   g | ]}t d t|d tj|d ddddqS )functionname	argumentsFensure_ascii)rN   rO   )typerM   )r   r
   rJ   dumps)r   function_callr   r   r   r      s    Tz,Error in extracting tool call from response.)r+   r	   r0   findallfind	Exceptionr%   	exception)r   rE   r>   function_call_tuplesraw_function_callsrG   rH   r   r   r   extract_tool_calls|   s4   


z'Hermes2ProToolParser.extract_tool_callsprevious_textcurrent_textprevious_token_idscurrent_token_idsdelta_token_idsNc                 C   s  |  |}t|t| jkr)|t| j d  | jkr)|d t| j  }|| }td| td| | j|vrDtd t|dS z|| j}|| j}	|| j}
|| j}d }d }|
|krz|	|krz| j|vrztd t|dW S | j|v rtd || }|	| jd 	| jd 
 }|	| jd 
 }|	| jd  }| jrtjntjtj @ }|
|kr|
|krt|d	kr|	| jd }nd }d }d }|  jd	7  _d
| _| jd td| j n|
|kr|
|kr|	| jd }d }n|
|krw||	krw| jd u st| jdkr#td W d S | j| j d}|rv|tu r<|ddn|}d|vrFW d S |d}|d | d }td| | j| j  |7  < tt| jt|djdddgdW S n|| jd}|| jd}tg |d}|W S z|rt|pd|nd }td| W n& tjj j!y   td Y W d S  t"j#j$y   td Y W d S w | js|d u rW d S |d}|rd| _tt| jdt% t|djddd gdW S W d S |d u r|d urt|d}|W S d }|W S td!| j t| j| jkr(| ji  | j| j d}|d}td"| td#| |sQ|sQtd$| d }n|s_|r_t&d% d }n|r|s|d}t'(d&t')| d' |* t'j+}|r|,d	}nt"j-|d
d(}td)|| ||vrW d S ||t| }|d | }td*| tt| jt|djdddgd}| j| j  |7  < na|r-|r-z	t"| d}W n t.y   d
}Y nw t/|trt|
 d	kr|
 d d+kr|r|
 d d }td,| tt| jt|djdddgd}| j| j  |7  < | jt| jd	 krA|| j| j< |W S | j| |W S  t.yY   t0d- Y d S w ).Nzdelta_text: %szdelta_token_ids: %szNo tool call tokens found!)rH   z/Generating text content! skipping tool parsing.z!tool_call_end_token in delta_textr   r   rI   Fr!   zStarting on a new tool %sz/attempting to close tool call, but no tool callrO   zutf-8unicode_escapez"}z@Finishing tool and found diff that had not been streamed yet: %s)rO   T)exclude_none)indexrM   )rG   )rG   rH   z{}zParsed tool call %sz(not enough tokens to parse into JSON yetzunable to parse JSONrN   rM   )rN   )rc   rR   idrM   z,Trying to parse current tool call with ID %szdiffing old arguments: %szagainst new ones: %szSkipping text %s - no argumentszSshould be impossible to have arguments reset mid-call. skipping streaming anything.z\{"name":\s*"z"\s*,\s*"arguments":\s*(.*)rP   zfinding %s in %sz&First tokens in arguments received: %s}zgot diff %sz+Error trying to handle streaming tool call.)1r=   lenr8   r%   debugr+   r   countr,   splitrstriplstripr'   r   ALLSTRr)   r*   appendr(   getstrr3   r   rindexr   r   
model_dumpreplacepartial_json_parserrK   core
exceptionsMalformedJSONrJ   decoderJSONDecodeErrorr   r&   r-   searchescapestripr/   grouprS   rW   r$   rX   )r   r\   r]   r;   r^   r_   r`   r>   prev_tool_start_countprev_tool_end_countcur_tool_start_countcur_tool_end_counttool_call_portiontext_portion	full_textflagsdeltadiffend_loctextcurrent_tool_callfunction_nameprev_argumentscur_argumentsrL   cur_arguments_jsonargs_delta_start_locarguments_deltais_complete_jsonr   r   r   extract_tool_calls_streaming   s  


























	






z1Hermes2ProToolParser.extract_tool_calls_streaming)__name__
__module____qualname__r   r#   rp   r=   r   rA   r	   r[   r   intr   r   __classcell__r   r   r9   r   r   !   s8    5	
4	r   )rJ   collections.abcr   rt   regexr-    partial_json_parser.core.optionsr   vllm.entrypoints.chat_utilsr   0vllm.entrypoints.openai.chat_completion.protocolr   'vllm.entrypoints.openai.engine.protocolr   r   r   r	   r
   r   vllm.loggerr   vllm.tokenizersr   vllm.tokenizers.mistralr   &vllm.tool_parsers.abstract_tool_parserr   r   r%   r   r   r   r   r   <module>   s    