mirror of
https://git.datalinker.icu/vllm-project/vllm.git
synced 2025-12-13 16:35:30 +08:00
[CI] Reorganize entrypoints tests (#27403)
Signed-off-by: chaunceyjiang <chaunceyjiang@gmail.com>
This commit is contained in:
parent
3b7bdf983b
commit
d00ce29d89
@ -599,145 +599,6 @@ async def test_structured_outputs_choice_chat_logprobs(
|
|||||||
assert item.logprob >= -9999.0, f"Failed (top_logprobs={top_logprobs})"
|
assert item.logprob >= -9999.0, f"Failed (top_logprobs={top_logprobs})"
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.asyncio
|
|
||||||
async def test_named_tool_use(
|
|
||||||
client: openai.AsyncOpenAI,
|
|
||||||
sample_json_schema,
|
|
||||||
):
|
|
||||||
messages = [
|
|
||||||
{"role": "system", "content": "you are a helpful assistant"},
|
|
||||||
{
|
|
||||||
"role": "user",
|
|
||||||
"content": (
|
|
||||||
"Give an example JSON for an employee profile using the specified tool."
|
|
||||||
),
|
|
||||||
},
|
|
||||||
]
|
|
||||||
tools = [
|
|
||||||
{
|
|
||||||
"type": "function",
|
|
||||||
"function": {
|
|
||||||
"name": "dummy_function_name",
|
|
||||||
"description": "This is a dummy function",
|
|
||||||
"parameters": sample_json_schema,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
]
|
|
||||||
tool_choice = {"type": "function", "function": {"name": "dummy_function_name"}}
|
|
||||||
|
|
||||||
# non-streaming
|
|
||||||
|
|
||||||
chat_completion = await client.chat.completions.create(
|
|
||||||
model=MODEL_NAME,
|
|
||||||
messages=messages,
|
|
||||||
max_completion_tokens=1000,
|
|
||||||
tools=tools,
|
|
||||||
tool_choice=tool_choice,
|
|
||||||
)
|
|
||||||
message = chat_completion.choices[0].message
|
|
||||||
assert len(message.content) == 0
|
|
||||||
json_string = message.tool_calls[0].function.arguments
|
|
||||||
json1 = json.loads(json_string)
|
|
||||||
jsonschema.validate(instance=json1, schema=sample_json_schema)
|
|
||||||
|
|
||||||
messages.append({"role": "assistant", "content": json_string})
|
|
||||||
messages.append(
|
|
||||||
{"role": "user", "content": "Give me another one with a different name and age"}
|
|
||||||
)
|
|
||||||
|
|
||||||
# streaming
|
|
||||||
|
|
||||||
stream = await client.chat.completions.create(
|
|
||||||
model=MODEL_NAME,
|
|
||||||
messages=messages,
|
|
||||||
max_completion_tokens=1000,
|
|
||||||
tools=tools,
|
|
||||||
tool_choice=tool_choice,
|
|
||||||
stream=True,
|
|
||||||
)
|
|
||||||
|
|
||||||
output = []
|
|
||||||
finish_reason_count = 0
|
|
||||||
async for chunk in stream:
|
|
||||||
delta = chunk.choices[0].delta
|
|
||||||
if delta.role:
|
|
||||||
assert delta.role == "assistant"
|
|
||||||
assert delta.content is None or len(delta.content) == 0
|
|
||||||
if delta.tool_calls:
|
|
||||||
output.append(delta.tool_calls[0].function.arguments)
|
|
||||||
if chunk.choices[0].finish_reason is not None:
|
|
||||||
finish_reason_count += 1
|
|
||||||
# finish reason should only return in last block
|
|
||||||
assert finish_reason_count == 1
|
|
||||||
json2 = json.loads("".join(output))
|
|
||||||
jsonschema.validate(instance=json2, schema=sample_json_schema)
|
|
||||||
assert json1["name"] != json2["name"]
|
|
||||||
assert json1["age"] != json2["age"]
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.asyncio
|
|
||||||
async def test_inconsistent_tool_choice_and_tools(
|
|
||||||
client: openai.AsyncOpenAI, sample_json_schema
|
|
||||||
):
|
|
||||||
messages = [
|
|
||||||
{"role": "system", "content": "you are a helpful assistant"},
|
|
||||||
{
|
|
||||||
"role": "user",
|
|
||||||
"content": f"Give an example JSON for an employee profile that "
|
|
||||||
f"fits this schema: {sample_json_schema}",
|
|
||||||
},
|
|
||||||
]
|
|
||||||
|
|
||||||
with pytest.raises(openai.BadRequestError):
|
|
||||||
await client.chat.completions.create(
|
|
||||||
model=MODEL_NAME,
|
|
||||||
messages=messages,
|
|
||||||
max_completion_tokens=1000,
|
|
||||||
tool_choice={
|
|
||||||
"type": "function",
|
|
||||||
"function": {"name": "dummy_function_name"},
|
|
||||||
},
|
|
||||||
)
|
|
||||||
|
|
||||||
with pytest.raises(openai.BadRequestError):
|
|
||||||
await client.chat.completions.create(
|
|
||||||
model=MODEL_NAME,
|
|
||||||
messages=messages,
|
|
||||||
max_completion_tokens=1000,
|
|
||||||
tools=[
|
|
||||||
{
|
|
||||||
"type": "function",
|
|
||||||
"function": {
|
|
||||||
"name": "dummy_function_name",
|
|
||||||
"description": "This is a dummy function",
|
|
||||||
"parameters": sample_json_schema,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
],
|
|
||||||
tool_choice={
|
|
||||||
"type": "function",
|
|
||||||
"function": {"name": "nondefined_function_name"},
|
|
||||||
},
|
|
||||||
)
|
|
||||||
with pytest.raises(openai.BadRequestError):
|
|
||||||
await client.chat.completions.create(
|
|
||||||
model=MODEL_NAME,
|
|
||||||
messages=messages,
|
|
||||||
max_completion_tokens=1000,
|
|
||||||
tools=[
|
|
||||||
{
|
|
||||||
"type": "function",
|
|
||||||
"function": {
|
|
||||||
"name": "dummy_function_name",
|
|
||||||
"description": "This is a dummy function",
|
|
||||||
"parameters": sample_json_schema,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
],
|
|
||||||
tool_choice={},
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.asyncio
|
@pytest.mark.asyncio
|
||||||
async def test_response_format_json_object(client: openai.AsyncOpenAI):
|
async def test_response_format_json_object(client: openai.AsyncOpenAI):
|
||||||
for _ in range(2):
|
for _ in range(2):
|
||||||
|
|||||||
@ -2,7 +2,9 @@
|
|||||||
# SPDX-FileCopyrightText: Copyright contributors to the vLLM project
|
# SPDX-FileCopyrightText: Copyright contributors to the vLLM project
|
||||||
|
|
||||||
import datetime
|
import datetime
|
||||||
|
import json
|
||||||
|
|
||||||
|
import jsonschema
|
||||||
import openai # use the official client for correctness check
|
import openai # use the official client for correctness check
|
||||||
import pytest
|
import pytest
|
||||||
import pytest_asyncio
|
import pytest_asyncio
|
||||||
@ -341,3 +343,142 @@ async def test_no_args_tool_call(
|
|||||||
else:
|
else:
|
||||||
# No tool called — just print model's direct reply
|
# No tool called — just print model's direct reply
|
||||||
assert message.content is not None
|
assert message.content is not None
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.asyncio
|
||||||
|
async def test_named_tool_use(
|
||||||
|
client: openai.AsyncOpenAI,
|
||||||
|
sample_json_schema,
|
||||||
|
):
|
||||||
|
messages = [
|
||||||
|
{"role": "system", "content": "you are a helpful assistant"},
|
||||||
|
{
|
||||||
|
"role": "user",
|
||||||
|
"content": (
|
||||||
|
"Give an example JSON for an employee profile using the specified tool."
|
||||||
|
),
|
||||||
|
},
|
||||||
|
]
|
||||||
|
tools = [
|
||||||
|
{
|
||||||
|
"type": "function",
|
||||||
|
"function": {
|
||||||
|
"name": "dummy_function_name",
|
||||||
|
"description": "This is a dummy function",
|
||||||
|
"parameters": sample_json_schema,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
]
|
||||||
|
tool_choice = {"type": "function", "function": {"name": "dummy_function_name"}}
|
||||||
|
|
||||||
|
# non-streaming
|
||||||
|
|
||||||
|
chat_completion = await client.chat.completions.create(
|
||||||
|
model=MODEL_NAME,
|
||||||
|
messages=messages,
|
||||||
|
max_completion_tokens=1000,
|
||||||
|
tools=tools,
|
||||||
|
tool_choice=tool_choice,
|
||||||
|
)
|
||||||
|
message = chat_completion.choices[0].message
|
||||||
|
assert len(message.content) == 0
|
||||||
|
json_string = message.tool_calls[0].function.arguments
|
||||||
|
json1 = json.loads(json_string)
|
||||||
|
jsonschema.validate(instance=json1, schema=sample_json_schema)
|
||||||
|
|
||||||
|
messages.append({"role": "assistant", "content": json_string})
|
||||||
|
messages.append(
|
||||||
|
{"role": "user", "content": "Give me another one with a different name and age"}
|
||||||
|
)
|
||||||
|
|
||||||
|
# streaming
|
||||||
|
|
||||||
|
stream = await client.chat.completions.create(
|
||||||
|
model=MODEL_NAME,
|
||||||
|
messages=messages,
|
||||||
|
max_completion_tokens=1000,
|
||||||
|
tools=tools,
|
||||||
|
tool_choice=tool_choice,
|
||||||
|
stream=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
output = []
|
||||||
|
finish_reason_count = 0
|
||||||
|
async for chunk in stream:
|
||||||
|
delta = chunk.choices[0].delta
|
||||||
|
if delta.role:
|
||||||
|
assert delta.role == "assistant"
|
||||||
|
assert delta.content is None or len(delta.content) == 0
|
||||||
|
if delta.tool_calls:
|
||||||
|
output.append(delta.tool_calls[0].function.arguments)
|
||||||
|
if chunk.choices[0].finish_reason is not None:
|
||||||
|
finish_reason_count += 1
|
||||||
|
# finish reason should only return in last block
|
||||||
|
assert finish_reason_count == 1
|
||||||
|
json2 = json.loads("".join(output))
|
||||||
|
jsonschema.validate(instance=json2, schema=sample_json_schema)
|
||||||
|
assert json1["name"] != json2["name"]
|
||||||
|
assert json1["age"] != json2["age"]
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.asyncio
|
||||||
|
async def test_inconsistent_tool_choice_and_tools(
|
||||||
|
client: openai.AsyncOpenAI, sample_json_schema
|
||||||
|
):
|
||||||
|
messages = [
|
||||||
|
{"role": "system", "content": "you are a helpful assistant"},
|
||||||
|
{
|
||||||
|
"role": "user",
|
||||||
|
"content": f"Give an example JSON for an employee profile that "
|
||||||
|
f"fits this schema: {sample_json_schema}",
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
with pytest.raises(openai.BadRequestError):
|
||||||
|
await client.chat.completions.create(
|
||||||
|
model=MODEL_NAME,
|
||||||
|
messages=messages,
|
||||||
|
max_completion_tokens=1000,
|
||||||
|
tool_choice={
|
||||||
|
"type": "function",
|
||||||
|
"function": {"name": "dummy_function_name"},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
with pytest.raises(openai.BadRequestError):
|
||||||
|
await client.chat.completions.create(
|
||||||
|
model=MODEL_NAME,
|
||||||
|
messages=messages,
|
||||||
|
max_completion_tokens=1000,
|
||||||
|
tools=[
|
||||||
|
{
|
||||||
|
"type": "function",
|
||||||
|
"function": {
|
||||||
|
"name": "dummy_function_name",
|
||||||
|
"description": "This is a dummy function",
|
||||||
|
"parameters": sample_json_schema,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
],
|
||||||
|
tool_choice={
|
||||||
|
"type": "function",
|
||||||
|
"function": {"name": "nondefined_function_name"},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
with pytest.raises(openai.BadRequestError):
|
||||||
|
await client.chat.completions.create(
|
||||||
|
model=MODEL_NAME,
|
||||||
|
messages=messages,
|
||||||
|
max_completion_tokens=1000,
|
||||||
|
tools=[
|
||||||
|
{
|
||||||
|
"type": "function",
|
||||||
|
"function": {
|
||||||
|
"name": "dummy_function_name",
|
||||||
|
"description": "This is a dummy function",
|
||||||
|
"parameters": sample_json_schema,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
],
|
||||||
|
tool_choice={},
|
||||||
|
)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user