Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion python/sglang/srt/function_call/multi_format_detector.py
Original file line number Diff line number Diff line change
Expand Up @@ -1046,7 +1046,10 @@ def _deserialize_glm_value(value: str) -> Any:
except Exception:
pass
try:
return ast.literal_eval(value)
result = ast.literal_eval(value)
Comment thread
flukeskywalker marked this conversation as resolved.
# Keep literal_eval results only when they remain JSON-serializable.
json.dumps(result)
Comment thread
flukeskywalker marked this conversation as resolved.
Comment thread
flukeskywalker marked this conversation as resolved.
return result
except Exception:
pass
return value
Expand Down
12 changes: 12 additions & 0 deletions test/registered/function_call/test_multi_format_detector.py
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,18 @@ def test_python_tuple_literal_value(self):
# ast.literal handles tuple syntax; serialized as a JSON array.
self.assertEqual(args["days"], [1, 2])

def test_python_set_literal_value_stays_string(self):
text = (
"<tool_call>get_weather"
"<arg_key>days</arg_key><arg_value>{1, 2}</arg_value>"
"</tool_call>"
)
result = self.det.detect_and_parse(text, self.tools)
args = json.loads(result.calls[0].parameters)
# ast.literal_eval yields a set, which JSON cannot represent; the raw
# string is kept so the arguments dict stays serializable.
self.assertEqual(args["days"], "{1, 2}")


class TestGptOssDialect(unittest.TestCase):
def setUp(self):
Expand Down
Loading