28 Commits

Author SHA1 Message Date
4bcb1f70c5 Stop voice session when app goes to background
User feedback: voice session should stop when leaving app or locking screen.

Previously:
- App goes to background → session stays active (broken state)
- STT/TTS cannot work in background anyway
- Wasted battery, confusing UX

Now:
- background/inactive → automatically stops session
- Cleans up all state (STT, refs, pending transcripts)
- User must manually restart via FAB when returning

Behavior:
User locks screen → session stops → FAB becomes gray
User switches app → session stops → clean state
User returns → must press FAB to start new session

app/(tabs)/_layout.tsx:238-256
2026-01-28 20:10:23 -08:00
e695b08561 Reduce STT restart delay from 800ms to 300ms
Makes voice conversation feel much more responsive.
The 800ms delay was overkill - 300ms is sufficient for TTS audio to release.
2026-01-28 20:01:13 -08:00
c026921278 Hide Debug tab from navigation bar 2026-01-28 19:58:28 -08:00
d6353c8533 2026-01-29: Stable version with voice debug and iOS STT fix
Добавлено:
- Voice Debug tab - real-time логи STT/API/TTS/Timer
- iOS STT fix - отправка последнего partial как final при onEnd
- iOS auto-stop - автоматическая остановка STT после 2s тишины
- Voice API selector в Profile (voice_ask / ask_wellnuo_ai)

Исправлено:
- iOS никогда не отправлял isFinal:true - теперь отправляет через onEnd
- STT не останавливался после тишины - добавлен auto-stop таймер
- Profile Voice API selector восстановлен после rollback

Известные issues:
- TypeScript ошибки (setTimeout type) - не критично
- updateVoiceApiType отсутствует в VoiceContext - нужно добавить

Стабильная версия для тестирования на iPhone.
2026-01-28 19:45:40 -08:00
05f872d067 fix: voice session improvements - FAB stop, echo prevention, chat TTS
- FAB button now correctly stops session during speaking/processing states
- Echo prevention: STT stopped during TTS playback, results ignored during speaking
- Chat TTS only speaks when voice session is active (no auto-speak for text chat)
- Session stop now aborts in-flight API requests and prevents race conditions
- STT restarts after TTS with 800ms delay for audio focus release
- Pending interrupt transcript processed after TTS completion
- ChatContext added for message persistence across tab navigation
- VoiceFAB redesigned with state-based animations
- console.error replaced with console.warn across voice pipeline
- no-speech STT errors silenced (normal silence behavior)
2026-01-27 22:59:55 -08:00
3ef1d8e54c Allow user to interrupt Julia voice by speaking
- Enable STT listening during TTS playback to detect user interruption
- When voice detected during Julia's speech, immediately stop TTS
- Store interrupted transcript and process it after TTS stops
- Remove 'speaking' status check from STT watchdog to allow parallel STT+TTS
- Add pending transcript mechanism to handle race condition between
  TTS stop and STT final result

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

Co-Authored-By: Claude <noreply@anthropic.com>
2026-01-27 16:49:19 -08:00
bdb4ceb8d2 Preserve voice session across tab navigation
Add watchdog mechanism to ensure STT continues when switching tabs:
- Monitor STT state every 500ms and restart if session active but STT stopped
- Handle AppState changes to restart STT when app returns to foreground
- Prevents session interruption due to native audio session changes

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

Co-Authored-By: Claude <noreply@anthropic.com>
2026-01-27 16:47:27 -08:00
5efd696ef2 Auto-restart STT after TTS finishes speaking
Adds logic to detect when voice status transitions from 'speaking' to
'listening' and automatically restarts the speech recognition. This
enables continuous voice conversation flow - after Julia speaks her
response, the app immediately starts listening for the next user input.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2026-01-27 16:43:53 -08:00
8f64a6e6af Change STT language from English to Russian (ru-RU)
🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2026-01-27 16:37:38 -08:00
59f1f088ed Keep STT listening during TTS playback for interruption detection
- Add sessionActiveRef to track when voice session is active
- Add shouldRestartSTTRef to auto-restart STT after it ends
- STT now continues listening during TTS playback
- Voice detection callback checks both status and isSpeaking
- Final results during TTS are ignored (user interrupted)
- STT automatically restarts after ending if session is still active

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

Co-Authored-By: Claude <noreply@anthropic.com>
2026-01-27 16:36:08 -08:00
3c7a48df5b Integrate TTS interruption in VoiceFAB when voice detected
- Add onVoiceDetected callback to useSpeechRecognition hook
  - Triggered on first interim result (voice activity detected)
  - Uses voiceDetectedRef to ensure callback fires only once per session
  - Reset flag on session start/end

- Connect STT to VoiceContext in _layout.tsx
  - Use useSpeechRecognition with onVoiceDetected callback
  - Call interruptIfSpeaking() when voice detected during 'speaking' state
  - Forward STT results to VoiceContext (setTranscript, sendTranscript)
  - Start/stop STT based on isListening state

- Export interruptIfSpeaking from VoiceContext provider

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

Co-Authored-By: Claude <noreply@anthropic.com>
2026-01-27 16:34:07 -08:00
764c149e2e Add toggle listening mode on VoiceFAB tap
- FAB now toggles between idle and listening states
- Green background (idle) → Red background (listening)
- Icon switches between mic-outline and mic
- Connects to VoiceContext for state management

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

Co-Authored-By: Claude <noreply@anthropic.com>
2026-01-27 16:30:20 -08:00
356205d8c0 Remove LiveKit SDK and related code
- Remove @livekit/react-native-expo-plugin from app.json
- Remove @config-plugins/react-native-webrtc plugin
- Delete utils/audioSession.ts (depended on LiveKit AudioSession)
- Update VoiceCallContext.tsx comments
- Update callManager.ts comments
- Update _layout.tsx TODO comment
- Remove LiveKit documentation files
- Add interruptIfSpeaking to VoiceContext for TTS interrupt

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

Co-Authored-By: Claude <noreply@anthropic.com>
2026-01-27 16:28:23 -08:00
9b4d39fdc5 Integrate VoiceFAB into tabs layout
Add floating action button for voice calls to the tab bar layout:
- Import and render VoiceFAB component
- Add placeholder handler for voice call initiation
- Wrap Tabs in View to properly position FAB overlay
- FAB automatically hides when a call is active (via VoiceCallContext)

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

Co-Authored-By: Claude <noreply@anthropic.com>
2026-01-27 16:25:35 -08:00
Sergei
ef533de4d5 Fix Android audio to use speaker instead of earpiece
- Configure LiveKit Expo plugin with audioType: "media" in app.json
  This forces speaker output on Android instead of earpiece
- Remove microphone icon from voice messages in chat
- Remove audio output picker button (no longer needed)
- Clean up audioSession.ts configuration

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

Co-Authored-By: Claude <noreply@anthropic.com>
2026-01-26 14:02:27 -08:00
Sergei
5d2e8c029f fix: Prevent tab bar from being overlapped by Android navigation buttons
- Add SafeAreaProvider wrapper in root layout for reliable insets on Android
- Add minimum 16px bottom padding on Android to prevent overlap with
  gesture navigation or software buttons (Samsung, Pixel, etc.)
- Keep 10px minimum for other platforms

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

Co-Authored-By: Claude <noreply@anthropic.com>
2026-01-24 20:59:49 -08:00
Sergei
06ab4722e5 feat: Remove Debug (Voice) tab from navigation
- Delete voice.tsx debug screen file
- Remove voice tab configuration from tabs layout

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

Co-Authored-By: Claude <noreply@anthropic.com>
2026-01-24 20:52:58 -08:00
Sergei
513d9c3c7d fix: Use safe area insets for tab bar to avoid Samsung nav button overlap
Use useSafeAreaInsets() to dynamically calculate tab bar height and bottom
padding instead of hardcoded values. This ensures the tab bar properly
accounts for Android navigation buttons (Samsung) and iOS home indicator.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2026-01-24 20:33:59 -08:00
Sergei
a23116a796 Remove Debug tab completely
- Remove debug screen from tab navigator
- Delete app/(tabs)/debug.tsx file

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

Co-Authored-By: Claude <noreply@anthropic.com>
2026-01-24 20:14:33 -08:00
Sergei
204cb87f05 Fix voice call race condition - ensure beneficiaryData is passed
- Fix race condition where connect() was called before beneficiaryData loaded
- Add connectCalledRef to prevent duplicate connect calls
- Wait for beneficiaryData.deploymentId before initiating call
- Add 5s timeout fallback for edge cases (API failure/no beneficiaries)
- Hide Debug tab, show only Julia tab in navigation
- Add Android keyboard layout fix for password fields
- Bump version to 1.0.5

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

Co-Authored-By: Claude <noreply@anthropic.com>
2026-01-21 14:30:59 -08:00
Sergei
e3192ead12 Voice call improvements: single call limit, hide debug tab, remove speaker toggle
Changes:
- Add CallManager singleton to ensure only 1 call per device at a time
- Hide Debug tab from production (href: null)
- Remove speaker/earpiece toggle button (always use speaker)
- Agent uses voice_ask API (fast ~1 sec latency)

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

Co-Authored-By: Claude <noreply@anthropic.com>
2026-01-19 23:55:27 -08:00
Sergei
57577b42c9 Fix Android audio routing - use music stream for speaker output
- Changed audioStreamType from 'voiceCall' to 'music' on Android
  - voiceCall stream defaults to earpiece
  - music stream defaults to speaker
- Added Debug tab to test voice calls with detailed logs
- Added speaker/earpiece toggle button with proper stream switching
- Full Android AudioSession support for LiveKit voice calls

audioSession.ts:
- configureAudioForVoiceCall: uses music/media for speaker output
- setAudioOutput: switches between music (speaker) and voiceCall (earpiece)
- reconfigureAudioForPlayback: ensures speaker output on Android

debug.tsx:
- Added platform info display
- Added speaker toggle with logging
- Improved UI with control rows
2026-01-19 22:54:59 -08:00
Sergei
cd9dddda34 Add Chat tab with Julia AI + voice call improvements
- Enable Chat tab (replace Debug) - text chat with Julia AI
- Add voice call button in chat header and input area
- Add speaker/earpiece toggle in voice-call screen
- setAudioOutput() function for switching audio output
2026-01-18 22:00:26 -08:00
Sergei
059bc29b6b WIP: LiveKit voice call integration with Julia AI agent
NOT TESTED ON REAL DEVICE - simulator only verification

Components:
- LiveKit Cloud agent deployment (julia-agent/julia-ai/)
- React Native LiveKit client (hooks/useLiveKitRoom.ts)
- Voice call screen with audio session management
- WellNuo voice_ask API integration in Python agent

Tech stack:
- LiveKit Cloud for agent hosting
- @livekit/react-native SDK
- Deepgram STT/TTS (via LiveKit Cloud)
- Silero VAD for voice activity detection

Known issues:
- Microphone permissions may need manual testing on real device
- LiveKit audio playback not verified on physical hardware
- Agent greeting audio not confirmed working end-to-end

Next steps:
- Test on physical iOS device
- Verify microphone capture works
- Confirm TTS audio playback
- Test full conversation loop
2026-01-18 20:16:25 -08:00
Sergei
dde0ecb9cd Add Julia AI voice agent with LiveKit integration
Voice AI Features:
- LiveKit Agents integration for real-time voice calls
- Julia AI agent (Python) deployed to LiveKit Cloud
- Token server for authentication
- Debug screen with voice call testing
- Voice call screen with full-screen UI

Agent Configuration:
- STT: Deepgram Nova-2
- LLM: OpenAI GPT-4o
- TTS: Deepgram Aura Asteria (female voice)
- Turn Detection: LiveKit Multilingual Model
- VAD: Silero
- Noise Cancellation: LiveKit BVC

Files added:
- julia-agent/ - Complete agent code and token server
- app/voice-call.tsx - Full-screen voice call UI
- services/livekitService.ts - LiveKit client service
- contexts/VoiceTranscriptContext.tsx - Transcript state
- polyfills/livekit-globals.ts - WebRTC polyfills

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

Co-Authored-By: Claude <noreply@anthropic.com>
2026-01-17 17:58:31 -08:00
Sergei
c1380b55dd Add unified assistant with Ultravox voice AI
Chat screen now supports both:
- Text messaging (keyboard input)
- High-quality Ultravox voice calls (WebRTC)

Features:
- Voice call button in input bar (phone icon)
- Green status bar when call is active
- Transcripts from voice calls appear in chat history
- Voice badge on messages from voice conversation
- Mute button during calls
- Auto-end call when leaving screen

Background audio configured for iOS (audio, voip modes)
2026-01-16 12:20:17 -08:00
Sergei
da2c4bebc9 Integrate voice chat with TTS and speech recognition
App screens:
- chat.tsx: Voice-enabled chat with TTS responses
- debug.tsx: TTS debugging and testing screen
- index.tsx: Updated home with voice indicators
- _layout.tsx: Added TTS and error boundaries

Config:
- app.json: Microphone permissions for voice input
- package.json: Added Sherpa ONNX dependencies
- constants/theme.ts: Voice UI colors

Features:
- Voice input via speech recognition
- TTS voice output for chat responses
- Real-time voice activity indication
- Debug screen for TTS testing
- Error boundaries for stability

User experience:
- Hands-free chat interaction
- Visual feedback during voice processing
- Graceful error handling
2026-01-14 19:09:50 -08:00
Sergei
8bc9649146 WellNuo Lite v1.0.0 - simplified version for App Store review
- Removed voice input features
- Simplified profile page (only legal links and logout)
- Chat with AI context working
- Auto-select first beneficiary
- Dashboard WebView intact

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-24 17:13:13 -08:00