Jarvis AI Voice Assistant
Jarvis AI Voice Assistant Module
The Jarvis module (lib/features/jarvis/) provides hands-free conversational voice assistance and operational automation within PLANOVI. It allows users to ask questions regarding energy yields, create calendar appointments, search cooperative documentation, and set up reminders using natural language speech or chat.
Architecture & Data Flow
Jarvis uses a hybrid client/edge architecture. Microphone capture and text-to-speech rendering occur natively on the Flutter client, while NLP intent parsing, LLM generation, and database queries execute inside a serverless Supabase Edge Function (supabase/functions/jarvis/).
sequenceDiagram
autonumber
actor User
participant App as JarvisVoiceScreen
participant Rec as "VoiceRecorderProvider (record)"
participant API as JarvisApiService
participant Edge as "Supabase Edge Function (/jarvis)"
participant LLM as "OpenAI / AI Model"
participant DB as Postgres Database
participant TTS as "JarvisTtsService (flutter_tts)"
User->>App: Press & hold microphone button
App->>Rec: startRecording()
User->>App: Speaks command ("Jaki mamy stan magazynu energii?")
User->>App: Release microphone button
App->>Rec: stopRecording() -> yields audioPath (.m4a/.aac)
App->>API: sendToJarvis(audioPath, userTimezone, requiresAudio=true)
API->>Edge: POST multipart/form-data with Bearer Token
Edge->>LLM: Speech-To-Text / Whisper Transcription
Edge->>DB: Query tenant energy telemetry & balance
Edge->>LLM: Formulate contextual response
Edge-->>API: JSON Response (text, audio_url, pending_action, reminder_data)
API-->>App: ChatMessage added to JarvisChatProvider
App->>TTS: Play synthesized speech response
TTS-->>User: Audio playback + animated UI waveform
File Structure & Responsibilities
lib/features/jarvis/├── models/│ └── chat_message.dart # Data model for user/assistant messages & actions├── providers/│ ├── jarvis_chat_provider.dart # Manages active conversation, streaming & actions│ └── voice_recorder_provider.dart # Audio recording lifecycle, amplitude meters├── screens/│ ├── jarvis_screen.dart # Standard chat interface view│ ├── jarvis_voice_screen.dart # Immersive fullscreen voice assistant UI│ └── jarvis_settings_screen.dart # Voice speed, pitch, language & AI parameters├── services/│ ├── jarvis_api_service.dart # HTTP/Multipart client calling /functions/v1/jarvis│ ├── jarvis_document_service.dart # Auto-generates summary documents from queries│ ├── jarvis_tts_service.dart # Text-To-Speech wrapper using flutter_tts│ ├── offer_pdf_service.dart # Generates PDF quotes from assistant recommendations│ └── reminder_service.dart # Background timer triggers and alarm player├── theme/│ └── jarvis_colors.dart # Futuristic cyan/neon dark styling tokens└── widgets/ ├── chat/ # Chat bubble widgets, bottom input, quick actions └── waveform_visualizer.dart # Real-time microphone audio visualizerKey Components
1. JarvisApiService
- Located at:
lib/features/jarvis/services/jarvis_api_service.dart - Handles authentication with Supabase:
- Automatically checks
currentSession.isExpiredand invokes_supabase.auth.refreshSession()before calling edge endpoints. - Dispatches
multipart/form-datawhen an audio recording file is provided. - Dispatches standard
application/jsonwhen sending typed text queries.
- Automatically checks
- Parameters transmitted:
company_id: Active tenant identifier for RLS enforcement.user_timezone: e.g.,Europe/Warsaw, ensuring accurate relative calendar scheduling.requires_audio: Whether the client requests pre-synthesized audio back from the backend.calendar_save_pref: User preference for internal vs Google Calendar storage.
2. VoiceRecorderProvider
- Uses the
recordpackage to capture microphone audio. - Emits real-time amplitude values (
getAmplitude()) consumed byWaveformVisualizerto render interactive speech waves. - Produces compressed M4A/AAC files saved to the temporary application directory.
3. JarvisTtsService
- Configures
flutter_ttsfor responsive local audio synthesis:- Default language:
pl-PL(Polish), falling back toen-US. - Controls speech rate, pitch, and audio ducking so ambient sounds don’t collide.
- Default language:
4. ReminderService
- Listens for timed notifications returned in assistant payloads.
- Uses
audioplayersto trigger audible chime tones and displays modal alerts when scheduled reminders trigger.
Intent Actions & Interactive Payloads
When Jarvis determines that a user’s prompt requires a platform action (e.g. creating a meeting, adding an energy device, or submitting a vote), the Edge Function returns a pending_action dictionary.
graph LR
Intent[NLP Intent Detected] --> Action{Requires Confirmation?}
Action -->|Yes| Prompt[Render Confirmation Card in Chat]
Action -->|No| DirectExec[Execute Database Mutation]
Prompt --> UserConfirm[User Clicks 'Zatwierdź']
UserConfirm --> API_Execute[API Dispatches Confirmed Action]
API_Execute --> DB[(Postgres Database)]
Examples of supported pending_action intents:
schedule_meeting: Prepopulates title, start/end timestamps, and participant emails into the Scheduler module.device_power_limit: Submits a power limitation command to an active inverter viaDeviceControlProvider.generate_report: Triggers thegenerate-reportedge function and downloads the generated PDF.
Troubleshooting & Support Guide
1. Microphone Permission Denied
- Symptom: User taps the microphone, but recording immediately aborts or throws
RecordException. - Remedy:
- Android: Verify
RECORD_AUDIOpermission is declared inAndroidManifest.xmland granted in App Settings. - iOS: Check
NSMicrophoneUsageDescriptioninInfo.plist. - Web: Ensure the browser was accessed over
https://(browsers block microphone APIs on insecure HTTP origins).
- Android: Verify
2. “Brak aktywnej sesji” / Session Expired
- Symptom: Red snackbar indicating missing or expired session.
- Remedy: The JWT token could not be automatically refreshed. The user should log out and log back in to clear invalid cached credentials in
FlutterSecureStorage.
3. Edge Function 504 Timeout
- Symptom: Chat shows indefinite loading spinner or
Function timeouterror. - Remedy: Complex queries involving large PDF context analysis may exceed Deno’s 60-second limit. Advise users to narrow down specific queries or check Edge Function logs in the Supabase Dashboard.