Skip to content

Commit cb1b60e

Browse files
committed
fix: cannot immediately stop the AI
1 parent 4fe0d71 commit cb1b60e

File tree

1 file changed

+13
-8
lines changed

1 file changed

+13
-8
lines changed

src/renderer/src/context/vad-context.tsx

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import { useInterrupt } from '@/components/canvas/live2d';
88
import { audioTaskQueue } from '@/utils/task-queue';
99
import { useSendAudio } from '@/hooks/utils/use-send-audio';
1010
import { SubtitleContext } from './subtitle-context';
11-
import { AiStateContext } from './ai-state-context';
11+
import { AiStateContext, AiState } from './ai-state-context';
1212
import { useLocalStorage } from '@/hooks/utils/use-local-storage';
1313
import { toaster } from '@/components/ui/toaster';
1414

@@ -108,7 +108,7 @@ export function VADProvider({ children }: { children: React.ReactNode }) {
108108
// Refs for VAD instance and state
109109
const vadRef = useRef<MicVAD | null>(null);
110110
const previousTriggeredProbabilityRef = useRef(0);
111-
const previousAiStateRef = useRef<string>('idle');
111+
const previousAiStateRef = useRef<AiState>('idle');
112112

113113
// Persistent state management
114114
const [micOn, setMicOn] = useLocalStorage('micOn', DEFAULT_VAD_STATE.micOn);
@@ -144,7 +144,7 @@ export function VADProvider({ children }: { children: React.ReactNode }) {
144144
// Refs for callback stability
145145
const interruptRef = useRef(interrupt);
146146
const sendAudioPartitionRef = useRef(sendAudioPartition);
147-
const aiStateRef = useRef<string>(aiState);
147+
const aiStateRef = useRef<AiState>(aiState);
148148
const setSubtitleTextRef = useRef(setSubtitleText);
149149
const setAiStateRef = useRef(setAiState);
150150

@@ -195,21 +195,25 @@ export function VADProvider({ children }: { children: React.ReactNode }) {
195195
* Handle speech start event (initial detection)
196196
*/
197197
const handleSpeechStart = useCallback(() => {
198-
console.log('Speech started - entering listening state');
199-
// Save current AI state before changing to listening
198+
console.log('Speech started - saving current state');
199+
// Save current AI state but DON'T change to listening yet
200200
previousAiStateRef.current = aiStateRef.current;
201201
isProcessingRef.current = true;
202-
setAiStateRef.current('listening');
202+
// Don't change state here - wait for onSpeechRealStart
203203
}, []);
204204

205205
/**
206206
* Handle real speech start event (confirmed speech)
207207
*/
208208
const handleSpeechRealStart = useCallback(() => {
209-
console.log('Real speech confirmed - interrupting AI if needed');
210-
if (aiStateRef.current === 'thinking-speaking') {
209+
console.log('Real speech confirmed - checking if need to interrupt');
210+
// Check if we need to interrupt based on the PREVIOUS state (before speech started)
211+
if (previousAiStateRef.current === 'thinking-speaking') {
212+
console.log('Interrupting AI speech due to user speaking');
211213
interruptRef.current();
212214
}
215+
// Now change to listening state
216+
setAiStateRef.current('listening');
213217
}, []);
214218

215219
/**
@@ -238,6 +242,7 @@ export function VADProvider({ children }: { children: React.ReactNode }) {
238242
setPreviousTriggeredProbability(0);
239243
sendAudioPartitionRef.current(audio);
240244
isProcessingRef.current = false;
245+
setAiStateRef.current("thinking-speaking");
241246
}, []);
242247

243248
/**

0 commit comments

Comments
 (0)