main
py 80 lines 2.39 KB
Raw
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 """Ling3 parser for reasoning and tool calls.
4
5 Ling3 uses the same XML tool-call format as GLM-4.7 and defaults thinking on.
6 It follows the GLM-style ``<think>`` / ``</think>`` reasoning format and
7 treats ``<tool_call>`` as an implicit reasoning terminator.
8 """
9
10 from __future__ import annotations
11
12 from dataclasses import replace
13 from typing import TYPE_CHECKING
14
15 from vllm.entrypoints.openai.chat_completion.protocol import ChatCompletionRequest
16 from vllm.entrypoints.openai.responses.protocol import ResponsesRequest
17 from vllm.parser.engine.adapters import make_adapters
18 from vllm.parser.engine.parser_engine import ParserEngine
19 from vllm.parser.glm47_moe import (
20 THINK_END,
21 THINK_START,
22 Glm47MoeParser,
23 glm47_moe_config,
24 )
25
26 if TYPE_CHECKING:
27 from vllm.tokenizers import TokenizerLike
28 from vllm.tool_parsers.abstract_tool_parser import Tool
29
30
31 class Ling3Parser(Glm47MoeParser):
32 """Ling3 parser backed by the GLM XML parser engine."""
33
34 def __init__(
35 self,
36 tokenizer: TokenizerLike,
37 tools: list[Tool] | None = None,
38 **kwargs,
39 ) -> None:
40 chat_kwargs = kwargs.get("chat_template_kwargs", {}) or {}
41 thinking = chat_kwargs.get("thinking", None)
42 enable_thinking = chat_kwargs.get("enable_thinking", None)
43 self.thinking_enabled = (
44 True
45 if thinking is None and enable_thinking is None
46 else bool(thinking) or bool(enable_thinking)
47 )
48 parser_config = replace(
49 glm47_moe_config(thinking=self.thinking_enabled),
50 name="ling3",
51 )
52 kwargs.setdefault(
53 "parser_engine_config",
54 parser_config,
55 )
56 ParserEngine.__init__(self, tokenizer, tools, **kwargs)
57
58 @property
59 def reasoning_start_str(self) -> str:
60 return THINK_START
61
62 @property
63 def reasoning_end_str(self) -> str:
64 return THINK_END
65
66 def extract_reasoning(
67 self,
68 model_output: str,
69 request: ChatCompletionRequest | ResponsesRequest,
70 ) -> tuple[str | None, str | None]:
71 if not self.thinking_enabled:
72 return None, model_output
73
74 return super().extract_reasoning(model_output, request)
75
76
77 (
78 Ling3ParserReasoningAdapter,
79 Ling3ParserToolAdapter,
80 ) = make_adapters(Ling3Parser)