From efd93adfa87ebca70c12b291f6e82cc16f1e1596 Mon Sep 17 00:00:00 2001 From: a6kme Date: Mon, 22 Sep 2025 14:52:40 +0000 Subject: [PATCH] fix: fix ui of webrtc call --- api/requirements.txt | 2 +- .../run/[runId]/hooks/useWebSocketRTC.tsx | 38 +++++++++++++++++-- 2 files changed, 35 insertions(+), 5 deletions(-) diff --git a/api/requirements.txt b/api/requirements.txt index e27f7d9..5b6af6c 100644 --- a/api/requirements.txt +++ b/api/requirements.txt @@ -1,4 +1,4 @@ -pipecat-ai[cartesia,deepgram,openai,elevenlabs,groq,google,azure,soundfile,silero,webrtc] @ git+https://github.com/dograh-hq/pipecat.git@d03d892 +pipecat-ai[cartesia,deepgram,openai,elevenlabs,groq,google,azure,soundfile,silero,webrtc] @ git+https://github.com/dograh-hq/pipecat.git@9b0eba6 langfuse==3.4.0 fastapi==0.116.2 asyncpg==0.30.0 diff --git a/ui/src/app/workflow/[workflowId]/run/[runId]/hooks/useWebSocketRTC.tsx b/ui/src/app/workflow/[workflowId]/run/[runId]/hooks/useWebSocketRTC.tsx index a314a56..64947ed 100644 --- a/ui/src/app/workflow/[workflowId]/run/[runId]/hooks/useWebSocketRTC.tsx +++ b/ui/src/app/workflow/[workflowId]/run/[runId]/hooks/useWebSocketRTC.tsx @@ -1,4 +1,4 @@ -import { useCallback,useEffect, useRef, useState } from "react"; +import { useCallback, useEffect, useRef, useState } from "react"; import { client } from "@/client/client.gen"; import { validateUserConfigurationsApiV1UserConfigurationsUserValidateGet, validateWorkflowApiV1WorkflowWorkflowIdValidatePost } from "@/client/sdk.gen"; @@ -100,8 +100,37 @@ export const useWebSocketRTC = ({ workflowId, workflowRunId, accessToken, initia logger.info(`ICE connection state changed: ${pc.iceConnectionState}`); if (pc.iceConnectionState === 'connected' || pc.iceConnectionState === 'completed') { setConnectionStatus('connected'); - } else if (pc.iceConnectionState === 'failed' || pc.iceConnectionState === 'disconnected') { + } else if (pc.iceConnectionState === 'failed') { setConnectionStatus('failed'); + } else if (pc.iceConnectionState === 'disconnected') { + // Server-initiated disconnect - clean up gracefully + logger.info('Server initiated disconnect - cleaning up connection'); + + // Close WebSocket if still open + if (wsRef.current) { + wsRef.current.close(); + wsRef.current = null; + } + + // Mark as completed to trigger recording check + setConnectionActive(false); + setIsCompleted(true); + setConnectionStatus('idle'); + + // Clean up peer connection + if (pc.getTransceivers) { + pc.getTransceivers().forEach((transceiver) => { + if (transceiver.stop) { + transceiver.stop(); + } + }); + } + + pc.getSenders().forEach((sender) => { + if (sender.track) { + sender.track.stop(); + } + }); } }); @@ -136,7 +165,8 @@ export const useWebSocketRTC = ({ workflowId, workflowRunId, accessToken, initia ws.onclose = () => { logger.info('WebSocket closed'); wsRef.current = null; - if (connectionActive) { + // Don't set failed status if already completed (graceful disconnect) + if (connectionActive && !isCompleted) { setConnectionStatus('failed'); } }; @@ -193,7 +223,7 @@ export const useWebSocketRTC = ({ workflowId, workflowRunId, accessToken, initia } }; }); - }, [getWebSocketUrl, connectionActive]); + }, [getWebSocketUrl, connectionActive, isCompleted]); const negotiate = async () => { const pc = pcRef.current;