diff --git a/src/llamafactory/data/tool_utils.py b/src/llamafactory/data/tool_utils.py
index 69a13c5745..970352838a 100644
--- a/src/llamafactory/data/tool_utils.py
+++ b/src/llamafactory/data/tool_utils.py
@@ -521,7 +521,7 @@ def function_formatter(functions: list["FunctionCall"]) -> str:
prompt += "\n"
function_texts.append(prompt)
- return "\n".join(function_texts)
+ return "\n" + "\n".join(function_texts) + "\n"
@override
@staticmethod
diff --git a/tests/data/test_formatter.py b/tests/data/test_formatter.py
index 3aaa6f991d..05396c3651 100644
--- a/tests/data/test_formatter.py
+++ b/tests/data/test_formatter.py
@@ -294,6 +294,54 @@ def test_qwen_multi_tool_extractor():
]
+@pytest.mark.runs_on(["cpu", "mps"])
+def test_minimax2_function_formatter():
+ formatter = FunctionFormatter(slots=["{{content}}"], tool_format="minimax2")
+ tool_calls = json.dumps(FUNCTION)
+ assert formatter.apply(content=tool_calls) == [
+ "\n"
+ '\n'
+ 'bar\n'
+ '10\n'
+ "\n"
+ ""
+ ]
+
+
+@pytest.mark.runs_on(["cpu", "mps"])
+def test_minimax2_multi_function_formatter():
+ formatter = FunctionFormatter(slots=["{{content}}"], tool_format="minimax2")
+ tool_calls = json.dumps([FUNCTION] * 2)
+ invoke = '\nbar\n10\n'
+ assert formatter.apply(content=tool_calls) == [f"\n{invoke}\n{invoke}\n"]
+
+
+@pytest.mark.runs_on(["cpu", "mps"])
+def test_minimax2_tool_extractor():
+ formatter = ToolFormatter(tool_format="minimax2")
+ result = (
+ "\n"
+ '\n'
+ 'bar\n'
+ '10\n'
+ "\n"
+ ""
+ )
+ assert formatter.extract(result) == [("test_tool", """{"foo": "bar", "size": 10}""")]
+
+
+@pytest.mark.runs_on(["cpu", "mps"])
+def test_minimax2_tool_round_trip():
+ formatter = FunctionFormatter(slots=["{{content}}"], tool_format="minimax2")
+ tool_formatter = ToolFormatter(tool_format="minimax2")
+ original = {"name": "my_func", "arguments": {"arg1": "hello", "arg2": 42, "arg3": True}}
+ formatted = formatter.apply(content=json.dumps(original))
+ extracted = tool_formatter.extract(formatted[0])
+ assert len(extracted) == 1
+ assert extracted[0][0] == original["name"]
+ assert json.loads(extracted[0][1]) == original["arguments"]
+
+
@pytest.mark.runs_on(["cpu", "mps"])
def test_lfm2_function_formatter():
formatter = FunctionFormatter(slots=["{{content}}<|im_end|>\n"], tool_format="lfm2")