o
    
۾i{                     @   s   d dl Z d dlZd dlmZ d dlmZ d dl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 eeZG d	d
 d
eZdS )    N)Sequence)Any)ChatCompletionRequest)DeltaFunctionCallDeltaMessageDeltaToolCallExtractedToolCallInformationFunctionCallToolCall)init_logger)TokenizerLike)
ToolParserc                       s  e Zd Zdef fddZdefddZdd Zd	edefd
dZdedede	fddZ
de	dee fddZdedee de	fddZdededee fddZdededB dedB 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 )+MinimaxM2ToolParser	tokenizerc                    s>  t  | g | _d| _d| _d| _d| _d| _d| _d| _	d | _
g | _d| _d| _d| _d| _d| _d | _d | _d	| _d| _d| _d| _d	| _d| _d| _i | _d | _|   td
tj| _ tdtj| _!tdtj| _"| j#swt$d| j%&| j| _'| j%&| j| _(| j'd u s| j(d u rt)dt*+d| j,j- d S )Nz<minimax:tool_call>z</minimax:tool_call>z<invoke name=z	</invoke>z<parameter name=z</parameter>Fr    z,<minimax:tool_call>(.*?)</minimax:tool_call>z<invoke name=(.*?)</invoke>z!<parameter name=(.*?)</parameter>zUThe model tokenizer must be passed to the ToolParser constructor during construction.zTMiniMax M2 Tool parser could not locate tool call start/end tokens in the tokenizer!z)vLLM Successfully import tool parser %s !).super__init__prev_tool_call_arrtool_call_start_tokentool_call_end_tokeninvoke_start_prefixinvoke_end_tokenparameter_prefixparameter_end_tokencurrent_tool_name_sentcurrent_tool_idstreamed_args_for_toolis_tool_call_startedfailed_countcurrent_tool_indexinvoke_indexheader_sentcurrent_function_namecurrent_param_namecurrent_param_valueparam_countin_paramin_functionaccumulated_textjson_startedjson_closedaccumulated_paramsstreaming_request_reset_streaming_staterecompileDOTALLtool_call_complete_regexinvoke_complete_regexparameter_complete_regexmodel_tokenizer
ValueErrorvocabgettool_call_start_token_idtool_call_end_token_idRuntimeErrorloggerdebug	__class____name__)selfr   r=    \/home/ubuntu/.local/lib/python3.10/site-packages/vllm/tool_parsers/minimax_m2_tool_parser.pyr       sd   zMinimaxM2ToolParser.__init__returnc                 C   s   dt  jdd  S )zGenerate a unique tool call ID.call_N   )uuiduuid4hexr?   rA   rA   rB   _generate_tool_call_idf   s   z*MinimaxM2ToolParser._generate_tool_call_idc                 C   sx   d| _ d| _d| _d| _d| _d| _d| _d| _d| _d| _	d| _
d| _d| _d| _i | _d| _| j  | j  dS )zReset all streaming state.r   FNr   )r   r    r   r!   r   r"   r#   r$   r%   r&   r'   r(   r)   r*   r+   r,   r   clearr   rI   rA   rA   rB   r-   j   s$   
z*MinimaxM2ToolParser._reset_streaming_statename_strc                 C   s@   |  }|dr|ds|dr|dr|dd S |S )z Extract name from quoted string."'   )strip
startswithendswith)r?   rL   rA   rA   rB   _extract_name   s   z!MinimaxM2ToolParser._extract_namevalue
param_typec                 C   s   |  ||gS )zIConvert parameter value to the correct type (legacy single-type version).)_convert_param_value_with_types)r?   rU   rV   rA   rA   rB   _convert_param_value   s   z(MinimaxM2ToolParser._convert_param_valueschemac           	      C   s  |du rdgS t |tsdgS t }d|v r9|d }t |tr%|| nt |tr9|D ]}t |tr8|| q,d|v rt |d tr|d r|d D ]M}|du rX|d qLt |trc|d qLt |trn|d qLt |try|d qLt |tr|d qLt |tr|d	 qLt |tr|d
 qLdD ]}||v rt || tr|| D ]}| 	|}|
| qq|sdgS t|S )a5  
        Extract all possible types from a JSON schema definition.
        Handles anyOf, oneOf, allOf, type arrays, and enum fields.

        Args:
            schema: The JSON schema definition for a parameter

        Returns:
            List of type strings (e.g., ["string", "integer", "null"])
        Nstringtypeenumnullbooleanintegernumberarrayobject)anyOfoneOfallOf)
isinstancedictsetstraddlistboolintfloat_extract_types_from_schemaupdate)	r?   rY   types
type_valuetrU   choice_fieldchoice	extractedrA   rA   rB   ro      sP   












z.MinimaxM2ToolParser._extract_types_from_schemaparam_typesc              
   C   sJ  |  dv rdS dd |D }g d}|D ]|}||vrq|dv r$|  S |dv r;zt|W   S  ttfy:   Y qw |dv razt|}|t|krO|W   S t|W   S  ttfy`   Y qw |d	v rz|   }|d
v rr dS |dv ry dS q|dv rzt|W   S  tjy   Y qw qzt|W S  tjy   | Y S w )a<  
        Convert parameter value to the correct type based on a list of possible types.
        Tries each type in order until one succeeds.

        Args:
            value: The string value to convert
            param_types: List of possible type strings

        Returns:
            The converted value
        )r]   nonenilNc                 S   s   g | ]}|  qS rA   )lower).0rs   rA   rA   rB   
<listcomp>   s    zGMinimaxM2ToolParser._convert_param_value_with_types.<locals>.<listcomp>)r_   rm   r`   rn   r^   rl   rb   ra   rZ   ri   text)rZ   ri   r}   )r_   rm   )r`   rn   )r^   rl   )true1yesonT)false0nooffF)rb   ra   )	rz   rm   r5   	TypeErrorrn   rQ   jsonloadsJSONDecodeError)r?   rU   rw   normalized_typestype_priorityrV   val	lower_valrA   rA   rB   rW      sR   $z3MinimaxM2ToolParser._convert_param_value_with_types
param_nameparam_configc                 C   s0   ||vrdgS || }t |tsdgS | |S )a<  
        Get parameter types from parameter configuration.
        Handles anyOf, oneOf, allOf, and direct type definitions.

        Args:
            param_name: The name of the parameter
            param_config: The properties dict from the tool schema

        Returns:
            List of type strings
        rZ   )rf   rg   ro   )r?   r   r   param_schemarA   rA   rB   _get_param_types_from_config  s   

z0MinimaxM2ToolParser._get_param_types_from_config
invoke_strtoolsNc                 C   s,  t d|}|s
dS | |d}i }|r?|D ]&}t|dr>|jj|kr>t|jdr>|jj}t|t	r<d|v r<|d } nqi }| j
|D ]?}	t d|	t j}
|
r| |
d}|
d }|d	rm|dd }|d	rx|dd
 }| ||}| ||||< qGtdt|tj|ddddS )zParse a single <invoke> block.z^([^>]+)NrO   function
parameters
propertiesz^([^>]+)>(.*)   
rP   Fensure_asciiname	arguments)r[   r   )r.   searchrT   grouphasattrr   r   r   rf   rg   r3   findallr0   rQ   rR   rS   r   rW   r
   r	   r   dumps)r?   r   r   
name_matchfunction_namer   toolparams
param_dictmatchparam_matchr   param_valuerV   rA   rA   rB   _parse_single_invoke.  sN   


z(MinimaxM2ToolParser._parse_single_invokemodel_outputrequestc           	      C   s  | j |vrtdg |dS zag }| j|D ]}| j|D ]}| ||r'|jnd}|r1|| qq|s=tdg |dW S | j	  |D ]}| j|j
j|j
jd qD|| j }|dkrd|d| nd}td||dW S  ty   td tdg |d Y S w )z>Extract tool calls from complete model output (non-streaming).F)tools_called
tool_callscontentNr   r   TzError extracting tool calls)r   r   r1   r   r2   r   r   appendr   rK   r   r   r   find	Exceptionr;   	exception)	r?   r   r   r   tool_call_matchinvoke_match	tool_callfirst_tool_idxr   rA   rA   rB   extract_tool_callsc  sJ   




z&MinimaxM2ToolParser.extract_tool_callsprevious_textcurrent_text
delta_textprevious_token_idscurrent_token_idsdelta_token_idsc           /      C   sn  |r| j |v r|   || _|sM|rK| j|vrKt| j|}|dkrAt| jdkrA|| j || j	 }	|	dkr?t
ddS dS | jsK|rKt
ddS dS || _| jr|| js||| j}
|
| jkr||  jd7  _d| _d| _d| _d| _d| _i | _dS | js| j|v s| j |v rd| _| j |v r|d|| j  }|rt
|dS dS | | j	r| dkrdS t
|dS || j}| j|krdS g }d}	 || j|}|dkrn|| |t| j7 }q| jt|krdS || j }|| j|}|dkr||d }n|||t| j  }| js~| j|v r||| jt| j }|d	|}|dkr|||| }| || _|  | _ d| _d| _t| j| jkri| j| ji d
 t| j!| jkri| j!d t
t"| j| j t#| jdd
ddgdS dS | jr| jr| jsd| _| jt| j!k r| j!| j  d7  < t
t"| jt#dddgdS | jsd| _| jsT| j|v rT|| j$}| j|krRd| _|| jt| j }|| j|}|dkr!||| }z+| %|| jr| jj&nd}|r| jt| jk r|j'j(}t)*|| j| j d< W n
 t+y    Y nw t
t"| jt#dddgd}| jt| j!k rB| j!| j  d7  < d| _d| _i | _t,-d |S dS g }d}	 || j$|}|dkrfn|| |t| j$7 }qY| j.s| jt|k rt|| jkr|| j }|t| j$ }||d }d	|v r|d	} |d|  }!| |!| _/||  d }"||"d }#|#0dr|#dd }#|#| j1}$|$dkr|#| j$}%|#| j}&|%dkr|&dks|%|&k r|%}$n|&dkr|&}$n| j|v rt|#}$ndS |$dkr|#d|$ }'|'dr|'dd }'|'| j| j/< i }(| jr`| jj&r`| jj&D ]-})t2|)dr^|)j'j3| jkr^t2|)j'dr^|)j'j4}*t5|*t6r\d|*v r\|*d }( nq2| 7| j/|(}+| 8|'|+},t)j9|,dd}-| jdkrd| j/ d|- }.n	d| j/ d|- }.|  jd7  _| jt| j!k r| j!| j  |.7  < t
t"| jt#|.ddgdS dS )z/Extract tool calls from streaming model output.r   r   )r   NrO   FTrP   >r   r   )indexidr   r[   )r   {)r   )r   r   r   }z"[M2_STREAMING] Tool call completedr   r   r   r   rM   z": z, "):r   r-   r,   r9   lenr1   r   r   countr   r   r   r(   r*   r'   r   r   r!   r%   r)   r+   r8   r   rstriprS   rQ   r   r   r   rT   r"   rJ   r   r   r   r   r   r   r   r   r   r   r   r   r;   r<   r&   r#   rR   r   r   r   r   rf   rg   r   rW   r   )/r?   r   r   r   r   r   r   r   complete_calls
open_callsinvoke_endscontent_beforeinvoke_starts_countinvoke_start_positionsidxinvoke_start_idxinvoke_end_idx	tool_text
func_startfunc_endfunction_name_rawtotal_param_countinvoke_startinvoke_content_endinvoke_contentparsed_toolargsresultparam_starts	param_idxparam_start	remainingname_endparam_name_rawvalue_start
value_textparam_end_idxnext_param_idxfunc_end_idxr   r   r   r   rV   converted_valueserialized_valuejson_fragmentrA   rA   rB   extract_tool_calls_streaming  s  



















	


	









	z0MinimaxM2ToolParser.extract_tool_calls_streaming)r>   
__module____qualname__r   r   ri   rJ   r-   rT   r   rX   rk   ro   rW   rg   r   r
   r   r   r   r   r   rm   r   r   __classcell__rA   rA   r@   rB   r      sh    F<
I

5
6	r   )r   rF   collections.abcr   typingr   regexr.   0vllm.entrypoints.openai.chat_completion.protocolr   'vllm.entrypoints.openai.engine.protocolr   r   r   r   r	   r
   vllm.loggerr   vllm.tokenizersr   &vllm.tool_parsers.abstract_tool_parserr   r>   r;   r   rA   rA   rA   rB   <module>   s    