Wyoming Protocol Documentation

repository·main·Indexed 17 days ago

https://github.com/ohf-voice/wyoming

A peer-to-peer TCP protocol for voice assistant communication, facilitating the exchange of JSON metadata and binary audio payloads between services like Home Assistant and voice processing engines. It supports speech recognition (ASR), text-to-speech (TTS), wake word detection, intent recognition, and voice satellite control using a client-server event model.

Tokens
20.4K
Snippets
64
Records
98
Agent score
63%

What's inside Wyoming

  1. What is the Wyoming Protocol?

    main
    The Wyoming Protocol is a peer-to-peer TCP protocol designed for voice assistants. It uses a combination of JSON Lines (JSONL) for event headers and metadata, and raw binary payloads (typically PCM audio) for data transmission. It is used by Home Assistant to communicate with various voice services.
  2. How the Wyoming Protocol event flow works

    main

    The Wyoming Protocol operates using a client-server event model where events are exchanged over a connection.

    Event Directionality:

    • indicates an event from the client to the server.
    • indicates an event from the server to the client.

    Standard Connection Lifecycle:

    1. Service Description: The client must first send a describe event, and the server responds with an info event.
    2. Program Selection: If a server exposes multiple programs of the same type (e.g., multiple asr programs), the client can optionally send a select-program event with the name of the desired program. If omitted, the first program of each type listed in the info event is used.
    3. Request Execution: Once a program is selected, the client sends request events (e.g., transcribe, synthesize, detect, recognize) specific to that program.
  3. Understand the Wyoming Protocol message format

    main

    A Wyoming message consists of a single-line JSON header followed by optional data and a binary payload. The structure is as follows:

    1. JSON Header (Required, UTF-8, single line ending in \n):
      • type: The event type (string).
      • data: Event-specific metadata (object, optional).
      • data_length: The number of bytes of additional UTF-8 data following the header (int, optional).
      • payload_length: The number of bytes of the binary payload following the data (int, optional).
    2. Additional Data (Optional, UTF-8):
      • A JSON object containing event-specific data, merged with the header's data field.
      • Must be exactly data_length bytes long.
      • Follows the header immediately.
    3. Payload (Optional, Binary):
      • Typically PCM audio or other binary data.
      • Must be exactly payload_length bytes long.
      • Follows the additional data or the header if no additional data is present.
    { "type": "...", "data": { ... }, "data_length": ..., "payload_length": ...}\n
    <data_length bytes (optional)>
    <payload_length bytes (optional)>
  4. Implement Intent Handling with Wyoming

    main

    Once an intent is recognized, it must be handled by the server.

    Structured Intents

    1. → intent (required)
    2. ← handled (if successful)
    3. ← not-handled (if unsuccessful)

    Text-Only Intents

    1. → transcript (required: include text to handle)
    2. ← handled (if successful)
    3. ← not-handled (if unsuccessful)

    Streaming Text-Only Intents (Successful)

    1. → transcript (required: include text to handle)
    2. ← handled-start (required)
    3. ← handled-chunk (required: chunk of response text)
    4. ← handled (sent for backwards compatibility)
    5. ← handled-stop (required)
  5. Implement Text-to-Speech (TTS) with Wyoming

    main

    To generate speech from text, use the following event sequences.

    Standard TTS

    1. → synthesize (required: include text)
    2. ← audio-start
    3. ← audio-chunk (one or more chunks)
    4. ← audio-stop

    Streaming TTS

    1. → synthesize-start (required)
    2. → synthesize-chunk (required: send text chunks as they are produced)
    3. ← audio-start, ← audio-chunk (one or more), ← audio-stop (server sends audio chunks as they are produced)
    4. → synthesize (sent for backwards compatibility)
    5. → synthesize-stop (end of text stream)
    6. ← audio-start, ← audio-chunk (one or more), ← audio-stop (final audio must be sent)
    7. ← synthesize-stopped (server acknowledges final audio has been sent)
  6. Implement Speech-to-Text (ASR) with Wyoming

    main

    To perform speech recognition, use the following event sequences depending on whether you need standard or streaming transcription.

    Standard Transcription

    1. → transcribe (optional: include name of model or language)
    2. → audio-start (required)
    3. → audio-chunk (required: send chunks until silence is detected)
    4. → audio-stop (required)
    5. ← transcript (required: contains the text transcription)

    Streaming Transcription

    1. → transcribe (optional)
    2. → audio-start (required)
    3. → audio-chunk (required: send chunks until silence is detected)
    4. ← transcript-start (required)
    5. ← transcript-chunk (required: server sends transcript chunks as they are produced)
    6. → audio-stop (required)
    7. ← transcript (sent for backwards compatibility)
    8. ← transcript-stop (required)
  7. Select a specific program for a connection

    main

    By default, a server uses the first program of each type listed in its info response. To use a specific program, send a select-program event immediately after connecting and before sending any request events (like describe or transcribe).

    • The name must match a program name provided in the info event.
    • The selection applies for the lifetime of the connection.
    • The domain (e.g., asr, tts) is implied by the subsequent request events.
    {
      "type": "select-program",
      "name": "my-custom-asr-model"
    }
  8. Implement Wake Word Detection with Wyoming

    main

    To detect specific wake words, follow this flow:

    1. → detect (optional: include names of wake words to detect)
    2. → audio-start (required)
    3. → audio-chunk (required: keep sending chunks until a detection is received)
    4. ← detection (sent for each wake word detection)
    5. → audio-stop (optional: manually end the audio stream)
    6. ← not-detected (sent after audio-stop if no detections occurred)
  9. Implement Intent Recognition with Wyoming

    main

    To recognize user intents, use the following flows.

    Single Intent

    1. → recognize (required)
    2. ← intent (if successful)
    3. ← not-recognized (if unsuccessful)

    Multiple Intents

    1. → recognize (required)
    2. ← intents-start (if successful)
    3. ← intent (one or more intents)
    4. ← intents-stop (if successful)
    5. ← not-recognized (if unsuccessful)
  10. Discover service capabilities with Info and Describe events

    main

    Wyoming uses a discovery pattern to allow clients to understand what services a server provides.

    1. Describe: The client sends a Describe event (type describe) to request information.
    2. Info: The server responds with an Info event (type info) containing a detailed breakdown of available services, models, and hardware capabilities.

    The Info event includes lists of programs for various domains such as asr (speech-to-text), tts (text-to-speech), handle (intent handling), intent (intent recognition), wake (wake word detection), mic (audio input), and snd (audio output), as well as satellite metadata.

    # Client requesting info
    describe_event = Describe()
    # The server would then respond with an Info event