o
    -i$                     @   s   d dl Z 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
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ChatCompletionToolsParam)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e	 dB de
fddZdedede
d	edef
ddZded
ee	 dB dedB fddZdedee 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 )$Qwen3CoderToolParser	tokenizerc                    s   t  | d| _g | _d | _g | _d| _d| _d| _d| _	d| _
d| _d| _d| _|   td	tj| _td
tj| _tdtj| _tdtj| _| jsUtd| j| j| _| j| j| _| jd u so| jd u rstdtd| jj  d S )NFz<tool_call>z</tool_call>z
<function=z</function>z<parameter=z</parameter>r   z<tool_call>(.*?)</tool_call>z.<tool_call>(.*?)</tool_call>|<tool_call>(.*?)$z*<function=(.*?)</function>|<function=(.*)$zB<parameter=(.*?)(?:</parameter>|(?=<parameter=)|(?=</function>)|$)zUThe model tokenizer must be passed to the ToolParser constructor during construction.zSQwen3 XML Tool parser could not locate tool call start/end tokens in the tokenizer!z)vLLM Successfully import tool parser %s !)!super__init__current_tool_name_sentprev_tool_call_arrcurrent_tool_idstreamed_args_for_tooltool_call_start_tokentool_call_end_tokentool_call_prefixfunction_end_tokenparameter_prefixparameter_end_tokenis_tool_call_startedfailed_count_reset_streaming_staterecompileDOTALLtool_call_complete_regextool_call_regextool_call_function_regextool_call_parameter_regexmodel_tokenizer
ValueErrorvocabgettool_call_start_token_idtool_call_end_token_idRuntimeErrorloggerinfo	__class____name__)selfr   r0    e/home/ubuntu/veenaModal/venv/lib/python3.10/site-packages/vllm/tool_parsers/qwen3coder_tool_parser.pyr   !   sP   zQwen3CoderToolParser.__init__returnc                 C   s   dt  jdd  S )zGenerate a unique tool call ID.call_N   )uuiduuid4hexr2   r4   r4   r5   _generate_tool_call_idY   s   z+Qwen3CoderToolParser._generate_tool_call_idc                 C   s^   d| _ d| _d| _d| _d| _d| _d| _d| _d| _d| _	d| _
d| _d| _i | _d| _dS )zReset all streaming state.r   FN )current_tool_indexr   header_sentr   current_function_namecurrent_param_namecurrent_param_valueparam_countin_paramin_functionaccumulated_textjson_startedjson_closedaccumulated_paramsstreaming_requestr<   r4   r4   r5   r   ]   s   
z+Qwen3CoderToolParser._reset_streaming_state	func_nametoolsNc                 C   s   |du ri S |D ]H}t |drt |drt |jdsq|jdkrP|jj|krPt |jds0i   S |jj}t|trCd|v rC|d   S t|trL|  S i   S qtd| i S )z.Extract argument configuration for a function.Ntypefunctionname
parameters
propertiesz+Tool '%s' is not defined in the tools list.)	hasattrrO   rN   rP   rQ   
isinstancedictr.   debug)r2   rL   rM   configparamsr4   r4   r5   _get_arguments_configp   s*   


z*Qwen3CoderToolParser._get_arguments_configparam_value
param_nameparam_configc              
   C   s  |  dkrdS ||vr|i krtd|| |S t|| tr3d|| v r3t|| d    }nd}|dv r;|S |dsT|dsT|d	sT|d
sT|drozt|W S  t	t
fyn   td||| | Y S w |dsy|drzt|}|t| dkr|W S t|W S  t	t
fy   td||| | Y S w |dv r|  }|dvrtd||| |dkS |dv s|ds|drzt|}|W S  tjt
t	fy   td||| Y nw zt|}W |S  t	tt
fy   td||| Y |S w )z8Convert parameter value based on its type in the schema.nullNzoParsed parameter '%s' is not defined in the tool parameters for tool '%s', directly returning the string value.rN   string)r^   strtextvarcharcharenumintuintlongshortunsignedz[Parsed value '%s' of parameter '%s' is not an integer in tool '%s', degenerating to string.numfloatr   zXParsed value '%s' of parameter '%s' is not a float in tool '%s', degenerating to string.)booleanboolbinary)truefalsezmParsed value '%s' of parameter '%s' is not a boolean (`true` or `false`) in tool '%s', degenerating to false.rn   )objectarrayarrrU   listzvParsed value '%s' of parameter '%s' cannot be parsed with json.loads in tool '%s', will try other methods to parse it.z}Parsed value '%s' of parameter '%s' cannot be converted via Python `ast.literal_eval()` in tool '%s', degenerating to string.)lowerr.   rV   rT   rU   r_   strip
startswithrd   r(   	TypeErrorrj   jsonloadsJSONDecodeErrorastliteral_evalSyntaxError)r2   rZ   r[   r\   rL   
param_typefloat_param_valuer4   r4   r5   _convert_param_value   s   
		
	
z)Qwen3CoderToolParser._convert_param_valuefunction_call_strc                 C   s   | d}|d | }| ||}||d d  }i }| j|D ]7}| d}	|d |	 }
t||	d d  }|drC|dd  }|drN|d d }| ||
||||
< q!tdt	|t
j|dddd	S )
N>   
rO   Fensure_asciirP   	arguments)rN   rO   )indexrY   r&   findallr_   rv   endswithr   r   r
   rx   dumps)r2   r   rM   	end_indexfunction_namer\   rQ   
param_dict
match_textidxr[   rZ   r4   r4   r5   _parse_xml_function_call   s,   




z-Qwen3CoderToolParser._parse_xml_function_callmodel_outputc                 C   s^   | j |}dd |D }t|dkr|g}g }|D ]}|| j| qdd |D }|S )Nc                 S   $   g | ]}|d  r|d  n|d qS r   r   r4   .0matchr4   r4   r5   
<listcomp>      z<Qwen3CoderToolParser._get_function_calls.<locals>.<listcomp>r   c                 S   r   r   r4   r   r4   r4   r5   r     r   )r$   r   lenextendr%   )r2   r   matched_rangesraw_tool_callsraw_function_calls	tool_callfunction_callsr4   r4   r5   _get_function_calls  s   z(Qwen3CoderToolParser._get_function_callsrequestc           	         s
  j |vrtdg |dS zc|}t|dkr tdg |dW S  fdd|D }j  |D ]}|rBj|jj|jj	d q1|
j}|
j }|dkrU|n|}|d | }tt|dk||rk|dW S d dW S  ty   td tdg |d Y S w )NF)tools_called
tool_callscontentr   c                    s   g | ]	} | jqS r4   )r   rM   )r   r   r   r2   r4   r5   r   5  s    z;Qwen3CoderToolParser.extract_tool_calls.<locals>.<listcomp>r   z,Error in extracting tool call from response.)r   r	   r   r   r   clearappendrO   rP   r   findr   	Exceptionr.   	exception)	r2   r   r   r   r   r   content_indexr   r   r4   r   r5   extract_tool_calls#  sN   





z'Qwen3CoderToolParser.extract_tool_callsprevious_textcurrent_text
delta_textprevious_token_idscurrent_token_idsdelta_token_idsc           3         sX  |s	    | _|sH|rF j|vrFt j|}|dkr<t jdkr<| j| j	 }	|	dkr:t
ddS d S  jsF|rFt
ddS d S | _ jr js| j	}
|
 jkr  jd7  _d _d _d _d _i  _| j} j|krd _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sv j|v rt| jt j }|d|}|dkrt|||  _   _d _d _t fd	d
 jD }|sa j jdd t
t  j jt! jddddgdS d S  jr* js j"|vrd _t
t  jt!dddgdS  jsd _ js j#|v rd _| jt j }| j#|}|dkr||| }z5 $| jr҈ jj%nd }|rt& jD ]\}}|'d|j(j)kr|j(j*}| j| d<  nqW n
 t+y   Y nw t
t  jt!dddgd}d _d _i  _|S g }d}	 | j"|}|dkr1n|| |t j"7 }q$ j,s= jt|k r=t| jkr=| j }|t j" }||d  } d| v r=| d}!| d |!  _-||! d }"||"d  }#|#.dr|#dd  }#|# j/}$|$dkr|# j"}%|# j#}&|%dkr|&dks|%|&k r|%}$n|&dkr|&}$n j	|v rt|#}$nd S |$dkr=|#d |$ }'|'dr|'d d }'|' j j-<  0 jpd jr jj%nd }( 1|' j-|( jpd})t2j3|)dd}* jdkrd j- d|* }+n	d j- d|* }+  jd7  _t
t  jt!|+ddgdS  j,r* j/|v r| j/},|d |, }- j4sid|-v ri|-d}.|-|.d d  }- j4sy|-.dry|-dd  }- j4|- }/|/ j j-<  0 jpd jr jj%nd }( 1|/ j-pd|( jpd})t2j3|)dd}*d _,d _4t
t  jt!dddgdS |}- j4sd|-v r|-d}.|-|.d d  }- j4s|-.dr|-dd  }-|-r* j4rt2j3 j4dddd nd}0  j4|-7  _4t2j3 j4dddd }1|1t|0d  }2|2r*t
t  jt!|2ddgdS d S )Nr   r>   )r   r   FTr   r   c                 3   s     | ]}| d  jkV  qdS )rP   N)r*   rA   )r   toolr<   r4   r5   	<genexpr>  s
    
zDQwen3CoderToolParser.extract_tool_calls_streaming.<locals>.<genexpr>z{}r   rO   )r   idrO   rN   )r   {)r   )r   rO   rP   r   }r   r   "z": z, ")5r   rK   r,   r   r#   r   r   countr   r   r   r   rG   rI   rF   r?   r@   rD   rH   rJ   r+   r   rstripr   ru   r   r   r   rA   r=   r   anyr   r   r   r   r   rM   	enumerater*   rO   rP   r   r   rE   rB   rv   r   rY   r   rx   r   rC   )3r2   r   r   r   r   r   r   r   complete_calls
open_calls	tool_endstool_startscontent_beforetool_starts_counttool_start_positionsr   tool_start_idxtool_end_idx	tool_text
func_startfunc_endalready_addedfunc_content_endfunc_contentparsed_toolir   argsresultparam_starts	param_idxparam_start	remainingname_endvalue_start
value_textparam_end_idxnext_param_idxfunc_end_idxrZ   r\   converted_valueserialized_valuejson_fragmentend_idxvalue_chunkgt_idx
full_valueprev_escapedfull_escapeddelta_escapedr4   r<   r5   extract_tool_calls_streamingW  s<  






















	









	





z1Qwen3CoderToolParser.extract_tool_calls_streaming)r1   
__module____qualname__r   r   r_   r=   r   rs   r   rU   rY   r   r   r   r   r   r   r	   r   r   rd   r   r   __classcell__r4   r4   r3   r5   r       sl    8


j


4	r   )r{   rx   r9   collections.abcr   typingr   regexr    0vllm.entrypoints.openai.chat_completion.protocolr   r   'vllm.entrypoints.openai.engine.protocolr   r   r   r	   r
   r   vllm.loggerr   vllm.tokenizersr   &vllm.tool_parsers.abstract_tool_parserr   r1   r.   r   r4   r4   r4   r5   <module>   s    