
    .`ia                         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Z	d dl
m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          Z G d de          ZdS )    N)Sequence)Any)ParserCreate)make_tool_call_id)ChatCompletionRequestChatCompletionToolsParam)DeltaFunctionCallDeltaMessageDeltaToolCallExtractedToolCallInformationFunctionCallToolCall)init_logger)TokenizerLike)
ToolParserc                      e Zd ZdZd Zd ZdedefdZdedefdZ	de
fd	Zd
ede
fdZdedeedz  ef         fdZdedefdZdedefdZdefdZd+dedz  fdZdedeeef         fdZdefdZdefdZd Zdee         dz  fdZdedeeef         dedz  fd Zdedeeef         dedz  fd!Zd"edefd#Zd$edefd%Zd&ed$ede fd'Z!d(e d$edefd)Z"d* Z#dS ),StreamingXMLToolCallParserze
    Simplified streaming XML tool call parser
    Supports streaming input, parsing, and output
    c                     |                                   d | _        d| _        d| _        d| _        d| _        d| _        d| _        d S )N<tool_call>z</tool_call>
<function=z</function>z<parameter=</parameter>)reset_streaming_statetoolstool_call_start_tokentool_call_end_tokenfunction_start_tokenfunction_end_tokenparameter_start_tokenparameter_end_tokenselfs    z/home/jaya/work/projects/VOICE-AGENT/VIET/agent-env/lib/python3.11/site-packages/vllm/tool_parsers/qwen3xml_tool_parser.py__init__z#StreamingXMLToolCallParser.__init__'   sT    ""$$$ =A
*7"(6 )5!'4*7"(6       c                 z   g | _         d| _        d| _        d| _        d| _        d| _        i | _        d| _        d| _        d| _	        d| _
        d| _        d| _        d| _        d| _        d| _        d| _        d| _        d| _        d| _        d| _        t+                      | _        |                                  dS )zReset streaming parsing stater   NF )deltastool_call_indexcurrent_call_idlast_completed_call_idcurrent_function_namecurrent_function_open
parameterscurrent_param_namecurrent_param_valuecurrent_param_value_convertedcurrent_param_is_firstshould_emit_end_newlinestart_quote_emittedstreaming_bufferlast_processed_postext_content_buffer_pre_inside_parameter_pre_param_buffer_pre_current_param_namedefer_current_parameterdeferred_param_raw_valuer   parsersetup_parserr    s    r"   r   z0StreamingXMLToolCallParser.reset_streaming_state3   s      #&*#%)"%*""&#% -/*&+#',$#(  ""##%  &+"!#'+$',$(*% #nnr$   	xml_chunkreturnc                     t           j                  } xj        |z  c_                                         }|r9	  j        |d         } j        ^ j        |v rUt           fd|D                       }|s8 j        r                     d            j	        r                     d            j        s j
        |v rjt           fd|D                       }|sM j        r                     d            j	        r                     d                                d           n2# t          $ r%}t                              d|           Y d}~nd}~ww xY w                     |          }|S  j        r> j        dk    r3t#           j        	          }	                     |	           d
 _        |	S  j         j        |v s	 j
        |v rv j        r                     d            j        |v r j	        r                     d            j
        |v r                     d                                |          }|S t#          d	          S )a  
        Parse single streaming XML chunk and return Delta response
        This is the actual streaming interface that receives chunks
        one by one and maintains internal state

        Args:
            xml_chunk: Single XML chunk string
        Returns:
            DeltaMessage: Contains delta information generated by this chunk,
            returns empty response if no complete elements
        Nc              3   f   K   | ]+}|j         ot          fd |j         D                       V  ,dS )c              3      K   | ]H}|j         o<|j        j        k    o,t          |j         j        t
                    o|j         j        d v V  IdS ))}{}N)functionidr)   
isinstance	argumentsstr.0tcr!   s     r"   	<genexpr>zUStreamingXMLToolCallParser.parse_single_streaming_chunks.<locals>.<genexpr>.<genexpr>x   s{       $ $ %' %'K %O(*1E(E%O(22;3H#(N(N%O *,)>+)M$ $ $ $ $ $r$   N
tool_callsanyrK   tdr!   s     r"   rM   zKStreamingXMLToolCallParser.parse_single_streaming_chunks.<locals>.<genexpr>u   w       - -  M 	 # $ $ $ $ +--$ $ $ ! !- - - - - -r$   	parameterrE   c              3   f   K   | ]+}|j         ot          fd |j         D                       V  ,dS )c              3   |   K   | ]6}|j         d k    o&|j        o|j        j        dk    o|j        j        k    V  7dS )rE   r&   N)typerE   rH   rF   r)   rJ   s     r"   rM   zUStreamingXMLToolCallParser.parse_single_streaming_chunks.<locals>.<genexpr>.<genexpr>   ss       $ $ %' %'Gz$9 %F(*%F(*(=(C%F )+1E(E$ $ $ $ $ $r$   NrN   rQ   s     r"   rM   zKStreamingXMLToolCallParser.parse_single_streaming_chunks.<locals>.<genexpr>   rS   r$   	tool_callzError with fallback parsing: %sr   contentr&   )lenr'   r4   _process_complete_xml_elementsr)   r   rP   r.   _end_elementr+   r   	Exceptionloggerwarning$_merge_new_deltas_to_single_responser6   r(   r
   _emit_delta)
r!   r>   initial_delta_countfound_elements
new_deltashas_function_closehas_toolcall_closeeresult_delta
text_deltas
   `         r"   parse_single_streaming_chunksz8StreamingXMLToolCallParser.parse_single_streaming_chunksU   s$    "$+..*<<>> f	.<E![)<)=)=>
 (4/9<< *- - - - - #-- - - * *& . :2 ; --k:::5 : --j999 (40I==), - - - - #-- - - * *& . 72 ; --k:::5 : --j999))+666 E E E@!DDDDDDDDE  DD# L   ' "D,@A,E,E)$2JKKK
  ,,,+-(!! #/'944+y88 * 3%%k222*i77D<V7%%j111+y88%%k222#HH'    $#  ----s   C.D- -
E7EEtextc                 v    dddddd}|                                 D ]\  }}|                    ||          }|S )z
        Escape XML special characters
        Args:
            text: Original text
        Returns:
            Escaped text
        z&amp;z&lt;z&gt;z&quot;z&apos;)&<>"')itemsreplace)r!   rl   xml_escapescharescapes        r"   _escape_xml_special_charsz4StreamingXMLToolCallParser._escape_xml_special_chars   sZ     
 
 (--// 	. 	.LD&<<f--DDr$   c                    d}| j         t          | j                  k     r<|                     | j                   \  }}|n|                     |          r|| _         \	 |                     |          }|                                                    d          s'|                                                    d          rC| j        dk    r8| j	        r1t          | j	                  }|                     |           d| _	        |                                                    d          r| j        dk    r| j        r| j        r|                     d           | j        s| j        r|                     d	           t          dddt#          | j        d
z
  | j        d	t%          dd                    g          }|                     |           |                                  | j                            |d           d}n2# t,          $ r%}t.                              d|           Y d}~nd}~ww xY w|| _         | j         t          | j                  k     <|S )z
        Process complete XML elements in buffer

        Returns:
            bool: Whether complete elements were found and processed
        FNr   z<function name=r   rY   r&   rT   rE      namerH   indexrF   rW   rE   )rolerZ   	reasoningrO   Tz#Error when parsing XML elements: %s)r5   r[   r4   _find_next_complete_element_should_skip_element_preprocess_xml_chunkstrip
startswithr(   r6   r
   rb   r)   r.   r]   r,   r+   r   r	   !_reset_xml_parser_after_tool_callr<   Parser^   r_   r`   )r!   	found_anyelementend_pospreprocessed_elementrj   final_deltarh   s           r"   r\   z9StreamingXMLToolCallParser._process_complete_xml_elements   s    	%D,A(B(BBB#??@WXXGW ((11 *1'3I'+'A'A''J'J$ -2244??NN2 05577BBCTUU2
 ,11. 2 ".d6N!O!O!OJ$$Z000/1D,
 )..00;;MJJ=,q00, 1 . 7))+6661 6T5O 6))*555".! $"&)&*&:Q&>#'#7%/):PR)S)S)S	  $	# # #K $$[111::<<<!!"6>>> 		 I I IDaHHHHHHHHI '.D#G %D,A(B(BBBJ s    F%H 
H5H00H5r   c                     |                     | j                  s4|                     | j                  s|                     | j                  rdS | j        |r| xj        |z  c_        dS | j        dS | S )z
        Determine whether an element should be skipped

        Args:
            element: Element to evaluate

        Returns:
            bool: True means should skip, False means should process
        FNT)r   r   r   r   r)   r6   )r!   r   s     r"   r   z/StreamingXMLToolCallParser._should_skip_element5  s     t9::	!!$";<<	 !!$"<==	
 5 'G'$$/$$4 +5 {r$   	start_posNc                    | j         |d         }|sd|fS |                    d          r|                    dd          }|                    dd          }|dk    r0|dk    r*||k     r|d|         ||z   fS |d|dz            ||z   dz   fS |dk    r|d|         ||z   fS |dk    r|d|dz            ||z   dz   fS | j        g|ddt	          |                   k    rd|fS |                    d          s|ddt	          |                   k    rd|fS ||t	          |          z   fS d|fS |                    d          }|dk    r|d|         }|||z   fS |}||t	          |          z   fS )a  
        Find next complete XML element from specified position

        Args:
            start_pos: Position to start searching

        Returns:
            (Complete element string, element end position),
            returns (None, start_pos) if no complete element found
        Nro   rz   rp   r   r   )r4   r   findr)   r[   )r!   r   buffertag_endtag_end2next_tag_postext_content	remainings           r"   r   z6StreamingXMLToolCallParser._find_next_complete_elementY  s    &yzz2 	#?"S!! 1	= kk#q))G{{3**H"}}RX%%!(7(+Y-@@@ ".HqL.19x3G!3KKKBhwh'W)<<<Rn1n-y8/Ca/GGG '/}V}!===#Y.)),77	?!\-CKK-%@@@  $Y.  &y3v;;'>>>  ?* ";;s++Lr!!%m|m4#Y%=== #	 )c)nn"<<<r$   initial_countc                    t          | j                  |k    rt          d          S | j        |d         }t          |          dk    r|d         S g }d}|D ]}|j        r
||j        z  }|j        r|j        D ]}d}|D ]}|j        |j        k    r|} n|r|j        r|j        r"|j        j        r|j        j        |j        _        |j        rE|j        j        9|j        j        d|j        _        |j        j        }	|j        xj        |	z  c_        |j	        r|j	        |_	        |
                    |           Ōt          |r|nd|          S )a  
        Merge newly generated deltas from this processing
        into a single DeltaMessage

        Args:
            initial_count: Delta count before processing

        Returns:
            Merged DeltaMessage containing all newly generated delta information
        NrY   rz   r   r&   )rZ   rO   )r[   r'   r
   rZ   rO   rF   rE   r|   rH   rW   append)
r!   r   re   merged_tool_callsmerged_contentdeltarX   existing_callexistingnew_argss
             r"   ra   z?StreamingXMLToolCallParser._merge_new_deltas_to_single_response  s    t{},,---- [0
z??aa=  24   	<  	<E} 0%-/ <!&!1 < <I$(M$5 " "#;),66,4M!E 7 % <)? <$- R)2D2I R:C:L:QM27%.
I ) 2 < H,5?GCE 6 @ (1'9'CH)2<<H<<$> @1:M. *00;;;;&4>NN$(
 
 
 	
r$   chunkc                    d}|                     | j                  s|                     | j                  rd}|                     | j                  s|                     | j                  rd}|                     | j                  s|                     | j                  rd}t          j        dd|          }t          j        dd|          }|}| j	        r|                     d          rD| j
        }d| _        || _        d| _	        d| _
        d	| _        |                     |          }| dS | j
        dk    r| j        r|                     | j                  nd
}|dv }|dv p)|                     d          p|                     d          }	d|v pd|v pd|v }
d}|	rd}n
|r|
rd|v rd}|sd| _	        |                     |          S | xj
        |z  c_
        dS |                     d          rAt          j        d|          }|r|                    d          | _        d| _	        d| _
        |S |s|                     |          }|S )z
        Preprocess XML chunk, handle non-standard formats,
        and escape special characters

        Args:
            chunk: Original XML chunk

        Returns:
            Processed XML chunk
        FTz<function=([^>]+)>z<function name="\1">z<parameter=([^>]+)>z<parameter name="\1">r   r&   Nstring)object)arrayarrsequencedictlist[{(rr   z<parameter name=z<parameter name="([^"]+)">rz   )r   r   r   r   r   r   r   resubr7   r8   r:   r;   r9   rx   _get_param_typematchgroup)r!   r   is_tool_call	processedoriginal_chunk	body_text	safe_text
param_typeis_object_typeis_complex_typehas_container_hint
need_deferms                r"   r   z0StreamingXMLToolCallParser._preprocess_xml_chunk  s
    D677 	 5;K;K$<
 <
 	   LD566 	 %:J:J#;
 ;
 	   LD677 	 5;K;K$<
 <
 	   LF02I5QQ	F13KYWW	% @	 ##N33 = 2	 04,09--2*)+&/3, ::9EE	#1111 )R//  7&,,T-IJJJ%  &0:%=N"&BB 9%00889%0088 $ . 3>13>1 ' "'J& 
*%)

&*.* !N22 &*
% N 6;2#==nMMM&&.8&&r  233 	6	BBA :/0wwqzz,)-D&%'D"
  	B66yAAIr$   r   c                 :    | j                             |           dS )z&Emit Delta response (streaming output)N)r'   r   )r!   r   s     r"   rb   z&StreamingXMLToolCallParser._emit_deltaO  s    5!!!!!r$   incoming_tagc                     | j         r|                     d           |dv r| j        r|                     d           |dk    r| j        r|                     d           dS dS dS )a  Before starting to process new elements,
        if there are unclosed tags from before,
        automatically complete their endings to the parser.
        - If there are unclosed parameters,
        it's equivalent to feeding `</parameter>`
        - When about to start a new function or tool_call,
        if there are unclosed functions, complete `</function>`.
        - When about to start a new tool_call,
        if there are unclosed tool_calls, complete `</tool_call>`.
        rT   )rE   rX   rE   rX   N)r.   r]   r+   r)   )r!   r   s     r"   $_auto_close_open_parameter_if_neededz?StreamingXMLToolCallParser._auto_close_open_parameter_if_neededS  s     " 	+k*** 4449S4j))) ;&&4+?&k***** '&&&r$   r|   attrsc                    |dk    rdS |dk    rH|                      d           i | _        t                      | _        d| _        | xj        dz  c_        dS |                    d          s|dk    r| j        s|                     di            |                      d           |                     ||          }|| _	        d| _
        |rUt          t          | j        dz
  | j        dt          |d          	          g
          }|                     |           dS dS |                    d          s|dk    r|                      d           |                     ||          }|| _        d| _        d| _        d| _        |r| j        sbd| d}t          t          | j        dz
  | j        dt          d|          	          g
          }|                     |           d| _        dS d| d}t          t          | j        dz
  | j        dt          d|          	          g
          }|                     |           d| _        dS dS dS )zHandle XML start element eventsrootNrX   Trz   rE   r&   r{   r}   rO   rT   Fz{"z": z, ")r   r-   r   r)   r1   r(   r   _start_element_extract_function_namer+   r,   r
   r   r	   rb   _extract_parameter_namer.   r/   r0   r3   )r!   r|   r   function_namer   
param_name
json_startjson_continues           r"   r   z)StreamingXMLToolCallParser._start_elementl  s    6>>F; 55kBBB DO#4#6#6D *.D'  A%    __Z(( I	8TZ-?-?' 5##K444 55jAAA 77eDDM)6D&)-D& ($%"&"6":#3!+%6%2b& & &	  	      '''''( ( __[)) 1	8dk.A.A 55kBBB55dEBBJ&0D#')D$13D.',D$
  $8 #8 "7z!6!6!6J()&*&:Q&>#'#7%/):)-*" *" *"	  	$  E $$U+++26D/// %:*$9$9$9M()&*&:Q&>#'#7%/):)-*" *" *"	  	$  E $$U+++27D///I$8 $8 /B.Ar$   datac                    |r| j         r| j        rM|}| j        rd|z   }d| _        |                    d          rd| _        |dd         }| xj        |z  c_        dS |                     | j                   }| j        s|                    d          r
|dd         }|dv ra| j        sZt          t          | j
        dz
  | j        dt          dd	
                    g          }|                     |           d| _        |sdS |}| j        rd|z   }d| _        |                    d          rd| _        |dd         }| xj        |z  c_        |                     | j        |          }|                     ||          }|t!          | j                  d         }|| _        t          t          | j
        dz
  | j        dt          d|
                    g          }|                     |           dS dS dS )z Handle XML character data events
FTNr   rz   r   rI   rl   varcharrv   enumrE   rq   r{   r}   r   )r.   r:   r2   endswithr/   r   r   r3   r
   r   r(   r)   r	   rb   _convert_param_value_convert_for_json_streamingr[   r0   )	r!   r   original_datar   quote_deltaconverted_valueoutput_data
delta_datar   s	            r"   
_char_dataz%StreamingXMLToolCallParser._char_data  s    G	$D+ G	$ + 	 $/ 9$(=$8M38D0 ))$// 737D0$1#2#$6M((M9((--d.EFFJ +  0E0E  ABBx RRR0 S +%"&"6":#3!+%6DC%P%P%P	   	 	 	   ---+/(  M+ 5 $} 4/4,%%d++ 3/3, -crc 2$$5$$ #77(* O ::?JWWK$S)K%L%L%N%NOJ1<D. !"2Q6/'!2
!S!S!S	  	 	 	E U#####OG	$ G	$ G	$ G	$r$   c                    |dk    rdS |                     d          s|dk    s|dk    r| j        r|                                  |                     d          s|dk    r3| j        r+| j        }| j        }| j        r| j        r| j        n|}d}d}	 | j        r|dz   }n|}t          j        |          }t          j
        |d          }n(# t          $ r t          j
        |d          }|}Y nw xY wt          t          | j        d	z
  | j        dt!          d|
                    g          }|                     |           d| _        || j        |<   d| _        d| _        d| _        d| _        d| _        d| _        dS |                     |          }	|                     ||	          }
|	dv r|s[| j        sTt          t          | j        d	z
  | j        dt!          dd
                    g          }|                     |           nSt          t          | j        d	z
  | j        dt!          dd
                    g          }|                     |           d| _        |
| j        |<   d| _        d| _        d| _        d| _        dS |                     d          s|dk    r| j        rTt          t          | j        d	z
  | j        dt!          dd
                    g          }|                     |           nSt          t          | j        d	z
  | j        dt!          dd
                    g          }|                     |           d| _        dS |dk    r| j        r1| j        r|                     d           |                     d           t          t          | j        d	z
  | j        dt!          dd
                    g          }|                     |           | j                                        r*t          | j                  }|                     |           |                                  dS dS )zHandle XML end element eventsr   NrE   rX   rT   r   Fensure_asciirz   r{   r}   r   r&   r   z""rq   rC   rD   rY   )r   r.   r   r/   r:   r;   r2   astliteral_evaljsondumpsr^   r
   r   r(   r)   r	   rb   r-   r0   r3   r   r   r,   r]   r6   r   r   )r!   r|   r   param_valueraw_textparsed_valueoutput_argumentsraw_for_parser   r   r   rj   s               r"   r]   z'StreamingXMLToolCallParser._end_element  s|    6>>F
 OOJ''	8+/:+=+=ATAT% BU55777 OOK((]	5,0K,?,?% -@ 0J2K
 + - 4%D11$ 
  $#' , 3 1(04(0#&#3M#B#BL'+z,U'S'S'S$$  , , ,'+z('O'O'O$#+LLL,
 %%"&"6":#3!+%6%)5E& & &	  	      ''' 05,.:
+*.'+-(572+0(/4,02---j99J #77ZPPO QQQ" ,4+C , ))&*&:Q&>#'#7%/):PT)U)U)U	  $	 	 	E $$U++++ ))&*&:Q&>#'#7%/):PS)T)T)T	  $	 	 	E $$U++++0D(*9DOJ'&*D#')D$13D.',D$$$__Z(( 8	5DJ,>,> ($%"&"6":#3!+%6DC%P%P%P	   	 	 	   '''' %%"&"6":#3!+%6DD%Q%Q%Q	   	 	 	   ''').D&&&[   ) .* 3%%k222!!*--- !"2Q6/'!2!K!K!K	  	 	 	E U### '--// -)$2JKKK
  ,,,22444447 ! s   9C "C32C3c                     d| j         _        | j        | j         _        | j        | j         _        | j        | j         _        dS )z Set up XML parser event handlersTN)r<   buffer_textr   StartElementHandlerr]   EndElementHandlerr   CharacterDataHandlerr    s    r"   r=   z'StreamingXMLToolCallParser.setup_parser  s8    "&*.*='(,(9%+/?(((r$   r   c                     || _         dS )z"Set tool configuration informationN)r   )r!   r   s     r"   	set_toolsz$StreamingXMLToolCallParser.set_tools  s    


r$   c                     |rd|v r|d         S d|v r=|                     dd          }t          |          dk    r|d         dk    r|d         S dS )z*Extract function name from various formatsr|   =rz      r   rE   Nsplitr[   r!   r|   r   partss       r"   r   z1StreamingXMLToolCallParser._extract_function_name  sc     	!Vu__= $;;JJsA&&E5zzQ58z#9#9Qxtr$   c                     |rd|v r|d         S d|v r=|                     dd          }t          |          dk    r|d         dk    r|d         S dS )z+Extract parameter name from various formatsr|   r   rz   r   r   rT   Nr   r   s       r"   r   z2StreamingXMLToolCallParser._extract_parameter_name  sc     	!Vu__= $;;JJsA&&E5zzQ58{#:#:Qxtr$   r   c           	         | j         r| j        sdS | j         D ]n}t          |d          r%t          |d          rt          |j        d          s9|j        dk    r)|j        j        | j        k    rt          |j        d          s dS |j        j        }t          |t                    rjd|v rf|d         }||v rYt          ||         t                    r>| 	                    t          ||                             dd                              c S nnt          |t                    rY||v rU||         }t          |t                    r8| 	                    t          |                    dd                              c S  npdS )zGet parameter type based on tool configuration, defaults to string
        Args:
            param_name: Parameter name

        Returns:
            Parameter type
        r   rW   rE   r|   r-   
properties)r   r+   hasattrrE   rW   r|   r-   rG   r   repair_param_typerI   get)r!   r   toolparamsr   param_configs         r"   r   z*StreamingXMLToolCallParser._get_param_type  s    z 	!; 	8J 	 	D4(( j)).5dmV.L.L 	Z''M&$*DDDt}l;; $#881fd++ 0F0F!'!5J!Z//J":.5 5/  $55
: 6 : :68 L LMM        -- *2F2F#)*#5L!,55 #55 0 0 B BCC       xr$   r   c                    |dv s|                     d          s|                     d          s|                     d          s|                     d          sq|                     d          s\|                     d          sG|                     d          s2|d	v s.|d
v s*|                     d          s|                     d          r|S dS )zRepair unknown parameter types by treating them as string
        Args:
            param_type: Parameter type

        Returns:
            Repaired parameter type
        r   intuintlongshortunsignednumfloatbooleanboolbinary)r   r   r   r   r   r   r   )r   )r!   r   s     r"   r   z,StreamingXMLToolCallParser.repair_param_type  s    NNN$$U++ O$$V,, O $$V,, O $$W--	 O
 $$Z00 O $$U++ O $$W-- O :::DDD((00 E((00 E
 8r$   r   c                 R   |                                 dk    rdS |                                                                 }|dv r|S |                    d          sT|                    d          s?|                    d          s*|                    d          s|                    d          rD	 t          |          S # t          t
          f$ r t                              d	|           Y nw xY w|S |                    d
          s|                    d          rk	 t          |          }|t          |          z
  dk    r|nt          |          S # t          t
          f$ r t                              d|           Y nw xY w|S |dv r|                                 }|dk    S |S )zConvert value based on parameter type
        Args:
            param_value: Parameter value
            param_type: Parameter type

        Returns:
            Converted value
        nullNr   r   r   r  r  r  z[Parsed value '%s' of parameter '%s' is not an integer in tool '%s', degenerating to string.r  r  r   zXParsed value '%s' of parameter '%s' is not a float in tool '%s', degenerating to string.r  true)	lowerr   r   r   
ValueError	TypeErrorr_   r`   r  )r!   r   r   float_param_values       r"   r   z/StreamingXMLToolCallParser._convert_param_value$  s    &((4%%''--//
MMM!!%((#	$$V,,#	 $$V,,#	 $$W--	#	
 $$Z00#	;'''	*   <     ""5)) 	Z-B-B7-K-K 	+0+=+=! )3/@+A+AAQFF &%.//
 	*   <     888%++--K&((s$   1C   ,C/.C/5E ,FFr   c                     ||dk    rdS |dv rt          j        |d          dd         S t          |t                    st          j        |d          S |S )a   Convert converted_value based on
        whether it's empty and if type is string
        Args:
            converted_value: Converted value
            param_type: Parameter type

        Returns:
            Converted string for streaming output
        Nr&   r   Fr   rz   r   )r   r   rG   rI   )r!   r   r   s      r"   r   z6StreamingXMLToolCallParser._convert_for_json_streamingX  sr     "o&;&;2MMM:oEBBB1R4HH os33 'z/FFFF&&r$   c                 Z   t                      | _        |                                  | j        r| j        | _        d| _        d| _        d| _        i | _        d| _        d| _	        d| _
        d| _        d| _        d| _        d| _        d| _        d| _        d| _        d| _        d| _        dS )z
        Each tool_call is treated as a separate XML document,
        so we need to reset the parser after each tool_call.
        NFr&   )r   r<   r=   r)   r*   r+   r,   r-   r.   r/   r0   r1   r2   r3   r6   r7   r8   r9   r:   r;   r    s    r"   r   z<StreamingXMLToolCallParser._reset_xml_parser_after_tool_callp  s     #nn  	?*.*>D'#%)"%*""&#% -/*&+#',$#( #%  &+"!#'+$',$(*%%%r$   )N)$__name__
__module____qualname____doc__r#   r   rI   r
   rk   rx   r  r\   r   r   tupler   ra   r   rb   r   r   r   r   r]   r=   r   r   r   r   r   r   r   r   r   r   r    r$   r"   r   r   !   sI        

7 
7 
7     Dy.s y.| y. y. y. y.vc c    *N N N N N`"C "D " " " "HA=S A=U3:s?=S A= A= A= A=F>
# >
, >
 >
 >
 >
@q3 q3 q q q qf" " " " "+ +t + + + +2X83 X8tCH~ X8 X8 X8 X8tI$s I$ I$ I$ I$Vj5 j5 j5 j5 j5X; ; ;t$<=D    
3 
tCH~ 
#PT* 
 
 
 

C 
S#X 
3QU: 
 
 
 
&# &# & & & &PC C    82 2 2 2 2 2 2h'3 'C 'TW ' ' ' '0+ + + + +r$   r   c                        e Zd Zdef fdZdededefdZdeded	ed
e	e
         de	e
         de	e
         dededz  fdZ xZS )Qwen3XMLToolParser	tokenizerc                     t                                          |           t                      | _        g | _        g | _        t                              d| j        j	                   d S )Nz)vLLM Successfully import tool parser %s !)
superr#   r   r<   prev_tool_call_arrstreamed_args_for_toolr_   info	__class__r  )r!   r  r!  s     r"   r#   zQwen3XMLToolParser.__init__  sd    ###022 /113#79P	
 	
 	
 	
 	
r$   model_outputrequestr?   c                 \   | j                                          g | _        g | _        |r| j                             |j                   | j                             |          }|j        st          g d|j	                  S g }|j        D ]z}|j
        ro|j
        j        rb|                    t          |j        |j        t!          |j
        j        |j
        j                                       |j        |j        nt'          | j                  dz
  }t'          | j                  |k    r5| j                            ddd           t'          | j                  |k    5t'          | j                  |k    r2| j                            d           t'          | j                  |k    2|j
        j        | j        |         d<   |j
        j        | j        |         d<   |j
        j        r|j
        j        | j        |<   |t          |t'          |          d	k    |j	                  S )
NF)rO   tools_calledrZ   r{   )rF   rW   rE   rz   r&   r|   rH   r   )r<   r   r  r  r   r   rk   rO   r   rZ   rE   r|   r   r   rF   rW   r   rH   r~   r[   )r!   r"  r#  resultrO   rX   
tool_indexs          r"   extract_tool_callsz%Qwen3XMLToolParser.extract_tool_calls  sc   
 	))+++"$&(# 	1K!!'-000::<HH  4	/"    J#. & &	% %)*<*A %%% (|!*%1%.%7%<*3*<*F& & &  	 	 	 %?6 " !899A=  d566*DD/66QS7T7TUUU d566*DDd9::jHH3::2>>> d9::jHH
 "*/ +J7? "*4 +J7D
 !)3 %.8 3J? 0% __q0   r$   previous_textcurrent_text
delta_textprevious_token_idscurrent_token_idsdelta_token_idsNc                 b   |sH| j                                          g | _        g | _        |r| j                             |j                   |sw|ru|                    | j         j                  |                    | j         j                  z
  }|dk    r| j         j	        dk    s| j         j	        s|rt          d          S d S | j                             |          }	|	rN|	j        rF|	j        D ]=}
|
j        r2|
j        |
j        nt          | j                  dz
  }t          | j                  |k    r5| j                            ddd           t          | j                  |k    5t          | j                  |k    r2| j                            d           t          | j                  |k    2|
j        j        r|
j        j        | j        |         d<   |
j        j        D| j        |         dxx         |
j        j        z  cc<   | j        |xx         |
j        j        z  cc<   ?|	S )Nr   r&   rY   rz   r{   r|   rH   )r<   r   r  r  r   r   countr   r   r(   r
   rk   rO   rE   r~   r[   r   r|   rH   )r!   r)  r*  r+  r,  r-  r.  r#  
open_callsr&  rX   r'  s               r"   extract_tool_calls_streamingz/Qwen3XMLToolParser.extract_tool_calls_streaming  s     	5K--///&(D#*,D' 5%%gm444  	o 	%++1 ""4;#BCCDJ aK/!33{2 4  4 $B////4 :::FF  	f' 	#.  	%  %?6 " !899A=  d566*DD/66QS7T7TUUU d566*DDd9::jHH3::2>>> d9::jHH !). %.3 /
;FC
 !)3? /
;KHHH%.8HHH 3J???%.8??? r$   )r  r  r  r   r#   rI   r   r   r(  r   r   r
   r2  __classcell__)r!  s   @r"   r  r    s        

- 

 

 

 

 

 

@@ '@ 
&	@ @ @ @DFF F 	F
 %SMF $C=F "#F 'F 
	F F F F F F F Fr$   r  ) r   r   collections.abcr   typingr   xml.parsers.expatr   regexr   vllm.entrypoints.chat_utilsr   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   r  r_   r   r  r  r$   r"   <module>r>     s   


  $ $ $ $ $ $       * * * * * *     9 9 9 9 9 9                       $ # # # # # ) ) ) ) ) )      
X		m+ m+ m+ m+ m+ m+ m+ m+`#U U U U U U U U U Ur$   