main
py 114 lines 3.06 KB
Raw
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 import json
5
6 import openai # use the official client for correctness check
7 import pytest
8
9 MODEL_NAME = "Qwen/Qwen3-1.7B"
10 NAMESPACE = "mcp__computer_use"
11 TOOL_NAME = "get_app_state"
12 FLAT_TOOL_NAME = f"{NAMESPACE}__{TOOL_NAME}"
13
14 tools = [
15 {
16 "type": "namespace",
17 "name": NAMESPACE,
18 "description": "Computer control tools.",
19 "tools": [
20 {
21 "type": "function",
22 "name": TOOL_NAME,
23 "description": "Get the current state of a desktop application.",
24 "parameters": {
25 "type": "object",
26 "properties": {
27 "app": {
28 "type": "string",
29 "description": "Application name, for example Chrome.",
30 }
31 },
32 "required": ["app"],
33 "additionalProperties": False,
34 },
35 }
36 ],
37 }
38 ]
39
40 prompt = [
41 {
42 "role": "user",
43 "content": "Use the computer app state tool to inspect Google Chrome.",
44 },
45 ]
46
47
48 def _assert_namespace_tool_call(tool_call) -> None:
49 assert tool_call.type == "function_call"
50 assert tool_call.name == TOOL_NAME
51 assert tool_call.namespace == NAMESPACE
52 assert tool_call.name != FLAT_TOOL_NAME
53
54 args = json.loads(tool_call.arguments)
55 assert args["app"]
56
57
58 @pytest.mark.asyncio
59 @pytest.mark.parametrize("model_name", [MODEL_NAME])
60 async def test_namespace_tool_separator(client: openai.AsyncOpenAI, model_name: str):
61 response = await client.responses.create(
62 model=model_name,
63 input=prompt,
64 tools=tools,
65 temperature=0.0,
66 )
67
68 assert len(response.output) >= 1
69 tool_call = next(
70 (out for out in response.output if out.type == "function_call"), None
71 )
72 assert tool_call is not None
73 _assert_namespace_tool_call(tool_call)
74
75
76 @pytest.mark.asyncio
77 @pytest.mark.parametrize("model_name", [MODEL_NAME])
78 async def test_namespace_tool_separator_streaming(
79 client: openai.AsyncOpenAI, model_name: str
80 ):
81 stream = await client.responses.create(
82 model=model_name,
83 input=prompt,
84 tools=tools,
85 temperature=0.0,
86 stream=True,
87 )
88 events = [event async for event in stream]
89
90 added_call = next(
91 (
92 event.item
93 for event in events
94 if event.type == "response.output_item.added"
95 and getattr(event.item, "type", None) == "function_call"
96 ),
97 None,
98 )
99 done_call = next(
100 (
101 event.item
102 for event in events
103 if event.type == "response.output_item.done"
104 and getattr(event.item, "type", None) == "function_call"
105 ),
106 None,
107 )
108
109 assert added_call is not None
110 assert added_call.name == TOOL_NAME
111 assert added_call.namespace == NAMESPACE
112
113 assert done_call is not None
114 _assert_namespace_tool_call(done_call)