Signed-off-by: chickeyton <ngton2014@gmail.com> Signed-off-by: Yueqian Lin <linyueqian@outlook.com> Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com> Co-authored-by: Yueqian Lin <linyueqian@outlook.com>
This commit is contained in:
49 files changed
+3056
-1715
No files matched your search
@@ -5,6 +5,7 @@
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import base64
|
||||
from dataclasses import fields
|
||||
from pathlib import Path
|
||||
from typing import Any
|
||||
@@ -16,10 +17,13 @@ from vllm_omni.config.stage_config import DuplexSessionRuntimeConfig, PipelineCo
|
||||
from vllm_omni.engine.duplex.config import DuplexCapabilities, DuplexSessionConfig
|
||||
from vllm_omni.engine.duplex.contracts import DuplexAppendPlan
|
||||
from vllm_omni.engine.duplex.plugin import (
|
||||
DefaultDuplexModelSessionState,
|
||||
DuplexDataPlane,
|
||||
DuplexDataPlaneContext,
|
||||
DuplexModelPlugin,
|
||||
DuplexModelSessionState,
|
||||
DuplexRuntimeConfigError,
|
||||
PcmAppendBuffer,
|
||||
coerce_int,
|
||||
load_duplex_plugin,
|
||||
payload_turn_id,
|
||||
@@ -322,3 +326,119 @@ def test_pipeline_config_binds_one_duplex_plugin_path() -> None:
|
||||
for source in framework_sources
|
||||
if "completed_append_cache_size" in source.read_text(encoding="utf-8")
|
||||
] == []
|
||||
|
||||
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Plugin defaults shared by every model #
|
||||
# --------------------------------------------------------------------------- #
|
||||
|
||||
|
||||
def test_default_silence_unit_is_16k_zeros_and_follows_the_plugin_attributes() -> None:
|
||||
plugin = FakePlugin(_encode_audio)
|
||||
|
||||
unit = plugin.silence_unit_payload()
|
||||
|
||||
assert unit["type"] == "audio"
|
||||
assert unit["format"] == "pcm_f32le"
|
||||
assert unit["sample_rate_hz"] == 16000
|
||||
assert base64.b64decode(unit["audio"]) == bytes(16000 * 4)
|
||||
|
||||
class FramePlugin(FakePlugin):
|
||||
silence_continuation_samples = 1920
|
||||
silence_continuation_sample_rate_hz = 24000
|
||||
|
||||
frame_unit = FramePlugin(_encode_audio).silence_unit_payload()
|
||||
assert frame_unit["sample_rate_hz"] == 24000
|
||||
assert len(base64.b64decode(frame_unit["audio"])) == 1920 * 4
|
||||
|
||||
|
||||
def test_default_extra_body_validation_rejects_the_private_keys_naming_the_plugin() -> None:
|
||||
class PrivateKeysPlugin(FakePlugin):
|
||||
plugin_id = "keyed"
|
||||
private_runtime_config_keys = frozenset({"secret_a", "secret_b"})
|
||||
|
||||
def validate_client_extra_body(self, extra_body: object) -> None:
|
||||
DuplexModelPlugin.validate_client_extra_body(self, extra_body)
|
||||
|
||||
plugin = PrivateKeysPlugin(_encode_audio)
|
||||
plugin.validate_client_extra_body(None)
|
||||
plugin.validate_client_extra_body({"auto_response": True})
|
||||
with pytest.raises(
|
||||
DuplexRuntimeConfigError, match="keyed runtime configuration is server-owned: secret_a, secret_b"
|
||||
):
|
||||
plugin.validate_client_extra_body({"secret_b": 1, "secret_a": 2})
|
||||
|
||||
|
||||
def test_default_data_plane_context_is_the_framework_dataclass() -> None:
|
||||
class DefaultContextPlugin(FakePlugin):
|
||||
def data_plane_context(self, **kwargs):
|
||||
return DuplexModelPlugin.data_plane_context(self, **kwargs)
|
||||
|
||||
context = DefaultContextPlugin(_encode_audio).data_plane_context(
|
||||
epoch=2,
|
||||
turn_id=3,
|
||||
active_response_turn_id=1,
|
||||
active_response_id="resp",
|
||||
auto_responds=True,
|
||||
response_format="pcm16",
|
||||
speed=1.5,
|
||||
modalities=("audio",),
|
||||
)
|
||||
|
||||
assert isinstance(context, DuplexDataPlaneContext)
|
||||
assert context == DuplexDataPlaneContext(
|
||||
epoch=2,
|
||||
turn_id=3,
|
||||
active_response_turn_id=1,
|
||||
active_response_id="resp",
|
||||
auto_responds=True,
|
||||
response_format="pcm16",
|
||||
speed=1.5,
|
||||
modalities=("audio",),
|
||||
)
|
||||
|
||||
|
||||
def test_default_session_state_implements_the_shared_transitions() -> None:
|
||||
class Buffer(PcmAppendBuffer):
|
||||
pending_byte_count = 0
|
||||
|
||||
def clear(self) -> None: ...
|
||||
|
||||
def clear_force_listen(self) -> None: ...
|
||||
|
||||
def has_pending(self) -> bool:
|
||||
return False
|
||||
|
||||
def has_reserved(self) -> bool:
|
||||
return False
|
||||
|
||||
def prepare_append(self, payload, *, operation_id, chunk_period_ms, allow_emit):
|
||||
return None
|
||||
|
||||
def prepare_commit(self, *, operation_id, chunk_period_ms):
|
||||
raise NotImplementedError
|
||||
|
||||
def flush(self, *, chunk_period_ms):
|
||||
return None
|
||||
|
||||
state = DefaultDuplexModelSessionState(audio_buffer=Buffer())
|
||||
|
||||
assert isinstance(state, DuplexModelSessionState)
|
||||
assert state.committed_audio_reserved_bytes == 0 and state.continuation_units == 0
|
||||
state.retain_committed_audio({"audio": "a"}, operation_id="op-1", reserved_bytes=10)
|
||||
state.retain_committed_audio({"audio": "b"}, operation_id="op-2", reserved_bytes=5)
|
||||
state.deferred_response_create = True
|
||||
assert state.committed_audio_payload == {"audio": "b"}
|
||||
assert state.committed_audio_operation_id == "op-2"
|
||||
assert state.clear_committed_audio() == 15
|
||||
assert state.committed_audio_payload is None
|
||||
assert state.committed_audio_operation_id is None
|
||||
assert state.deferred_response_create is False
|
||||
|
||||
state.continuation_owner_id = "response:r"
|
||||
state.continuation_units = 3
|
||||
state.pending_silence_owner_id = "response:r"
|
||||
state.clear_continuation()
|
||||
assert state.continuation_owner_id is None
|
||||
assert state.continuation_units == 0
|
||||
assert state.pending_silence_task is None and state.pending_silence_owner_id is None
|
||||
Reference in new issue
Block a user