sarvamconv_ai_sdk 1.0.1
sarvamconv_ai_sdk: ^1.0.1 copied to clipboard
Flutter SDK for Sarvam Conversational AI - Real-time voice and text interactions
Sarvam Conversational AI SDK for Flutter #
A Flutter SDK for building real-time voice-to-voice and text-based conversational AI applications with Sarvam AI agents.
Features #
- π€ Real-time voice conversations with automatic audio handling
- π¬ Text-based chat interactions
- π Support for 11 Indian languages
- π Proxy server support for secure API key management
- π± iOS and Android support
Installation #
Add to your pubspec.yaml:
dependencies:
sarvamconv_ai_sdk: ^1.0.0
Platform Setup #
iOS - Add to ios/Runner/Info.plist:
<key>NSMicrophoneUsageDescription</key>
<string>This app needs microphone access for voice conversations</string>
Android - Add to android/app/src/main/AndroidManifest.xml:
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.INTERNET" />
Quick Start #
Voice Conversation #
import 'package:sarvamconv_ai_sdk/sarvamconv_ai_sdk.dart';
// 1. Create audio interface
final audioInterface = DefaultAudioInterface(inputSampleRate: 16000);
// 2. Create configuration
final config = InteractionConfig(
orgId: 'your_org_id',
workspaceId: 'your_workspace_id',
appId: 'your_app_id',
userIdentifier: 'user123',
userIdentifierType: UserIdentifierType.custom,
interactionType: InteractionType.call,
sampleRate: 16000,
);
// 3. Create and start agent
final agent = SamvaadAgent(
apiKey: 'your_api_key',
config: config,
audioInterface: audioInterface,
textCallback: (msg) async {
if (msg is ServerTextChunkMsg) {
print('Agent: ${msg.text}');
}
},
eventCallback: (event) async {
if (event is ServerInteractionConnectedEvent) {
print('Connected!');
}
},
);
await agent.start();
await agent.waitForConnect(timeout: Duration(seconds: 10));
// 4. Stop when done
await agent.stop();
Text Conversation #
final config = InteractionConfig(
orgId: 'your_org_id',
workspaceId: 'your_workspace_id',
appId: 'your_app_id',
userIdentifier: 'user@example.com',
userIdentifierType: UserIdentifierType.email,
interactionType: InteractionType.chat, // Use chat for text
sampleRate: 16000,
);
final agent = SamvaadAgent(
apiKey: 'your_api_key',
config: config,
textCallback: (msg) async {
if (msg is ServerTextMsg) {
print('Agent: ${msg.text}');
}
},
);
await agent.start();
await agent.waitForConnect(timeout: Duration(seconds: 10));
// Send text messages
await agent.sendText('Hello, how can you help me?');
// Stop when done
await agent.stop();
Configuration Options #
| Field | Type | Required | Description |
|---|---|---|---|
orgId |
String | Yes | Your organization ID |
workspaceId |
String | Yes | Your workspace ID |
appId |
String | Yes | Your application ID |
userIdentifier |
String | Yes | User identifier (email, phone, or custom) |
userIdentifierType |
UserIdentifierType | Yes | .email, .phoneNumber, .custom, .unknown |
interactionType |
InteractionType | Yes | .call (voice) or .chat (text) |
sampleRate |
int | Yes | Audio sample rate: 8000, 16000, or 48000 |
version |
int? | No | App version (uses latest if not specified) |
initialLanguageName |
SarvamToolLanguageName? | No | Starting language |
agentVariables |
Map? | No | Custom variables for the agent |
Supported Languages #
SarvamToolLanguageName.english // English
SarvamToolLanguageName.hindi // Hindi
SarvamToolLanguageName.bengali // Bengali
SarvamToolLanguageName.tamil // Tamil
SarvamToolLanguageName.telugu // Telugu
SarvamToolLanguageName.marathi // Marathi
SarvamToolLanguageName.gujarati // Gujarati
SarvamToolLanguageName.kannada // Kannada
SarvamToolLanguageName.malayalam // Malayalam
SarvamToolLanguageName.punjabi // Punjabi
SarvamToolLanguageName.odia // Odia
Proxy Server Setup (Production) #
For production apps, hide your API key using a proxy server:
βββββββββββββββββββ βββββββββββββββββββ βββββββββββββββββββ
β Flutter App β βββββββΆ β Proxy Server β βββββββΆ β Sarvam API β
β (No API Key) β β (Adds API Key) β β β
βββββββββββββββββββ βββββββββββββββββββ βββββββββββββββββββ
Flutter Client (with Proxy) #
final agent = SamvaadAgent(
config: config,
// No API key - proxy adds it
baseUrl: 'https://your-proxy-server.com/sarvam-proxy/',
headers: {
'Authorization': 'Bearer user_session_token',
},
audioInterface: DefaultAudioInterface(),
);
Node.js Proxy Server #
const express = require('express');
const { createProxyMiddleware } = require('http-proxy-middleware');
const app = express();
const SARVAM_API_KEY = process.env.SARVAM_API_KEY;
app.use('/sarvam-proxy', createProxyMiddleware({
target: 'https://apps.sarvam.ai/api/app-runtime',
changeOrigin: true,
pathRewrite: { '^/sarvam-proxy': '' },
onProxyReq: (proxyReq, req, res) => {
// Add API key
proxyReq.setHeader('X-API-Key', SARVAM_API_KEY);
// Verify user auth
if (!req.headers['authorization']) {
res.status(401).json({ error: 'Unauthorized' });
return;
}
},
}));
app.listen(3000);
Python Proxy Server (FastAPI) #
from fastapi import FastAPI, Request, HTTPException
from fastapi.responses import StreamingResponse
import httpx
import os
app = FastAPI()
SARVAM_API_KEY = os.environ.get("SARVAM_API_KEY")
@app.api_route("/sarvam-proxy/{path:path}", methods=["GET", "POST", "PUT", "DELETE"])
async def proxy(request: Request, path: str):
if not request.headers.get("Authorization"):
raise HTTPException(status_code=401, detail="Unauthorized")
target_url = f"https://apps.sarvam.ai/api/app-runtime/{path}"
if request.query_params:
target_url += f"?{request.query_params}"
async with httpx.AsyncClient() as client:
headers = dict(request.headers)
headers["X-API-Key"] = SARVAM_API_KEY
headers.pop("host", None)
response = await client.request(
method=request.method,
url=target_url,
headers=headers,
content=await request.body(),
)
return StreamingResponse(
content=response.iter_bytes(),
status_code=response.status_code,
)
Security Best Practices #
- Always authenticate users before proxying requests
- Rate limit to prevent abuse
- Never commit
.envfiles with API keys - Validate request paths to only allow expected endpoints
# .env (never commit!)
SARVAM_API_KEY=sk_samvaad_your_api_key
Event Handling #
eventCallback: (event) async {
if (event is ServerInteractionConnectedEvent) {
print('Connected: ${event.interactionId}');
} else if (event is ServerInteractionEndEvent) {
print('Call ended');
} else if (event is ServerUserInterruptEvent) {
print('User interrupted');
} else if (event is ServerUserSpeechStartEvent) {
print('User speaking...');
} else if (event is ServerUserSpeechEndEvent) {
print('User stopped speaking');
}
}
Error Handling #
try {
await agent.start();
final connected = await agent.waitForConnect(
timeout: Duration(seconds: 10),
);
if (!connected) {
throw Exception('Connection timeout');
}
} catch (e) {
print('Error: $e');
} finally {
await agent.stop();
}
Cleanup #
Always stop the agent when done:
@override
void dispose() {
agent?.stop();
super.dispose();
}
Example App #
See the example app for a complete implementation with:
- Voice call screen with real-time transcription
- Settings management
- Audio visualization
License #
MIT License - see LICENSE for details.