Skip to main content

Chat Management

As of yet, the AI-Human chat live transcription feed is sent with a series of events on the main SignalWire (-> WSClient.on) event.

When user is talking:

note: Every partial result replaces last partial result unless a speech_detect event is sent.

When AI is talking uninterrupted:

note: Every response utterance adds up to the final complete response.

When user interrupts ('barge'):

handling in code

Deciding who spoke last

It looks necessary to keep track of partial text from both AI and user as conversation progresses. But to decide who spoke last, we use the following heuristic:

if lastevent is ai.response_utterance, then AI spoke last
if lastevent is ai.completion type=normal, then AI spoke last
if lastevent is ai.completion type=barged, then user spoke last

if lastevent is ai.partial_result barged=true, then user spoke last and this is the new beginning of user speech
if lastevent is ai.speech_detect, then user spoke last

Deciding when things go to history

if lastevent is ai.response_utterance, then add to partial result; last_spoken=ai
if lastevent is ai.completion type=normal, then push to history; reset ai partial result; last_spoken=ai
if lastevent is ai.completion type=barged, then push to history; reset ai partial result; last_spoken=user

if lastevent is ai.partial_result barged=true, then replace user partial result; last_spoken=user
if lastevent is ai.partial_result barged=false, then replace user partial result; last_spoken=user
if lastevent is ai.speech_detect, then add to history; reset user partial result; last_spoken=user

Code description:

The Call class manages the SignalWireClient and the Call object. So for now, it is a reasonable place to hook into the SignalWireClient chat events.

The Chat class manages the chat state. The Chat UI is rendered by chat.ui.ts

To render chat UI, I'm simply transforming all chat history into DOM with a pure function.