o
    پi!                     @   s  d dl Z d dlmZmZmZmZmZmZmZm	Z	 d dl
mZmZmZmZmZ d dlmZmZ d dlmZ d dlmZ d dlmZ d dlmZ d d	lmZ d d
lmZ d dlm Z  d dl!m"Z" d dl#m$Z$ d dl%m&Z& d dl'm(Z( d dl)m*Z* d dl+m,Z, d dl-m.Z. d dl/m0Z0 d dl1m2Z2 d dl3m4Z4 d dl5m6Z6 d dl7m8Z8 d dl9m:Z: d dl;m<Z< d dl=m>Z> d dl?m@Z@ e AeBZCG dd dZDdS )    N)DictListLiteralOptionalSetTupleTypeUnion)!LegacyStructuralTagResponseFormatStructuresResponseFormatToolToolCallConstraint
ToolChoice)ToolStrictLevelenvs)BaseFormatDetector)ToolCallItem)DeepSeekV3Detector)DeepSeekV31Detector)DeepSeekV32Detector)GigaChat3Detector)Glm4MoeDetector)Glm47MoeDetector)GptOssDetector)HermesDetector)InternlmDetector)KimiK2Detector)Lfm2Detector)Llama32Detector)MiMoDetector)MinimaxM2Detector)MistralDetector)PythonicDetector)Qwen3CoderDetector)Qwen25Detector)Step3Detector)TrinityDetector)get_json_schema_constraintc                   @   s6  e Zd ZU dZi dedededededede	d	e
d
ededededededededeeeeeeedZeeee f ed< dee defddZ dede!fddZ"dede#ee$e% f fddZ&d ede#ee$e% f fd!d"Z'de(fd#d$Z)d%e*e+e,d& f de-e. fd'd(Z/d)S )*FunctionCallParseraX  
    Parser for function/tool calls in model outputs.

    This class handles both streaming and non-streaming parsing of function calls using a detector.
    In streaming scenarios, each time new_text is received, it calls detector.parse_streaming_increment
    and returns the resulting normal_text and calls to the upper layer (or SSE).
    
deepseekv3deepseekv31deepseekv32glmglm45glm47zgpt-osskimi_k2lfm2llama3mimomistralpythonicqwenqwen25qwen3_coderstep3)step3p5z
minimax-m2trinityinterns1hermes	gigachat3ToolCallParserEnumtoolstool_call_parserc                 C   sB   | j |}|r| }ntd| || _|| _tj | _d S )NzUnsupported tool_call_parser: )r>   get
ValueErrordetectorr?   r   SGLANG_TOOL_STRICT_LEVELtool_strict_level)selfr?   r@   detector_classrC    rH   a/home/ubuntu/.local/lib/python3.10/site-packages/sglang/srt/function_call/function_call_parser.py__init__J   s   zFunctionCallParser.__init__textreturnc                 C   s   | j sdS | j|S )a6  
        Check if the given text contains a tool call in the format supported by this parser.
        This delegates to the detector's implementation.

        Args:
            text: The text to check for tool calls

        Returns:
            True if the text contains a tool call, False otherwise
        F)r?   rC   has_tool_call)rF   rK   rH   rH   rI   rM   U   s   z FunctionCallParser.has_tool_call	full_textc                 C   s:   | j s|g fS | j|| j }|j}|r|j|fS |g fS )aj  
        One-time parsing of the full text to extract tool calls.

        Args:
            full_text: The complete text to parse

        Returns:
            A tuple containing:
            - The remaining text after parsing that was not consumed by the detector (can be treated as normal text)
            - A list of tool calls parsed from the text
        )r?   rC   detect_and_parsecallsnormal_text)rF   rN   parsed_resulttool_call_listrH   rH   rI   parse_non_streamd   s   
z#FunctionCallParser.parse_non_stream
chunk_textc                 C   sR   | j s|g fS d}g }| j|| j }|jr|j}|jr%||j |j}||fS )aE  
        Streaming incremental parsing of chunks of text as they arrive.

        Args:
            chunk_text: The new chunk of text to parse

        Returns:
            A tuple containing:
            - The normal text that should be displayed to the user
            - A list of tool calls parsed from the chunk
         )r?   rC   parse_streaming_incrementrQ   rP   extend)rF   rU   final_normal_textfinal_calls	sp_resultrH   rH   rI   parse_stream_chunky   s   z%FunctionCallParser.parse_stream_chunkc           
      C   s   t  }t }| j }| jD ]6}|j}|j}|dusJ ||}|jp(| jt	j
k}|r.|jni }	|t|j|	p8i |jd ||j qtd|t |dS )z
        Generate a structural tag response format for all available tools.

        This creates the necessary structural tags that guide the model's output format.
        N)beginschemaendstructural_tag)type
structurestriggers)listsetrC   structure_infor?   functionnamestrictrE   r   	PARAMETER
parametersappendr   r]   r_   addtriggerr
   )
rF   tool_structurestool_trigger_setget_structure_infotoolrg   rh   info	is_strictr^   rH   rH   rI   get_structure_tag   s0   

z$FunctionCallParser.get_structure_tagtool_choice)autorequiredc                 C   sl   | j  r!|dkr!tdd | jD s| jtjkr!|  }d|fS |dks*t|t	r4t
| j|}d|fS dS )a  
        Returns the appropriate structure constraint for tool calls based on the tool_choice.
        The constraint is used to guide the model's output format.

        Args:
            tool_choice: The tool choice setting from the request

        Returns:
            A tuple of (constraint_type, constraint_value) to be added to sampling parameters,
            or None if no constraint applies.
        rw   c                 s   s    | ]}|j jV  qd S )N)rg   ri   ).0rr   rH   rH   rI   	<genexpr>   s    z>FunctionCallParser.get_structure_constraint.<locals>.<genexpr>r`   rx   json_schemaN)rC   supports_structural_taganyr?   rE   r   FUNCTIONru   
isinstancer   r'   )rF   rv   tagr{   rH   rH   rI   get_structure_constraint   s   z+FunctionCallParser.get_structure_constraintN)0__name__
__module____qualname____doc__r   r   r   r   r   r   r   r   r   r   r!   r"   r$   r#   r%   r    r&   r   r   r   r>   r   strr   r   __annotations__r   r   rJ   boolrM   r   rd   r   rT   r\   r
   ru   r	   r   r   r   r   r   rH   rH   rH   rI   r(   '   sl   
 	
'r(   )Eloggingtypingr   r   r   r   r   r   r   r	   &sglang.srt.entrypoints.openai.protocolr
   r   r   r   r   sglang.srt.environr   r   -sglang.srt.function_call.base_format_detectorr   #sglang.srt.function_call.core_typesr   ,sglang.srt.function_call.deepseekv3_detectorr   -sglang.srt.function_call.deepseekv31_detectorr   -sglang.srt.function_call.deepseekv32_detectorr   +sglang.srt.function_call.gigachat3_detectorr   *sglang.srt.function_call.glm4_moe_detectorr   +sglang.srt.function_call.glm47_moe_detectorr   )sglang.srt.function_call.gpt_oss_detectorr   (sglang.srt.function_call.hermes_detectorr   *sglang.srt.function_call.internlm_detectorr   (sglang.srt.function_call.kimik2_detectorr   &sglang.srt.function_call.lfm2_detectorr   )sglang.srt.function_call.llama32_detectorr   &sglang.srt.function_call.mimo_detectorr   #sglang.srt.function_call.minimax_m2r    )sglang.srt.function_call.mistral_detectorr!   *sglang.srt.function_call.pythonic_detectorr"   -sglang.srt.function_call.qwen3_coder_detectorr#   (sglang.srt.function_call.qwen25_detectorr$   'sglang.srt.function_call.step3_detectorr%   )sglang.srt.function_call.trinity_detectorr&   sglang.srt.function_call.utilsr'   	getLoggerr   loggerr(   rH   rH   rH   rI   <module>   s:    (
