Repository navigation
Conversation
Signed-off-by: stevenkuang-tencent <stevenkuang@tencent.com>
| self.tool_calls_start_token: str = "<tool_calls>" | ||
| self.tool_calls_end_token: str = "</tool_calls>" | ||
| init_kwargs = getattr(tokenizer, "init_kwargs", None) or {} | ||
| self.suffix: str = init_kwargs.get("token_suffix") or "" |
There was a problem hiding this comment.
⚪ Severity: LOW
The token_suffix value from the tokenizer config is interpolated into regex patterns (lines 289-303) without re.escape(). A malicious model's tokenizer_config.json could supply regex metacharacters to alter pattern matching of tool calls. Other parsers in this codebase (e.g., deepseekv32_tool_parser.py) correctly use re.escape().
Helpful? Add 👍 / 👎
💡 Fix Suggestion
Suggestion: Apply re.escape() to the token strings when interpolating them into regex patterns on lines 289-303. The token values (which contain the unescaped suffix) should be escaped before being used in regex compilation. For example, change the regex constructions to use re.escape(self.tool_call_start_token) instead of directly interpolating self.tool_call_start_token. Specifically:
self.tool_call_regex = re.compile(
re.escape(self.tool_call_start_token) + r"(.*?)"
+ re.escape(self.tool_sep_token) + r"(.*?)"
+ re.escape(self.tool_call_end_token),
re.DOTALL,
)
self.tool_call_portion_regex = re.compile(
re.escape(self.tool_call_start_token) + r"(.*?)"
+ re.escape(self.tool_sep_token) + r"(.*)",
re.DOTALL,
)
self.func_args_regex = re.compile(
re.escape(self.arg_key_start_token) + r"(.*?)"
+ re.escape(self.arg_key_end_token) + r"\s*"
+ re.escape(self.arg_value_start_token) + r"(.*?)"
+ re.escape(self.arg_value_end_token),
re.DOTALL,
)This follows the same pattern used in deepseekv32_tool_parser.py and ensures that any regex metacharacters in the suffix from the tokenizer config are treated as literals.
There was a problem hiding this comment.
Thanks for these fixes!
For context, there's an ongoing effort to migrate parsers onto the declarative parser engine (https://github.com/vllm-project/vllm/tree/main/vllm/parser/engine) (GLM-4.7, MiniMax-M2, Qwen3 already there), and hy_v3 is a good candidate. If hv_v3 is ported over, the JSON Schema union types crash would be fixed structurally, and the issue with token suffix not recognized becomes a one-place config parameter.
Would you be willing to help with migrating hv over?
…oject#47192) Signed-off-by: stevenkuang-tencent <stevenkuang@tencent.com>
…oject#47192) Signed-off-by: stevenkuang-tencent <stevenkuang@tencent.com>
Purpose
Support Hy3 token suffix and JSON Schema array types.
Test Plan
Tests for the hy_v3 reasoning parser and tool parser.
Test Result
Passed
Add two enhancements to the hy_v3 reasoning parser and tool parser