Skip to content

Commit c7b630d

Browse files
committed
[None][fixes] Add tool call parsing fixes and Qwen3 coder parser
Signed-off-by: William Zhang <[email protected]>
1 parent b26e161 commit c7b630d

File tree

5 files changed

+437
-70
lines changed

5 files changed

+437
-70
lines changed

tensorrt_llm/serve/chat_utils.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import json
12
import uuid
23
from functools import partial
34
from typing import (Any, Callable, Coroutine, Dict, Iterable, List, Literal,
@@ -185,6 +186,36 @@ def parse_chat_message_content(
185186
content,
186187
mm_data_tracker,
187188
)
189+
if role == "assistant":
190+
result.update(_parse_assistant_message_content(message))
191+
elif role == "tool":
192+
result.update(_parse_tool_message_content(message))
193+
return result
194+
195+
196+
# Adapted from: https://github.com/vllm-project/vllm/blob/4574d48bab9c4e38b7c0a830eeefc8f0980e8c58/vllm/entrypoints/chat_utils.py#L1406
197+
def _parse_assistant_message_content(message: Dict[str, Any]) -> Dict[str, Any]:
198+
result = {}
199+
tool_calls = message.get("tool_calls")
200+
if tool_calls is not None:
201+
result["tool_calls"] = []
202+
for item in tool_calls:
203+
if content := item["function"].get("arguments"):
204+
if isinstance(content, str):
205+
item["function"]["arguments"] = json.loads(content)
206+
else:
207+
item["function"]["arguments"] = content
208+
else:
209+
item["function"]["arguments"] = {}
210+
result["tool_calls"].append(item)
211+
212+
return result
213+
214+
215+
def _parse_tool_message_content(message: Dict[str, Any]) -> Dict[str, Any]:
216+
result = {}
217+
if "tool_call_id" in message:
218+
result["tool_call_id"] = message["tool_call_id"]
188219
return result
189220

190221

tensorrt_llm/serve/openai_protocol.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -396,6 +396,12 @@ class CustomChatCompletionContentPartParam(TypedDict, total=False):
396396

397397
class CustomChatCompletionMessageParam(TypedDict, total=False):
398398
"""Enables custom roles in the Chat Completion API."""
399+
400+
# This is so custom fields not in any of the `ChatCompletionMessage<XYZ>Param` defined by OpenAI
401+
# are still allowed.
402+
# Examples include: assistant messages with `reasoning` / `reasoning_content`.
403+
__pydantic_config__ = ConfigDict(extra="allow") # type: ignore
404+
399405
role: Required[str]
400406
"""The role of the message's author."""
401407

tensorrt_llm/serve/tool_parser/tool_parser_factory.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
from typing import Type
22

33
from .base_tool_parser import BaseToolParser
4+
from .qwen3_coder_parser import Qwen3CoderToolParser
45
from .qwen3_tool_parser import Qwen3ToolParser
56

67

78
class ToolParserFactory:
89
parsers: dict[str, Type[BaseToolParser]] = {
910
"qwen3": Qwen3ToolParser,
11+
"qwen3_coder": Qwen3CoderToolParser,
1012
}
1113

1214
@staticmethod

tests/integration/test_lists/test-db/l0_a10.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ l0_a10:
7373
# executor
7474
- unittest/executor/test_rpc.py
7575
# trtllm-serve CPU-only
76+
- unittest/llmapi/apps/test_chat_utils.py
7677
- unittest/llmapi/apps/test_tool_parsers.py
7778
- unittest/llmapi/apps/test_harmony_channel_validation.py
7879
- condition:

0 commit comments

Comments
 (0)