Kotlin SDK

ElevenAgents SDK: Android ऐप्स के लिए कस्टमाइज़्ड, इंटरैक्टिव वॉइस एजेंट मिनटों में डिप्लॉय करें।

ElevenAgents कैसे काम करता है, इसकी जानकारी के लिए ElevenAgents ओवरव्यू देखें।

इंस्टॉलेशन

अपनी ऐप-लेवल build.gradle फ़ाइल में नीचे दी गई डिपेंडेंसी शामिल करके अपने Android प्रोजेक्ट में ElevenLabs SDK जोड़ें:

build.gradle.kts
dependencies {
// ElevenLabs Agents SDK (Android)
implementation("io.elevenlabs:elevenlabs-android:<latest>")
// Kotlin coroutines, AndroidX, etc., as needed by your app
}

इस SDK का इस्तेमाल करने वाली एक उदाहरण Android ऐप यहां मिल सकती है

आवश्यकताएं

  • Android API लेवल 21 (Android 5.0) या उससे ऊपर
  • API कॉल के लिए इंटरनेट अनुमति
  • वॉइस इनपुट के लिए माइक्रोफ़ोन अनुमति
  • HTTPS कॉल के लिए नेटवर्क सुरक्षा कॉन्फ़िगरेशन

सेटअप

मैनिफ़ेस्ट कॉन्फ़िगरेशन

अपने AndroidManifest.xml में ज़रूरी अनुमतियां जोड़ें:

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />

रनटाइम अनुमतियां

Android 6.0 (API लेवल 23) और उससे ऊपर के लिए, आपको रनटाइम पर माइक्रोफ़ोन अनुमति मांगनी होगी:

import android.Manifest
import android.content.pm.PackageManager
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
private fun requestMicrophonePermission() {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.RECORD_AUDIO)
!= PackageManager.PERMISSION_GRANTED) {
if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.RECORD_AUDIO)) {
// Show explanation to the user
showPermissionExplanationDialog()
} else {
ActivityCompat.requestPermissions(
this,
arrayOf(Manifest.permission.RECORD_AUDIO),
MICROPHONE_PERMISSION_REQUEST_CODE
)
}
}
}

इस्तेमाल

अपने Application क्लास या मुख्य activity में ElevenLabs SDK को इनिशियलाइज़ करें:

इनमें से किसी एक के साथ बातचीत सेशन शुरू करें:

  • पब्लिक एजेंट: agentId पास करें
  • प्राइवेट एजेंट: अपने बैकएंड से उपलब्ध कराया गया conversationToken पास करें (अपनी API key को कभी भी क्लाइंट के सामने न रखें)।
import io.elevenlabs.ConversationClient
import io.elevenlabs.ConversationConfig
import io.elevenlabs.ConversationSession
import io.elevenlabs.ClientTool
import io.elevenlabs.ClientToolResult
// Start a public agent session (token generated for you)
val config = ConversationConfig(
agentId = "<your_public_agent_id>", // OR conversationToken = "<token>"
userId = "your-user-id",
// Optional callbacks
onConnect = { conversationId ->
// Called when the conversation is connected and returns the conversation ID. You can access conversationId via session.getId() too
},
onMessage = { source, messageJson ->
// Raw JSON messages from data channel; useful for logging/telemetry
},
onModeChange = { mode ->
// "speaking" | "listening" — drive UI indicators
},
onStatusChange = { status ->
// "connected" | "connecting" | "disconnected"
},
onCanSendFeedbackChange = { canSend ->
// Enable/disable thumbs up/down buttons for feedback reporting
},
onUnhandledClientToolCall = { call ->
// Agent requested a client tool not registered on the device
},
onVadScore = { score ->
// Voice Activity Detection score, range from 0 to 1 where higher values indicate higher confidence of speech
},
onAudioAlignment = { alignment ->
// Character-level timing data for synchronized text display
val chars = alignment["chars"] as? List<*>
val startTimes = alignment["char_start_times_ms"] as? List<*>
val durations = alignment["char_durations_ms"] as? List<*>
Log.d("ExampleApp", "Audio alignment: $chars")
},
// List of client tools the agent can invoke
clientTools = mapOf(
"logMessage" to object : ClientTool {
override suspend fun execute(parameters: Map<String, Any>): ClientToolResult {
val message = parameters["message"] as? String
Log.d("ExampleApp", "[INFO] Client Tool Log: $message")
return ClientToolResult.success("Message logged successfully")
}
}
),
)
// In an Activity context
val session: ConversationSession = ConversationClient.startSession(config, this)

ध्यान दें कि ElevenAgents को माइक्रोफ़ोन एक्सेस की ज़रूरत होती है। बातचीत शुरू होने से पहले अपनी ऐप के UI में अनुमतियों की जानकारी दें और उन्हें मांगें, खासकर Android 6.0+ पर, जहां रनटाइम अनुमतियां ज़रूरी हैं।

अगर सर्वर पर किसी टूल के लिए expects_response=false कॉन्फ़िगर किया गया है, तो execute से null लौटाएं, ताकि एजेंट को टूल परिणाम वापस भेजना छोड़ दिया जाए।

पब्लिक बनाम प्राइवेट एजेंट

  • पब्लिक एजेंट (कोई auth नहीं): ConversationConfig में agentId के साथ इनिशियलाइज़ करें। डिवाइस पर API key की ज़रूरत के बिना SDK ElevenLabs से conversation token मांगता है।
  • प्राइवेट एजेंट (auth): ConversationConfig में conversationToken के साथ इनिशियलाइज़ करें। आपका सर्वर आपकी ElevenLabs API key का इस्तेमाल करके ElevenLabs से conversation token मांगता है।
क्लाइंट में कभी भी API keys एम्बेड न करें। उन्हें आसानी से निकाला जा सकता है और गलत इस्तेमाल किया जा सकता है।

क्लाइंट टूल्स

एजेंट को डिवाइस की लोकल क्षमताओं को कॉल करने देने के लिए क्लाइंट टूल्स रजिस्टर करें।

val config = ConversationConfig(
agentId = "<public_agent>",
clientTools = mapOf(
"logMessage" to object : io.elevenlabs.ClientTool {
override suspend fun execute(parameters: Map<String, Any>): io.elevenlabs.ClientToolResult? {
val message = parameters["message"] as? String ?: return io.elevenlabs.ClientToolResult.failure("Missing 'message'")
android.util.Log.d("ClientTool", "Log: $message")
return null // No response needed for fire-and-forget tools
}
}
)
)

जब एजेंट client_tool_call जारी करता है, तो SDK उससे मेल खाने वाला टूल चलाता है और client_tool_result के साथ जवाब देता है। अगर टूल रजिस्टर नहीं है, तो onUnhandledClientToolCall को कॉल किया जाता है और एजेंट को असफलता परिणाम लौटाया जाता है (अगर जवाब अपेक्षित हो)।

कॉलबैक ओवरव्यू

  • onConnect - WebRTC कनेक्शन बन जाने पर कॉल किया जाता है। बातचीत ID लौटाता है।
  • onMessage - नया संदेश मिलने पर कॉल किया जाता है। ये यूज़र की वॉइस के अस्थायी या अंतिम ट्रांसक्रिप्शन, LLM से बने जवाब या debug संदेश हो सकते हैं। स्रोत ("ai" या "user") और raw JSON संदेश देता है।
  • onModeChange - बातचीत मोड बदलने पर कॉल किया जाता है। इससे पता चलता है कि एजेंट बोल रहा है ("speaking") या सुन रहा है ("listening")।
  • onStatusChange - बातचीत की स्थिति बदलने पर कॉल किया जाता है ("connected", "connecting", या "disconnected")।
  • onCanSendFeedbackChange - फ़ीडबैक भेजने की क्षमता बदलने पर कॉल किया जाता है। फ़ीडबैक बटन सक्षम/अक्षम करता है।
  • onUnhandledClientToolCall - एजेंट द्वारा ऐसा क्लाइंट टूल मांगे जाने पर कॉल किया जाता है जो डिवाइस पर रजिस्टर नहीं है।
  • onVadScore - वॉइस एक्टिविटी डिटेक्शन स्कोर बदलने पर कॉल किया जाता है। रेंज 0 से 1 तक है, जिसमें बड़े मान बोलने की अधिक विश्वसनीयता दिखाते हैं।
  • onAudioAlignment - ऑडियो अलाइनमेंट डेटा मिलने पर कॉल किया जाता है, जो एजेंट की स्पीच के लिए कैरेक्टर-लेवल टाइमिंग जानकारी देता है।

एजेंट के लिए सभी क्लाइंट इवेंट डिफ़ॉल्ट रूप से सक्षम नहीं होते। अगर आपने कोई कॉलबैक सक्षम किया है, लेकिन इवेंट नहीं मिल रहे हैं, तो सुनिश्चित करें कि आपके ElevenLabs एजेंट में संबंधित इवेंट सक्षम है। आप इसे ElevenLabs डैशबोर्ड में एजेंट सेटिंग्स के “Advanced” टैब में कर सकते हैं।

मेथड्स

startSession

startSession मेथड WebRTC कनेक्शन शुरू करता है और ElevenLabs Agents एजेंट के साथ संवाद करने के लिए माइक्रोफ़ोन का इस्तेमाल शुरू करता है।

पब्लिक एजेंट

पब्लिक एजेंटों के लिए (यानी जिन एजेंटों में authentication सक्षम नहीं है), सिर्फ़ agentId ज़रूरी है। Agent ID को ElevenLabs UI से पाया जा सकता है।

val session = ConversationClient.startSession(
config = ConversationConfig(
agentId = "your-agent-id"
),
context = this
)
प्राइवेट एजेंट

प्राइवेट एजेंटों के लिए, आपको ElevenLabs API से मिला conversationToken पास करना होगा। यह token बनाने के लिए ElevenLabs API key चाहिए।

conversationToken 10 मिनट तक मान्य रहता है।
// Server-side token generation (Node.js example)
app.get("/conversation-token", yourAuthMiddleware, async (req, res) => {
const response = await fetch(
`https://api.elevenlabs.io/v1/convai/conversation/token?agent_id=${process.env.AGENT_ID}`,
{
headers: {
// Requesting a conversation token requires your ElevenLabs API key
// Do NOT expose your API key to the client!
"xi-api-key": process.env.ELEVENLABS_API_KEY,
},
}
);
if (!response.ok) {
return res.status(500).send("Failed to get conversation token");
}
const body = await response.json();
res.send(body.token);
});

फिर token को startSession मेथड में पास करें। ध्यान दें कि प्राइवेट एजेंटों के लिए सिर्फ़ conversationToken ज़रूरी है।

// Get conversation token from your server
val conversationToken = fetchConversationTokenFromServer()
// For private agents, pass in the conversation token
val session = ConversationClient.startSession(
config = ConversationConfig(
conversationToken = conversationToken
),
context = this
)

बातचीत में यूज़र की पहचान के लिए आप वैकल्पिक रूप से यूज़र ID पास कर सकते हैं। यह आपकी अपनी ग्राहक पहचान हो सकती है। इसे सर्वर पर भेजे जाने वाले बातचीत आरंभ डेटा में शामिल किया जाएगा।

val session = ConversationClient.startSession(
config = ConversationConfig(
agentId = "your-agent-id",
userId = "your-user-id"
),
context = this
)

endSession

बातचीत को मैन्युअल रूप से खत्म करने का मेथड। यह कनेक्शन डिस्कनेक्ट करके बातचीत खत्म कर देगा।

session.endSession()

sendUserMessage

सक्रिय बातचीत के दौरान एजेंट को टेक्स्ट संदेश भेजें। इससे एजेंट से जवाब ट्रिगर होगा।

session.sendUserMessage("Hello, how can you help me?")

sendContextualUpdate

एजेंट को संदर्भ संबंधी जानकारी भेजता है, जिससे जवाब ट्रिगर नहीं होता।

session.sendContextualUpdate(
"User navigated to the profile page. Consider this for next response."
)

sendFeedback

बातचीत की गुणवत्ता पर फ़ीडबैक दें। इससे एजेंट की परफ़ॉर्मेंस बेहतर बनाने में मदद मिलती है। फ़ीडबैक की अनुमति होने पर अपने thumbs up/down UI को सक्षम करने के लिए onCanSendFeedbackChange इस्तेमाल करें।

// Positive feedback
session.sendFeedback(true)
// Negative feedback
session.sendFeedback(false)

sendUserActivity

रुकावटों को रोकने के लिए एजेंट को यूज़र गतिविधि के बारे में सूचित करता है। यह तब उपयोगी है जब यूज़र ऐप का सक्रिय रूप से इस्तेमाल कर रहा हो और एजेंट को बोलना रोकना चाहिए, जैसे जब यूज़र चैट में टाइप कर रहा हो।

यह सिग्नल मिलने के बाद एजेंट लगभग 2 सेकंड तक बोलना रोक देगा।

session.sendUserActivity()

getId

बातचीत ID पाएं।

val conversationId = session.getId()
Log.d("Conversation", "Conversation ID: $conversationId")
// e.g., "conv_123"

म्यूट/ अनम्यूट

session.toggleMute()
session.setMicMuted(true) // mute
session.setMicMuted(false) // unmute

UI लेबल को “Mute” और “Unmute” के बीच अपडेट करने के लिए session.isMuted देखें।

प्रॉपर्टीज़

status

बातचीत की वर्तमान स्थिति पाएं।

val status = session.status
Log.d("Conversation", "Current status: $status")
// Values: DISCONNECTED, CONNECTING, CONNECTED

ProGuard / R8

अगर आप shrink/obfuscate करते हैं, तो सुनिश्चित करें कि Gson models और LiveKit रखे गए हों। उदाहरण नियम (ज़रूरत के अनुसार समायोजित करें):

-keep class io.elevenlabs.** { *; }
-keep class io.livekit.** { *; }
-keepattributes *Annotation*

समस्या निवारण

  • सुनिश्चित करें कि रनटाइम पर माइक्रोफ़ोन अनुमति दी गई है
  • अगर reconnect अटक जाता है, तो जांचें कि आपकी ऐप session.endSession() कॉल करती है और reconnect करने से पहले नया session instance शुरू करती है
  • emulators के लिए, जांचें कि ऑडियो input/output routes काम कर रहे हैं; physical devices आमतौर पर ज़्यादा भरोसेमंद होते हैं

उदाहरण इम्प्लीमेंटेशन

उदाहरण इम्प्लीमेंटेशन के लिए ElevenLabs Android SDK repository में उदाहरण ऐप देखें। ऐप इनमें से चीज़ें दिखाती है:

  • एक टैप में कनेक्ट/डिस्कनेक्ट
  • बोलने/सुनने का इंडिकेटर
  • UI enable/disable के साथ फ़ीडबैक बटन
  • sendUserActivity() से टाइपिंग इंडिकेटर
  • इनपुट से संदर्भ संबंधी और यूज़र संदेश
  • माइक्रोफ़ोन म्यूट/अनम्यूट बटन