fix: do not strip whitespace from GLM tool call values (#20543)

Co-authored-by: Kangyan-Zhou <zky314343421@gmail.com>
This commit is contained in:
Lawrence Wu
2026-04-09 11:14:15 -07:00
committed by GitHub
co-authored by Kangyan-Zhou
parent 8b991d98a1
commit 8eb235ab51
3 changed files with 66 additions and 2 deletions
@@ -759,7 +759,6 @@ class Glm47MoeDetector(BaseFormatDetector):
arguments = {} arguments = {}
for arg_key, arg_value in pairs: for arg_key, arg_value in pairs:
arg_key = arg_key.strip() arg_key = arg_key.strip()
arg_value = arg_value.strip()
arg_type = get_argument_type(func_name, arg_key, tools) arg_type = get_argument_type(func_name, arg_key, tools)
parsed_value, is_good_json = parse_arguments(arg_value, arg_type) parsed_value, is_good_json = parse_arguments(arg_value, arg_type)
@@ -613,7 +613,6 @@ class Glm4MoeDetector(BaseFormatDetector):
arguments = {} arguments = {}
for arg_key, arg_value in pairs: for arg_key, arg_value in pairs:
arg_key = arg_key.strip() arg_key = arg_key.strip()
arg_value = arg_value.strip()
arg_type = get_argument_type(func_name, arg_key, tools) arg_type = get_argument_type(func_name, arg_key, tools)
parsed_value, is_good_json = parse_arguments(arg_value, arg_type) parsed_value, is_good_json = parse_arguments(arg_value, arg_type)
@@ -2276,6 +2276,39 @@ class TestGlm4MoeDetector(unittest.TestCase):
self.assertIsInstance(result, StreamingParseResult) self.assertIsInstance(result, StreamingParseResult)
self.assertEqual(result.calls, []) self.assertEqual(result.calls, [])
def test_whitespace_preserved_in_arg_values(self):
"""Test that leading/trailing whitespace in arg values is not stripped."""
tools_with_string = [
Tool(
type="function",
function=Function(
name="apply_diff",
description="Apply a diff",
parameters={
"type": "object",
"properties": {
"old_string": {"type": "string"},
"new_string": {"type": "string"},
},
"required": ["old_string", "new_string"],
},
),
)
]
text = (
"<tool_call>apply_diff\n"
"<arg_key>old_string</arg_key>\n"
"<arg_value> indented code</arg_value>\n"
"<arg_key>new_string</arg_key>\n"
"<arg_value> also indented</arg_value>\n"
"</tool_call>"
)
result = self.detector.detect_and_parse(text, tools_with_string)
self.assertEqual(len(result.calls), 1)
params = json.loads(result.calls[0].parameters)
self.assertEqual(params["old_string"], " indented code")
self.assertEqual(params["new_string"], " also indented")
class TestGlm47MoeDetector(unittest.TestCase): class TestGlm47MoeDetector(unittest.TestCase):
def setUp(self): def setUp(self):
@@ -2552,6 +2585,39 @@ class TestGlm47MoeDetector(unittest.TestCase):
) )
check_single_todos(result, expected_output) check_single_todos(result, expected_output)
def test_whitespace_preserved_in_arg_values(self):
"""Test that leading/trailing whitespace in arg values is not stripped."""
tools_with_string = [
Tool(
type="function",
function=Function(
name="apply_diff",
description="Apply a diff",
parameters={
"type": "object",
"properties": {
"old_string": {"type": "string"},
"new_string": {"type": "string"},
},
"required": ["old_string", "new_string"],
},
),
)
]
text = (
"<tool_call>apply_diff"
"<arg_key>old_string</arg_key>"
"<arg_value> indented code</arg_value>"
"<arg_key>new_string</arg_key>"
"<arg_value> also indented</arg_value>"
"</tool_call>"
)
result = self.detector.detect_and_parse(text, tools_with_string)
self.assertEqual(len(result.calls), 1)
params = json.loads(result.calls[0].parameters)
self.assertEqual(params["old_string"], " indented code")
self.assertEqual(params["new_string"], " also indented")
class TestJsonArrayParser(unittest.TestCase): class TestJsonArrayParser(unittest.TestCase):
def setUp(self): def setUp(self):