Files
smart-home-tablet/lib/debug.ts
Cosmo 05b300d472
All checks were successful
Deploy / deploy (push) Successful in 1m47s
chore(voice): security, cleanup, resilience
Безопасность:
- 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 не примонтирован
  (локальная разработка / нестандартная конфигурация).
2026-04-27 12:44:18 +00:00

37 lines
1.3 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* Гейт для браузерных дебаг-логов голосового стека.
*
* Production: логи молчат. Чтобы включить — выставить
* `NEXT_PUBLIC_VOICE_DEBUG=1` в env (на этапе билда). На клиенте
* также можно временно включить `localStorage.setItem('voice-debug', '1')`.
*
* Серверные логи (`/api/voice/chat`, `/api/voice/stt`) НЕ пропускаются
* через эту функцию — они полезны в Docker logs и не утекают в браузер.
*/
const ENV_ENABLED = process.env.NEXT_PUBLIC_VOICE_DEBUG === '1'
function runtimeEnabled(): boolean {
if (ENV_ENABLED) return true
if (typeof window === 'undefined') return false
try {
return window.localStorage?.getItem('voice-debug') === '1'
} catch {
return false
}
}
export function vlog(...args: any[]): void {
if (runtimeEnabled()) console.log(...args)
}
export function vwarn(...args: any[]): void {
// Warnings оставляем всегда — это анонимные ошибки, не PII.
console.warn(...args)
}
export function verror(...args: any[]): void {
// Errors всегда — нам нужно знать о реальных падениях.
console.error(...args)
}