voicebot_flutter 0.4.0
voicebot_flutter: ^0.4.0 copied to clipboard
Drop-in voice and text store assistant for Flutter apps. The same VoiceBot assistant that runs as the web widget, native in your app over WebSocket + PCM16.
0.4.0 #
Optional, themeable UI kit — exported from a separate library so the headless core stays UI-free.
- New
package:voicebot_flutter/ui.dartbarrel (separate fromvoicebot_flutter.dart): import it only if you want the prebuilt widgets; headless apps never pull in Material UI from the core. VoicebotLauncher— turnkey all-in-one: floats aVoiceButtonover every screen via a rootOverlayEntry, manages theChatPanel(open/minimize/close), and owns the client/session lifecycle. Drop it once near the app root. Wires minimize ≠ close (HANDOFF §4): minimize collapses to the launcher and keeps the session alive (noend); close (X) callsendSession()+ tears down. Bot/server end auto-collapses and resets for the next open. Programmaticopen()/minimizePanel()/close()/toggle()via aGlobalKey<VoicebotLauncherState>.VoiceButton— floating circular launcher (FAB) reflecting the live phase from thestatus+audioStatestreams: idle (mic) · connecting (spinner) · listening (animated pulse ring) · speaking (accent). Themeable size/position/colors/elevation/icon. Exported standalone for custom layouts.ChatPanel— the assistant window: header (title + minimize + close), scrollable transcript (user vs bot bubbles, live streaming partials with the partial-replace rule), footer (multiline text input + send + mic toggle/mute). Animated slide-up + fade; respects safe area + keyboard insets. Exported standalone.VoicebotTheme— sensible defaults that blend with the ambient MaterialColorScheme(override any field),copyWith, and aVoicebotThemeProviderinherited widget.VoicebotLabelsholds every user-facing string (localizable — nothing hardcoded in the widgets). The kit is fully replaceable: every widget binds only to the publicVoicebotSessionstreams.- Example rewritten: a mock storefront with the floating
VoicebotLauncheras the primary demo (tool handlers + deep links + live context wired viaonClientReady/onSessionStarted); headless usage still available via the core API. - Pure Dart/Flutter (
material/widgetsonly) — no new deps, no native code; the android/iOS compile gates are untouched.dart analyze --fatal-infosclean; widget tests added forVoiceButton/ChatPanel/VoicebotLauncher(minimize-keeps-alive vs close-sends-end). - Cross-SDK parity: this UI model (
VoicebotLauncher/VoiceButton/ChatPanel/VoicebotTheme) is the shared spec the RN SDK mirrors so docs describe one model.
0.3.0 #
Native audio device-readiness (VOIC-46) — the voice path is completed for real devices.
- iOS:
setPreferredIOBufferDuration(0.02)to hold capture→WS-frame latency within the ≤40 ms AC; the interruption handler now honors.shouldResumeand restarts the engine/tap after a call/Siri; route changes rebuild theAVAudioConverteragainst the new input format (Bluetooth/wired headset) so capture doesn't silently garble. - Android:
OnAudioFocusChangeListenerpauses the mic uplink + playback on incoming call / focus loss and auto-resumes on gain — gated by a separatefocusPausedflag so a user-initiated mute is preserved;AudioDeviceCallbackre-assertsMODE_IN_COMMUNICATIONon BT/headset connect/disconnect. - Self-VAD / speakerphone: corrected the false "avoided by WS choice" note — the mitigation is hardware AEC (already enabled,
.voiceChat/MODE_IN_COMMUNICATION+AcousticEchoCanceler); documented as a device-dependent known limitation. - CI: added
android-build(flutter build apk) andios-build(flutter build ios --no-codesign) jobs — the native modules now compile on every push (the Android module had never been compiled before). - Synced the iOS podspec version to the package version.
- Open: physical-device test matrix (iOS 16+ / Android 24+) is the only remaining VOIC-46 AC — the native code compiles in CI, but a hardware run is required to sign off latency / AEC / interruption behavior.
0.2.1 #
CI/CD + pub.dev OIDC automated publishing; pubspec metadata (homepage/repository) + api base -> api.monoverse.tech.
Store compliance (VOIC-52 / T9).
- Added
docs/STORE_SUBMISSION.md— copy-paste App Store + Play Store checklist for merchants embedding the SDK (mic string, privacy manifest, Apple 5.1.2 third-party-AI disclosure, export/encryption, RECORD_AUDIO, Play Data safety, GenAI policy, foreground-only note). ios/Resources/PrivacyInfo.xcprivacynow declaresNSPrivacyCollectedDataTypeAudioData(App Functionality, not linked, not tracking). Native code audited: no required-reason APIs used (flutter_secure_storageuses the Keychain, which is not a required-reason API and ships its own manifest), soNSPrivacyAccessedAPITypesstays empty. README + example mic string aligned to the third-party-AI disclosure.
0.2.0 #
Auth model corrected to web-parity + Mode B + context enrichment (VOIC-44 / VOIC-49).
- Auth (breaking):
MobileIssueTokenProvider(Mode A) now signs with the EXACT PROTOCOL §1 canonical preimageHMAC_SHA256(secret, "{METHOD}\n{path}\n{ts}\n{nonce}\n{sha256hex(body)}").hex()and sendsX-VoiceBot-{Tenant-Id,Timestamp,Nonce,Signature}+X-VoiceBot-App-Id(timestamp = epoch seconds). The default signer is now the real HMAC-SHA256 (cryptoadded as a direct dep); still injectable for hardware-key delegation.AppCredentialreshaped to{tenantId, appId, sharedSecret}(mirror the web key).JsonPoster.bodyis nowList<int>(raw signed bytes). - Auth — Mode B: new
PublishableKeyTokenProvidercallingPOST /api/v1/mobile/issue-token-publicwith{api_key:"vb_pk_…", app_id, attestation?, lang?}. - Context enrichment (no backend change):
session.updateContext(AppContext)→client_contextframe andsession.sendCartEvent(CartEvent)→cart_eventframe (PROTOCOL §10). New zero-PIIAppContext(screen/route/product/category/locale/custom) andCartEvent/CartLineItemtypes. Retained context auto-re-sends on resume. - New exported HMAC helpers:
buildSignaturePreimage,computeSignature,defaultHmacSigner,IssueTokenSigner. - README rewritten into a full SDK landing page; tests expanded to 55.
0.1.0 #
First milestone (VOIC-43 / VOIC-44 / VOIC-46 / VOIC-48): headless core + text path
- native-audio scaffolding.
- Headless core:
VoicebotClient.init,VoicebotSessionsealed state machine (connecting → ready → streaming → reconnecting → ended/failed). WsTransportported from the web widgetws-client.ts: exponential backoff, ~25s heartbeat ping, fatal-close-code set{4400, 4401, 4403, 4503, 1008, 1011}, reconnect capped at 3 attempts (VOIC-44 AC).- Protocol codec for all
docs/PROTOCOL.mdenvelopes (user_text,action_ack, binary uplink;ready/session_state/transcript/turn_complete/barge_in/tool_call/action/errorinbound). ToolHandlerRegistrywithregisterToolHandler+registerDeepLinkMap; unregistered tool auto-replies{success: false, error: "no_handler"}.AudioSourceengine-agnostic PCM16 in/out interface (VOIC-44 boundary) plus a nativePlatformAudioSourcebacked by AVAudioEngine (iOS) / AudioRecord (Android).- Lifecycle:
minimize()(UI-only, keeps WS) vsendSession()(sendsend, tears down). - Stream-based events: transcripts, audio state, tool calls, actions, status, errors.
- Native scaffolding: iOS Swift (AVAudioEngine + AVAudioConverter +
.voiceChatAEC, 24 kHz scheduled-buffer playback, interruption/route observers) and Android Kotlin (AudioRecordVOICE_COMMUNICATION+ AcousticEchoCanceler, AudioTrack 24 kHz, audio-focus/device callbacks). Device-tuning TODOs marked inline.