Skip to main content

OTTO Voice Commands

Web Speech API integration for hands-free query input and multilingual intelligence card readout. Runs entirely in the browser — no server-side audio processing.

Features

  • <svg className="w-4 h-4 inline-block align-text-bottom flex-shrink-0" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M12 1a3 3 0 0 0-3 3v8a3 3 0 0 0 6 0V4a3 3 0 0 0-3-3z"/><path d="M19 10v2a7 7 0 0 1-14 0v-2"/><line x1="12" y1="19" x2="12" y2="23"/><line x1="8" y1="23" x2="16" y2="23"/></svg>
    Voice InputSpeechRecognition API — captures query in natural language, sends to OTTO SSE stream on silence detection
  • <svg className="w-4 h-4 inline-block align-text-bottom flex-shrink-0" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><polygon points="11 5 6 9 2 9 2 15 6 15 11 19 11 5"/><path d="M15.54 8.46a5 5 0 0 1 0 7.07"/><path d="M19.07 4.93a10 10 0 0 1 0 14.14"/></svg>
    Voice ReadoutSpeechSynthesis API — reads intelligence card narrative aloud in the detected language
  • <svg className="w-4 h-4 inline-block align-text-bottom flex-shrink-0" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><circle cx="12" cy="12" r="10"/><line x1="2" y1="12" x2="22" y2="12"/><path d="M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z"/></svg>
    11 LanguagesEN FR DE ES IT ZH PT NL PL AR JA — language auto-detected by OTTO NLP engine
  • <svg className="w-4 h-4 inline-block align-text-bottom flex-shrink-0" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><polygon points="13 2 3 14 12 14 11 22 21 10 12 10 13 2"/></svg>
    Zero LatencyNo audio upload to server — browser handles STT/TTS entirely

Browser Support

BrowserSpeechRecognitionSpeechSynthesis
Chrome / Edge<svg className="w-4 h-4 inline-block align-text-bottom flex-shrink-0" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round"><polyline points="20 6 9 17 4 12"/></svg> Full support<svg className="w-4 h-4 inline-block align-text-bottom flex-shrink-0" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round"><polyline points="20 6 9 17 4 12"/></svg> Full support
Safari<svg className="w-4 h-4 inline-block align-text-bottom flex-shrink-0" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round"><polyline points="20 6 9 17 4 12"/></svg> Full support<svg className="w-4 h-4 inline-block align-text-bottom flex-shrink-0" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round"><polyline points="20 6 9 17 4 12"/></svg> Full support
Firefox<svg className="w-4 h-4 inline-block align-text-bottom flex-shrink-0" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg> Not supported<svg className="w-4 h-4 inline-block align-text-bottom flex-shrink-0" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round"><polyline points="20 6 9 17 4 12"/></svg> Supported
Mobile Chrome<svg className="w-4 h-4 inline-block align-text-bottom flex-shrink-0" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round"><polyline points="20 6 9 17 4 12"/></svg> Full support<svg className="w-4 h-4 inline-block align-text-bottom flex-shrink-0" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round"><polyline points="20 6 9 17 4 12"/></svg> Full support

Voice Button Component

// VoiceButton — built into IntelligenceCard.tsx
// Reads the card narrative in the user's detected language
<VoiceButton text={card.narrative} lang={card.language || 'en'} />