From cb35d87eb45a23249bc0ab2eb7fb9418a152bea2 Mon Sep 17 00:00:00 2001 From: Xin Wang Date: Fri, 6 Feb 2026 10:46:24 +0800 Subject: [PATCH] Update web client --- docs/duplex_interaction.svg | 96 +++++++++++++++++++++++++++++++++++++ examples/web_client.html | 4 +- 2 files changed, 97 insertions(+), 3 deletions(-) create mode 100644 docs/duplex_interaction.svg diff --git a/docs/duplex_interaction.svg b/docs/duplex_interaction.svg new file mode 100644 index 0000000..9ccd0bb --- /dev/null +++ b/docs/duplex_interaction.svg @@ -0,0 +1,96 @@ + + + + + + + + + + Web Client + WS JSON commands + WS binary PCM audio + + + FastAPI /ws + Session + Transport + + + DuplexPipeline + process_audio / process_text + + + ConversationManager + turns + state + + + VADProcessor + speech/silence + + + EOU Detector + end-of-utterance + + + ASR + transcripts + + + LLM (stream) + llmResponse events + + + TTS (stream) + PCM audio + + + Web Client + audio playback + UI + + + JSON / PCM + + + dispatch + + + turn mgmt + + + audio chunks + + + vad status + + + audio buffer + + + EOU -> LLM + + + text stream + + + PCM audio + + + events: trackStart/End + + + UI updates + + + barge-in detection + + + interrupt event + cancel + diff --git a/examples/web_client.html b/examples/web_client.html index 02ab70e..6838171 100644 --- a/examples/web_client.html +++ b/examples/web_client.html @@ -331,7 +331,6 @@ -

Chat

@@ -372,7 +371,6 @@ const outputSelect = document.getElementById("outputSelect"); const startMicBtn = document.getElementById("startMicBtn"); const stopMicBtn = document.getElementById("stopMicBtn"); - const interruptBtn = document.getElementById("interruptBtn"); const refreshDevicesBtn = document.getElementById("refreshDevicesBtn"); const sendChatBtn = document.getElementById("sendChatBtn"); const clearLogBtn = document.getElementById("clearLogBtn"); @@ -504,6 +502,7 @@ setStatus(true, "Session open"); logLine("sys", "WebSocket connected"); ensureAudioContext(); + sendCommand({ command: "invite", option: { codec: "pcm", sampleRate: targetSampleRate } }); }; ws.onclose = () => { @@ -653,7 +652,6 @@ }); startMicBtn.addEventListener("click", startMic); stopMicBtn.addEventListener("click", stopMic); - interruptBtn.addEventListener("click", () => sendCommand({ command: "interrupt" })); sendChatBtn.addEventListener("click", () => { const text = chatInput.value.trim(); if (!text) return;