diff --git a/vllm/reasoning/hy_v3_reasoning_parser.py b/vllm/reasoning/hy_v3_reasoning_parser.py
index 5beac22996..59631a3340 100644
--- a/vllm/reasoning/hy_v3_reasoning_parser.py
+++ b/vllm/reasoning/hy_v3_reasoning_parser.py
@@ -26,6 +26,8 @@ class HYV3ReasoningParser(BaseThinkingReasoningParser):
"""
def __init__(self, tokenizer: TokenizerLike, *args, **kwargs):
+ init_kwargs = getattr(tokenizer, "init_kwargs", None) or {}
+ self.suffix: str = init_kwargs.get("token_suffix") or ""
super().__init__(tokenizer, *args, **kwargs)
# First, If there is reasoning_effort in chat_kwargs,
@@ -52,12 +54,12 @@ class HYV3ReasoningParser(BaseThinkingReasoningParser):
@property
def start_token(self) -> str:
"""The token that starts reasoning content."""
- return ""
+ return f""
@property
def end_token(self) -> str:
"""The token that ends reasoning content."""
- return ""
+ return f""
def is_reasoning_end(self, input_ids: Sequence[int]) -> bool:
if self._identity_parser is not None:
diff --git a/vllm/tool_parsers/hy_v3_tool_parser.py b/vllm/tool_parsers/hy_v3_tool_parser.py
index 619be5e9cc..0ffaf92d86 100644
--- a/vllm/tool_parsers/hy_v3_tool_parser.py
+++ b/vllm/tool_parsers/hy_v3_tool_parser.py
@@ -108,6 +108,14 @@ class HYV3ToolParser(ToolParser):
Note: single ``type`` has the highest priority.
"""
if "type" in arg_schema:
+ type_val = arg_schema["type"]
+ # JSON Schema allows "type" to be an array to represent union types,
+ # e.g. "type": ["string", "object"].
+ # Expand it into an anyOf-equivalent format:
+ # [{"type": "string"}, {"type": "object"}]
+ # so that _get_types / _parse_value can handle it uniformly later.
+ if isinstance(type_val, list):
+ return [{"type": t} for t in type_val]
return [arg_schema]
if "anyOf" in arg_schema:
return arg_schema["anyOf"]
@@ -261,19 +269,22 @@ class HYV3ToolParser(ToolParser):
self._current_arg_is_string: bool = False # is current arg pure string?
self._streamed_json_len: int = 0 # bytes of JSON already sent
- self.tool_calls_start_token: str = ""
- self.tool_calls_end_token: str = ""
+ init_kwargs = getattr(tokenizer, "init_kwargs", None) or {}
+ self.suffix: str = init_kwargs.get("token_suffix") or ""
- self.tool_call_start_token: str = ""
- self.tool_call_end_token: str = ""
+ self.tool_calls_start_token: str = f""
+ self.tool_calls_end_token: str = f""
- self.tool_sep_token: str = ""
+ self.tool_call_start_token: str = f""
+ self.tool_call_end_token: str = f""
- self.arg_key_start_token: str = ""
- self.arg_key_end_token: str = ""
+ self.tool_sep_token: str = f""
- self.arg_value_start_token: str = ""
- self.arg_value_end_token: str = ""
+ self.arg_key_start_token: str = f""
+ self.arg_key_end_token: str = f""
+
+ self.arg_value_start_token: str = f""
+ self.arg_value_end_token: str = f""
self.tool_call_regex = re.compile(
rf"{self.tool_call_start_token}(.*?){self.tool_sep_token}"