chore(voice): security, cleanup, resilience
All checks were successful
Deploy / deploy (push) Successful in 1m47s
All checks were successful
Deploy / deploy (push) Successful in 1m47s
Безопасность: - Rate-limit на /api/voice/chat (20/мин per cookie/IP, env VOICE_RATE_LIMIT). Защищает от случайных циклов и утечки PIN. - Усечение user prompt'а до 4000 символов в /api/voice/chat. - Tool-loop защита от циклов: если LLM дважды просит тот же tool с теми же args — прерываем (раньше мог уйти в бесконечный цикл при tool error'ах). Чистка кода: - lib/debug.ts — vlog/vwarn/verror гейтят браузерные логи за NEXT_PUBLIC_VOICE_DEBUG=1 (или localStorage 'voice-debug=1'). Серверные console.log оставлены — полезны в Docker logs. - lib/audio-wav.ts — вынесена дублированная floatToWav из VoiceController. - Удалены orphan компоненты FocusCard.tsx и CountdownCard.tsx (не подключены, отвергнуты по UX-фидбеку). Resilience: - WakeWordDetector: drop-on-busy в onChunk — на медленных устройствах (Android, бюджетный CPU) backlog inference больше не копится. - voice-history fallback на /tmp/voice-history если /data не примонтирован (локальная разработка / нестандартная конфигурация).
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
import { useEffect, useRef, useState } from 'react'
|
||||
import { motion, AnimatePresence } from 'framer-motion'
|
||||
import { X } from 'lucide-react'
|
||||
import { vwarn } from '@/lib/debug'
|
||||
|
||||
type VoiceState = 'idle' | 'wake' | 'listening' | 'command' | 'response' | 'error'
|
||||
type Agent = 'cosmo' | 'lusya'
|
||||
@@ -112,7 +113,7 @@ export default function VoiceOverlay() {
|
||||
source.start()
|
||||
return
|
||||
} catch (e: any) {
|
||||
console.warn('[voice] AudioContext playback failed, fallback to <audio>:', e?.message || e)
|
||||
vwarn('[voice] AudioContext playback failed, fallback to <audio>:', e?.message || e)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -133,7 +134,7 @@ export default function VoiceOverlay() {
|
||||
try {
|
||||
await audio.play()
|
||||
} catch (e: any) {
|
||||
console.warn('[voice] audio.play() rejected:', e?.name || e?.message || e)
|
||||
vwarn('[voice] audio.play() rejected:', e?.name || e?.message || e)
|
||||
finish()
|
||||
}
|
||||
} catch {
|
||||
|
||||
Reference in New Issue
Block a user