Skip to content

vllm_omni.protocol.duplex.commands

The client-event vocabulary a full-duplex session accepts.

Seven of the seventeen are events OpenAI's Realtime API has no equivalent for, because they only make sense when the model and the user can talk at the same time: the user cuts in (barge_in), the client reports how much audio it played (playback.ack), a turn transition is signalled locally (turn.signal), input is abandoned without committing (input.cancel), text is pushed into a live turn (input.text.append), and the session is kept alive or closed explicitly (session.heartbeat / session.close). Two more are OpenAI commands carrying duplex-only fields (Tier 2).

The remaining eight are OpenAI's, unchanged, and re-exported from vllm_omni.protocol.realtime.commands rather than redeclared --- they are the same objects. They are re-exported so this module is the whole vocabulary and a duplex consumer never has to import the Tier 1 package directly; keeping them declared there means a GA-only consumer is still not handed events its clients never send.

None of these carries the engine's mailbox rendering: payload() and its channel live in vllm_omni.engine.duplex.commands, because for four of the seventeen the runner's channel is not the client event type at all.

AckPlayback dataclass

Bases: RealtimeCommand

committed_ms class-attribute instance-attribute

committed_ms: int | None = None

item_id class-attribute instance-attribute

item_id: str | None = None

played_ms instance-attribute

played_ms: int

response_id class-attribute instance-attribute

response_id: str | None = None

wire_type class-attribute

wire_type: str = 'playback.ack'

AppendAudio dataclass

Bases: AppendAudio

Tier 2: OpenAI's input_audio_buffer.append plus the duplex hints.

OpenAI's append is just base64 audio. The duplex lane also lets a client declare this chunk's own format and rate, whether it believes the chunk is speech, camera frames captured alongside it, and its timing --- all additive, all ignored by a stock client. Empty audio with video_frames is legal when session capabilities allow video without required audio.

audio_end_ms class-attribute instance-attribute

audio_end_ms: int | None = None

duration_ms class-attribute instance-attribute

duration_ms: int | None = None

format class-attribute instance-attribute

format: str = 'pcm16'

hints class-attribute instance-attribute

hints: Mapping[str, object] = field(default_factory=dict)

is_speech class-attribute instance-attribute

is_speech: bool | None = None

sample_rate_hz class-attribute instance-attribute

sample_rate_hz: int | None = None

video_frames class-attribute instance-attribute

video_frames: tuple[str, ...] = ()

AppendText dataclass

Bases: RealtimeCommand

text instance-attribute

text: str

wire_type class-attribute

wire_type: str = 'input.text.append'

BargeIn dataclass

Bases: RealtimeCommand

wire_type class-attribute

wire_type: str = 'barge_in'

CancelInput dataclass

Bases: RealtimeCommand

wire_type class-attribute

wire_type: str = 'input.cancel'

CancelResponse dataclass

Bases: RealtimeCommand

response_id class-attribute instance-attribute

response_id: str | None = None

wire_type class-attribute

wire_type: str = 'response.cancel'

ClearInput dataclass

Bases: RealtimeCommand

wire_type class-attribute

wire_type: str = 'input_audio_buffer.clear'

ClearOutputAudio dataclass

Bases: RealtimeCommand

response_id class-attribute instance-attribute

response_id: str | None = None

wire_type class-attribute

wire_type: str = 'output_audio_buffer.clear'

CloseSession dataclass

Bases: RealtimeCommand

Graceful close requested through the command stream (session.close).

reason class-attribute instance-attribute

reason: str = 'client_close'

wire_type class-attribute

wire_type: str = 'session.close'

Commit dataclass

Bases: Commit

Tier 2: OpenAI's input_audio_buffer.commit plus duplex turn control.

OpenAI's commit carries nothing and always produces an item. Here a commit may be non-final, may decline to start a response, and may declare itself silence --- the semantic divergence documented in docs/serving/realtime_duplex_api.md ("Commit != response").

create_response class-attribute instance-attribute

create_response: bool | None = None

is_speech class-attribute instance-attribute

is_speech: bool | None = None

realtime_item_id class-attribute instance-attribute

realtime_item_id: str | None = None

CreateItem dataclass

Bases: RealtimeCommand

conversation.item.create (history injection or function-call output).

item instance-attribute

item: Mapping[str, object]

previous_item_id class-attribute instance-attribute

previous_item_id: str | None = None

wire_type class-attribute

wire_type: str = 'conversation.item.create'

CreateResponse dataclass

Bases: RealtimeCommand

options class-attribute instance-attribute

options: Mapping[str, object] = field(default_factory=dict)

wire_type class-attribute

wire_type: str = 'response.create'

DeleteItem dataclass

Bases: RealtimeCommand

item_id instance-attribute

item_id: str

wire_type class-attribute

wire_type: str = 'conversation.item.delete'

Heartbeat dataclass

Bases: RealtimeCommand

wire_type class-attribute

wire_type: str = 'session.heartbeat'

RealtimeCommand dataclass

One decoded OpenAI Realtime client event.

wire_type is the event type the client sent; the typed fields are what survived decoding, so a consumer reads them instead of re-parsing JSON.

There is deliberately no rendering method here. A server receives commands, it does not emit them, and how a runtime represents one internally is its own business --- the duplex engine renders its mailbox dictionary in vllm_omni.engine.duplex.commands.

event_id class-attribute instance-attribute

event_id: str | None = None

wire_type class-attribute

wire_type: str = ''

SignalTurn dataclass

Bases: RealtimeCommand

Generic turn.signal (local turn transitions such as user_started).

event instance-attribute

event: str

signal_payload class-attribute instance-attribute

signal_payload: Mapping[str, object] = field(
    default_factory=dict
)

wire_type class-attribute

wire_type: str = 'turn.signal'

TruncateItem dataclass

Bases: RealtimeCommand

audio_end_ms instance-attribute

audio_end_ms: int

content_index class-attribute instance-attribute

content_index: int = 0

item_id instance-attribute

item_id: str

wire_type class-attribute

wire_type: str = 'conversation.item.truncate'

UpdateSession dataclass

Bases: RealtimeCommand

session.update: a Realtime session object patch.

patch class-attribute instance-attribute

patch: Mapping[str, object] = field(default_factory=dict)

wire_type class-attribute

wire_type: str = 'session.update'