Vanira Flutter SDK — Scaffold
Status: Scaffold only. The protocol and session class are defined. Full implementation requires wiring
flutter_webrtcintoVaniraSession.
Architecture
The Flutter SDK mirrors the TypeScript SDK's core layer exactly. The signaling protocol, DataChannel event schema, and state machine are identical. Only the runtime (Dart vs JavaScript) and platform APIs differ.
flutter-sdk/
lib/
src/
vanira_session.dart ← Core session — mirrors TypeScript WebRTCClient
vanira_sdk.dart ← Public export
pubspec.yaml
README.md
TypeScript → Dart mapping
| TypeScript (npm SDK) | Dart (Flutter SDK) |
|---|---|
new RTCPeerConnection(config) |
createPeerConnection(config) (flutter_webrtc) |
navigator.mediaDevices.getUserMedia() |
navigator.mediaDevices.getUserMedia() (flutter_webrtc) |
pc.createDataChannel('control', {}) |
pc.createDataChannel('control', RTCDataChannelInit()) |
pc.createOffer() |
await pc.createOffer({}) |
pc.setLocalDescription(offer) |
await pc.setLocalDescription(offer) |
pc.setRemoteDescription(answer) |
await pc.setRemoteDescription(...) |
pc.onConnectionState = handler |
pc.onConnectionState.listen(handler) |
pc.onIceGatheringState listener |
pc.onIceGatheringState.listen(handler) |
fetch(url, { method: 'POST', ... }) |
http.post(Uri.parse(url), body: jsonEncode(...)) |
JSON.stringify / JSON.parse |
jsonEncode / jsonDecode (dart:convert) |
new Audio() + srcObject |
Not needed — flutter_webrtc routes audio automatically |
setTimeout(fn, 5000) |
Future.delayed(const Duration(seconds: 5), fn) |
Promise / async-await |
Future / async-await (same pattern) |
onConnected callback |
VoidCallback / Function() |
onTranscription callback |
Function(String text, bool isFinal) |
DataChannel protocol
The event schema is identical to the browser/RN SDK. Dart's jsonDecode
produces Map<String, dynamic> which maps directly to the TypeScript interface.
Server → client events
| event | payload fields | action |
|---|---|---|
clearAudio |
— | No-op (flutter_webrtc manages audio) |
transcription |
text, isFinal |
Call onTranscription(text, isFinal) |
mark |
name |
Log only |
client_tool_call |
tool_call_id, name, arguments |
Send ack immediately, call onClientToolCall |
Client → server events
| method | event name | payload |
|---|---|---|
sendToolResult(id, res) |
client_tool_result |
{ call_id, result } |
sendContextUpdate(ctx) |
client_context_update |
{ data: { context } } |
sendActionTrigger(name) |
client_action_trigger |
{ data: { action_name, data } } |
triggerActionInterrupt() |
action_interrupt |
— |
Implementation steps
1. Add dependencies to pubspec.yaml
dependencies:
flutter_webrtc: ^0.9.0
http: ^1.2.0
permission_handler: ^11.0.0
2. Request microphone permission
import 'package:permission_handler/permission_handler.dart';
await Permission.microphone.request();
3. Register globals (Android / iOS)
// In main.dart before runApp()
import 'package:flutter_webrtc/flutter_webrtc.dart';
// No explicit registerGlobals() needed in flutter_webrtc >= 0.9
// flutter_webrtc auto-initializes on first API call
4. Wire VaniraSession.connect()
Uncomment and implement all TODO blocks in lib/src/vanira_session.dart.
Each TODO maps to a numbered step in the TypeScript SDK's connect() method.
5. HTTP signaling (already portable)
The signaling endpoint and JSON body are identical to the TypeScript SDK:
final response = await http.post(
Uri.parse('$serverUrl/webrtc?agent=${agentId}_$callId'),
headers: {'Content-Type': 'application/json'},
body: jsonEncode({
'offer': offer.toMap(),
'agentId': agentId,
'callId': callId,
}),
);
final answer = jsonDecode(response.body)['answer'];
6. Distribution
Publish to pub.flutter-io.cn as vanira_sdk:
name: vanira_sdk
version: 0.0.1
homepage: https://vanira.io
repository: https://github.com/vanira-ai/flutter-sdk
Known differences from browser/RN SDK
| Topic | Browser / RN | Flutter |
|---|---|---|
| Audio output | new Audio() / native stack |
Automatic via flutter_webrtc |
playedStream event |
Sent when audio.onended fires |
Never sent — no onended equiv. |
| Screen share | Browser: getDisplayMedia(); RN: N/A |
N/A — not supported |
| CDN distribution | <script> tag via unpkg |
flutter pub add vanira_sdk |
| Widget | <vanira-convai> custom element |
Flutter StatefulWidget |
| State management | React hooks / Redux | Riverpod / Provider / setState |
| Env vars | import.meta.env.VITE_* |
flutter_dotenv or const String.fromEnvironment |
Libraries
- vanira_sdk
- Vanira Voice AI — Flutter SDK (local
vanira-sdk/flutter-sdk).