Fix MiniMax tool calling (#456)
Co-authored-by: n1majne3 <24203125+n1majne3@users.noreply.github.com>
This commit is contained in:
+4
-2
@@ -26,8 +26,10 @@ from strix.utils.resource_paths import get_strix_resource_path
|
|||||||
litellm.drop_params = True
|
litellm.drop_params = True
|
||||||
litellm.modify_params = True
|
litellm.modify_params = True
|
||||||
|
|
||||||
_THINKING_BLOCK_RE = re.compile(r"<thinking[^>]*>.*?</thinking>", re.DOTALL)
|
_THINKING_BLOCK_RE = re.compile(r"<think(?:ing)?[^>]*>.*?</think(?:ing)?>", re.DOTALL)
|
||||||
_THINKING_BLOCK_OR_OPEN_RE = re.compile(r"<thinking[^>]*>.*?(?:</thinking>|\Z)", 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:
|
def _find_end_tag_outside_thinking(content: str, end_tag: str) -> int:
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import html
|
import html
|
||||||
|
import json
|
||||||
import re
|
import re
|
||||||
from typing import Any
|
from typing import Any
|
||||||
|
|
||||||
@@ -6,6 +7,7 @@ from typing import Any
|
|||||||
_INVOKE_OPEN = re.compile(r'<invoke\s+name=["\']([^"\']+)["\']>')
|
_INVOKE_OPEN = re.compile(r'<invoke\s+name=["\']([^"\']+)["\']>')
|
||||||
_PARAM_NAME_ATTR = re.compile(r'<parameter\s+name=["\']([^"\']+)["\']>')
|
_PARAM_NAME_ATTR = re.compile(r'<parameter\s+name=["\']([^"\']+)["\']>')
|
||||||
_FUNCTION_CALLS_TAG = re.compile(r"</?function_calls>")
|
_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*([^>]*?)>")
|
_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.
|
"""Convert alternative tool-call XML formats to the expected one.
|
||||||
|
|
||||||
Handles:
|
Handles:
|
||||||
|
<minimax:tool_call>...</minimax:tool_call> → stripped
|
||||||
<function_calls>...</function_calls> → stripped
|
<function_calls>...</function_calls> → stripped
|
||||||
<invoke name="X"> → <function=X>
|
<invoke name="X"> → <function=X>
|
||||||
<parameter name="X"> → <parameter=X>
|
<parameter name="X"> → <parameter=X>
|
||||||
@@ -20,6 +23,8 @@ def normalize_tool_format(content: str) -> str:
|
|||||||
<function="X"> → <function=X>
|
<function="X"> → <function=X>
|
||||||
<parameter="X"> → <parameter=X>
|
<parameter="X"> → <parameter=X>
|
||||||
"""
|
"""
|
||||||
|
content = _MINIMAX_TOOL_CALL_TAG.sub("", content)
|
||||||
|
|
||||||
if (
|
if (
|
||||||
"<invoke" in content
|
"<invoke" in content
|
||||||
or "<function_calls" 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)
|
param_value = html.unescape(param_value)
|
||||||
args[param_name] = 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})
|
tool_invocations.append({"toolName": fn_name, "args": args})
|
||||||
|
|
||||||
return tool_invocations if tool_invocations else None
|
return tool_invocations if tool_invocations else None
|
||||||
|
|||||||
Reference in New Issue
Block a user