+20









Zhou Taichang
Claude Opus 4.7
NumberWan
dsinghvi
Dnoob
Yueqian Lin
Hongsheng Liu
knlnguyen1802
Samit
rein yang
Nick Cao
zhumingjue138
Ricardo Noriega
lyj-jjj
Cursor
gcanlin
wangyu
weizhoublue
weizhoublue
dengyunyang
汪志鹏
WeiQing Chen
Jie Liu
Yueqian Lin
NATURE
bjf-frz
amy-why-3459
Y. Fisher
Zeyu Huang | 黃澤宇
Copilot Autofix powered by AI
eb4e60ee64
Signed-off-by: tzhouam <tzhouam@connect.ust.hk> Signed-off-by: Zhou Taichang <tzhouam@connect.ust.hk> Signed-off-by: NumberWan <wantszkin2003@gmail.com> Signed-off-by: Divyansh Singhvi <divyanshsinghvi@gmail.com> Signed-off-by: dsinghvi <divyanshsinghvi@gmail.com> Signed-off-by: Dnoob <dxpouo@gmail.com> Signed-off-by: Yueqian Lin <70319226+linyueqian@users.noreply.github.com> Signed-off-by: knlnguyen1802 <knlnguyen1802@gmail.com> Signed-off-by: rein yang <ruiruyang2@gmail.com> Signed-off-by: Nick Cao <ncao@redhat.com> Signed-off-by: zhumingjue <zhumingjue@huawei.com> Signed-off-by: Ricardo Noriega De Soto <rnoriega@redhat.com> Signed-off-by: lyj-jjj <liuyingjun5@huawei.com> Signed-off-by: gcanlin <canlinguosdu@gmail.com> Signed-off-by: wangyu <410167048@qq.com> Signed-off-by: weizhoublue <weizhoublue@github.com> Signed-off-by: weizhou.lan@daocloud.io <weizhou.lan@daocloud.io> Signed-off-by: dengyunyang <584797741@qq.com> Signed-off-by: 汪志鹏 <wangzhipeng628@gmail.com> Signed-off-by: David Chen <530634352@qq.com> Signed-off-by: Jie Liu <33612777+keeper-jie@users.noreply.github.com> Signed-off-by: Yueqian Lin <linyueqian@outlook.com> Signed-off-by: princepride <wangzhipeng628@gmail.com> Signed-off-by: natureofnature <wzliu@connect.hku.hk> Signed-off-by: bjf-frz <frz123db@gmail.com> Signed-off-by: amy-why-3459 <wuhaiyan17@huawei.com> Signed-off-by: KexiongYu <yukexiong1@huawei.com> Signed-off-by: Huang, Zeyu <11222265+fhfuih@users.noreply.github.com> Signed-off-by: Zeyu Huang | 黃澤宇 <11222265+fhfuih@users.noreply.github.com> Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com> Co-authored-by: NumberWan <wantszkin2003@gmail.com> Co-authored-by: dsinghvi <divyanshsinghvi@gmail.com> Co-authored-by: Dnoob <dxpouo@gmail.com> Co-authored-by: Yueqian Lin <70319226+linyueqian@users.noreply.github.com> Co-authored-by: Hongsheng Liu <liuhongsheng4@huawei.com> Co-authored-by: knlnguyen1802 <knlnguyen1802@gmail.com> Co-authored-by: Samit <285365963@qq.com> Co-authored-by: rein yang <73573651+R2-Y@users.noreply.github.com> Co-authored-by: Nick Cao <ncao@redhat.com> Co-authored-by: zhumingjue138 <zhumingjue@huawei.com> Co-authored-by: Ricardo Noriega <rnoriega@redhat.com> Co-authored-by: lyj-jjj <liuyingjun5@huawei.com> Co-authored-by: Cursor <cursoragent@cursor.com> Co-authored-by: gcanlin <canlinguosdu@gmail.com> Co-authored-by: wangyu <53896905+yenuo26@users.noreply.github.com> Co-authored-by: weizhoublue <45163302+weizhoublue@users.noreply.github.com> Co-authored-by: weizhoublue <weizhoublue@github.com> Co-authored-by: dengyunyang <584797741@qq.com> Co-authored-by: 汪志鹏 <wangzhipeng628@gmail.com> Co-authored-by: WeiQing Chen <40507679+david6666666@users.noreply.github.com> Co-authored-by: Jie Liu <33612777+keeper-jie@users.noreply.github.com> Co-authored-by: Yueqian Lin <linyueqian@outlook.com> Co-authored-by: NATURE <wzliu@connect.hku.hk> Co-authored-by: bjf-frz <frz123db@gmail.com> Co-authored-by: amy-why-3459 <wuhaiyan17@huawei.com> Co-authored-by: Y. Fisher <yukexiong1@huawei.com> Co-authored-by: Zeyu Huang | 黃澤宇 <11222265+fhfuih@users.noreply.github.com> Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
113 lines
4.5 KiB
Python
113 lines
4.5 KiB
Python
# SPDX-License-Identifier: Apache-2.0
|
|
# SPDX-FileCopyrightText: Copyright contributors to the vLLM project
|
|
"""Tests for chat endpoint speaker validation."""
|
|
|
|
import asyncio
|
|
from types import SimpleNamespace
|
|
|
|
import pytest
|
|
from pytest_mock import MockerFixture
|
|
|
|
from vllm_omni.entrypoints.openai.utils import (
|
|
get_supported_speakers_from_hf_config,
|
|
validate_requested_speaker,
|
|
)
|
|
|
|
pytestmark = [pytest.mark.core_model, pytest.mark.cpu]
|
|
|
|
|
|
@pytest.fixture
|
|
def serving_chat():
|
|
from vllm_omni.entrypoints.openai.serving_chat import OmniOpenAIServingChat
|
|
|
|
instance = object.__new__(OmniOpenAIServingChat)
|
|
instance._supported_speakers = None
|
|
instance.has_kv_connector = False
|
|
return instance
|
|
|
|
|
|
def _make_hf_config(mocker: MockerFixture, *, speaker_id: dict | None = None, spk_id: dict | None = None):
|
|
hf_config = mocker.MagicMock()
|
|
talker_config = mocker.MagicMock()
|
|
talker_config.speaker_id = speaker_id
|
|
talker_config.spk_id = spk_id
|
|
hf_config.talker_config = talker_config
|
|
return hf_config
|
|
|
|
|
|
def test_validate_requested_speaker_accepts_case_insensitive_value():
|
|
supported = {"vivian", "ethan"}
|
|
assert validate_requested_speaker("Vivian", supported) == "vivian"
|
|
assert validate_requested_speaker(" vivian ", supported) == "vivian"
|
|
|
|
|
|
def test_validate_requested_speaker_rejects_invalid_value_with_supported_list():
|
|
supported = {"vivian", "ethan"}
|
|
with pytest.raises(ValueError, match="Invalid speaker 'uncle_fu'. Supported: ethan, vivian"):
|
|
validate_requested_speaker("uncle_fu", supported)
|
|
|
|
|
|
def test_validate_requested_speaker_skips_validation_when_supported_empty():
|
|
assert validate_requested_speaker("anything", set()) == "anything"
|
|
assert validate_requested_speaker(" ", {"vivian"}) is None
|
|
|
|
|
|
def test_get_supported_speakers_from_hf_config_uses_spk_id_fallback(mocker: MockerFixture):
|
|
hf_config = _make_hf_config(mocker, speaker_id=None, spk_id={"Serena": 0})
|
|
assert get_supported_speakers_from_hf_config(hf_config) == {"serena"}
|
|
|
|
|
|
def test_get_supported_speakers_caches_normalized_keys(mocker: MockerFixture, serving_chat):
|
|
serving_chat.model_config = mocker.MagicMock()
|
|
serving_chat.model_config.hf_config = _make_hf_config(mocker, speaker_id={"Vivian": 0, "Ethan": 1})
|
|
|
|
assert serving_chat._get_supported_speakers() == {"vivian", "ethan"}
|
|
|
|
# Cached value should be reused even if the config changes afterwards.
|
|
serving_chat.model_config.hf_config.talker_config.speaker_id = {"Serena": 2}
|
|
assert serving_chat._get_supported_speakers() == {"vivian", "ethan"}
|
|
|
|
|
|
def test_create_chat_completion_converts_value_error_to_error_response(mocker: MockerFixture, serving_chat):
|
|
serving_chat._diffusion_mode = False
|
|
serving_chat._check_model = mocker.AsyncMock(return_value=None)
|
|
serving_chat.engine_client = mocker.MagicMock(errored=False)
|
|
serving_chat._maybe_get_adapters = mocker.MagicMock(return_value=None)
|
|
serving_chat.models = mocker.MagicMock()
|
|
serving_chat.models.model_name.return_value = "test-model"
|
|
serving_chat.renderer = mocker.MagicMock()
|
|
serving_chat.renderer.get_tokenizer.return_value = mocker.MagicMock()
|
|
serving_chat.reasoning_parser_cls = None
|
|
serving_chat.tool_parser = None
|
|
serving_chat.use_harmony = False
|
|
serving_chat.enable_auto_tools = False
|
|
serving_chat.exclude_tools_when_tool_choice_none = False
|
|
serving_chat.trust_request_chat_template = False
|
|
serving_chat.chat_template = None
|
|
serving_chat.chat_template_content_format = "string"
|
|
serving_chat.default_chat_template_kwargs = {}
|
|
serving_chat._validate_chat_template = mocker.MagicMock(return_value=None)
|
|
serving_chat._prepare_extra_chat_template_kwargs = mocker.MagicMock(return_value={})
|
|
serving_chat._preprocess_chat = mocker.AsyncMock(
|
|
side_effect=ValueError("Invalid speaker 'uncle_fu'. Supported: ethan, vivian")
|
|
)
|
|
serving_chat.create_error_response = mocker.MagicMock(return_value="error-response")
|
|
|
|
request = SimpleNamespace(
|
|
tool_choice=None,
|
|
tools=None,
|
|
chat_template=None,
|
|
chat_template_kwargs=None,
|
|
reasoning_effort=None,
|
|
messages=[],
|
|
add_generation_prompt=False,
|
|
continue_final_message=False,
|
|
add_special_tokens=False,
|
|
request_id="speaker-test",
|
|
)
|
|
|
|
result = asyncio.run(serving_chat.create_chat_completion(request))
|
|
|
|
assert result == "error-response"
|
|
serving_chat.create_error_response.assert_called_once_with("Invalid speaker 'uncle_fu'. Supported: ethan, vivian")
|