A high-throughput and memory-efficient inference and serving engine for LLMs
Mirrored from https://github.com/tduncan-lum/Nvidia-Optimization-Stack---VLLM.git
Synced Nov 5, 23:30 UTC
[Tool Parser][1/3] Pass tools to ToolParser constructor (#38029)
Signed-off-by: sfeng33 <4florafeng@gmail.com>
Flora Feng committed
Mar 25, 2026 at 22:29 UTC
e2db2b42347ae27da3083c530c71b251861ed220
38 files changed
+147
-92
vllm/entrypoints/openai/chat_completion/serving.py
+2
-2
@@ -565,7 +565,7 @@ class OpenAIServingChat(OpenAIServing):
565
)
566
567
tool_parsers: list[ToolParser | None] = [
568
- self.tool_parser(tokenizer)
568
+ self.tool_parser(tokenizer, request.tools)
569
] * num_choices
570
else:
571
tool_parsers = [None] * num_choices
@@ -1331,7 +1331,7 @@ class OpenAIServingChat(OpenAIServing):
1331
"Tokenizer not available when `skip_tokenizer_init=True`"
1332
)
1333
1334
- tool_parser = self.tool_parser(tokenizer)
1334
+ tool_parser = self.tool_parser(tokenizer, request.tools)
1335
# NOTE: We use token_ids for openai tool parser
1336
tool_call_info = tool_parser.extract_tool_calls(
1337
"",
vllm/entrypoints/openai/engine/serving.py
+1
-1
@@ -925,7 +925,7 @@ class OpenAIServing:
925
926
# Automatic Tool Call Parsing
927
try:
928
- tool_parser = tool_parser_cls(tokenizer)
928
+ tool_parser = tool_parser_cls(tokenizer, request.tools)
929
except RuntimeError as e:
930
logger.exception("Error in tool parser creation.")
931
raise e
vllm/entrypoints/openai/parser/responses_parser.py
+1
-1
@@ -52,7 +52,7 @@ class ResponsesParser:
52
self.reasoning_parser_instance = reasoning_parser_cls(tokenizer)
53
self.tool_parser_instance = None
54
if tool_parser_cls is not None:
55
- self.tool_parser_instance = tool_parser_cls(tokenizer)
55
+ self.tool_parser_instance = tool_parser_cls(tokenizer, request.tools)
56
57
# Store the last finish_reason to determine response status
58
self.finish_reason: str | None = None
vllm/entrypoints/openai/responses/serving.py
+1
-1
@@ -1344,7 +1344,7 @@ class OpenAIServingResponses(OpenAIServing):
1344
reasoning_parser = self.parser.reasoning_parser_cls(tokenizer)
1345
tool_parser = None
1346
if self.parser and self.parser.tool_parser_cls:
1347
- tool_parser = self.parser.tool_parser_cls(tokenizer)
1347
+ tool_parser = self.parser.tool_parser_cls(tokenizer, request.tools)
1348
reasoning_ended = False
1349
tool_call_text_started = False
1350
previous_text = ""
vllm/entrypoints/serve/render/serving.py
+3
-1
@@ -545,6 +545,8 @@ class OpenAIServingRender:
545
)
546
raise NotImplementedError(msg)
547
tokenizer = renderer.get_tokenizer()
548
- request = tool_parser(tokenizer).adjust_request(request=request) # type: ignore[arg-type]
548
+ request = tool_parser(tokenizer, request.tools).adjust_request(
549
+ request=request # type: ignore[arg-type]
550
+ )
551
552
return conversation, [engine_input]
vllm/tool_parsers/abstract_tool_parser.py
+14
-2
@@ -5,13 +5,18 @@ import importlib
5
import os
6
from collections.abc import Callable, Sequence
7
from functools import cached_property
8
+from typing import TypeAlias
9
10
from openai.types.responses import (
11
ResponseFormatTextJSONSchemaConfig,
12
ResponseTextConfig,
13
)
14
+from openai.types.responses.tool import Tool as ResponsesTool
15
14
-from vllm.entrypoints.openai.chat_completion.protocol import ChatCompletionRequest
16
+from vllm.entrypoints.openai.chat_completion.protocol import (
17
+ ChatCompletionRequest,
18
+ ChatCompletionToolsParam,
19
+)
20
from vllm.entrypoints.openai.engine.protocol import (
21
DeltaMessage,
22
ExtractedToolCallInformation,
@@ -30,6 +35,8 @@ from vllm.utils.import_utils import import_from_path
35
36
logger = init_logger(__name__)
37
38
+Tool: TypeAlias = ChatCompletionToolsParam | ResponsesTool
39
+
40
41
class ToolParser:
42
"""
@@ -38,7 +45,11 @@ class ToolParser:
45
derived classes.
46
"""
47
41
- def __init__(self, tokenizer: TokenizerLike):
48
+ def __init__(
49
+ self,
50
+ tokenizer: TokenizerLike,
51
+ tools: list[Tool] | None = None,
52
+ ):
53
self.prev_tool_call_arr: list[dict] = []
54
# the index of the tool call that is currently being parsed
55
self.current_tool_id: int = -1
@@ -46,6 +57,7 @@ class ToolParser:
57
self.streamed_args_for_tool: list[str] = []
58
59
self.model_tokenizer = tokenizer
60
+ self.tools = tools
61
62
@cached_property
63
def vocab(self) -> dict[str, int]:
vllm/tool_parsers/deepseekv31_tool_parser.py
+3
-3
@@ -19,14 +19,14 @@ from vllm.entrypoints.openai.engine.protocol import (
19
)
20
from vllm.logger import init_logger
21
from vllm.tokenizers import TokenizerLike
22
-from vllm.tool_parsers.abstract_tool_parser import ToolParser
22
+from vllm.tool_parsers.abstract_tool_parser import Tool, ToolParser
23
24
logger = init_logger(__name__)
25
26
27
class DeepSeekV31ToolParser(ToolParser):
28
- def __init__(self, tokenizer: TokenizerLike):
29
- super().__init__(tokenizer)
28
+ def __init__(self, tokenizer: TokenizerLike, tools: list[Tool] | None = None):
29
+ super().__init__(tokenizer, tools)
30
31
self.current_tool_name_sent: bool = False
32
self.prev_tool_call_arr: list[dict] = []
vllm/tool_parsers/deepseekv32_tool_parser.py
+3
-2
@@ -22,6 +22,7 @@ from vllm.entrypoints.openai.engine.protocol import (
22
from vllm.logger import init_logger
23
from vllm.tokenizers import TokenizerLike
24
from vllm.tool_parsers.abstract_tool_parser import (
25
+ Tool,
26
ToolParser,
27
)
28
@@ -43,8 +44,8 @@ class DeepSeekV32ToolParser(ToolParser):
44
</|DSML|function_calls>
45
"""
46
46
- def __init__(self, tokenizer: TokenizerLike):
47
- super().__init__(tokenizer)
47
+ def __init__(self, tokenizer: TokenizerLike, tools: list[Tool] | None = None):
48
+ super().__init__(tokenizer, tools)
49
50
self.prev_tool_call_arr: list[dict] = []
51
vllm/tool_parsers/deepseekv3_tool_parser.py
+3
-2
@@ -20,6 +20,7 @@ from vllm.entrypoints.openai.engine.protocol import (
20
from vllm.logger import init_logger
21
from vllm.tokenizers import TokenizerLike
22
from vllm.tool_parsers.abstract_tool_parser import (
23
+ Tool,
24
ToolParser,
25
)
26
@@ -27,8 +28,8 @@ logger = init_logger(__name__)
28
29
30
class DeepSeekV3ToolParser(ToolParser):
30
- def __init__(self, tokenizer: TokenizerLike):
31
- super().__init__(tokenizer)
31
+ def __init__(self, tokenizer: TokenizerLike, tools: list[Tool] | None = None):
32
+ super().__init__(tokenizer, tools)
33
34
self.current_tool_name_sent: bool = False
35
self.prev_tool_call_arr: list[dict] = []
vllm/tool_parsers/ernie45_tool_parser.py
+3
-2
@@ -20,6 +20,7 @@ from vllm.entrypoints.openai.engine.protocol import (
20
from vllm.logger import init_logger
21
from vllm.tokenizers import TokenizerLike
22
from vllm.tool_parsers.abstract_tool_parser import (
23
+ Tool,
24
ToolParser,
25
)
26
@@ -27,12 +28,12 @@ logger = init_logger(__name__)
28
29
30
class Ernie45ToolParser(ToolParser):
30
- def __init__(self, tokenizer: TokenizerLike):
31
+ def __init__(self, tokenizer: TokenizerLike, tools: list[Tool] | None = None):
32
"""
33
Ernie thinking model format:
34
abc\n</think>\n\n\n<tool_call>\ndef\n</tool_call>\n
35
"""
35
- super().__init__(tokenizer)
36
+ super().__init__(tokenizer, tools)
37
self.current_tool_name_sent = False
38
self.prev_tool_call_arr: list[dict] = []
39
self.current_tool_id = -1
vllm/tool_parsers/functiongemma_tool_parser.py
+3
-3
@@ -20,7 +20,7 @@ from vllm.entrypoints.openai.engine.protocol import (
20
)
21
from vllm.logger import init_logger
22
from vllm.tokenizers import TokenizerLike
23
-from vllm.tool_parsers.abstract_tool_parser import ToolParser
23
+from vllm.tool_parsers.abstract_tool_parser import Tool, ToolParser
24
25
logger = init_logger(__name__)
26
@@ -33,8 +33,8 @@ class FunctionGemmaToolParser(ToolParser):
33
<start_function_call>call:func_name{param:<escape>value<escape>}<end_function_call>
34
"""
35
36
- def __init__(self, tokenizer: TokenizerLike):
37
- super().__init__(tokenizer)
36
+ def __init__(self, tokenizer: TokenizerLike, tools: list[Tool] | None = None):
37
+ super().__init__(tokenizer, tools)
38
39
# Streaming state
40
self.current_tool_name_sent: bool = False
vllm/tool_parsers/gigachat3_tool_parser.py
+3
-3
@@ -20,7 +20,7 @@ from vllm.entrypoints.openai.engine.protocol import (
20
)
21
from vllm.logger import init_logger
22
from vllm.tokenizers import TokenizerLike
23
-from vllm.tool_parsers.abstract_tool_parser import ToolParser
23
+from vllm.tool_parsers.abstract_tool_parser import Tool, ToolParser
24
25
logger = init_logger(__name__)
26
@@ -46,8 +46,8 @@ ARGS_REGEX = re.compile(
46
47
48
class GigaChat3ToolParser(ToolParser):
49
- def __init__(self, tokenizer: TokenizerLike):
50
- super().__init__(tokenizer)
49
+ def __init__(self, tokenizer: TokenizerLike, tools: list[Tool] | None = None):
50
+ super().__init__(tokenizer, tools)
51
self.tool_started: bool = False
52
self.tool_name_sent: bool = False
53
self.tool_id: str | None = None
vllm/tool_parsers/glm47_moe_tool_parser.py
+3
-2
@@ -16,14 +16,15 @@ import regex as re
16
17
from vllm.logger import init_logger
18
from vllm.tokenizers import TokenizerLike
19
+from vllm.tool_parsers.abstract_tool_parser import Tool
20
from vllm.tool_parsers.glm4_moe_tool_parser import Glm4MoeModelToolParser
21
22
logger = init_logger(__name__)
23
24
25
class Glm47MoeModelToolParser(Glm4MoeModelToolParser):
25
- def __init__(self, tokenizer: TokenizerLike):
26
- super().__init__(tokenizer)
26
+ def __init__(self, tokenizer: TokenizerLike, tools: list[Tool] | None = None):
27
+ super().__init__(tokenizer, tools)
28
# GLM-4.7 format: <tool_call>func_name[<arg_key>...]*</tool_call>
29
# The function name can be followed by a newline, whitespace, or
30
# directly by <arg_key> tags (no separator). The arg section is
vllm/tool_parsers/glm4_moe_tool_parser.py
+4
-4
@@ -21,7 +21,6 @@ import regex as re
21
from vllm.entrypoints.chat_utils import make_tool_call_id
22
from vllm.entrypoints.openai.chat_completion.protocol import (
23
ChatCompletionRequest,
24
- ChatCompletionToolsParam,
24
)
25
from vllm.entrypoints.openai.engine.protocol import (
26
DeltaFunctionCall,
@@ -34,6 +33,7 @@ from vllm.entrypoints.openai.engine.protocol import (
33
from vllm.logger import init_logger
34
from vllm.tokenizers import TokenizerLike
35
from vllm.tool_parsers.abstract_tool_parser import (
36
+ Tool,
37
ToolParser,
38
)
39
@@ -48,8 +48,8 @@ class Glm4MoeModelToolParser(ToolParser):
48
rather than waiting for the complete </arg_value> tag.
49
"""
50
51
- def __init__(self, tokenizer: TokenizerLike):
52
- super().__init__(tokenizer)
51
+ def __init__(self, tokenizer: TokenizerLike, tools: list[Tool] | None = None):
52
+ super().__init__(tokenizer, tools)
53
# Stateful streaming fields
54
self.current_tool_name_sent: bool = False
55
self.prev_tool_call_arr: list[dict[str, Any]] = []
@@ -122,7 +122,7 @@ class Glm4MoeModelToolParser(ToolParser):
122
def _is_string_type(
123
tool_name: str,
124
arg_name: str,
125
- tools: list[ChatCompletionToolsParam] | None,
125
+ tools: list[Tool] | None,
126
) -> bool:
127
if tools is None:
128
return False
vllm/tool_parsers/granite4_tool_parser.py
+3
-2
@@ -22,6 +22,7 @@ from vllm.entrypoints.openai.engine.protocol import (
22
from vllm.logger import init_logger
23
from vllm.tokenizers import TokenizerLike
24
from vllm.tool_parsers.abstract_tool_parser import (
25
+ Tool,
26
ToolParser,
27
)
28
@@ -43,8 +44,8 @@ FuncT = TypeVar("FuncT", bound=_FunctionCallCtor)
44
45
46
class Granite4ToolParser(ToolParser):
46
- def __init__(self, tokenizer: TokenizerLike):
47
- super().__init__(tokenizer)
47
+ def __init__(self, tokenizer: TokenizerLike, tools: list[Tool] | None = None):
48
+ super().__init__(tokenizer, tools)
49
50
self.prev_tool_call_arr: list[dict] = []
51
self.current_tool_id: int = -1
vllm/tool_parsers/granite_20b_fc_tool_parser.py
+3
-2
@@ -24,6 +24,7 @@ from vllm.entrypoints.openai.engine.protocol import (
24
from vllm.logger import init_logger
25
from vllm.tokenizers import TokenizerLike
26
from vllm.tool_parsers.abstract_tool_parser import (
27
+ Tool,
28
ToolParser,
29
)
30
from vllm.tool_parsers.utils import (
@@ -46,8 +47,8 @@ class Granite20bFCToolParser(ToolParser):
47
are all set
48
"""
49
49
- def __init__(self, tokenizer: TokenizerLike):
50
- super().__init__(tokenizer)
50
+ def __init__(self, tokenizer: TokenizerLike, tools: list[Tool] | None = None):
51
+ super().__init__(tokenizer, tools)
52
53
self.bot_token = "<function_call>"
54
self.tool_start_token = self.bot_token
vllm/tool_parsers/granite_tool_parser.py
+3
-2
@@ -22,6 +22,7 @@ from vllm.entrypoints.openai.engine.protocol import (
22
from vllm.logger import init_logger
23
from vllm.tokenizers import TokenizerLike
24
from vllm.tool_parsers.abstract_tool_parser import (
25
+ Tool,
26
ToolParser,
27
)
28
from vllm.tool_parsers.utils import (
@@ -44,8 +45,8 @@ class GraniteToolParser(ToolParser):
45
are all set
46
"""
47
47
- def __init__(self, tokenizer: TokenizerLike):
48
- super().__init__(tokenizer)
48
+ def __init__(self, tokenizer: TokenizerLike, tools: list[Tool] | None = None):
49
+ super().__init__(tokenizer, tools)
50
# for granite 3.0, the token `<|tool_call|>`
51
self.bot_token = "<|tool_call|>"
52
# for granite 3.1, the string `<tool_call>`
vllm/tool_parsers/hermes_tool_parser.py
+3
-2
@@ -23,6 +23,7 @@ from vllm.entrypoints.openai.engine.protocol import (
23
from vllm.logger import init_logger
24
from vllm.tokenizers import TokenizerLike
25
from vllm.tool_parsers.abstract_tool_parser import (
26
+ Tool,
27
ToolParser,
28
)
29
from vllm.utils.mistral import is_mistral_tokenizer
@@ -31,8 +32,8 @@ logger = init_logger(__name__)
32
33
34
class Hermes2ProToolParser(ToolParser):
34
- def __init__(self, tokenizer: TokenizerLike):
35
- super().__init__(tokenizer)
35
+ def __init__(self, tokenizer: TokenizerLike, tools: list[Tool] | None = None):
36
+ super().__init__(tokenizer, tools)
37
38
if is_mistral_tokenizer(tokenizer):
39
logger.error("Detected Mistral tokenizer when using a Hermes model")
vllm/tool_parsers/hunyuan_a13b_tool_parser.py
+3
-2
@@ -22,6 +22,7 @@ from vllm.entrypoints.openai.engine.protocol import (
22
from vllm.logger import init_logger
23
from vllm.tokenizers import TokenizerLike
24
from vllm.tool_parsers.abstract_tool_parser import (
25
+ Tool,
26
ToolParser,
27
)
28
from vllm.tool_parsers.utils import consume_space
@@ -31,8 +32,8 @@ logger = init_logger(__name__)
32
33
34
class HunyuanA13BToolParser(ToolParser):
34
- def __init__(self, tokenizer: TokenizerLike):
35
- super().__init__(tokenizer)
35
+ def __init__(self, tokenizer: TokenizerLike, tools: list[Tool] | None = None):
36
+ super().__init__(tokenizer, tools)
37
38
# Initialize state for streaming mode
39
self.prev_tool_calls: list[dict] = []
vllm/tool_parsers/internlm2_tool_parser.py
+3
-2
@@ -22,6 +22,7 @@ from vllm.entrypoints.openai.engine.protocol import (
22
from vllm.logger import init_logger
23
from vllm.tokenizers import TokenizerLike
24
from vllm.tool_parsers.abstract_tool_parser import (
25
+ Tool,
26
ToolParser,
27
)
28
from vllm.tool_parsers.utils import extract_intermediate_diff
@@ -30,8 +31,8 @@ logger = init_logger(__name__)
31
32
33
class Internlm2ToolParser(ToolParser):
33
- def __init__(self, tokenizer: TokenizerLike):
34
- super().__init__(tokenizer)
34
+ def __init__(self, tokenizer: TokenizerLike, tools: list[Tool] | None = None):
35
+ super().__init__(tokenizer, tools)
36
self.position = 0
37
38
def adjust_request(self, request: ChatCompletionRequest) -> ChatCompletionRequest:
vllm/tool_parsers/jamba_tool_parser.py
+3
-3
@@ -22,7 +22,7 @@ from vllm.entrypoints.openai.engine.protocol import (
22
)
23
from vllm.logger import init_logger
24
from vllm.tokenizers import TokenizerLike
25
-from vllm.tool_parsers import ToolParser
25
+from vllm.tool_parsers.abstract_tool_parser import Tool, ToolParser
26
from vllm.tool_parsers.utils import extract_intermediate_diff
27
from vllm.utils.mistral import is_mistral_tokenizer
28
@@ -30,8 +30,8 @@ logger = init_logger(__name__)
30
31
32
class JambaToolParser(ToolParser):
33
- def __init__(self, tokenizer: TokenizerLike):
34
- super().__init__(tokenizer)
33
+ def __init__(self, tokenizer: TokenizerLike, tools: list[Tool] | None = None):
34
+ super().__init__(tokenizer, tools)
35
36
if is_mistral_tokenizer(self.model_tokenizer):
37
raise ValueError(
vllm/tool_parsers/kimi_k2_tool_parser.py
+3
-2
@@ -20,6 +20,7 @@ from vllm.entrypoints.openai.engine.protocol import (
20
from vllm.logger import init_logger
21
from vllm.tokenizers import TokenizerLike
22
from vllm.tool_parsers.abstract_tool_parser import (
23
+ Tool,
24
ToolParser,
25
)
26
@@ -27,8 +28,8 @@ logger = init_logger(__name__)
28
29
30
class KimiK2ToolParser(ToolParser):
30
- def __init__(self, tokenizer: TokenizerLike):
31
- super().__init__(tokenizer)
31
+ def __init__(self, tokenizer: TokenizerLike, tools: list[Tool] | None = None):
32
+ super().__init__(tokenizer, tools)
33
self.current_tool_name_sent: bool = False
34
self.prev_tool_call_arr: list[dict] = []
35
self.current_tool_id: int = -1
vllm/tool_parsers/llama4_pythonic_tool_parser.py
+7
-2
@@ -17,6 +17,7 @@ from vllm.entrypoints.openai.engine.protocol import (
17
)
18
from vllm.logger import init_logger
19
from vllm.tool_parsers.abstract_tool_parser import (
20
+ Tool,
21
ToolParser,
22
)
23
from vllm.tool_parsers.utils import (
@@ -47,8 +48,12 @@ class Llama4PythonicToolParser(ToolParser):
48
re.DOTALL,
49
)
50
50
- def __init__(self, tokenizer: PreTrainedTokenizerBase):
51
- super().__init__(tokenizer)
51
+ def __init__(
52
+ self,
53
+ tokenizer: PreTrainedTokenizerBase,
54
+ tools: list[Tool] | None = None,
55
+ ):
56
+ super().__init__(tokenizer, tools)
57
58
# Rename for readability. This is NOT a tool id.
59
@property
vllm/tool_parsers/llama_tool_parser.py
+7
-2
@@ -24,6 +24,7 @@ from vllm.entrypoints.openai.engine.protocol import (
24
)
25
from vllm.logger import init_logger
26
from vllm.tool_parsers.abstract_tool_parser import (
27
+ Tool,
28
ToolParser,
29
)
30
from vllm.tool_parsers.utils import (
@@ -44,8 +45,12 @@ class Llama3JsonToolParser(ToolParser):
45
llama4_json are set.
46
"""
47
47
- def __init__(self, tokenizer: PreTrainedTokenizerBase):
48
- super().__init__(tokenizer)
48
+ def __init__(
49
+ self,
50
+ tokenizer: PreTrainedTokenizerBase,
51
+ tools: list[Tool] | None = None,
52
+ ):
53
+ super().__init__(tokenizer, tools)
54
55
# initialize properties used for state when parsing tool calls in
56
# streaming mode
vllm/tool_parsers/longcat_tool_parser.py
+3
-2
@@ -4,12 +4,13 @@
4
import regex as re
5
6
from vllm.tokenizers import TokenizerLike
7
+from vllm.tool_parsers.abstract_tool_parser import Tool
8
from vllm.tool_parsers.hermes_tool_parser import Hermes2ProToolParser
9
10
11
class LongcatFlashToolParser(Hermes2ProToolParser):
11
- def __init__(self, tokenizer: TokenizerLike):
12
- super().__init__(tokenizer)
12
+ def __init__(self, tokenizer: TokenizerLike, tools: list[Tool] | None = None):
13
+ super().__init__(tokenizer, tools)
14
15
self.tool_call_start_token: str = "<longcat_tool_call>"
16
self.tool_call_end_token: str = "</longcat_tool_call>"
vllm/tool_parsers/minimax_m2_tool_parser.py
+3
-2
@@ -22,6 +22,7 @@ from vllm.entrypoints.openai.engine.protocol import (
22
from vllm.logger import init_logger
23
from vllm.tokenizers import TokenizerLike
24
from vllm.tool_parsers.abstract_tool_parser import (
25
+ Tool,
26
ToolParser,
27
)
28
@@ -29,8 +30,8 @@ logger = init_logger(__name__)
30
31
32
class MinimaxM2ToolParser(ToolParser):
32
- def __init__(self, tokenizer: TokenizerLike):
33
- super().__init__(tokenizer)
33
+ def __init__(self, tokenizer: TokenizerLike, tools: list[Tool] | None = None):
34
+ super().__init__(tokenizer, tools)
35
36
self.prev_tool_call_arr: list[dict] = []
37
vllm/tool_parsers/minimax_tool_parser.py
+3
-2
@@ -22,6 +22,7 @@ from vllm.entrypoints.openai.engine.protocol import (
22
from vllm.logger import init_logger
23
from vllm.tokenizers import TokenizerLike
24
from vllm.tool_parsers.abstract_tool_parser import (
25
+ Tool,
26
ToolParser,
27
)
28
from vllm.tool_parsers.utils import extract_intermediate_diff
@@ -30,8 +31,8 @@ logger = init_logger(__name__)
31
32
33
class MinimaxToolParser(ToolParser):
33
- def __init__(self, tokenizer: TokenizerLike):
34
- super().__init__(tokenizer)
34
+ def __init__(self, tokenizer: TokenizerLike, tools: list[Tool] | None = None):
35
+ super().__init__(tokenizer, tools)
36
37
# Initialize streaming state for tracking tool call progress
38
self.streaming_state: dict[str, Any] = {
vllm/tool_parsers/mistral_tool_parser.py
+3
-2
@@ -26,6 +26,7 @@ from vllm.entrypoints.openai.engine.protocol import (
26
from vllm.logger import init_logger
27
from vllm.tokenizers import TokenizerLike
28
from vllm.tool_parsers.abstract_tool_parser import (
29
+ Tool,
30
ToolParser,
31
)
32
from vllm.utils.mistral import is_mistral_tokenizer
@@ -78,8 +79,8 @@ class MistralToolParser(ToolParser):
79
Used when --enable-auto-tool-choice --tool-call-parser mistral are all set
80
"""
81
81
- def __init__(self, tokenizer: TokenizerLike):
82
- super().__init__(tokenizer)
82
+ def __init__(self, tokenizer: TokenizerLike, tools: list[Tool] | None = None):
83
+ super().__init__(tokenizer, tools)
84
85
if not is_mistral_tokenizer(self.model_tokenizer):
86
logger.info("Non-Mistral tokenizer detected when using a Mistral model...")
vllm/tool_parsers/olmo3_tool_parser.py
+7
-2
@@ -17,6 +17,7 @@ from vllm.entrypoints.openai.engine.protocol import (
17
)
18
from vllm.logger import init_logger
19
from vllm.tool_parsers.abstract_tool_parser import (
20
+ Tool,
21
ToolParser,
22
)
23
from vllm.tool_parsers.utils import (
@@ -51,8 +52,12 @@ class Olmo3PythonicToolParser(ToolParser):
52
re.DOTALL,
53
)
54
54
- def __init__(self, tokenizer: PreTrainedTokenizerBase):
55
- super().__init__(tokenizer)
55
+ def __init__(
56
+ self,
57
+ tokenizer: PreTrainedTokenizerBase,
58
+ tools: list[Tool] | None = None,
59
+ ):
60
+ super().__init__(tokenizer, tools)
61
62
# Rename for readability. This is NOT a tool id.
63
@property
vllm/tool_parsers/openai_tool_parser.py
+3
-2
@@ -16,6 +16,7 @@ from vllm.entrypoints.openai.engine.protocol import (
16
from vllm.entrypoints.openai.parser.harmony_utils import parse_output_into_messages
17
from vllm.logger import init_logger
18
from vllm.tool_parsers.abstract_tool_parser import (
19
+ Tool,
20
ToolParser,
21
)
22
@@ -28,8 +29,8 @@ logger = init_logger(__name__)
29
30
31
class OpenAIToolParser(ToolParser):
31
- def __init__(self, tokenizer: "TokenizerLike"):
32
- super().__init__(tokenizer)
32
+ def __init__(self, tokenizer: "TokenizerLike", tools: list[Tool] | None = None):
33
+ super().__init__(tokenizer, tools)
34
35
def extract_tool_calls(
36
self,
vllm/tool_parsers/phi4mini_tool_parser.py
+7
-2
@@ -20,6 +20,7 @@ from vllm.entrypoints.openai.engine.protocol import (
20
)
21
from vllm.logger import init_logger
22
from vllm.tool_parsers.abstract_tool_parser import (
23
+ Tool,
24
ToolParser,
25
)
26
@@ -35,8 +36,12 @@ class Phi4MiniJsonToolParser(ToolParser):
36
are all set
37
"""
38
38
- def __init__(self, tokenizer: PreTrainedTokenizerBase) -> None:
39
- super().__init__(tokenizer)
39
+ def __init__(
40
+ self,
41
+ tokenizer: PreTrainedTokenizerBase,
42
+ tools: list[Tool] | None = None,
43
+ ) -> None:
44
+ super().__init__(tokenizer, tools)
45
46
# initialize properties used for state when parsing tool calls in
47
# streaming mode
vllm/tool_parsers/pythonic_tool_parser.py
+7
-2
@@ -17,6 +17,7 @@ from vllm.entrypoints.openai.engine.protocol import (
17
)
18
from vllm.logger import init_logger
19
from vllm.tool_parsers.abstract_tool_parser import (
20
+ Tool,
21
ToolParser,
22
)
23
from vllm.tool_parsers.utils import (
@@ -49,8 +50,12 @@ class PythonicToolParser(ToolParser):
50
re.DOTALL,
51
)
52
52
- def __init__(self, tokenizer: PreTrainedTokenizerBase):
53
- super().__init__(tokenizer)
53
+ def __init__(
54
+ self,
55
+ tokenizer: PreTrainedTokenizerBase,
56
+ tools: list[Tool] | None = None,
57
+ ):
58
+ super().__init__(tokenizer, tools)
59
60
# Rename for readability. This is NOT a tool id.
61
@property
vllm/tool_parsers/qwen3coder_tool_parser.py
+5
-7
@@ -10,7 +10,6 @@ import regex as re
10
11
from vllm.entrypoints.openai.chat_completion.protocol import (
12
ChatCompletionRequest,
13
- ChatCompletionToolsParam,
13
)
14
from vllm.entrypoints.openai.engine.protocol import (
15
DeltaFunctionCall,
@@ -23,6 +22,7 @@ from vllm.entrypoints.openai.engine.protocol import (
22
from vllm.logger import init_logger
23
from vllm.tokenizers import TokenizerLike
24
from vllm.tool_parsers.abstract_tool_parser import (
25
+ Tool,
26
ToolParser,
27
)
28
@@ -30,8 +30,8 @@ logger = init_logger(__name__)
30
31
32
class Qwen3CoderToolParser(ToolParser):
33
- def __init__(self, tokenizer: TokenizerLike):
34
- super().__init__(tokenizer)
33
+ def __init__(self, tokenizer: TokenizerLike, tools: list[Tool] | None = None):
34
+ super().__init__(tokenizer, tools)
35
36
self.current_tool_name_sent: bool = False
37
self.prev_tool_call_arr: list[dict] = []
@@ -109,9 +109,7 @@ class Qwen3CoderToolParser(ToolParser):
109
self.accumulated_params = {}
110
self.streaming_request = None
111
112
- def _get_arguments_config(
113
- self, func_name: str, tools: list[ChatCompletionToolsParam] | None
114
- ) -> dict:
112
+ def _get_arguments_config(self, func_name: str, tools: list[Tool] | None) -> dict:
113
"""Extract argument configuration for a function."""
114
if tools is None:
115
return {}
@@ -246,7 +244,7 @@ class Qwen3CoderToolParser(ToolParser):
244
return param_value
245
246
def _parse_xml_function_call(
249
- self, function_call_str: str, tools: list[ChatCompletionToolsParam] | None
247
+ self, function_call_str: str, tools: list[Tool] | None
248
) -> ToolCall | None:
249
# Extract function name
250
end_index = function_call_str.find(">")
vllm/tool_parsers/qwen3xml_tool_parser.py
+5
-5
@@ -11,7 +11,6 @@ import regex as re
11
from vllm.entrypoints.chat_utils import make_tool_call_id
12
from vllm.entrypoints.openai.chat_completion.protocol import (
13
ChatCompletionRequest,
14
- ChatCompletionToolsParam,
14
)
15
from vllm.entrypoints.openai.engine.protocol import (
16
DeltaFunctionCall,
@@ -24,6 +23,7 @@ from vllm.entrypoints.openai.engine.protocol import (
23
from vllm.logger import init_logger
24
from vllm.tokenizers import TokenizerLike
25
from vllm.tool_parsers.abstract_tool_parser import (
26
+ Tool,
27
ToolParser,
28
)
29
@@ -40,7 +40,7 @@ class StreamingXMLToolCallParser:
40
self.reset_streaming_state()
41
42
# Tool configuration information
43
- self.tools: list[ChatCompletionToolsParam] | None = None
43
+ self.tools: list[Tool] | None = None
44
self.tool_call_start_token: str = "<tool_call>"
45
self.tool_call_end_token: str = "</tool_call>"
46
self.function_start_token: str = "<function="
@@ -961,7 +961,7 @@ class StreamingXMLToolCallParser:
961
self.parser.EndElementHandler = self._end_element
962
self.parser.CharacterDataHandler = self._char_data
963
964
- def set_tools(self, tools: list[ChatCompletionToolsParam] | None):
964
+ def set_tools(self, tools: list[Tool] | None):
965
"""Set tool configuration information"""
966
self.tools = tools
967
@@ -1167,8 +1167,8 @@ class StreamingXMLToolCallParser:
1167
1168
1169
class Qwen3XMLToolParser(ToolParser):
1170
- def __init__(self, tokenizer: TokenizerLike):
1171
- super().__init__(tokenizer)
1170
+ def __init__(self, tokenizer: TokenizerLike, tools: list[Tool] | None = None):
1171
+ super().__init__(tokenizer, tools)
1172
self.parser = StreamingXMLToolCallParser()
1173
1174
# Add missing attributes for compatibility with serving_chat.py
vllm/tool_parsers/seed_oss_tool_parser.py
+4
-4
@@ -13,7 +13,6 @@ import regex as re
13
14
from vllm.entrypoints.openai.chat_completion.protocol import (
15
ChatCompletionRequest,
16
- ChatCompletionToolsParam,
16
)
17
from vllm.entrypoints.openai.engine.protocol import (
18
DeltaFunctionCall,
@@ -26,6 +25,7 @@ from vllm.entrypoints.openai.engine.protocol import (
25
from vllm.logger import init_logger
26
from vllm.tokenizers import TokenizerLike
27
from vllm.tool_parsers.abstract_tool_parser import (
28
+ Tool,
29
ToolParser,
30
)
31
@@ -36,8 +36,8 @@ class SeedOssToolParser(ToolParser):
36
TOOL_CALL_START = "<seed:tool_call>"
37
TOOL_CALL_END = "</seed:tool_call>"
38
39
- def __init__(self, tokenizer: TokenizerLike):
40
- super().__init__(tokenizer)
39
+ def __init__(self, tokenizer: TokenizerLike, tools: list[Tool] | None = None):
40
+ super().__init__(tokenizer, tools)
41
42
# --- streaming state ---
43
self._reset_streaming_state()
@@ -109,7 +109,7 @@ class SeedOssToolParser(ToolParser):
109
self.json_closed = False
110
111
def _parse_xml_function_call(
112
- self, function_call_str: str, tools: list[ChatCompletionToolsParam] | None
112
+ self, function_call_str: str, tools: list[Tool] | None
113
) -> ToolCall | None:
114
def get_arguments_config(func_name: str) -> dict:
115
if tools is None:
vllm/tool_parsers/step3_tool_parser.py
+3
-2
@@ -22,6 +22,7 @@ from vllm.entrypoints.openai.engine.protocol import (
22
from vllm.logger import init_logger
23
from vllm.tokenizers import TokenizerLike
24
from vllm.tool_parsers.abstract_tool_parser import (
25
+ Tool,
26
ToolParser,
27
)
28
from vllm.utils import random_uuid
@@ -43,8 +44,8 @@ class Step3ToolParser(ToolParser):
44
TOOL_SEP = "<|tool_sep|>"
45
SPECIAL_TOKENS = [TOOL_CALLS_BEGIN, TOOL_CALLS_END, TOOL_CALL_BEGIN, TOOL_CALL_END]
46
46
- def __init__(self, tokenizer: TokenizerLike):
47
- super().__init__(tokenizer)
47
+ def __init__(self, tokenizer: TokenizerLike, tools: list[Tool] | None = None):
48
+ super().__init__(tokenizer, tools)
49
self.position = 0
50
# Explicit state flags for robust streaming
51
self.tool_block_started = False
vllm/tool_parsers/step3p5_tool_parser.py
+5
-6
@@ -11,7 +11,6 @@ import regex as re
11
from vllm.entrypoints.chat_utils import make_tool_call_id
12
from vllm.entrypoints.openai.chat_completion.protocol import (
13
ChatCompletionRequest,
14
- ChatCompletionToolsParam,
14
)
15
from vllm.entrypoints.openai.engine.protocol import (
16
DeltaFunctionCall,
@@ -23,7 +22,7 @@ from vllm.entrypoints.openai.engine.protocol import (
22
)
23
from vllm.logger import init_logger
24
from vllm.tokenizers import TokenizerLike
26
-from vllm.tool_parsers.abstract_tool_parser import ToolParser
25
+from vllm.tool_parsers.abstract_tool_parser import Tool, ToolParser
26
27
logger = init_logger(__name__)
28
@@ -38,7 +37,7 @@ class StreamingXMLToolCallParser:
37
self.reset_streaming_state()
38
39
# Tool configuration information
41
- self.tools: list[ChatCompletionToolsParam] | None = None
40
+ self.tools: list[Tool] | None = None
41
self.tool_call_start_token: str = "<tool_call>"
42
self.tool_call_end_token: str = "</tool_call>"
43
self.function_start_token: str = "<function="
@@ -1161,7 +1160,7 @@ class StreamingXMLToolCallParser:
1160
self.parser.EndElementHandler = self._end_element
1161
self.parser.CharacterDataHandler = self._char_data
1162
1164
- def set_tools(self, tools: list[ChatCompletionToolsParam] | None):
1163
+ def set_tools(self, tools: list[Tool] | None):
1164
"""Set tool configuration information"""
1165
self.tools = tools
1166
@@ -1365,8 +1364,8 @@ class StreamingXMLToolCallParser:
1364
1365
1366
class Step3p5ToolParser(ToolParser):
1368
- def __init__(self, tokenizer: TokenizerLike):
1369
- super().__init__(tokenizer)
1367
+ def __init__(self, tokenizer: TokenizerLike, tools: list[Tool] | None = None):
1368
+ super().__init__(tokenizer, tools)
1369
self.parser = StreamingXMLToolCallParser()
1370
1371
# Add missing attributes for compatibility with serving_chat.py
vllm/tool_parsers/xlam_tool_parser.py
+4
-2
@@ -6,6 +6,7 @@ from collections.abc import Sequence
6
from typing import Any, Optional, Union
7
8
import regex as re
9
+
10
from vllm.entrypoints.openai.chat_completion.protocol import (
11
ChatCompletionRequest,
12
)
@@ -19,6 +20,7 @@ from vllm.entrypoints.openai.engine.protocol import (
20
ToolCall,
21
)
22
from vllm.tool_parsers.abstract_tool_parser import (
23
+ Tool,
24
ToolParser,
25
)
26
from vllm.logger import init_logger
@@ -29,8 +31,8 @@ logger = init_logger(__name__)
31
32
33
class xLAMToolParser(ToolParser):
32
- def __init__(self, tokenizer: TokenizerLike):
33
- super().__init__(tokenizer)
34
+ def __init__(self, tokenizer: TokenizerLike, tools: list[Tool] | None = None):
35
+ super().__init__(tokenizer, tools)
36
37
# Initialize state for streaming mode
38
self.prev_tool_calls: list[dict] = []