"""Regression tests for Qwen/OpenClaude tool-call formats."""
from __future__ import annotations
import json
import unittest
from tool_calls import (
extract_tool_call,
extract_tool_calls,
has_complete_tool_call,
normalize_openai_tool_arguments,
recover_forced_tool_call,
)
ALLOWED = {"Bash", "Read", "WebSearch"}
class ToolCallTests(unittest.TestCase):
def parsed(self, text: str) -> dict:
call, visible = extract_tool_call(text, ALLOWED)
self.assertIsNotNone(call)
self.assertEqual(visible, "")
return call
def test_json_wrapper(self) -> None:
call = self.parsed(
'{"name":"Bash","arguments":{"command":"pwd"}}'
)
self.assertEqual(call["function"]["name"], "Bash")
self.assertEqual(json.loads(call["function"]["arguments"]), {"command": "pwd"})
def test_python_literal_wrapper_from_dolphin(self) -> None:
call = self.parsed(
"{'name': 'WebSearch', "
"'arguments': {'query': 'Gitlawb OpenClaude GitHub'}}"
)
self.assertEqual(call["function"]["name"], "WebSearch")
self.assertEqual(
json.loads(call["function"]["arguments"]),
{"query": "Gitlawb OpenClaude GitHub"},
)
def test_python_literal_does_not_execute_expressions(self) -> None:
text = (
"{'name': 'Bash', "
"'arguments': __import__('os').system('id')}"
)
call, visible = extract_tool_call(text, ALLOWED)
self.assertIsNone(call)
self.assertEqual(visible, text)
def test_xml_wrapped_json_from_openclaude(self) -> None:
call = self.parsed(
'{"name":"Bash","arguments":{"command":"ls -la"}}'
)
self.assertEqual(call["function"]["name"], "Bash")
self.assertEqual(
json.loads(call["function"]["arguments"]), {"command": "ls -la"}
)
self.assertTrue(
has_complete_tool_call(
'{"name":"Bash","arguments":{"command":"pwd"}}'
)
)
def test_fenced_self_closing_openclaude_tag(self) -> None:
text = '''```xml
```'''
call = self.parsed(text)
self.assertEqual(call["function"]["name"], "Bash")
self.assertEqual(
json.loads(call["function"]["arguments"]),
{"command": "ls /tmp", "description": "List files"},
)
self.assertTrue(has_complete_tool_call(''))
def test_bare_ampersand_in_tool_attribute_is_preserved(self) -> None:
call = self.parsed(
''
)
self.assertEqual(
json.loads(call["function"]["arguments"]),
{
"command": (
"curl https://api.example.test/forecast?latitude=0"
"¤t_weather=true"
)
},
)
def test_standard_xml_function(self) -> None:
call = self.parsed(
"/tmp/a.txt"
""
)
self.assertEqual(call["function"]["name"], "Read")
self.assertEqual(
json.loads(call["function"]["arguments"]), {"file_path": "/tmp/a.txt"}
)
def test_literal_assistant_tool_text(self) -> None:
call = self.parsed(
'[Assistant called tool Bash with arguments {"command":"echo ok"}]'
)
self.assertEqual(
json.loads(call["function"]["arguments"]), {"command": "echo ok"}
)
def test_function_call_alias_from_qwen_is_supported(self) -> None:
text = (
'{"name":"Read","arguments":{"file_path":"app.py"}}'
''
)
calls, visible = extract_tool_calls(text, {"Read"})
self.assertEqual(visible, "")
self.assertEqual(len(calls), 1)
self.assertEqual(calls[0]["function"]["name"], "Read")
self.assertEqual(
json.loads(calls[0]["function"]["arguments"]),
{"file_path": "app.py"},
)
self.assertTrue(has_complete_tool_call(text))
def test_qwen_compact_textual_tool_call(self) -> None:
call = self.parsed(
'```python\nwebsearch with query="python 3.13 features and highlights"\n```'
)
self.assertEqual(call["function"]["name"], "WebSearch")
self.assertEqual(
json.loads(call["function"]["arguments"]),
{"query": "python 3.13 features and highlights"},
)
self.assertTrue(has_complete_tool_call('websearch with query="python"'))
def test_qwen_compact_textual_tool_call_supports_all_programming_tools(self) -> None:
samples = {
"Bash": 'bash with command="printf ok"',
"Read": 'read with file_path="/tmp/fixture.py"',
"Write": 'write with file_path="/tmp/new.py" content="pass"',
"Edit": (
'edit with file_path="/tmp/fixture.py" '
'old_string="left" new_string="right"'
),
"Glob": 'glob with pattern="**/*.py" path="/tmp"',
"Grep": 'grep with pattern="TODO" path="/tmp"',
"WebSearch": 'websearch with query="Qwen3 tool calling"',
"WebFetch": (
'webfetch with url="https://example.com" '
'prompt="summarize"'
),
"Task": 'agent with description="inspect the fixture"',
}
allowed = set(samples)
for expected_name, text in samples.items():
with self.subTest(tool=expected_name):
call, visible = extract_tool_call(text, allowed)
self.assertIsNotNone(call)
self.assertEqual(visible, "")
self.assertEqual(call["function"]["name"], expected_name)
def test_forced_tool_recovers_argument_only_json(self) -> None:
call = recover_forced_tool_call(
'{"file_path":"/tmp/project/app.py"}',
"Read",
)
self.assertIsNotNone(call)
self.assertEqual(call["function"]["name"], "Read")
self.assertEqual(
json.loads(call["function"]["arguments"]),
{"file_path": "/tmp/project/app.py"},
)
def test_forced_tool_recovery_rejects_prose_and_named_calls(self) -> None:
self.assertIsNone(recover_forced_tool_call("I would read the file.", "Read"))
self.assertIsNone(
recover_forced_tool_call(
'{"name":"Read","arguments":{"file_path":"/tmp/a"}}',
"Read",
)
)
def test_unknown_tool_is_not_exposed(self) -> None:
call, visible = extract_tool_call('', ALLOWED)
self.assertIsNone(call)
self.assertIn("Delete", visible)
def test_multiple_adjacent_calls_are_preserved_in_order(self) -> None:
calls, visible = extract_tool_calls(
'{"name":"Read","arguments":{"file_path":"/tmp/á.json"}}'
'\n'
'{"name":"Bash","arguments":{"command":"wc -c /tmp/á.json"}}'
"",
ALLOWED,
)
self.assertEqual(visible, "")
self.assertEqual(
[call["function"]["name"] for call in calls],
["Read", "Bash"],
)
self.assertEqual(
json.loads(calls[0]["function"]["arguments"]),
{"file_path": "/tmp/á.json"},
)
self.assertNotEqual(calls[0]["id"], calls[1]["id"])
def test_mixed_parallel_formats_are_preserved(self) -> None:
calls, visible = extract_tool_calls(
'\n'
"WebSearch"
'Qwen3 unicode 日本語'
"",
ALLOWED,
)
self.assertEqual(visible, "")
self.assertEqual(
[call["function"]["name"] for call in calls],
["Read", "WebSearch"],
)
self.assertEqual(
json.loads(calls[0]["function"]["arguments"]),
{"file_path": "/tmp/a & b.txt"},
)
def test_extreme_parallel_batch_has_unique_ids(self) -> None:
text = "".join(
""
+ json.dumps(
{
"name": "Read",
"arguments": {"file_path": f"/tmp/file-{index}.txt"},
}
)
+ ""
for index in range(64)
)
calls, visible = extract_tool_calls(text, ALLOWED)
self.assertEqual(visible, "")
self.assertEqual(len(calls), 64)
self.assertEqual(len({call["id"] for call in calls}), 64)
self.assertEqual(
json.loads(calls[-1]["function"]["arguments"]),
{"file_path": "/tmp/file-63.txt"},
)
def test_large_unicode_argument_is_not_truncated(self) -> None:
value = ("á日本語&" * 8192) + "fim"
text = (
""
+ json.dumps(
{"name": "WebSearch", "arguments": {"query": value}},
ensure_ascii=False,
)
+ ""
)
call = self.parsed(text)
self.assertEqual(json.loads(call["function"]["arguments"])["query"], value)
def test_openai_history_arguments_are_mappings_for_qwen_template(self) -> None:
self.assertEqual(
normalize_openai_tool_arguments('{"command":"pwd"}'),
{"command": "pwd"},
)
self.assertEqual(
normalize_openai_tool_arguments({"file_path": "/tmp/a.txt"}),
{"file_path": "/tmp/a.txt"},
)
self.assertEqual(normalize_openai_tool_arguments("not-json"), {})
def test_official_qwen_json_format_round_trips_tricky_arguments_deterministically(self) -> None:
cases = [
{"file_path": "README.md"},
{"path": "a/b c.py", "line": 17, "flag": True},
{"query": "a & b ? x=1&y=2", "unicode": "ação — 東京 🚀"},
{"content": "brace } inside string { and quote \" ok"},
{"nested": {"items": [1, 2, {"x": "y"}], "empty": {}}, "none": None},
{"command": "printf '%s\n' '{\"a\":1}' && echo done"},
]
for arguments in cases:
with self.subTest(arguments=arguments):
payload = json.dumps(
{"name": "Read", "arguments": arguments},
ensure_ascii=False,
separators=(",", ":"),
)
text = f"{payload}"
calls, visible = extract_tool_calls(text, {"Read"})
self.assertEqual(visible, "")
self.assertEqual(len(calls), 1)
self.assertEqual(calls[0]["function"]["name"], "Read")
self.assertEqual(json.loads(calls[0]["function"]["arguments"]), arguments)
self.assertTrue(has_complete_tool_call(text, {"Read"}))
def test_stopping_signal_rejects_unadvertised_complete_tool(self) -> None:
text = '{"name":"MadeUpTool","arguments":{}}'
self.assertFalse(has_complete_tool_call(text, {"Read"}))
def test_stopping_signal_accepts_advertised_complete_tool(self) -> None:
text = '{"name":"Read","arguments":{"file_path":"README.md"}}'
self.assertTrue(has_complete_tool_call(text, {"Read"}))
if __name__ == "__main__":
unittest.main()