Skip to content

vllm.parser.glm47_moe

GLM-4.7 parser for reasoning and tool calls.

GLM-4.7 uses XML-like tool calls::

<tool_call>func_name<arg_key>key</arg_key><arg_value>value</arg_value></tool_call>

The function name can be followed directly by the first <arg_key> tag, and tool calls may have no arguments.

Classes:

  • Glm47MoeParser –

    GLM-4.7 parser backed by the declarative parser engine.

Glm47MoeParser

Bases: ParserEngine

GLM-4.7 parser backed by the declarative parser engine.

Source code in vllm/parser/glm47_moe.py
class Glm47MoeParser(ParserEngine):
    """GLM-4.7 parser backed by the declarative parser engine."""

    def __init__(
        self,
        tokenizer: TokenizerLike,
        tools: list[Tool] | None = None,
        **kwargs,
    ) -> None:
        chat_kwargs = kwargs.get("chat_template_kwargs", {}) or {}
        thinking = chat_kwargs.get("thinking", None)
        enable_thinking = chat_kwargs.get("enable_thinking", None)
        if (thinking is False or enable_thinking is False) and _glm53_always_thinks(
            tokenizer
        ):
            logger.warning_once(
                "Ignoring enable_thinking/thinking: the GLM-5.3 chat template "
                "has no thinking switch, so reasoning is always on and "
                "disabling extraction would leak it into the content."
            )
            thinking = None
            enable_thinking = None
        self.thinking_enabled = (
            True
            if thinking is None and enable_thinking is None
            else bool(thinking) or bool(enable_thinking)
        )
        kwargs.setdefault(
            "parser_engine_config",
            glm47_moe_config(thinking=self.thinking_enabled),
        )
        super().__init__(tokenizer, tools, **kwargs)

    def _emit_name_delta(self, idx: int, deltas, name: str | None) -> None:
        if name is not None:
            name = name.strip()
        super()._emit_name_delta(idx, deltas, name)

    def _handle_tool_end(self, event, deltas) -> None:
        idx = event.tool_index
        if 0 <= idx < len(self._tool_slots):
            self._tool_slots[idx].name = self._tool_slots[idx].name.strip()
        super()._handle_tool_end(event, deltas)

    def extract_reasoning(
        self,
        model_output: str,
        request: ChatCompletionRequest | ResponsesRequest,
    ) -> tuple[str | None, str | None]:
        if not self.thinking_enabled:
            return None, model_output
        return super().extract_reasoning(model_output, request)

_glm47_parse_args(raw_args, partial)

Return the arguments and the key of the open trailing value, if any.

Source code in vllm/parser/glm47_moe.py
def _glm47_parse_args(
    raw_args: str, partial: bool
) -> tuple[dict[str, object], str | None]:
    """Return the arguments and the key of the open trailing value, if any."""
    params: dict[str, object] = {}

    for match in _ARG_RE.finditer(raw_args):
        params[match.group("key").strip()] = match.group("value")

    open_key = None
    if partial:
        remaining = _ARG_RE.sub("", raw_args)
        match = _PARTIAL_ARG_RE.search(remaining)
        if match:
            key = match.group("key").strip()
            if key:
                params[key] = match.group("value")
                open_key = key

    return params, open_key