|
73 | 73 | from vllm.renderers import ChatParams |
74 | 74 | from vllm.sampling_params import BeamSearchParams, SamplingParams |
75 | 75 | from vllm.tokenizers import TokenizerLike |
76 | | -from vllm.tool_parsers.mistral_tool_parser import ( |
77 | | - MistralToolCall, |
78 | | - MistralToolParser, |
79 | | -) |
80 | 76 | from vllm.tool_parsers.utils import partial_json_loads |
81 | 77 | from vllm.utils.collection_utils import as_list |
82 | | -from vllm.utils.mistral import is_mistral_tokenizer |
| 78 | +from vllm.utils.mistral import is_mistral_tokenizer, is_mistral_tool_parser |
83 | 79 |
|
84 | 80 | if TYPE_CHECKING: |
85 | 81 | from vllm.entrypoints.serve.render.serving import OpenAIServingRender |
@@ -143,10 +139,12 @@ def __init__( |
143 | 139 | enable_auto_tools=enable_auto_tools, |
144 | 140 | model_name=self.model_config.model, |
145 | 141 | ) |
146 | | - _is_mistral_tool_parser = self.tool_parser is not None and issubclass( |
147 | | - self.tool_parser, MistralToolParser |
148 | | - ) |
149 | | - if _is_mistral_tool_parser and self.reasoning_parser_cls is not None: |
| 142 | + if ( |
| 143 | + is_mistral_tool_parser(self.tool_parser) |
| 144 | + and self.reasoning_parser_cls is not None |
| 145 | + ): |
| 146 | + from vllm.tool_parsers.mistral_tool_parser import MistralToolParser |
| 147 | + |
150 | 148 | MistralToolParser.model_can_reason = True |
151 | 149 |
|
152 | 150 | self.exclude_tools_when_tool_choice_none = exclude_tools_when_tool_choice_none |
@@ -823,6 +821,10 @@ async def chat_completion_stream_generator( |
823 | 821 | harmony_tools_streamed[i] |= tools_streamed_flag |
824 | 822 | # Mistral grammar path: combined reasoning + tool streaming |
825 | 823 | elif is_mistral_grammar_path: |
| 824 | + from vllm.tool_parsers.mistral_tool_parser import ( |
| 825 | + MistralToolParser, |
| 826 | + ) |
| 827 | + |
826 | 828 | assert tool_parser is not None |
827 | 829 | assert isinstance(tool_parser, MistralToolParser) |
828 | 830 | assert reasoning_end_arr is not None |
@@ -904,6 +906,10 @@ async def chat_completion_stream_generator( |
904 | 906 | else: |
905 | 907 | # Generate ID based on tokenizer type |
906 | 908 | if is_mistral_tokenizer(tokenizer): |
| 909 | + from vllm.tool_parsers.mistral_tool_parser import ( |
| 910 | + MistralToolCall, |
| 911 | + ) |
| 912 | + |
907 | 913 | tool_call_id = MistralToolCall.generate_random_id() |
908 | 914 | else: |
909 | 915 | tool_call_id = make_tool_call_id( |
@@ -1275,8 +1281,6 @@ async def chat_completion_full_generator( |
1275 | 1281 | request_metadata: RequestResponseMetadata, |
1276 | 1282 | reasoning_parser: ReasoningParser | None = None, |
1277 | 1283 | ) -> ErrorResponse | ChatCompletionResponse: |
1278 | | - from vllm.tokenizers.mistral import MistralTokenizer |
1279 | | - |
1280 | 1284 | created_time = int(time.time()) |
1281 | 1285 | final_res: RequestOutput | None = None |
1282 | 1286 |
|
@@ -1393,12 +1397,17 @@ async def chat_completion_full_generator( |
1393 | 1397 | enable_auto_tools=self.enable_auto_tools, |
1394 | 1398 | tool_parser_cls=self.tool_parser, |
1395 | 1399 | ) |
1396 | | - tool_call_class = ( |
1397 | | - MistralToolCall if is_mistral_tokenizer(tokenizer) else ToolCall |
1398 | | - ) |
| 1400 | + if is_mistral_tokenizer(tokenizer): |
| 1401 | + from vllm.tool_parsers.mistral_tool_parser import MistralToolCall |
| 1402 | + |
| 1403 | + tool_call_class: type[ToolCall] = MistralToolCall |
| 1404 | + else: |
| 1405 | + tool_call_class = ToolCall |
1399 | 1406 |
|
1400 | 1407 | use_mistral_tool_parser = request._grammar_from_tool_parser |
1401 | 1408 | if use_mistral_tool_parser: |
| 1409 | + from vllm.tool_parsers.mistral_tool_parser import MistralToolParser |
| 1410 | + |
1402 | 1411 | tool_call_items = MistralToolParser.build_non_streaming_tool_calls( |
1403 | 1412 | tool_calls |
1404 | 1413 | ) |
@@ -1436,7 +1445,7 @@ async def chat_completion_full_generator( |
1436 | 1445 | # Generate ID using the correct format (kimi_k2 or random), |
1437 | 1446 | # but leave it to the class if it's Mistral to preserve |
1438 | 1447 | # 9-char IDs |
1439 | | - if isinstance(tokenizer, MistralTokenizer): |
| 1448 | + if is_mistral_tokenizer(tokenizer): |
1440 | 1449 | tool_call_class_items.append(tool_call_class(function=tc)) |
1441 | 1450 | else: |
1442 | 1451 | generated_id = make_tool_call_id( |
@@ -1469,7 +1478,7 @@ async def chat_completion_full_generator( |
1469 | 1478 | # Generate ID using the correct format (kimi_k2 or random), |
1470 | 1479 | # but leave it to the class if it's Mistral to preserve |
1471 | 1480 | # 9-char IDs |
1472 | | - if isinstance(tokenizer, MistralTokenizer): |
| 1481 | + if is_mistral_tokenizer(tokenizer): |
1473 | 1482 | tool_call_class_items.append( |
1474 | 1483 | tool_call_class(function=tool_call) |
1475 | 1484 | ) |
@@ -1519,7 +1528,7 @@ async def chat_completion_full_generator( |
1519 | 1528 | # Generate ID using the correct format (kimi_k2 or random), |
1520 | 1529 | # but leave it to the class if it's Mistral to preserve |
1521 | 1530 | # 9-char IDs |
1522 | | - if isinstance(tokenizer, MistralTokenizer): |
| 1531 | + if is_mistral_tokenizer(tokenizer): |
1523 | 1532 | tool_call_items.append(tool_call_class(function=tc)) |
1524 | 1533 | else: |
1525 | 1534 | generated_id = make_tool_call_id( |
|
0 commit comments