mirror of
https://github.com/usestrix/strix.git
synced 2026-08-28 05:25:00 +00:00
fix: MiniMax tool call normalization and thinking block handling (#458)
Co-authored-by: 0xallam <ahmed39652003@gmail.com>
This commit is contained in:
parent
6da7315aa3
commit
a75ad2960e
2 changed files with 26 additions and 4 deletions
|
|
@ -1,4 +1,5 @@
|
|||
import asyncio
|
||||
import re
|
||||
from collections.abc import AsyncIterator
|
||||
from dataclasses import dataclass
|
||||
from typing import Any
|
||||
|
|
@ -25,6 +26,19 @@ 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)
|
||||
|
||||
|
||||
def _find_end_tag_outside_thinking(content: str, end_tag: str) -> int:
|
||||
thinking_spans = [(m.start(), m.end()) for m in _THINKING_BLOCK_OR_OPEN_RE.finditer(content)]
|
||||
start = 0
|
||||
while (idx := content.find(end_tag, start)) != -1:
|
||||
if not any(s <= idx < e for s, e in thinking_spans):
|
||||
return idx
|
||||
start = idx + 1
|
||||
return -1
|
||||
|
||||
|
||||
class LLMRequestFailedError(Exception):
|
||||
def __init__(self, message: str, details: str | None = None):
|
||||
|
|
@ -197,9 +211,10 @@ class LLM:
|
|||
delta = self._get_chunk_content(chunk)
|
||||
if delta:
|
||||
accumulated += delta
|
||||
if "</function>" in accumulated or "</invoke>" in accumulated:
|
||||
end_tag = "</function>" if "</function>" in accumulated else "</invoke>"
|
||||
pos = accumulated.find(end_tag)
|
||||
check_content = _THINKING_BLOCK_OR_OPEN_RE.sub("", accumulated)
|
||||
if "</function>" in check_content or "</invoke>" in check_content:
|
||||
end_tag = "</function>" if "</function>" in check_content else "</invoke>"
|
||||
pos = _find_end_tag_outside_thinking(accumulated, end_tag)
|
||||
accumulated = accumulated[: pos + len(end_tag)]
|
||||
yield LLMResponse(content=accumulated)
|
||||
done_streaming = 1
|
||||
|
|
@ -209,8 +224,10 @@ class LLM:
|
|||
if chunks:
|
||||
self._update_usage_stats(stream_chunk_builder(chunks))
|
||||
|
||||
accumulated = _THINKING_BLOCK_RE.sub("", accumulated)
|
||||
accumulated = normalize_tool_format(accumulated)
|
||||
accumulated = fix_incomplete_tool_call(_truncate_to_first_function(accumulated))
|
||||
|
||||
yield LLMResponse(
|
||||
content=accumulated,
|
||||
tool_invocations=parse_tool_invocations(accumulated),
|
||||
|
|
|
|||
|
|
@ -20,7 +20,12 @@ def normalize_tool_format(content: str) -> str:
|
|||
<function="X"> → <function=X>
|
||||
<parameter="X"> → <parameter=X>
|
||||
"""
|
||||
if "<invoke" in content or "<function_calls" in content:
|
||||
if (
|
||||
"<invoke" in content
|
||||
or "<function_calls" in content
|
||||
or '<parameter name="' in content
|
||||
or "<parameter name='" in content
|
||||
):
|
||||
content = _FUNCTION_CALLS_TAG.sub("", content)
|
||||
content = _INVOKE_OPEN.sub(r"<function=\1>", content)
|
||||
content = _PARAM_NAME_ATTR.sub(r"<parameter=\1>", content)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue