Add demo page shows state code
This commit is contained in:
@@ -39,6 +39,8 @@ const els = {
|
|||||||
micLabel: document.querySelector(".mic-btn__label"),
|
micLabel: document.querySelector(".mic-btn__label"),
|
||||||
micIndicator: document.getElementById("mic-indicator"),
|
micIndicator: document.getElementById("mic-indicator"),
|
||||||
botIndicator: document.getElementById("bot-indicator"),
|
botIndicator: document.getElementById("bot-indicator"),
|
||||||
|
stateIndicator: document.getElementById("state-indicator"),
|
||||||
|
stateLabel: document.getElementById("state-label"),
|
||||||
clearBtn: document.getElementById("clear-btn"),
|
clearBtn: document.getElementById("clear-btn"),
|
||||||
clearWsLogBtn: document.getElementById("clear-ws-log-btn"),
|
clearWsLogBtn: document.getElementById("clear-ws-log-btn"),
|
||||||
wsLog: document.getElementById("ws-log"),
|
wsLog: document.getElementById("ws-log"),
|
||||||
@@ -71,6 +73,7 @@ const state = {
|
|||||||
|
|
||||||
// Chat state.
|
// Chat state.
|
||||||
currentAssistantBubble: null,
|
currentAssistantBubble: null,
|
||||||
|
assistantState: "",
|
||||||
|
|
||||||
// VU meter smoothing.
|
// VU meter smoothing.
|
||||||
meterLevel: 0,
|
meterLevel: 0,
|
||||||
@@ -123,6 +126,15 @@ function setBotIndicator(active) {
|
|||||||
els.botIndicator.classList.toggle("is-active", active);
|
els.botIndicator.classList.toggle("is-active", active);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function setAssistantState(value) {
|
||||||
|
const text = typeof value === "string" ? value.trim() : "";
|
||||||
|
const label = text.length > 32 ? `${text.slice(0, 31)}…` : text;
|
||||||
|
state.assistantState = text;
|
||||||
|
els.stateIndicator.classList.toggle("is-active", Boolean(text));
|
||||||
|
els.stateLabel.textContent = label ? `State ${label}` : "State -";
|
||||||
|
els.stateIndicator.title = label ? `Assistant state: ${text}` : "Assistant state";
|
||||||
|
}
|
||||||
|
|
||||||
function addBubble(role, text) {
|
function addBubble(role, text) {
|
||||||
if (els.chatLog.querySelector(".chat__empty")) {
|
if (els.chatLog.querySelector(".chat__empty")) {
|
||||||
els.chatLog.innerHTML = "";
|
els.chatLog.innerHTML = "";
|
||||||
@@ -157,6 +169,7 @@ function scrollChatToBottom() {
|
|||||||
function clearChat() {
|
function clearChat() {
|
||||||
els.chatLog.innerHTML = "";
|
els.chatLog.innerHTML = "";
|
||||||
state.currentAssistantBubble = null;
|
state.currentAssistantBubble = null;
|
||||||
|
setAssistantState("");
|
||||||
const empty = document.createElement("div");
|
const empty = document.createElement("div");
|
||||||
empty.className = "chat__empty";
|
empty.className = "chat__empty";
|
||||||
empty.innerHTML = "<p>Chat cleared.</p>";
|
empty.innerHTML = "<p>Chat cleared.</p>";
|
||||||
@@ -769,6 +782,9 @@ function handleEvent(event) {
|
|||||||
case "response.text.final":
|
case "response.text.final":
|
||||||
handleAssistantFinal(event.text, event.interrupted);
|
handleAssistantFinal(event.text, event.interrupted);
|
||||||
break;
|
break;
|
||||||
|
case "response.state":
|
||||||
|
setAssistantState(event.state);
|
||||||
|
break;
|
||||||
case "input.transcript.final":
|
case "input.transcript.final":
|
||||||
handleUserTranscript(event.text);
|
handleUserTranscript(event.text);
|
||||||
break;
|
break;
|
||||||
@@ -885,6 +901,7 @@ async function connect() {
|
|||||||
state.ws = null;
|
state.ws = null;
|
||||||
state.connected = false;
|
state.connected = false;
|
||||||
state.connecting = false;
|
state.connecting = false;
|
||||||
|
setAssistantState("");
|
||||||
if (state.micEnabled) stopMic();
|
if (state.micEnabled) stopMic();
|
||||||
stopPlaybackQueue();
|
stopPlaybackQueue();
|
||||||
setConnectButton();
|
setConnectButton();
|
||||||
|
|||||||
@@ -118,6 +118,10 @@
|
|||||||
<span class="indicator__dot indicator__dot--bot"></span>
|
<span class="indicator__dot indicator__dot--bot"></span>
|
||||||
<span class="indicator__label">Bot</span>
|
<span class="indicator__label">Bot</span>
|
||||||
</span>
|
</span>
|
||||||
|
<span id="state-indicator" class="indicator indicator--state">
|
||||||
|
<span class="indicator__dot indicator__dot--state"></span>
|
||||||
|
<span id="state-label" class="indicator__label">State -</span>
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<button id="clear-btn" class="btn btn--ghost" type="button">
|
<button id="clear-btn" class="btn btn--ghost" type="button">
|
||||||
|
|||||||
@@ -671,10 +671,26 @@ body {
|
|||||||
animation: pulse 1s ease-in-out infinite;
|
animation: pulse 1s ease-in-out infinite;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.indicator.is-active .indicator__dot--state {
|
||||||
|
background: var(--warning);
|
||||||
|
border-color: var(--warning);
|
||||||
|
box-shadow: 0 0 0 4px rgba(255, 184, 77, 0.18);
|
||||||
|
}
|
||||||
|
|
||||||
.indicator.is-active .indicator__label {
|
.indicator.is-active .indicator__label {
|
||||||
color: var(--text);
|
color: var(--text);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.indicator--state {
|
||||||
|
max-width: 180px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.indicator--state .indicator__label {
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
.btn {
|
.btn {
|
||||||
appearance: none;
|
appearance: none;
|
||||||
border: 1px solid var(--border);
|
border: 1px solid var(--border);
|
||||||
|
|||||||
Reference in New Issue
Block a user