From 8eb235ab512528de4c55200c09e2cbc3159a94ba Mon Sep 17 00:00:00 2001 From: Lawrence Wu Date: Thu, 9 Apr 2026 11:14:15 -0700 Subject: [PATCH] fix: do not strip whitespace from GLM tool call values (#20543) Co-authored-by: Kangyan-Zhou --- .../srt/function_call/glm47_moe_detector.py | 1 - .../srt/function_call/glm4_moe_detector.py | 1 - .../test_function_call_parser.py | 66 +++++++++++++++++++ 3 files changed, 66 insertions(+), 2 deletions(-) diff --git a/python/sglang/srt/function_call/glm47_moe_detector.py b/python/sglang/srt/function_call/glm47_moe_detector.py index 0b25b11eb..9bc11d770 100644 --- a/python/sglang/srt/function_call/glm47_moe_detector.py +++ b/python/sglang/srt/function_call/glm47_moe_detector.py @@ -759,7 +759,6 @@ class Glm47MoeDetector(BaseFormatDetector): arguments = {} for arg_key, arg_value in pairs: arg_key = arg_key.strip() - arg_value = arg_value.strip() arg_type = get_argument_type(func_name, arg_key, tools) parsed_value, is_good_json = parse_arguments(arg_value, arg_type) diff --git a/python/sglang/srt/function_call/glm4_moe_detector.py b/python/sglang/srt/function_call/glm4_moe_detector.py index 0761e24e7..36992b3fe 100644 --- a/python/sglang/srt/function_call/glm4_moe_detector.py +++ b/python/sglang/srt/function_call/glm4_moe_detector.py @@ -613,7 +613,6 @@ class Glm4MoeDetector(BaseFormatDetector): arguments = {} for arg_key, arg_value in pairs: arg_key = arg_key.strip() - arg_value = arg_value.strip() arg_type = get_argument_type(func_name, arg_key, tools) parsed_value, is_good_json = parse_arguments(arg_value, arg_type) diff --git a/test/registered/unit/function_call/test_function_call_parser.py b/test/registered/unit/function_call/test_function_call_parser.py index 01aa99904..f0974d45e 100644 --- a/test/registered/unit/function_call/test_function_call_parser.py +++ b/test/registered/unit/function_call/test_function_call_parser.py @@ -2276,6 +2276,39 @@ class TestGlm4MoeDetector(unittest.TestCase): self.assertIsInstance(result, StreamingParseResult) 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 = ( + "apply_diff\n" + "old_string\n" + " indented code\n" + "new_string\n" + " also indented\n" + "" + ) + 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): def setUp(self): @@ -2552,6 +2585,39 @@ class TestGlm47MoeDetector(unittest.TestCase): ) 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 = ( + "apply_diff" + "old_string" + " indented code" + "new_string" + " also indented" + "" + ) + 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): def setUp(self):