Skip to content

Commit b6af24f

Browse files
authored
[CI][Entrypoints]: add filter to generation to filter out invalid tool calls (#22826)
Signed-off-by: Will Eaton <[email protected]>
1 parent 0ca2393 commit b6af24f

File tree

1 file changed

+32
-16
lines changed

1 file changed

+32
-16
lines changed

tests/entrypoints/openai/test_openai_schema.py

Lines changed: 32 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -54,38 +54,54 @@ def before_generate_case(context: schemathesis.hooks.HookContext, strategy):
5454
op = context.operation
5555
assert op is not None
5656

57-
def no_file_type(case: schemathesis.models.Case):
57+
def no_invalid_types(case: schemathesis.models.Case):
5858
"""
59-
This filter skips test cases for the `POST /tokenize` endpoint where the
60-
HTTP request body uses `"type": "file"` in any message's content.
61-
We expect these cases to fail because that type isn't implemented here
62-
https://github.com/vllm-project/vllm/blob/0b34593017953051b3225b1483ce0f4670e3eb0e/vllm/entrypoints/chat_utils.py#L1038-L1095
59+
This filter skips test cases with invalid data that schemathesis
60+
incorrectly generates due to permissive schema configurations.
61+
62+
1. Skips `POST /tokenize` endpoint cases with `"type": "file"` in
63+
message content, which isn't implemented.
64+
65+
2. Skips tool_calls with `"type": "custom"` which schemathesis
66+
incorrectly generates instead of the valid `"type": "function"`.
6367
6468
Example test cases that are skipped:
6569
curl -X POST -H 'Content-Type: application/json' \
66-
-d '{"messages": [{"role": "assistant"}, {"content": [{"file": {}, "type": "file"}], "role": "user"}]}' \
70+
-d '{"messages": [{"content": [{"file": {}, "type": "file"}], "role": "user"}]}' \
6771
http://localhost:8000/tokenize
6872
6973
curl -X POST -H 'Content-Type: application/json' \
70-
-d '{"messages": [{"content": [{"file": {}, "type": "file"}], "role": "user"}]}' \
71-
http://localhost:8000/tokenize
74+
-d '{"messages": [{"role": "assistant", "tool_calls": [{"custom": {"input": "", "name": ""}, "id": "", "type": "custom"}]}]}' \
75+
http://localhost:8000/v1/chat/completions
7276
""" # noqa: E501
73-
if (op.method.lower() == "post" and op.path == "/tokenize"
74-
and hasattr(case, "body") and isinstance(case.body, dict)
77+
if (hasattr(case, "body") and isinstance(case.body, dict)
7578
and "messages" in case.body
7679
and isinstance(case.body["messages"], list)
7780
and len(case.body["messages"]) > 0):
81+
7882
for message in case.body["messages"]:
7983
if not isinstance(message, dict):
8084
continue
81-
content = message.get("content", [])
82-
if not isinstance(content, list) or len(content) == 0:
83-
continue
84-
if any(item.get("type") == "file" for item in content):
85-
return False
85+
86+
# Check for invalid file type in tokenize endpoint
87+
if op.method.lower() == "post" and op.path == "/tokenize":
88+
content = message.get("content", [])
89+
if (isinstance(content, list) and len(content) > 0 and any(
90+
item.get("type") == "file" for item in content)):
91+
return False
92+
93+
# Check for invalid tool_calls with non-function types
94+
tool_calls = message.get("tool_calls", [])
95+
if isinstance(tool_calls, list):
96+
for tool_call in tool_calls:
97+
if isinstance(tool_call, dict):
98+
if tool_call.get("type") != "function":
99+
return False
100+
if "custom" in tool_call:
101+
return False
86102
return True
87103

88-
return strategy.filter(no_file_type)
104+
return strategy.filter(no_invalid_types)
89105

90106

91107
@schema.parametrize()

0 commit comments

Comments
 (0)