main
py 101 lines 3.61 KB
Raw
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 from unittest.mock import MagicMock
5
6 import pytest
7
8 from tests.tool_parsers.common_tests import (
9 ToolParserTestConfig,
10 ToolParserTests,
11 )
12 from vllm.tokenizers import TokenizerLike
13
14
15 class TestLongCatToolParser(ToolParserTests):
16 @pytest.fixture
17 def tokenizer(self, default_tokenizer: TokenizerLike) -> TokenizerLike:
18 """Add some longcat specific tokens to the default vocab."""
19 tokenizer = default_tokenizer
20 tokenizer_vocab = tokenizer.get_vocab()
21 tokenizer.get_vocab = MagicMock()
22 tokenizer_vocab.update(
23 {
24 "<longcat_tool_call>": 32000,
25 "</longcat_tool_call>": 32001,
26 }
27 )
28 tokenizer.get_vocab.return_value = tokenizer_vocab
29 return tokenizer
30
31 @pytest.fixture
32 def test_config(self) -> ToolParserTestConfig:
33 return ToolParserTestConfig(
34 parser_name="longcat",
35 # Test data
36 no_tool_calls_output="This is a regular response without any tool calls.",
37 single_tool_call_output=(
38 '<longcat_tool_call>{"name": "get_weather", '
39 '"arguments": {"city": "Tokyo"}}</longcat_tool_call>'
40 ),
41 parallel_tool_calls_output=(
42 '<longcat_tool_call>{"name": "get_weather", '
43 '"arguments": {"city": "Tokyo"}}</longcat_tool_call>\n'
44 '<longcat_tool_call>{"name": "get_time", '
45 '"arguments": {"timezone": "Asia/Tokyo"}}</longcat_tool_call>'
46 ),
47 various_data_types_output="""<longcat_tool_call>{
48 "name": "test_function",
49 "arguments": {
50 "string_field": "hello",
51 "int_field": 42,
52 "float_field": 3.14,
53 "bool_field": true,
54 "null_field": null,
55 "array_field": ["a", "b", "c"],
56 "object_field": {"nested": "value"},
57 "empty_array": [],
58 "empty_object": {}
59 }
60 }</longcat_tool_call>""",
61 empty_arguments_output=(
62 '<longcat_tool_call>{"name": "refresh", "arguments": {}}'
63 "</longcat_tool_call>"
64 ),
65 surrounding_text_output=(
66 "Let me check the weather for you.\n"
67 '<longcat_tool_call>{"name": "get_weather", '
68 '"arguments": {"city": "Tokyo"}}</longcat_tool_call>\n'
69 "Here is the result."
70 ),
71 escaped_strings_output="""<longcat_tool_call>{
72 "name": "test_function",
73 "arguments": {
74 "quoted": "He said \\"hello\\"",
75 "path": "C:\\\\Users\\\\file.txt",
76 "newline": "line1\\nline2",
77 "unicode": "emoji: 🎉"
78 }
79 }</longcat_tool_call>""",
80 malformed_input_outputs=[
81 '<longcat_tool_call>{"name": "func", "arguments": {',
82 (
83 '<longcat_tool_call>{"name": "func", '
84 '"arguments": "not a dict"}</longcat_tool_call>'
85 ),
86 "Some text with <longcat_tool_call>invalid json",
87 ],
88 # Expected results
89 single_tool_call_expected_name="get_weather",
90 single_tool_call_expected_args={"city": "Tokyo"},
91 single_tool_call_expected_content=None,
92 parallel_tool_calls_count=2,
93 parallel_tool_calls_names=["get_weather", "get_time"],
94 # xfail markers
95 xfail_streaming={
96 "test_malformed_input": "Streaming has complex buffering behavior",
97 },
98 xfail_nonstreaming={},
99 # Configuration
100 allow_empty_or_json_empty_args=True,
101 )