refactor: improve TTS abort handling and add debug logging
This commit is contained in:
@@ -26,16 +26,25 @@ export class TTSManager {
|
||||
public async generateAndWaitForPlayback(
|
||||
text: string,
|
||||
emitMessage: (msg: SessionOutboundMessage) => void,
|
||||
abortSignal?: AbortSignal
|
||||
abortSignal: AbortSignal
|
||||
): Promise<void> {
|
||||
// Check if already aborted
|
||||
if (abortSignal?.aborted) {
|
||||
throw new Error("TTS playback aborted");
|
||||
if (abortSignal.aborted) {
|
||||
console.log(
|
||||
`[TTS-Manager ${this.sessionId}] Aborted before generating audio`
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
// Generate TTS audio
|
||||
const { audio, format } = await synthesizeSpeech(text);
|
||||
|
||||
if (abortSignal.aborted) {
|
||||
console.log(
|
||||
`[TTS-Manager ${this.sessionId}] Aborted after generating audio`
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
// Create unique ID for this audio segment
|
||||
const audioId = uuidv4();
|
||||
|
||||
@@ -48,17 +57,18 @@ export class TTSManager {
|
||||
this.pendingPlaybacks.set(audioId, { resolve, reject });
|
||||
|
||||
// Handle abort signal
|
||||
if (abortSignal) {
|
||||
onAbort = () => {
|
||||
// Clean up pending playback
|
||||
this.pendingPlaybacks.delete(audioId);
|
||||
// Reject with abort error
|
||||
reject(new Error("TTS playback aborted"));
|
||||
};
|
||||
onAbort = () => {
|
||||
console.log(
|
||||
`[TTS-Manager ${this.sessionId}] Aborted while waiting for playback`
|
||||
);
|
||||
// Clean up pending playback
|
||||
this.pendingPlaybacks.delete(audioId);
|
||||
// Reject with abort error
|
||||
resolve();
|
||||
};
|
||||
|
||||
// Listen for abort (once: true for auto-cleanup if abort fires)
|
||||
abortSignal.addEventListener("abort", onAbort, { once: true });
|
||||
}
|
||||
// Listen for abort (once: true for auto-cleanup if abort fires)
|
||||
abortSignal.addEventListener("abort", onAbort, { once: true });
|
||||
});
|
||||
|
||||
// Clean up abort listener when promise settles (in case abort never fires)
|
||||
|
||||
@@ -135,6 +135,7 @@ export class Session {
|
||||
`[Session ${this.clientId}] Waiting for aborted stream to finish cleanup`
|
||||
);
|
||||
await this.currentStreamPromise;
|
||||
console.log(`[Session ${this.clientId}] Aborted stream finished cleanup`);
|
||||
}
|
||||
|
||||
// Emit user message activity log
|
||||
|
||||
@@ -45,17 +45,22 @@ export class VoiceAssistantWebSocketServer {
|
||||
this.conversationIdToWs.set(session.getConversationId(), ws);
|
||||
|
||||
console.log(
|
||||
`[WS] Client connected: ${clientId} with conversation ${session.getConversationId()} (total: ${this.sessions.size})`
|
||||
`[WS] Client connected: ${clientId} with conversation ${session.getConversationId()} (total: ${
|
||||
this.sessions.size
|
||||
})`
|
||||
);
|
||||
|
||||
// Send welcome message
|
||||
this.sendToClient(ws, wrapSessionMessage({
|
||||
type: "status",
|
||||
payload: {
|
||||
status: "connected",
|
||||
message: "WebSocket connection established",
|
||||
},
|
||||
}));
|
||||
this.sendToClient(
|
||||
ws,
|
||||
wrapSessionMessage({
|
||||
type: "status",
|
||||
payload: {
|
||||
status: "connected",
|
||||
message: "WebSocket connection established",
|
||||
},
|
||||
})
|
||||
);
|
||||
|
||||
// Set up message handler
|
||||
ws.on("message", (data) => {
|
||||
@@ -68,7 +73,9 @@ export class VoiceAssistantWebSocketServer {
|
||||
if (!session) return;
|
||||
|
||||
console.log(
|
||||
`[WS] Client disconnected: ${clientId} (total: ${this.sessions.size - 1})`
|
||||
`[WS] Client disconnected: ${clientId} (total: ${
|
||||
this.sessions.size - 1
|
||||
})`
|
||||
);
|
||||
|
||||
// Clean up session
|
||||
@@ -110,7 +117,7 @@ export class VoiceAssistantWebSocketServer {
|
||||
// Validate with Zod
|
||||
const message = WSInboundMessageSchema.parse(parsed);
|
||||
|
||||
console.log(`[WS] Received message type: ${message.type}`);
|
||||
console.log(`[WS] Received message type: ${message.type}`, message);
|
||||
|
||||
// Handle WebSocket-level messages
|
||||
switch (message.type) {
|
||||
@@ -138,13 +145,16 @@ export class VoiceAssistantWebSocketServer {
|
||||
} catch (error: any) {
|
||||
console.error("[WS] Failed to parse/handle message:", error);
|
||||
// Send error to client
|
||||
this.sendToClient(ws, wrapSessionMessage({
|
||||
type: "status",
|
||||
payload: {
|
||||
status: "error",
|
||||
message: `Invalid message: ${error.message}`,
|
||||
},
|
||||
}));
|
||||
this.sendToClient(
|
||||
ws,
|
||||
wrapSessionMessage({
|
||||
type: "status",
|
||||
payload: {
|
||||
status: "error",
|
||||
message: `Invalid message: ${error.message}`,
|
||||
},
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user