diff --git a/src/pages/views/workspace/WorkspaceInput.tsx b/src/pages/views/workspace/WorkspaceInput.tsx index 1236ec2..f72d18a 100644 --- a/src/pages/views/workspace/WorkspaceInput.tsx +++ b/src/pages/views/workspace/WorkspaceInput.tsx @@ -337,6 +337,38 @@ export const WorkspaceInput = forwardRef 0 || attachedDataSourceIds.length > 0 || attachedFeatureDataSourceIds.length > 0; const _canSend = Boolean(prompt.trim()) || attachments.length > 0; + const _buildPromptFromRefs = useCallback(() => { + const parts = [ + promptBeforeVoiceRef.current, + finalizedTextRef.current, + currentInterimRef.current, + ].filter(Boolean); + return parts.join(' '); + }, []); + + const voiceStream = useVoiceStream({ + onFinal: (text) => { + finalizedTextRef.current = finalizedTextRef.current + ? `${finalizedTextRef.current} ${text}` + : text; + currentInterimRef.current = ''; + setPrompt(_buildPromptFromRefs()); + }, + onInterim: (text) => { + currentInterimRef.current = text; + setPrompt(_buildPromptFromRefs()); + }, + onError: (error) => { + console.warn('Workspace voice stream error', error); + setVoiceActive(false); + }, + onStatusChange: (nextStatus) => { + if (nextStatus === 'idle' || nextStatus === 'error') { + setVoiceActive(false); + } + }, + }); + const _handleSend = useCallback(() => { if ((!prompt.trim() && attachments.length === 0) || isProcessing) return; if (voiceActive) { @@ -419,38 +451,6 @@ export const WorkspaceInput = forwardRef { - const parts = [ - promptBeforeVoiceRef.current, - finalizedTextRef.current, - currentInterimRef.current, - ].filter(Boolean); - return parts.join(' '); - }, []); - - const voiceStream = useVoiceStream({ - onFinal: (text) => { - finalizedTextRef.current = finalizedTextRef.current - ? `${finalizedTextRef.current} ${text}` - : text; - currentInterimRef.current = ''; - setPrompt(_buildPromptFromRefs()); - }, - onInterim: (text) => { - currentInterimRef.current = text; - setPrompt(_buildPromptFromRefs()); - }, - onError: (error) => { - console.warn('Workspace voice stream error', error); - setVoiceActive(false); - }, - onStatusChange: (nextStatus) => { - if (nextStatus === 'idle' || nextStatus === 'error') { - setVoiceActive(false); - } - }, - }); - const _stopVoiceCapture = useCallback(() => { if (currentInterimRef.current) { finalizedTextRef.current = finalizedTextRef.current