o
    پiT                     @   sn   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mZ d dl	m
Z
mZmZ eeZG dd deZdS )    N)List)Tool)BaseFormatDetector)StreamingParseResultStructureInfo_GetInfoFuncc                       s   e Zd ZdZ fddZdedefddZdedee	 de
fd	d
ZdedefddZdedee	 de
f fddZdefddZ  ZS )HermesDetectorz
    Detector for Hermes tool call format.

    Format:
        <tool_call>{"name": "...", "arguments": {...}}</tool_call>
    c                    s0   t    d| _d| _tdtj| _d| _d S )N<tool_call>z</tool_call>z,<tool_call>(.*?)</tool_call>|<tool_call>(.*) )	super__init__	bot_token	eot_tokenrecompileDOTALLtool_call_regex_normal_text_bufferself	__class__ \/home/ubuntu/.local/lib/python3.10/site-packages/sglang/srt/function_call/hermes_detector.pyr      s   

zHermesDetector.__init__textreturnc                 C   s
   | j |v S )N)r   )r   r   r   r   r   has_tool_call"   s   
zHermesDetector.has_tool_calltoolsc           
   
   C   s   | | j}|dkr|d|  n|}| j|vrt|g dS g }z:| j|D ],}|d p1|d }|s5q(t| }t|t	rK|
| || q(|
| || q(t||dW S  tyz }	 ztd|	  t|dW  Y d}	~	S d}	~	ww )zW
        One-time parsing: Detects and parses tool calls in the provided text.
        N)normal_textcallsr      zError in detect_and_parse: r   )findr   stripr   r   findalljsonloads
isinstancelistextendparse_base_json	Exceptionloggererror)
r   r   r   idxr   r    matchrawparseder   r   r   detect_and_parse%   s(   

zHermesDetector.detect_and_parsec                 C   s   |s|S |  j |7  _ | j| j v r| j | jd}d| _ |S | | j | j}|r;| j d |  }| j | d  | _ |S | j }d| _ |S )Nr
   )r   r   replace_ends_with_partial_token)r   r   cleanedpartial_len	safe_textr   r   r   _clean_normal_text>   s"   z!HermesDetector._clean_normal_textnew_textc           	         s   |  j |7  _ | j }| j|vr5| || j}|r(|d|  }|| d | _ n|}d| _ t| |dS || j}|dkrQ|d| }||d | _ t|dS t jd|d}|jrc| |j|_|S )zV
        Streaming parsing: handle normal text, partial tags, and tool calls.
        Nr
   r"   r   )r;   r   )	_bufferr   r6   r   r:   r#   r   parse_streaming_incrementr   )	r   r;   r   current_textr8   r9   bot_posr   resultr   r   r   r=   U   s&   

z(HermesDetector.parse_streaming_incrementc                 C   s   dd S )Nc                 S   s   t d|  d dddS )Nz<tool_call>{"name":"z", "arguments":z}</tool_call>r	   )beginendtrigger)r   )namer   r   r   <lambda>t   s
    
z/HermesDetector.structure_info.<locals>.<lambda>r   r   r   r   r   structure_infos   s   zHermesDetector.structure_info)__name__
__module____qualname____doc__r   strboolr   r   r   r   r4   r:   r=   r   rF   __classcell__r   r   r   r   r      s    	r   )r&   loggingr   typingr   &sglang.srt.entrypoints.openai.protocolr   -sglang.srt.function_call.base_format_detectorr   #sglang.srt.function_call.core_typesr   r   r   	getLoggerrG   r-   r   r   r   r   r   <module>   s    
