Fix voice input for iOS Safari and prevent infinite loop
Some checks failed
CI/CD Pipeline / Lint and Test (push) Has been cancelled
CI/CD Pipeline / E2E Tests (push) Has been cancelled
CI/CD Pipeline / Build Application (push) Has been cancelled

- Remove temperature parameter from GPT-5-mini activity extraction (not supported)
- Add classification state to useVoiceInput hook to avoid duplicate API calls
- Prevent infinite loop in VoiceFloatingButton by tracking lastClassifiedTranscript
- Use classification from backend directly instead of making second request
- iOS Safari now successfully transcribes with Azure Whisper and classifies with GPT-5-mini

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-10-02 07:15:44 +00:00
parent 46167a8307
commit a44faf6ef4
4 changed files with 72 additions and 14 deletions

View File

@@ -33,6 +33,7 @@ export function VoiceFloatingButton() {
const [open, setOpen] = useState(false);
const [isProcessing, setIsProcessing] = useState(false);
const [classificationResult, setClassificationResult] = useState<any>(null);
const [lastClassifiedTranscript, setLastClassifiedTranscript] = useState<string>('');
const [snackbar, setSnackbar] = useState<{
open: boolean;
message: string;
@@ -43,15 +44,16 @@ export function VoiceFloatingButton() {
severity: 'info',
});
const { isListening, isSupported, transcript, error, startListening, stopListening, reset } =
const { isListening, isSupported, transcript, classification, error, startListening, stopListening, reset } =
useVoiceInput();
// Auto-classify when we get a final transcript
// Auto-use classification from backend when transcription completes
React.useEffect(() => {
if (transcript && !isListening && !isProcessing && open) {
classifyTranscript(transcript);
if (classification && !isListening && !isProcessing && open) {
setClassificationResult(classification);
handleClassifiedIntent(classification);
}
}, [transcript, isListening, isProcessing, open]);
}, [classification, isListening, isProcessing, open]);
const handleOpen = () => {
if (!isSupported) {
@@ -65,6 +67,7 @@ export function VoiceFloatingButton() {
setOpen(true);
reset();
setClassificationResult(null);
setLastClassifiedTranscript('');
};
const handleClose = () => {
@@ -74,11 +77,13 @@ export function VoiceFloatingButton() {
setOpen(false);
reset();
setClassificationResult(null);
setLastClassifiedTranscript('');
};
const handleStartListening = () => {
reset();
setClassificationResult(null);
setLastClassifiedTranscript('');
startListening();
};
@@ -87,6 +92,8 @@ export function VoiceFloatingButton() {
};
const classifyTranscript = async (text: string) => {
// Mark this transcript as being classified to prevent duplicate calls
setLastClassifiedTranscript(text);
setIsProcessing(true);
try {
const response = await fetch('/api/voice/transcribe', {