diff --git a/tests/entrypoints/openai_api/test_api_server_guards.py b/tests/entrypoints/openai_api/test_api_server_guards.py index b7e2d449a..f59ebf7b5 100644 --- a/tests/entrypoints/openai_api/test_api_server_guards.py +++ b/tests/entrypoints/openai_api/test_api_server_guards.py @@ -58,8 +58,7 @@ from starlette.requests import Request from starlette.websockets import WebSocketDisconnect from vllm.v1.engine.exceptions import EngineDeadError, EngineGenerateError -from vllm_omni.entrypoints.duplex import openai as duplex_openai -from vllm_omni.entrypoints.openai import api_server +from vllm_omni.entrypoints.openai import api_server, realtime_connection from vllm_omni.entrypoints.serve.utils import errors as serve_errors pytestmark = [pytest.mark.core_model, pytest.mark.cpu] @@ -675,7 +674,11 @@ async def test_realtime_route_defaults_to_configured_duplex_handler( async def handle_connection(self) -> None: calls.append("legacy") - monkeypatch.setattr(duplex_openai, "RealtimeConnection", lambda _websocket, _serving: _LegacyConnection()) + monkeypatch.setattr( + realtime_connection, + "RealtimeConnection", + lambda _websocket, _serving: _LegacyConnection(), + ) query_params = {} if duplex_query is None else {"duplex": duplex_query} websocket = SimpleNamespace( app=SimpleNamespace( diff --git a/vllm_omni/entrypoints/duplex/openai.py b/vllm_omni/entrypoints/duplex/openai.py index 946c489bd..b2fbf570d 100644 --- a/vllm_omni/entrypoints/duplex/openai.py +++ b/vllm_omni/entrypoints/duplex/openai.py @@ -12,8 +12,6 @@ from vllm.logger import init_logger from vllm.utils import random_uuid from vllm_omni.entrypoints.duplex.warmup import DUPLEX_WARMUP_CLIENT_WAIT_S -from vllm_omni.entrypoints.openai.realtime.connection import OpenAIFullDuplexConnection -from vllm_omni.entrypoints.openai.realtime_connection import RealtimeConnection if TYPE_CHECKING: from vllm_omni.config.omni_config import BaseVllmOmniStageConfig @@ -23,6 +21,9 @@ logger = init_logger(__name__) _QWEN3_OMNI_REALTIME_ARCH = "Qwen3OmniMoeForConditionalGeneration" _QWEN3_OMNI_REALTIME_STAGES = {"thinker", "talker", "code2wav"} +# Keep OpenAI connection imports in the handlers: openai/__init__.py imports +# api_server, which imports this module. + def supports_qwen3_omni_realtime(stage_configs: Sequence[BaseVllmOmniStageConfig] | None) -> bool: stages = stage_configs or () @@ -59,6 +60,8 @@ async def dispatch_generic_realtime_websocket(websocket: WebSocket) -> None: await websocket.send_json({"type": "error", "error": "Realtime API is not available", "code": "unsupported"}) await websocket.close() return + from vllm_omni.entrypoints.openai.realtime_connection import RealtimeConnection + connection = RealtimeConnection(websocket, serving) await connection.handle_connection() @@ -93,6 +96,8 @@ async def dispatch_realtime_websocket(websocket: WebSocket) -> None: ) tokenizer = await state.engine_client.get_tokenizer() + from vllm_omni.entrypoints.openai.realtime.connection import OpenAIFullDuplexConnection + connection = OpenAIFullDuplexConnection( websocket=websocket, engine=state.engine_client,