Skip to content

[BUG] MiniMax models: tool calls fail — <parameter name="x"> not normalized, thinking blocks interfere with XML parsing #439

@n1majne3

Description

@n1majne3

Description

When using MiniMax models (M2.5, M2.7) with Strix, all tool calls fail with errors like "missing required positional argument" even though the model is attempting to call tools correctly.

Root Cause

There are two related issues:

1. Parameter format mismatch

MiniMax outputs tool call parameters in Anthropic-style XML with name attribute:

<parameter name="action">launch</parameter>

But Strix expects OpenAI-style format:

<parameter=action>launch</parameter>

The normalize_tool_format() function has a _PARAM_NAME_ATTR regex to handle this conversion, but it only triggers when "<invoke" in content or "<function_calls" in content. MiniMax uses <function=name> format (which IS supported for opening tags), but this does NOT trigger the name attribute normalization for <parameter name="x">.

2. Thinking blocks interfere with tool call parsing

MiniMax models output thinking in <thinking>...</thinking> blocks inline in the response content. When tool call XML appears inside thinking blocks, _stream() in llm.py incorrectly detects </function> inside the thinking block and truncates the response prematurely.

Claude/GPT/Gemini output thinking via the API reasoning field (separate from content), so this conflict does not occur with officially supported models.

Environment

  • Strix Version: 0.8.3
  • LLM: minimax/MiniMax-M2.5 and minimax/MiniMax-M2.7
  • API Base: https://api.minimax.com/v1 (OpenAI-compatible)

Evidence from events.jsonl

Raw model output captured in chat.message events shows the format:

<function=browser_action>
<parameter name="action">launch</parameter>
<parameter name="url">http://host.docker.internal/</parameter>
</function>

Tool execution fails because parameter parsing returns empty values.

Suggested Fixes

  1. In normalize_tool_format() in strix/llm/utils.py: extend the trigger condition to also run _PARAM_NAME_ATTR conversion when "<parameter name=" is detected in content, regardless of whether <invoke or <function_calls> is present.

  2. In _stream() in strix/llm/llm.py: strip <thinking>...</thinking> blocks from accumulated before checking for </function> tags, so that tool calls inside thinking blocks do not cause false positives.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions