Fix MiniMax tool calling (#456)

Co-authored-by: n1majne3 <24203125+n1majne3@users.noreply.github.com>
This commit is contained in:
n1majne3
2026-05-04 10:49:18 +08:00
committed by GitHub
parent e1f38f8339
commit 6b9bd4d5f2
2 changed files with 22 additions and 2 deletions
+4 -2
View File
@@ -26,8 +26,10 @@ from strix.utils.resource_paths import get_strix_resource_path
litellm.drop_params = True
litellm.modify_params = True
_THINKING_BLOCK_RE = re.compile(r"<thinking[^>]*>.*?</thinking>", re.DOTALL)
_THINKING_BLOCK_OR_OPEN_RE = re.compile(r"<thinking[^>]*>.*?(?:</thinking>|\Z)", re.DOTALL)
_THINKING_BLOCK_RE = re.compile(r"<think(?:ing)?[^>]*>.*?</think(?:ing)?>", re.DOTALL)
_THINKING_BLOCK_OR_OPEN_RE = re.compile(
r"<think(?:ing)?[^>]*>.*?(?:</think(?:ing)?>|\Z)", re.DOTALL
)
def _find_end_tag_outside_thinking(content: str, end_tag: str) -> int:
+18
View File
@@ -1,4 +1,5 @@
import html
import json
import re
from typing import Any
@@ -6,6 +7,7 @@ from typing import Any
_INVOKE_OPEN = re.compile(r'<invoke\s+name=["\']([^"\']+)["\']>')
_PARAM_NAME_ATTR = re.compile(r'<parameter\s+name=["\']([^"\']+)["\']>')
_FUNCTION_CALLS_TAG = re.compile(r"</?function_calls>")
_MINIMAX_TOOL_CALL_TAG = re.compile(r"</?minimax:tool_call>")
_STRIP_TAG_QUOTES = re.compile(r"<(function|parameter)\s*=\s*([^>]*?)>")
@@ -13,6 +15,7 @@ def normalize_tool_format(content: str) -> str:
"""Convert alternative tool-call XML formats to the expected one.
Handles:
<minimax:tool_call>...</minimax:tool_call> → stripped
<function_calls>...</function_calls> → stripped
<invoke name="X"> → <function=X>
<parameter name="X"> → <parameter=X>
@@ -20,6 +23,8 @@ def normalize_tool_format(content: str) -> str:
<function="X"> → <function=X>
<parameter="X"> → <parameter=X>
"""
content = _MINIMAX_TOOL_CALL_TAG.sub("", content)
if (
"<invoke" in content
or "<function_calls" in content
@@ -107,6 +112,19 @@ def parse_tool_invocations(content: str) -> list[dict[str, Any]] | None:
param_value = html.unescape(param_value)
args[param_name] = param_value
if not args:
body_stripped = html.unescape(fn_body.strip())
if body_stripped.startswith("{"):
try:
parsed = json.loads(body_stripped)
if isinstance(parsed, dict):
args = {
k: v if isinstance(v, str) else json.dumps(v)
for k, v in parsed.items()
}
except (json.JSONDecodeError, ValueError):
pass
tool_invocations.append({"toolName": fn_name, "args": args})
return tool_invocations if tool_invocations else None