vllm_omni.engine.duplex.events ¶
The event vocabulary one duplex session speaks, assembled from two layers.
The classes themselves no longer live here. vllm_omni.protocol.duplex.events carries the whole vocabulary --- 21 Tier 1 classes re-exported from vllm_omni.protocol.realtime.events, 9 Tier 2 ones and 12 Tier 3 ones --- so a non-duplex Realtime consumer can take the Tier 1 half and its wire rendering without the duplex session control plane (RFC #6592 P0a). The engine imports the duplex module and never the Tier 1 one directly.
What is genuinely engine-side stays: :data:DOMAIN_TERMINAL_EVENTS and :data:MODEL_OUTPUT_EVENTS are the session runner's epoch-filter policy, not wire contract --- they name internal event types, and which of them may never be dropped as stale is a runtime decision.
DuplexEvent is re-exported as the name the engine and the clients already use. It is an alias of :class:~vllm_omni.protocol.realtime.events.RealtimeEvent, not a subclass, because an event has no engine-internal half --- what the session emits is exactly what the socket sends. A command does have one (payload() renders the runner's mailbox), which is why DuplexCommand is a real class.
DOMAIN_TERMINAL_EVENTS module-attribute ¶
DOMAIN_TERMINAL_EVENTS = frozenset(
{
"response.done",
"response.listen",
"audio.cancelled",
"input.cancelled",
"session.closed",
}
)
MODEL_OUTPUT_EVENTS module-attribute ¶
MODEL_OUTPUT_EVENTS = frozenset(
{
"response.created",
"response.listen",
"response.speak",
"response.output_item.added",
"response.content_part.added",
"response.output_audio.delta",
"response.output_audio.done",
"response.output_text.delta",
"response.output_text.done",
"response.text.delta",
"response.text.done",
"response.message",
"response.output_item.done",
"response.content_part.done",
"response.done",
}
)
REALTIME_ERROR_TYPES_BY_CODE module-attribute ¶
REALTIME_ERROR_TYPES_BY_CODE: dict[str, str] = {
"bad_event": "invalid_request_error",
"bad_audio": "invalid_request_error",
"config_timeout": "invalid_request_error",
"invalid_json": "invalid_request_error",
"event_too_large": "invalid_request_error",
"unknown_event": "invalid_request_error",
"internal_error": "server_error",
"runtime_append_failed": "server_error",
"runtime_append_task_failed": "server_error",
"runtime_signal_failed": "server_error",
"runtime_abort_failed": "server_error",
"runtime_data_plane_stream_failed": "server_error",
"runtime_data_plane_text_without_audio": "server_error",
"resource_exhausted": "rate_limit_error",
"session_exists": "invalid_request_error",
"session_closed": "invalid_request_error",
"unknown_session": "invalid_request_error",
"invalid_duplex_runtime_config": "invalid_request_error",
"instructions_update_unsupported": "invalid_request_error",
"persona_update_unsupported": "invalid_request_error",
"voice_update_unsupported": "invalid_request_error",
"unsupported_nemotron_duplex_mode": "invalid_request_error",
"unsupported_native_response_options": "invalid_request_error",
"runtime_touch_failed": "server_error",
"engine_error": "server_error",
"input_backpressure": "rate_limit_error",
"response_already_active": "invalid_request_error",
"response_not_active": "invalid_request_error",
"response_create_without_input": "invalid_request_error",
"text_only_turn_unsupported": "invalid_request_error",
"commit_aborted": "server_error",
"input_audio_buffer_empty": "invalid_request_error",
"missing_item_id": "invalid_request_error",
"item_not_found": "invalid_request_error",
"playback_item_mismatch": "invalid_request_error",
"playback_item_not_found": "invalid_request_error",
"playback_ack_too_late": "invalid_request_error",
"unsupported_audio_format": "invalid_request_error",
"unsupported_turn_detection": "invalid_request_error",
"unsupported_ref_audio_path": "invalid_request_error",
"ref_audio_required": "invalid_request_error",
"model_update_unsupported": "invalid_request_error",
"voice_update_after_audio_unsupported": "invalid_request_error",
"ref_audio_update_unsupported": "invalid_request_error",
"native_text_append_unsupported": "invalid_request_error",
"invalid_video_frames": "invalid_request_error",
"invalid_input_modality": "invalid_request_error",
"invalid_function_call_output": "invalid_request_error",
"server_vad_unavailable": "server_error",
}
AudioDelta dataclass ¶
Bases: AudioDelta
Tier 2: OpenAI's AudioDelta plus the chunk's own format/rate and the duplex playback metadata.
AudioDone dataclass ¶
Bases: ResponseScopedEvent
ContentPartAdded dataclass ¶
ContentPartDone dataclass ¶
Bases: ContentPartAdded
DuplexRawEvent dataclass ¶
Bases: RealtimeEvent
A session-internal event with no dedicated Realtime type (duplex.<internal type>).
details class-attribute instance-attribute ¶
ErrorEvent dataclass ¶
Bases: ErrorEvent
Tier 2: OpenAI's ErrorEvent plus vLLM-Omni's error codes and any extra keys merged into the envelope.
FunctionCallArgumentsDelta dataclass ¶
Bases: RealtimeEvent
FunctionCallArgumentsDone dataclass ¶
Bases: RealtimeEvent
InputCleared dataclass ¶
Bases: RealtimeEvent
InputCommitted dataclass ¶
InputTranscriptionCompleted dataclass ¶
Bases: RealtimeEvent
wire_type class-attribute instance-attribute ¶
ItemAdded dataclass ¶
Bases: _ItemEvent
ItemCreated dataclass ¶
Bases: _ItemEvent
ItemDeleted dataclass ¶
ItemDone dataclass ¶
Bases: _ItemEvent
ItemRetrieved dataclass ¶
ItemTruncated dataclass ¶
Listen dataclass ¶
Bases: RealtimeEvent
The model decided to keep listening (no spoken response for this turn).
OutputAudioCleared dataclass ¶
Bases: RealtimeEvent
OutputItemAdded dataclass ¶
Bases: RealtimeEvent
OutputItemDone dataclass ¶
Bases: OutputItemAdded
OverlapDecision dataclass ¶
Bases: RealtimeEvent
details class-attribute instance-attribute ¶
PlaybackAcknowledged dataclass ¶
RateLimitsUpdated dataclass ¶
ResponseCreated dataclass ¶
Bases: ResponseCreated
Tier 2: OpenAI's ResponseCreated plus a top-level response_id.
OpenAI carries the id nested as response.id; the duplex lane also reports it at the top level, where every other response-scoped event already has one.
ResponseDone dataclass ¶
Bases: ResponseDone
Tier 2: OpenAI's ResponseDone plus a top-level response_id.
OpenAI carries the id nested as response.id; the duplex lane also reports it at the top level, where every other response-scoped event already has one.
SessionClosed dataclass ¶
Bases: RealtimeEvent
SessionCreated dataclass ¶
Bases: SessionCreated
Tier 2: OpenAI's SessionCreated plus the resume credentials a reconnecting client needs.
SessionExpired dataclass ¶
Bases: SessionClosed
SessionHeartbeatAck dataclass ¶
Bases: RealtimeEvent
SessionReplaced dataclass ¶
Bases: RealtimeEvent
A newer connection took the session over (sent to the replaced socket).
SessionResumed dataclass ¶
Bases: SessionCreated
SessionResyncRequired dataclass ¶
Bases: RealtimeEvent
The replay journal cannot bridge the gap; the client must start over.
SessionUpdated dataclass ¶
Speak dataclass ¶
SpeechStarted dataclass ¶
SpeechStopped dataclass ¶
TextDelta dataclass ¶
TextDone dataclass ¶
Bases: ResponseScopedEvent
TranscriptDelta dataclass ¶
Bases: TranscriptDelta
Tier 2: OpenAI's TranscriptDelta plus duplex request-start metrics on text-only units.