diff --git a/tests/tool_parsers/test_apertus_tool_parser.py b/tests/tool_parsers/test_apertus_tool_parser.py index 5ab0a2bcc7..4c8e75e40b 100644 --- a/tests/tool_parsers/test_apertus_tool_parser.py +++ b/tests/tool_parsers/test_apertus_tool_parser.py @@ -244,6 +244,22 @@ class TestStreamingExtraction: assert tcs[0]["name"] == "get_weather" assert json.loads(tcs[0]["arguments"]) == {"location": "Paris, France"} + @pytest.mark.parametrize( + "arguments", + ['{"value": -2e-3}', '{"value": 1.5e3}', '{"values": [1.5e3, -2e-3]}'], + ) + def test_streaming_scientific_notation(self, parser, mock_request, arguments): + model_output = ( + f'{TOOL_CALLS_PREFIX}[{{"calculate": {arguments}}}]{TOOL_CALLS_SUFFIX}' + ) + + results = self._simulate_streaming(parser, mock_request, list(model_output)) + tool_calls = self._collect_tool_calls(results) + + assert len(tool_calls) == 1 + assert tool_calls[0]["name"] == "calculate" + assert json.loads(tool_calls[0]["arguments"]) == json.loads(arguments) + def test_streaming_missing_tool_suffix(self, parser, mock_request): chunks = [ "<|tools_prefix|>", diff --git a/vllm/tool_parsers/apertus_tool_parser.py b/vllm/tool_parsers/apertus_tool_parser.py index af9654c0cb..35e65ccb7b 100644 --- a/vllm/tool_parsers/apertus_tool_parser.py +++ b/vllm/tool_parsers/apertus_tool_parser.py @@ -417,7 +417,9 @@ class ApertusToolParser(ToolParser): """ try: - parsed, _ = partial_json_loads(json_str, Allow.ALL) + # An exponent can change a number's already-streamed representation. + flags = Allow.ALL if is_final else Allow.ALL & ~Allow.NUM + parsed, _ = partial_json_loads(json_str, flags) if not isinstance(parsed, list): parsed = [parsed] if parsed else [] except Exception: