Files
vllm-omni/vllm_omni/engine/duplex/messages.py
T
chickeytonandClaude Opus 5 99ff4f3070 [Core][Frontend] Unified Full-duplex Framework (#7413)
Signed-off-by: chickeyton <ngton2014@gmail.com>
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-16 15:35:36 +08:00

115 lines
3.6 KiB
Python

# SPDX-License-Identifier: Apache-2.0
# SPDX-FileCopyrightText: Copyright contributors to the vLLM-Omni project
"""Queue envelopes exchanged between ``DuplexOmniEngine`` and ``DuplexOrchestrator``.
Sessions live inside the engine (``DuplexSessionRunner`` on the orchestrator
loop). The API layer only opens/closes/resumes/touches sessions through
correlated RPC and pushes ``DuplexCommand`` objects one-way; every session
output travels back as a ``DuplexSessionEventMessage``.
"""
from __future__ import annotations
from typing import TYPE_CHECKING, Literal
from vllm_omni.engine.messages import EngineQueueMessage
if TYPE_CHECKING:
from vllm_omni.engine.duplex.commands import DuplexCommand
from vllm_omni.engine.duplex.config import DuplexCapabilities, DuplexSessionConfig
from vllm_omni.engine.duplex.events import DuplexEvent
class DuplexSessionError(RuntimeError):
"""A session control operation was rejected by the engine."""
def __init__(
self,
message: str,
*,
code: str = "internal_error",
retryable: bool = False,
session_id: str | None = None,
) -> None:
super().__init__(message)
self.code = code
self.retryable = retryable
self.session_id = session_id
class OpenDuplexSessionMessage(EngineQueueMessage, kw_only=True):
type: Literal["open_duplex_session"] = "open_duplex_session"
control_id: str
session_id: str
#: Already normalized by ``DuplexOmni``; the queue is in-process, so the object crosses as is.
session_config: DuplexSessionConfig
class CloseDuplexSessionMessage(EngineQueueMessage, kw_only=True):
type: Literal["close_duplex_session"] = "close_duplex_session"
control_id: str
session_id: str
reason: str = "client_close"
class ResumeDuplexSessionMessage(EngineQueueMessage, kw_only=True):
type: Literal["resume_duplex_session"] = "resume_duplex_session"
control_id: str
session_id: str
expected_lease_generation: int
class TouchDuplexSessionMessage(EngineQueueMessage, kw_only=True):
type: Literal["touch_duplex_session"] = "touch_duplex_session"
control_id: str
session_id: str
activity: str
class DuplexSessionCommandMessage(EngineQueueMessage, kw_only=True):
"""One-way session command; rejections come back as ``ErrorEvent``."""
type: Literal["duplex_session_command"] = "duplex_session_command"
session_id: str
command: DuplexCommand
class DuplexControlResultMessage(EngineQueueMessage, kw_only=True):
type: Literal["duplex_control_result"] = "duplex_control_result"
control_id: str
operation: str
session_id: str
ok: bool
lease_generation: int | None = None
capabilities: DuplexCapabilities | None = None
#: The Realtime ``session`` object of the session (wire payload, already a dict).
public_session: dict[str, object] | None = None
error_code: str | None = None
error_message: str | None = None
error_retryable: bool = False
@property
def rpc_correlation_key(self) -> tuple[str, str]:
return ("duplex", self.control_id)
class DuplexSessionEventMessage(EngineQueueMessage, kw_only=True):
"""A typed session event on the engine output queue."""
type: Literal["duplex_session_event"] = "duplex_session_event"
session_id: str
event: DuplexEvent
__all__ = [
"CloseDuplexSessionMessage",
"DuplexControlResultMessage",
"DuplexSessionCommandMessage",
"DuplexSessionError",
"DuplexSessionEventMessage",
"OpenDuplexSessionMessage",
"ResumeDuplexSessionMessage",
"TouchDuplexSessionMessage",
]