33import { type RefObject , useCallback , useEffect , useMemo , useRef , useState } from 'react'
44import { createLogger } from '@sim/logger'
55import { generateId } from '@sim/utils/id'
6- import { DEFAULT_TTS_VOICE_ID } from '@/lib/api/contracts/media/tts-stream'
7- import { noop } from '@/lib/core/utils/request'
86import {
97 AGENT_STREAM_PROTOCOL_HEADER ,
108 AGENT_STREAM_PROTOCOL_V1 ,
@@ -19,23 +17,15 @@ import {
1917 ChatMessageContainer ,
2018 EmailAuth ,
2119 PasswordAuth ,
22- VoiceInterface ,
2320} from '@/app/(interfaces)/chat/components'
2421import { CHAT_ERROR_MESSAGES , CHAT_REQUEST_TIMEOUT_MS } from '@/app/(interfaces)/chat/constants'
25- import { useAudioStreaming , useChatStreaming } from '@/app/(interfaces)/chat/hooks'
22+ import { useChatStreaming } from '@/app/(interfaces)/chat/hooks'
2623import SSOAuth from '@/ee/sso/components/sso-auth'
2724import { useDeployedChatConfig } from '@/hooks/queries/chats'
2825import { useGitHubStars } from '@/hooks/queries/github-stars'
29- import { useVoiceSettings } from '@/hooks/queries/voice-settings'
3026
3127const logger = createLogger ( 'ChatClient' )
3228
33- interface AudioStreamingOptions {
34- voiceId : string
35- chatId : string
36- onError : ( error : Error ) => void
37- }
38-
3929interface ChatRequestFile {
4030 name : string
4131 size : number
@@ -49,10 +39,6 @@ interface ChatRequestPayload {
4939 files ?: ChatRequestFile [ ]
5040}
5141
52- const DEFAULT_VOICE_SETTINGS = {
53- voiceId : DEFAULT_TTS_VOICE_ID ,
54- }
55-
5642/**
5743 * Converts a File object to a base64 data URL
5844 */
@@ -65,33 +51,6 @@ function fileToBase64(file: File): Promise<string> {
6551 } )
6652}
6753
68- /**
69- * Creates an audio stream handler for text-to-speech conversion
70- * @param streamTextToAudio - Function to stream text to audio
71- * @param voiceId - The voice ID to use for TTS
72- * @param chatId - Optional chat ID for deployed chat authentication
73- * @returns Audio stream handler function or undefined
74- */
75- function createAudioStreamHandler (
76- streamTextToAudio : ( text : string , options : AudioStreamingOptions ) => Promise < void > ,
77- voiceId : string ,
78- chatId : string
79- ) {
80- return async ( text : string ) => {
81- try {
82- await streamTextToAudio ( text , {
83- voiceId,
84- chatId,
85- onError : ( error : Error ) => {
86- logger . error ( 'Audio streaming error:' , error )
87- } ,
88- } )
89- } catch ( error ) {
90- logger . error ( 'TTS error:' , error )
91- }
92- }
93- }
94-
9554export default function ChatClient ( { identifier } : { identifier : string } ) {
9655 const [ messages , setMessages ] = useState < ChatMessage [ ] > ( [ ] )
9756 const [ inputValue , setInputValue ] = useState ( '' )
@@ -105,13 +64,9 @@ export default function ChatClient({ identifier }: { identifier: string }) {
10564 const stickToBottomRef = useRef ( true )
10665 const ignoreScrollRef = useRef ( false )
10766
108- const [ isVoiceFirstMode , setIsVoiceFirstMode ] = useState ( false )
109-
11067 const { data : chatConfigResult , error : chatConfigError } = useDeployedChatConfig ( identifier )
111- const { data : voiceSettings } = useVoiceSettings ( )
11268 const { data : starCount } = useGitHubStars ( )
11369
114- const sttAvailable = voiceSettings ?. sttAvailable === true
11570 const authRequired = chatConfigResult ?. kind === 'auth' ? chatConfigResult . authType : null
11671 const chatConfig = chatConfigResult ?. kind === 'config' ? chatConfigResult . config : null
11772
@@ -135,8 +90,6 @@ export default function ChatClient({ identifier }: { identifier: string }) {
13590
13691 const { isStreamingResponse, abortControllerRef, stopStreaming, handleStreamedResponse } =
13792 useChatStreaming ( )
138- const audioContextRef = useRef < AudioContext | null > ( null )
139- const { isPlayingAudio, streamTextToAudio, stopAudio } = useAudioStreaming ( audioContextRef )
14093
14194 const NEAR_BOTTOM_THRESHOLD_PX = 100
14295
@@ -208,11 +161,10 @@ export default function ChatClient({ identifier }: { identifier: string }) {
208161
209162 container . addEventListener ( 'scroll' , handleScroll , { passive : true } )
210163 return ( ) => container . removeEventListener ( 'scroll' , handleScroll )
211- } , [ chatConfig , isVoiceFirstMode , authRequired ] )
164+ } , [ chatConfig , authRequired ] )
212165
213166 const handleSendMessage = async (
214167 messageParam ?: string ,
215- isVoiceInput = false ,
216168 files ?: Array < {
217169 id : string
218170 name : string
@@ -227,7 +179,6 @@ export default function ChatClient({ identifier }: { identifier: string }) {
227179
228180 logger . info ( 'Sending message:' , {
229181 messageToSend,
230- isVoiceInput,
231182 conversationId,
232183 filesCount : files ?. length ,
233184 } )
@@ -316,30 +267,12 @@ export default function ChatClient({ identifier }: { identifier: string }) {
316267 throw new Error ( 'Response body is missing' )
317268 }
318269
319- const shouldPlayAudio = isVoiceInput || isVoiceFirstMode
320- const audioHandler =
321- shouldPlayAudio && chatConfig ?. id
322- ? createAudioStreamHandler (
323- streamTextToAudio ,
324- DEFAULT_VOICE_SETTINGS . voiceId ,
325- chatConfig . id
326- )
327- : undefined
328-
329- logger . info ( 'Starting to handle streamed response:' , { shouldPlayAudio } )
330-
331270 await handleStreamedResponse (
332271 response ,
333272 setMessages ,
334273 setIsLoading ,
335274 ( ) => scrollToBottom ( { behavior : 'auto' } ) ,
336275 {
337- voiceSettings : {
338- isVoiceEnabled : shouldPlayAudio ,
339- voiceId : DEFAULT_VOICE_SETTINGS . voiceId ,
340- autoPlayResponses : shouldPlayAudio ,
341- } ,
342- audioStreamHandler : audioHandler ,
343276 outputConfigs : chatConfig ?. outputConfigs ,
344277 abortController,
345278 }
@@ -365,41 +298,6 @@ export default function ChatClient({ identifier }: { identifier: string }) {
365298 }
366299 }
367300
368- useEffect ( ( ) => {
369- return ( ) => {
370- stopAudio ( )
371- if ( audioContextRef . current && audioContextRef . current . state !== 'closed' ) {
372- audioContextRef . current . close ( )
373- }
374- }
375- } , [ stopAudio ] )
376-
377- const handleVoiceInterruption = useCallback ( ( ) => {
378- stopAudio ( )
379-
380- if ( isStreamingResponse ) {
381- stopStreaming ( setMessages )
382- }
383- } , [ isStreamingResponse , stopStreaming , setMessages , stopAudio ] )
384-
385- const handleVoiceStart = useCallback ( ( ) => {
386- if ( ! sttAvailable ) return
387- setIsVoiceFirstMode ( true )
388- } , [ sttAvailable ] )
389-
390- const handleExitVoiceMode = useCallback ( ( ) => {
391- setIsVoiceFirstMode ( false )
392- stopAudio ( )
393- } , [ stopAudio ] )
394-
395- const handleVoiceTranscript = useCallback (
396- ( transcript : string ) => {
397- logger . info ( 'Received voice transcript:' , transcript )
398- handleSendMessage ( transcript , true )
399- } ,
400- [ handleSendMessage ]
401- )
402-
403301 if ( chatConfigError ) {
404302 logger . error ( 'Error fetching chat config:' , chatConfigError )
405303 return < ChatErrorState error = { CHAT_ERROR_MESSAGES . CHAT_UNAVAILABLE } />
@@ -421,26 +319,6 @@ export default function ChatClient({ identifier }: { identifier: string }) {
421319 return < ChatLoadingState />
422320 }
423321
424- if ( isVoiceFirstMode ) {
425- return (
426- < VoiceInterface
427- onCallEnd = { handleExitVoiceMode }
428- onVoiceTranscript = { handleVoiceTranscript }
429- onVoiceStart = { noop }
430- onVoiceEnd = { noop }
431- onInterrupt = { handleVoiceInterruption }
432- isStreaming = { isStreamingResponse }
433- isPlayingAudio = { isPlayingAudio }
434- audioContextRef = { audioContextRef }
435- chatId = { chatConfig ?. id }
436- messages = { displayMessages . map ( ( msg ) => ( {
437- content : typeof msg . content === 'string' ? msg . content : JSON . stringify ( msg . content ) ,
438- type : msg . type ,
439- } ) ) }
440- />
441- )
442- }
443-
444322 return (
445323 < div className = 'light desktop-title-bar-page fixed inset-0 z-[100] flex flex-col bg-[var(--bg)] text-[var(--text-primary)]' >
446324 < DesktopTitleBarLane />
@@ -463,13 +341,11 @@ export default function ChatClient({ identifier }: { identifier: string }) {
463341 < div className = 'relative p-3 pb-4 md:p-4 md:pb-6' >
464342 < div className = 'relative mx-auto max-w-3xl md:max-w-[748px]' >
465343 < ChatInput
466- onSubmit = { ( value , isVoiceInput , files ) => {
467- void handleSendMessage ( value , isVoiceInput , files )
344+ onSubmit = { ( value , files ) => {
345+ void handleSendMessage ( value , files )
468346 } }
469347 isStreaming = { isStreamingResponse }
470348 onStopStreaming = { ( ) => stopStreaming ( setMessages ) }
471- onVoiceStart = { handleVoiceStart }
472- sttAvailable = { sttAvailable }
473349 />
474350 </ div >
475351 </ div >
0 commit comments