o
    iq`                     @   s   d dl Z d dlmZ d dlmZmZmZ d dl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)AnyOptionalUnion)ChatCompletionRequest)make_tool_call_id)DeltaFunctionCallDeltaMessageDeltaToolCallExtractedToolCallInformationFunctionCallToolCall)
ToolParser)init_logger)TokenizerLike)random_uuidc                       s   e Zd Zdef fddZdedeee e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edf fddZ  ZS )xLAMToolParser	tokenizerc                    sR   t  | g | _d| _d| _g | _g | _g | _g d| _d| _	dg g d| _
d S )NF)z```(?:json)?\s*([\s\S]*?)```z \[TOOL_CALLS\]([\s\S]*?)(?=\n|$)z!<tool_call>([\s\S]*?)</tool_call>z</think>([\s\S]*)current_tool_indextool_ids
sent_tools)super__init__prev_tool_callscurrent_tool_idcurrent_tool_name_sentstreamed_argscurrent_tools_sentprev_tool_call_arrjson_code_block_patternsthinking_tag_patternstreaming_state)selfr   	__class__ X/home/ubuntu/vllm_env/lib/python3.10/site-packages/vllm/tool_parsers/xlam_tool_parser.pyr       s   
zxLAMToolParser.__init__model_outputreturnc                 C   s  t | j|}|r`|d| td   }|d }z
t| ||fW S  tj	y_   | j
D ])}t ||}|r\|D ]}zt| ||fW      Y S  tj	y[   Y q?w q3Y nw | j
D ]0}t ||}|r|D ]#}zt| t |d| }||fW     S  tj	y   Y qow qc| drz
t| d|fW S  tj	y   d|v rd|v rd|v rd|f Y S Y |dfS Y |dfS Y |dfS w |dfS )	z
        Preprocess the model output to extract content and potential tool calls.
        Returns:
            Tuple of (content, potential_tool_calls_json)
        Nz</think>    [{name	arguments)researchr"   startlenstripgroupjsonloadsJSONDecodeErrorr!   findallsub
startswith)r$   r)   thinking_matchcontentthinking_contentjson_patternjson_matchesjson_strr'   r'   r(   preprocess_model_output>   sd   	








z&xLAMToolParser.preprocess_model_outputrequestc              
   C   s@  z~|  |\}}|stdg |dW S t|}t|ts+td tdg |p'|dW S g }t|D ]A\}}t|t	rBd|vsBd|vrItd| q1t
d| dt  d	t|d t|d t	ret|d n|d d
d}	||	 q1tt|dk||dW S  ty }
 ztdt|
 tdg |dW  Y d}
~
S d}
~
ww )zB
        Extract tool calls from a complete model output.
        F)tools_called
tool_callsr>   zTool calls data is not an arrayr/   r0   z$Invalid tool call format at index %dcall__function)r/   r0   )idtyperI   r   zError extracting tool calls: %sN)rC   r   r7   r8   
isinstancelistloggerdebug	enumeratedictr   r   r   dumpsappendr4   	Exception	exceptionstr)r$   r)   rD   r>   potential_tool_callstool_calls_datarF   idxcall	tool_caller'   r'   r(   extract_tool_callsz   sZ   



z!xLAMToolParser.extract_tool_callsprevious_textcurrent_text
delta_textprevious_token_idscurrent_token_idsdelta_token_idsNc           *   
   C   s  |  }| |\}	}
d|v pd|v pd|v pd|v }|dp;|dp;|dp;d|v p;|
dup;|o;d|v o;d	|v }|sCt|d
S zmt| dsQdg g d| _z|
rV|
n|}t|}t|t	re|| _
W n
 tjyp   Y nw t| drt| jdkrt| jdkr| jd du rd}t||}|r|d}t }ttdd|t|djdddgd}dg| _d| _d| jd< t| jd dkr| jd dddd n	d| jd d d< d| _|W S |
r|
n|}|
s|rtd|}|r|d  }|drd|v rd	|v r|}d}t	t||}t|}|dkr5d}t	t||}|r2W dS W dS t| jd |k rU| jd dddd t| jd |k s?t| jd  |k rq| jd  d t| jd  |k s_| jd }|dks||d k r|d }||k r| jd | d s|| jd< || _|}|| d}d!| d"t  }|| jd  |< tt|d|t|djdddgd}d| jd | d< d| _t| j|kr| jd t| j|ks|W S |dkr||k rd#}t||}|r| dkrd} t|D ]o}!|!|kr~| jd | d$ s~d| jd | d$< d%| jd | d&< t| j|krI| jd t| j|ks;| j|  d%7  < tt|td%d'jddd(gd}||d k ry| jd  d7  < | jd | _|  W S qd)}"t	t|"|}#|t|#k r|#| d}$||d k}%|dkrz1t|}t|t	r|t|k r|| }&t|&d*trt|&d* }$nt |&d*d%}$W n tjt!t"fy   Y nw | jd | d& }'| jd | d$ sA|$d+rAd| jd | d$< d+| jd | d&< t| j|kr$| jd t| j|ks| j|  d+7  < tt|td+d'jddd(gd}|W S |$|'r|$t|'d }(|(r|$| jd | d&< t| j|krq| jd t| j|ksc| j|  |(7  < tt|t|(d'jddd(gd}|W S |$#d,r|$|'kr||d k r| jd  d7  < | jd | _W dS  t$y }) zt%&d-|)  t|d
W  Y d})~)S d})~)ww ).z8
        Extract tool calls for streaming mode.
        z```jsonz```
[z[TOOL_CALLS]z<tool_call>r-   z	</think>[Nz"name"z"arguments")r>   r#   r   r   r   r   r+   Fz"name"\s*:\s*"([^"]+)"rI   )r/   T)exclude_none)indexrK   rJ   rI   )rF   r   r   r,   )	sent_namesent_arguments_prefixsent_argumentsrf   z"```(?:json)?\s*([\s\S]*?)(?:```|$)z"name"\s*:\s*"([^"]*)r   rG   rH   z4"name"\s*:\s*"[^"]+"\s*,\s*"arguments"\s*:\s*\{\s*\}rg   z{}rh   )r0   )re   rI   zL"name"\s*:\s*"[^"]+"\s*,\s*"arguments"\s*:\s*(\{(?:[^{}]|(?:\{[^{}]*\}))*\})r0   r.   }zError in streaming tool calls: )'r5   rC   r<   r	   hasattrr#   r7   r8   rL   rM   r    r9   r4   r   r1   r2   r6   r   r
   r   
model_dumpr   rS   r   finditerr   r   r3   rangegetrQ   rR   rV   KeyError
IndexErrorendswithrT   rN   rU   )*r$   r^   r_   r`   ra   rb   rc   rD   stripped_textpreprocessed_contentpreprocessed_tool_callshas_potential_json_blockis_tool_call_blocktool_calls_textparsed_toolsname_pattern
name_matchfunction_nametool_iddeltasearch_text
json_matchpotential_jsonname_matches
tool_countpartial_name_patternpartial_matchescurrent_idxnext_idx	tool_nameempty_args_patternempty_args_matchempty_args_tool_idxiargs_patternargs_matches	args_textis_last_toolcurrent_tool	sent_args	args_diffr\   r'   r'   r(   extract_tool_calls_streaming   s  











	









z+xLAMToolParser.extract_tool_calls_streaming)__name__
__module____qualname__r   r   rV   tupler   rC   r   r   r]   r   intr   r	   r   __classcell__r'   r'   r%   r(   r      s>    
<
@
	r   )r7   collections.abcr   typingr   r   r   regexr1   0vllm.entrypoints.openai.chat_completion.protocolr   vllm.entrypoints.chat_utilsr   'vllm.entrypoints.openai.engine.protocolr   r	   r
   r   r   r   &vllm.tool_parsers.abstract_tool_parserr   vllm.loggerr   vllm.tokenizersr   
vllm.utilsr   r   rN   r   r'   r'   r'   r(   <module>   s    