[BugFix] Fix leftovers of the legacy OpenAI realtime API event names (#7426)
Signed-off-by: Nick Cao <ncao@redhat.com> Co-authored-by: Codex <noreply@openai.com>
This commit is contained in:
1 parent
78e1a0ae5c
commit
d3493384cf
10 files changed
+103
-48
No files matched your search
@@ -2197,9 +2197,7 @@ def test_native_realtime_protocol_audio_delta_preserves_sample_rate_hz():
|
||||
)
|
||||
|
||||
audio_events = [
|
||||
payload
|
||||
for payload in payloads
|
||||
if payload["type"] in {"response.output_audio.delta", "response.output_audio.delta"}
|
||||
payload for payload in payloads if payload["type"] in {"response.output_audio.delta", "response.audio.delta"}
|
||||
]
|
||||
assert {payload["type"] for payload in audio_events} == {"response.output_audio.delta"}
|
||||
assert {payload["format"] for payload in audio_events} == {"pcm16"}
|
||||
|
||||
@@ -175,7 +175,7 @@ async def _run_realtime_audio_roundtrip(
|
||||
if event_type == "session.created":
|
||||
continue
|
||||
|
||||
if event_type == "response.audio.delta":
|
||||
if event_type == "response.output_audio.delta":
|
||||
delta_events += 1
|
||||
sr = event.get("sample_rate_hz")
|
||||
if isinstance(sr, int) and sr > 0:
|
||||
@@ -195,7 +195,7 @@ async def _run_realtime_audio_roundtrip(
|
||||
final_text = event.get("text", "") or "".join(text_chunks)
|
||||
continue
|
||||
|
||||
if event_type == "response.audio.done":
|
||||
if event_type == "response.output_audio.done":
|
||||
break
|
||||
|
||||
if event_type == "error":
|
||||
@@ -315,7 +315,7 @@ def _server_vad_pcm16_input() -> bytes:
|
||||
def _assert_realtime_smoke(result: dict) -> None:
|
||||
out_pcm = result["output_pcm"]
|
||||
assert result["delta_events"] >= 1
|
||||
assert out_pcm, "No output PCM from response.audio.delta"
|
||||
assert out_pcm, "No output PCM from response.output_audio.delta"
|
||||
assert len(out_pcm) % 2 == 0
|
||||
assert len(out_pcm) >= 4096, "Output audio unexpectedly small"
|
||||
assert result["output_sample_rate"] > 0
|
||||
@@ -388,7 +388,7 @@ class TestQwen3OmniRealtimeWebSocket:
|
||||
@hardware_test(res={"cuda": "H100", "rocm": "MI325"}, num_cards=2)
|
||||
@pytest.mark.parametrize("omni_server", realtime_async_chunk_server_params, indirect=True)
|
||||
def test_long_audio_response_completes_async_chunk(self, omni_server) -> None:
|
||||
"""Regression for #6474: long async-chunk audio must emit response.audio.done."""
|
||||
"""Regression for #6474: long async-chunk audio must emit response.output_audio.done."""
|
||||
issue_6474_pcm16 = _synthetic_pcm16_input(
|
||||
phrase_text=ISSUE_6474_SYNTH_PHRASE_TEXT,
|
||||
)
|
||||
@@ -450,8 +450,8 @@ class TestQwen3OmniRealtimeWebSocket:
|
||||
"input_audio_buffer.speech_stopped",
|
||||
"input_audio_buffer.committed",
|
||||
"response.created",
|
||||
"response.audio.delta",
|
||||
"response.audio.done",
|
||||
"response.output_audio.delta",
|
||||
"response.output_audio.done",
|
||||
"response.done",
|
||||
]
|
||||
input_item_ids: list[str] = []
|
||||
@@ -459,7 +459,7 @@ class TestQwen3OmniRealtimeWebSocket:
|
||||
for events in turns:
|
||||
event_types = [event["type"] for event in events]
|
||||
for event_type in required_sequence:
|
||||
if event_type != "response.audio.delta":
|
||||
if event_type != "response.output_audio.delta":
|
||||
assert event_types.count(event_type) == 1, event_types
|
||||
positions = [event_types.index(event_type) for event_type in required_sequence]
|
||||
assert positions == sorted(positions)
|
||||
@@ -486,7 +486,7 @@ class TestQwen3OmniRealtimeWebSocket:
|
||||
output_pcm = b"".join(
|
||||
base64.b64decode(event["delta"])
|
||||
for event in events
|
||||
if event["type"] == "response.audio.delta" and event.get("delta")
|
||||
if event["type"] == "response.output_audio.delta" and event.get("delta")
|
||||
)
|
||||
assert output_pcm
|
||||
assert created["id"] == done["id"]
|
||||
|
||||
@@ -14,6 +14,7 @@ import weakref
|
||||
from typing import Any
|
||||
|
||||
import pytest
|
||||
import torch
|
||||
from PIL import Image
|
||||
|
||||
from vllm_omni.entrypoints.openai import video_stream_base, video_stream_envs
|
||||
@@ -457,6 +458,54 @@ async def test_async_chunk_mode_is_read_by_engine_path_at_runtime(monkeypatch):
|
||||
assert not any(m.get("type") == "response.text.delta" for m in ws_off.sent)
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@pytest.mark.parametrize("async_chunk_mode", ["on", "off"])
|
||||
async def test_audio_events_use_output_audio_names(monkeypatch, async_chunk_mode):
|
||||
class AudioEngine:
|
||||
def generate(self, **_kwargs):
|
||||
async def _gen():
|
||||
yield _audio_result([torch.zeros(1)])
|
||||
|
||||
return _gen()
|
||||
|
||||
class AudioHandler(QwenOmniStreamingVideoHandler):
|
||||
async def _preprocess_to_engine_prompt(self, request):
|
||||
return {"prompt": "x"}
|
||||
|
||||
monkeypatch.setenv("VLLM_VIDEO_ASYNC_CHUNK", async_chunk_mode)
|
||||
monkeypatch.setattr(
|
||||
OmniStreamingVideoHandler,
|
||||
"_encode_audio_wav_b64",
|
||||
staticmethod(lambda _audio: "audio-b64"),
|
||||
)
|
||||
|
||||
ws = MockWebSocket()
|
||||
handler = AudioHandler(chat_service=object(), engine_client=AudioEngine())
|
||||
config = StreamingVideoSessionConfig(model="test", modalities=["text", "audio"])
|
||||
|
||||
await handler._process_query_engine(
|
||||
ws,
|
||||
config,
|
||||
[_b64(_make_jpeg())],
|
||||
bytearray(),
|
||||
[],
|
||||
"describe",
|
||||
"req-audio-events",
|
||||
asyncio.Event(),
|
||||
{},
|
||||
)
|
||||
|
||||
audio_events = [message for message in ws.sent if "audio" in message.get("type", "")]
|
||||
assert audio_events == [
|
||||
{
|
||||
"type": "response.output_audio.delta",
|
||||
"data": "audio-b64",
|
||||
"format": "wav",
|
||||
},
|
||||
{"type": "response.output_audio.done"},
|
||||
]
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_query_without_engine_client_sends_error():
|
||||
ws = MockWebSocket()
|
||||
|
||||
Reference in new issue
Block a user