o
    i5                     @   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 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mZmZ eeZ G dd deZ!dS )    N)Sequence)Allow)PreTrainedTokenizerBase)make_tool_call_id)ChatCompletionRequest)DeltaFunctionCallDeltaMessageDeltaToolCallExtractedToolCallInformationFunctionCallToolCall)init_logger)
ToolParser)find_common_prefixis_complete_jsonpartial_json_loadsc                       sv   e Zd ZdZ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 )Llama3JsonToolParserz
    Tool call parser for Llama 3.x and 4 models intended for use with the
    examples/tool_chat_template_llama.jinja template.

    Used when --enable-auto-tool-choice --tool-call-parser llama3_json or
    llama4_json are set.
    	tokenizerc                    sZ   t  | g | _d| _d| _g | _d| _|j| jddd | _t	
d| _t | _d S )NFz<|python_tag|>)add_special_tokensr   z\{)super__init__prev_tool_call_arrcurrent_tool_idcurrent_tool_name_sentstreamed_args_for_tool	bot_tokenencodebot_token_idrecompiletool_call_start_regexjsonJSONDecoderjson_decoder)selfr   	__class__ Y/home/ubuntu/vllm_env/lib/python3.10/site-packages/vllm/tool_parsers/llama_tool_parser.pyr   /   s   zLlama3JsonToolParser.__init__model_outputrequestreturnc                 C   s  | j |v sd|v stdg |dS d}g }z| jj|tjdD ]}| }||kr)qz4| j||d \}}|| }|d }	d|v rF|d n|d	 }
|	t
d
t|	tj|
dddd W q ty } zt|d}td| tdg |dW  Y d}~  W S d}~w ty   td tdg |d Y   W S w W n ty   td td| tdg |d Y S w |rtd|ddS tdg |dS )z
        Extract the tool calls from a complete model response.
        Only extracts JSON content and ignores any surrounding plain text.
        Supports both single JSON and multiple JSONs separated by semicolons.
        {F)tools_called
tool_callscontentr   )timeoutNname	arguments
parametersfunctionensure_ascii)r2   r3   )typer5   z'"zCouldn't extract tool call from JSON response. Required key '%s' not present. Returning output in content with empty tool calls.z^Error in extracting tool call from response. Returning output in content with empty tool callsz7Regex timeout occurred when matching tool call pattern.z3Regex timeout occurred when matching user input: %sT)r   r
   r!   finditerenvs%VLLM_TOOL_PARSE_REGEX_TIMEOUT_SECONDSstartr$   
raw_decodeappendr   r   r"   dumpsKeyErrorstrstriplogger	exception	ExceptionTimeoutErrorwarningdebug)r%   r*   r+   	end_indexr/   matchstart_indexobjjson_end_indexr2   arguments_or_paramsemissing_keyr(   r(   r)   extract_tool_callsC   s   	

5


z'Llama3JsonToolParser.extract_tool_callsprevious_textcurrent_text
delta_textprevious_token_idscurrent_token_idsdelta_token_idsNc                 C   s  | | js| dst|dS | jrtjntjtj @ }zg }	g }
zR| | jr/t| jnd}|t|k rtt||d  |\}}|
	t
||||   ||td 7 }d|v rid|vscJ d|d |d< |		| |t|k s7W n tjjjy   td Y W d S w t|	dkr|	| j ni }t|	dkrW d S t|	dkrt|	| jd	 kr| jdkr|d}|rtj|d
d}t| j| j }||d  }td| tt| jt|djdddgd}| j| j  |7  < nd }nd }t|	d	 | _d
| _| j	d td| j |W S | js;|d}|r8tt| jdt t|djdddgd}d| _nod }nl|d}d }|rt| j| j }tj|d
d}| j| j d}d }|
| j rl||d  }n|rtj|d
d}||krt||}||d  }|d urtt| jt|djdddgd}| j| j  |7  < |	| _|W S  ty   td td Y d S w )Nr-   )r0   r   z; r4   r3   z-model generated both parameters and argumentsz(not enough tokens to parse into JSON yet   Fr6   zgot arguments diff: %s)r3   T)exclude_none)indexr5   )r/    zstarting on new tool %dr2   r5   )r2   )rZ   r8   idr5   z+Error trying to handle streaming tool call.z=Skipping chunk as a result of tool streaming extraction error)
startswithr   r   r   r   ALLSTRlenr   r>   r   partial_json_parsercore
exceptionsMalformedJSONrC   rH   r   getr"   r?   r   r	   r   
model_dumpr   r   r   rE   rD   )r%   rR   rS   rT   rU   rV   rW   r+   flagstool_call_arris_complete	start_idxrL   end_idxcurrent_tool_callcur_argumentscur_args_jsonsentargument_diffdeltafunction_nameprev_argumentsprev_args_jsonprefixr(   r(   r)   extract_tool_calls_streaming   s   





"









z1Llama3JsonToolParser.extract_tool_calls_streaming)__name__
__module____qualname____doc__r   r   rA   r   r
   rQ   r   intr   rv   __classcell__r(   r(   r&   r)   r   &   s6    
]	r   )"r"   collections.abcr   ra   regexr    partial_json_parser.core.optionsr   transformersr   	vllm.envsr:   vllm.entrypoints.chat_utilsr   0vllm.entrypoints.openai.chat_completion.protocolr   'vllm.entrypoints.openai.engine.protocolr   r   r	   r
   r   r   vllm.loggerr   &vllm.tool_parsers.abstract_tool_parserr   vllm.tool_parsers.utilsr   r   r   rw   rC   r   r(   r(   r(   r)   <module>   s    