feat: integrate durable chat voice transport and deployment assets

This commit is contained in:
snowspeeder committed 2026-10-03 09:02:47 -04:00
1 parent e059660194
commit 523f6cbbf9
14 files changed
+487 -14

No files matched your search

+14 -1
View File
@@ -999,6 +999,13 @@ async function createRoom(token, attempt) {
let connectionEpoch = 0;
let tokenAbort = null;
let voiceConversationId = null;
function publishVoiceState(active) {
window.dispatchEvent(new CustomEvent('hope:voice-state', { detail: { active, conversation_id: voiceConversationId } }));
}
window.addEventListener('hope:conversation-selected', event => {
if ((room || connectionPromise) && event.detail?.conversation_id !== voiceConversationId) stopConversation();
});
function checkAttempt(attempt) {
if (attempt !== connectionEpoch || !HopeAuth.user || HopeAuth.user.status !== "ready") throw new Error("Connection cancelled");
}
@@ -1021,6 +1028,7 @@ function cleanupRoom() {
document.querySelectorAll('[id^="audio-"]').forEach(el => el.remove());
document.getElementById("audioUnlockBtn")?.remove();
muteBtn.disabled = true; micMuted = false; updateMuteIcon();
publishVoiceState(false); voiceConversationId = null;
}
function stopConversation() {
connectionEpoch++; tokenAbort?.abort(); tokenAbort = null; connectionPromise = null;
@@ -1034,6 +1042,9 @@ async function connectConversation() {
if (connectionPromise) return connectionPromise;
if (room && agentReady) return room;
const attempt = ++connectionEpoch;
if (window.HopeChat?.running) throw new Error('Wait for the current response or stop it before starting voice.');
voiceConversationId = window.HopeChat?.conversationId || null;
publishVoiceState(true);
startBtn.disabled = true; stopBtn.disabled = false;
const promise = (async () => {
try {
@@ -1142,8 +1153,10 @@ function updateMuteIcon() {
async function fetchToken(attempt) {
checkAttempt(attempt);
tokenAbort = new AbortController();
const data = await HopeAuth.request("/token", { method: "POST", body: JSON.stringify({}), signal: tokenAbort.signal });
const data = await HopeAuth.request("/token", { method: "POST", body: JSON.stringify(voiceConversationId ? { conversation_id: voiceConversationId } : {}), signal: tokenAbort.signal });
checkAttempt(attempt);
voiceConversationId = data.conversation_id || voiceConversationId;
publishVoiceState(true);
if (!data.token || typeof data.token !== "string") throw new Error("Token endpoint did not return a room token");
return data;
}