> This is a page from the ElevenLabs documentation. For a complete page index, fetch https://elevenlabs.io/docs/llms.txt. For the full documentation in a single file, fetch https://elevenlabs.io/docs/llms-full.txt.

# Kotlin SDK

> **Info**
>
> ElevenAgents कैसे काम करता है, इसकी जानकारी के लिए [ElevenAgents ओवरव्यू](/docs/hi/eleven-agents/overview) देखें।

## इंस्टॉलेशन

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

**`build.gradle.kts`**

```kotlin build.gradle.kts
dependencies {
    // ElevenLabs Agents SDK (Android)
    implementation("io.elevenlabs:elevenlabs-android:<latest>")

    // Kotlin coroutines, AndroidX, etc., as needed by your app
}
```

> **Tip**
>
> इस SDK का इस्तेमाल करने वाली एक उदाहरण Android ऐप
> [यहां](https://github.com/elevenlabs/elevenlabs-android/tree/main/example-app) मिल सकती है

## आवश्यकताएं

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

## सेटअप

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

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

```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) और उससे ऊपर के लिए, आपको रनटाइम पर माइक्रोफ़ोन अनुमति मांगनी होगी:

```kotlin
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 को कभी भी क्लाइंट के सामने न रखें)।

```kotlin
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+ पर, जहां रनटाइम अनुमतियां ज़रूरी हैं।

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

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

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

> **Error**
>
> क्लाइंट में कभी भी API keys एम्बेड न करें। उन्हें आसानी से निकाला जा सकता है और गलत इस्तेमाल किया जा सकता है।

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

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

```kotlin
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** - ऑडियो अलाइनमेंट डेटा मिलने पर कॉल किया जाता है, जो एजेंट की स्पीच के लिए कैरेक्टर-लेवल टाइमिंग जानकारी देता है।

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

### मेथड्स

#### startSession

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

##### पब्लिक एजेंट

पब्लिक एजेंटों के लिए (यानी जिन एजेंटों में authentication सक्षम नहीं है), सिर्फ़ `agentId` ज़रूरी है। Agent ID को [ElevenLabs UI](https://elevenlabs.io/app/agents) से पाया जा सकता है।

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

##### प्राइवेट एजेंट

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

> **Tip**
>
> `conversationToken` 10 मिनट तक मान्य रहता है।

```typescript maxLines=0
// 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` ज़रूरी है।

```kotlin

// 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 पास कर सकते हैं। यह आपकी अपनी ग्राहक पहचान हो सकती है। इसे सर्वर पर भेजे जाने वाले बातचीत आरंभ डेटा में शामिल किया जाएगा।

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

#### endSession

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

```kotlin
session.endSession()
```

#### sendUserMessage

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

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

#### sendContextualUpdate

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

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

#### sendFeedback

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

```kotlin
// Positive feedback
session.sendFeedback(true)

// Negative feedback
session.sendFeedback(false)
```

#### sendUserActivity

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

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

```kotlin
session.sendUserActivity()
```

#### getId

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

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

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

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

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

### प्रॉपर्टीज़

#### status

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

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

## ProGuard / R8

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

```proguard
-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](https://github.com/elevenlabs/elevenlabs-android/tree/main/example-app) में उदाहरण ऐप देखें। ऐप इनमें से चीज़ें दिखाती है:

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