> 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.

# React SDK

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

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

पैकेज मैनेजर के ज़रिए अपने प्रोजेक्ट में पैकेज इंस्टॉल करें।

```shell
npm install @elevenlabs/react
# or
yarn add @elevenlabs/react
# or
pnpm install @elevenlabs/react
```

> **Tip**
>
> पुराने वर्शन से अपग्रेड कर रहे हैं? अपने AI कोडिंग एजेंट के लिए
> `elevenlabs:sdk-migration` skill इंस्टॉल करने के लिए `npx skills add elevenlabs/packages` चलाएँ। यह इंपोर्ट बदलावों,
> `ConversationProvider` wrapping और API अपडेट्स को ऑटोमेट करता है।

> **Note**
>
> `@elevenlabs/react`, `@elevenlabs/client` से सब कुछ re-export करता है, इसलिए आपको
> दोनों पैकेज इंस्टॉल करने की ज़रूरत नहीं है।

## उपयोग

यहां एक न्यूनतम काम करने वाला उदाहरण है, जो किसी एजेंट से कनेक्ट होता है और यूज़र को वॉइस बातचीत शुरू और समाप्त करने देता है:

```tsx
import {
  ConversationProvider,
  useConversationControls,
  useConversationStatus,
} from "@elevenlabs/react";

function App() {
  return (
    <ConversationProvider>
      <Agent />
    </ConversationProvider>
  );
}

function Agent() {
  const { startSession, endSession } = useConversationControls();
  const { status } = useConversationStatus();

  if (status === "connected") {
    return <button onClick={endSession}>End</button>;
  }

  return (
    <button onClick={() => startSession({ agentId: "agent_7101k5zvyjhmfg983brhmhkd98n6" })}>
      Start
    </button>
  );
}
```

नीचे दिए गए सेक्शन हर भाग को विस्तार से समझाते हैं।

### ConversationProvider

सभी conversation hooks का इस्तेमाल `ConversationProvider` के अंदर होना चाहिए। अपने ऐप (या संबंधित subtree) को इस provider से wrap करें।

```tsx
import { ConversationProvider } from "@elevenlabs/react";

function App() {
  return (
    <ConversationProvider>
      <YourComponents />
    </ConversationProvider>
  );
}
```

#### Provider props

provider, `useConversation` जैसे ही विकल्प स्वीकार करता है — जिनमें callbacks, client tools, overrides और server location शामिल हैं — ताकि आप इन्हें हर hook consumer में देने के बजाय provider स्तर पर कॉन्फ़िगर कर सकें।

```tsx
<ConversationProvider
  onConnect={() => console.log("Connected")}
  onDisconnect={() => console.log("Disconnected")}
  onError={(error) => console.error("Error:", error)}
  clientTools={{
    displayMessage: (parameters: { text: string }) => {
      alert(parameters.text);
      return "Message displayed";
    },
  }}
  serverLocation="eu-residency"
>
  <YourComponents />
</ConversationProvider>
```

##### नियंत्रित म्यूट स्थिति

provider, नियंत्रित म्यूट स्थिति प्रबंधन के लिए `isMuted` और `onMutedChange` props सपोर्ट करता है। इससे आप म्यूट स्थिति को बाहर से बनाए रख सकते हैं (जैसे, सेशन्स के बीच)।

```tsx
const [muted, setMuted] = useState(false);

<ConversationProvider isMuted={muted} onMutedChange={setMuted}>
  <YourComponents />
</ConversationProvider>;
```

### useConversation

एक सुविधाजनक React hook, जो सभी granular hooks को एक ही return value में जोड़ता है। इसके लिए ऊपर `ConversationProvider` होना ज़रूरी है।

> **Note**
>
> बेहतर render performance के लिए, इसके बजाय [granular hooks](#granular-hooks) इस्तेमाल करने पर विचार करें।
> `useConversation` किसी भी state change पर फिर से render होता है, जबकि granular hooks सिर्फ़ तब
> फिर से render होते हैं जब उनकी state का खास हिस्सा बदलता है।

#### बातचीत शुरू करें

```tsx
import { useConversation } from "@elevenlabs/react";

function MyComponent() {
  const conversation = useConversation();
  // ...
}
```

ध्यान रखें कि ElevenAgents को वॉइस बातचीत के लिए माइक्रोफ़ोन एक्सेस चाहिए। बातचीत शुरू होने से पहले, अपने ऐप के UI में इसका कारण समझाने और एक्सेस की अनुमति देने पर विचार करें।

```js
// call after explaining to the user why the microphone access is needed
await navigator.mediaDevices.getUserMedia({ audio: true });
```

#### विकल्प

hook को वैकल्पिक रूप से options के साथ initialize किया जा सकता है। इन्हें `ConversationProvider` स्तर पर भी दिया जा सकता है।

```tsx
const conversation = useConversation({
  /* options object */
});
```

विकल्पों में शामिल हैं:

* **clientTools** - client tools के लिए object definition, जिन्हें एजेंट invoke कर सकता है। जानकारी के लिए [नीचे देखें](#client-tools)।
* **overrides** - बातचीत सेटिंग्स के overrides के लिए object definition। जानकारी के लिए [नीचे देखें](#conversation-overrides)।
* **textOnly** - क्या बातचीत सिर्फ़ टेक्स्ट मोड में चलनी चाहिए। जानकारी के लिए [नीचे देखें](#text-only)।
* **serverLocation** - server location बताएं (`"us"`, `"eu-residency"`, `"in-residency"`, `"global"`)। डिफ़ॉल्ट `"us"` है।

#### Callbacks का ओवरव्यू

* **onConnect** - बातचीत का कनेक्शन स्थापित होने पर कॉल किया जाने वाला handler।
* **onDisconnect** - बातचीत का कनेक्शन समाप्त होने पर कॉल किया जाने वाला handler।
* **onMessage** - नया संदेश मिलने पर कॉल किया जाने वाला handler। ये यूज़र की आवाज़ के tentative या final transcriptions, LLM से तैयार जवाब या debug option सक्षम होने पर debug message हो सकते हैं।
* **onError** - error आने पर कॉल किया जाने वाला handler।
* **onAudio** - ऑडियो डेटा मिलने पर कॉल किया जाने वाला handler।
* **onModeChange** - बातचीत मोड बदलने पर कॉल किया जाने वाला handler (speaking/listening)।
* **onStatusChange** - कनेक्शन स्थिति बदलने पर कॉल किया जाने वाला handler।
* **onCanSendFeedbackChange** - feedback भेजने की क्षमता बदलने पर कॉल किया जाने वाला handler।
* **onDebug** - debug जानकारी उपलब्ध होने पर कॉल किया जाने वाला handler।
* **onUnhandledClientToolCall** - अनहैंडल्ड client tool call मिलने पर कॉल किया जाने वाला handler।
* **onVadScore** - voice activity detection score बदलने पर कॉल किया जाने वाला handler।
* **onAudioAlignment** - ऑडियो alignment डेटा मिलने पर कॉल किया जाने वाला handler, जो एजेंट की आवाज़ के लिए character-level timing जानकारी देता है।
* **onAgentChatResponsePart** - एजेंट का response text तैयार होने के दौरान start, delta और stop events के रूप में कॉल किया जाने वाला handler। टेक्स्ट-ओनली मोड में हमेशा भेजा जाता है; वॉइस बातचीत के लिए एजेंट के `client_events` कॉन्फ़िगरेशन में `agent_chat_response_part` सक्षम करें।

##### Client Tools

Client tools, एजेंट को client-side functionality invoke करने देने का तरीका हैं। इनका उपयोग client में कार्रवाई शुरू करने के लिए किया जा सकता है, जैसे modal खोलना या यूज़र की ओर से API call करना।

Client tools की definition functions का एक object होती है और यह [ElevenLabs UI](https://elevenlabs.io/app/agents) में आपके कॉन्फ़िगरेशन के समान होनी चाहिए। वहां आप अलग-अलग tools को नाम और वर्णन दे सकते हैं, साथ ही एजेंट द्वारा पास किए जाने वाले parameters सेट कर सकते हैं।

```ts
const conversation = useConversation({
  clientTools: {
    displayMessage: (parameters: { text: string }) => {
      alert(parameters.text);

      return "Message displayed";
    },
  },
});
```

अगर function कोई value return करता है, तो वह response के रूप में एजेंट को वापस भेजी जाती है।

एजेंट को response का इंतज़ार करने और उस पर प्रतिक्रिया देने के लिए tool को ElevenLabs UI में बातचीत block करने के लिए स्पष्ट रूप से सेट करना होगा। वरना एजेंट सफलता मानकर बातचीत जारी रखता है।

> **Note**
>
> Client tools रजिस्टर करने के लिए अधिक React-idiomatic तरीके हेतु,
> [useConversationClientTool](#useconversationclienttool) देखें।

##### बातचीत overrides

आप बातचीत की कई सेटिंग्स override कर सकते हैं और अन्य यूज़र interactions के आधार पर उन्हें डायनामिक रूप से सेट कर सकते हैं।

हम विभिन्न सेटिंग्स override करने की सुविधा देते हैं। ये सेटिंग्स वैकल्पिक हैं और बातचीत के अनुभव को कस्टमाइज़ करने के लिए इस्तेमाल की जा सकती हैं।

ये सेटिंग्स उपलब्ध हैं:

```ts
const conversation = useConversation({
  overrides: {
    agent: {
      prompt: {
        prompt: "My custom prompt",
      },
      firstMessage: "My custom first message",
      language: "en",
    },
    tts: {
      voiceId: "custom voice id",
    },
    conversation: {
      textOnly: true,
    },
  },
});
```

##### सिर्फ़ टेक्स्ट

अगर आपका एजेंट सिर्फ़ टेक्स्ट मोड में चलने के लिए कॉन्फ़िगर है, यानी वह ऑडियो संदेश न भेजता है न पाता है, तो बातचीत का हल्का version इस्तेमाल करने के लिए आप इस flag का उपयोग कर सकते हैं। इस स्थिति में यूज़र से माइक्रोफ़ोन अनुमति नहीं मांगी जाएगी और कोई audio context नहीं बनाया जाएगा।

```ts
const conversation = useConversation({
  textOnly: true,
});
```

##### नियंत्रित स्थिति

आप hook options के ज़रिए बातचीत की स्थिति के कुछ पहलुओं को सीधे नियंत्रित कर सकते हैं:

```ts
const [micMuted, setMicMuted] = useState(false);

const conversation = useConversation({
  micMuted,
  // ... other options
});

// Update controlled state
setMicMuted(true); // This will automatically mute the microphone
```

##### डेटा रेज़िडेंसी

आप यह बता सकते हैं कि किस ElevenLabs server region से कनेक्ट करना है। अधिक जानकारी के लिए [डेटा रेज़िडेंसी गाइड](/docs/hi/overview/administration/data-residency) देखें।

```ts
const conversation = useConversation({
  serverLocation: "eu-residency", // or "us", "in-residency", "global"
});
```

#### Methods

##### startSession

`startSession` method कनेक्शन स्थापित करती है और ElevenLabs Agents एजेंट के साथ संवाद करने के लिए माइक्रोफ़ोन का उपयोग शुरू करती है। यह method एक options object स्वीकार करती है, जिसमें `signedUrl`, `conversationToken` या `agentId` ज़रूरी है।

Agent ID, [ElevenLabs UI](https://elevenlabs.io/app/agents) से प्राप्त की जा सकती है।

हम यह भी सुझाव देते हैं कि बातचीत को अपने यूज़र्स से मैप करने के लिए आप अपने end user IDs पास करें।

> **Note**
>
> कनेक्शन type, बातचीत के मोड के आधार पर अपने-आप तय होता है। वॉइस बातचीत
> WebRTC इस्तेमाल करती है और टेक्स्ट-ओनली बातचीत डिफ़ॉल्ट रूप से WebSocket इस्तेमाल करती है। ज़रूरत पड़ने पर आप फिर भी
> `connectionType` स्पष्ट रूप से बता सकते हैं।

```js
const conversation = useConversation();

// For public agents, pass in the agent ID
const conversationId = await conversation.startSession({
  agentId: "agent_7101k5zvyjhmfg983brhmhkd98n6",
  userId: "user_9302xkm82nds93", // optional field
});
```

Public agents (यानी जिन एजेंट्स में authentication सक्षम नहीं है) के लिए सिर्फ़ `agentId` ज़रूरी है।

अगर बातचीत के लिए authorization चाहिए, तो WebSocket कनेक्शन के लिए signed links या WebRTC कनेक्शन के लिए conversation token बनाने हेतु REST API इस्तेमाल करें।

`startSession`, `conversationId` resolve करने वाला promise return करती है। यह value एक globally unique conversation ID है, जिसका इस्तेमाल आप अलग-अलग बातचीत की पहचान के लिए कर सकते हैं।

#### WebSocket कनेक्शन

```js maxLines=0
// Node.js server

app.get("/signed-url", yourAuthMiddleware, async (req, res) => {
  const response = await fetch(
    `https://api.elevenlabs.io/v1/convai/conversation/get-signed-url?agent_id=${process.env.AGENT_ID}`,
    {
      headers: {
        // Requesting a signed url 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 signed URL");
  }

  const body = await response.json();
  res.send(body.signed_url);
});
```

```js
// Client

const response = await fetch("/signed-url", yourAuthHeaders);
const signedUrl = await response.text();

await conversation.startSession({
  signedUrl,
});
```

#### WebRTC कनेक्शन

```js maxLines=0
// Node.js server

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);
});
```

```js
// Client

const response = await fetch("/conversation-token", yourAuthHeaders);
const conversationToken = await response.text();

await conversation.startSession({
  conversationToken,
});
```

##### endSession

बातचीत को मैन्युअल रूप से समाप्त करने की method। यह method disconnect होकर बातचीत समाप्त कर देगी।

```js
await conversation.endSession();
```

##### setVolume

बातचीत का output volume सेट करती है। 0 और 1 के बीच के `volume` field वाला object स्वीकार करती है।

```js
await conversation.setVolume({ volume: 0.5 });
```

##### sendUserMessage

एजेंट को टेक्स्ट संदेश भेजती है।

इसका उपयोग यूज़र को माइक्रोफ़ोन इस्तेमाल करने के बजाय संदेश टाइप करने देने के लिए किया जा सकता है। `sendContextualUpdate` के विपरीत, इसे यूज़र संदेश माना जाएगा और यह एजेंट को बातचीत में अपनी बारी लेने के लिए कहेगा।

```js
const { sendUserMessage, sendUserActivity } = useConversation();
const [value, setValue] = useState("");

return (
  <>
    <input
      value={value}
      onChange={e => {
        setValue(e.target.value);
        sendUserActivity();
      }}
    />
    <button
      onClick={() => {
        sendUserMessage(value);
        setValue("");
      }}
    >
      SEND
    </button>
  </>
);
```

##### sendContextualUpdate

एजेंट को ऐसी contextual जानकारी भेजती है जो response trigger नहीं करेगी।

```js
const { sendContextualUpdate } = useConversation();

sendContextualUpdate(
  "User navigated to another page. Consider it for next response, but don't react to this contextual update."
);
```

##### sendFeedback

बातचीत की गुणवत्ता पर feedback दें। इससे एजेंट की performance बेहतर बनाने में मदद मिलती है।

```js
const { sendFeedback } = useConversation();

sendFeedback(true); // positive feedback
sendFeedback(false); // negative feedback
```

##### sendUserActivity

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

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

```js
const { sendUserActivity } = useConversation();

// Call this when user is typing to prevent interruption
sendUserActivity();
```

##### changeInputDevice

सक्रिय वॉइस बातचीत के दौरान ऑडियो input device बदलें। यह method सिर्फ़ वॉइस बातचीत के लिए उपलब्ध है।

```js
// Change to a specific input device
conversation.changeInputDevice({
  sampleRate: 16000,
  format: "pcm",
  preferHeadphonesForIosDevices: true,
  inputDeviceId: "a1b2c3d4e5f6", // Optional: specific device ID
});
```

##### changeOutputDevice

सक्रिय वॉइस बातचीत के दौरान ऑडियो output device बदलें। यह method सिर्फ़ वॉइस बातचीत के लिए उपलब्ध है।

```js
// Change to a specific output device
conversation.changeOutputDevice({
  sampleRate: 16000,
  format: "pcm",
  outputDeviceId: "a1b2c3d4e5f6", // Optional: specific device ID
});
```

> **Note**
>
> डिवाइस switching सिर्फ़ वॉइस बातचीत के लिए काम करती है। अगर कोई खास `deviceId` नहीं दिया गया है, तो
> browser अपने डिफ़ॉल्ट device selection का उपयोग करेगा। आप उपलब्ध डिवाइस को
> [MediaDevices.enumerateDevices()](https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/enumerateDevices)
> API से सूचीबद्ध कर सकते हैं।

##### getId

मौजूदा conversation ID return करती है।

```js
const { getId } = useConversation();
const conversationId = getId();
console.log(conversationId); // e.g., "conv_9001k1zph3fkeh5s8xg9z90swaqa"
```

##### getInputVolume / getOutputVolume

ऐसी methods जो मौजूदा input/output volume levels (0-1 scale) return करती हैं।

```js
const { getInputVolume, getOutputVolume } = useConversation();
const inputLevel = getInputVolume();
const outputLevel = getOutputVolume();
```

##### getInputByteFrequencyData / getOutputByteFrequencyData

ऐसी methods जो मौजूदा input/output frequency data वाले `Uint8Array`s return करती हैं। अधिक जानकारी के लिए [AnalyserNode.getByteFrequencyData](https://developer.mozilla.org/en-US/docs/Web/API/AnalyserNode/getByteFrequencyData) देखें।

```js
const { getInputByteFrequencyData, getOutputByteFrequencyData } = useConversation();
const inputFrequencyData = getInputByteFrequencyData();
const outputFrequencyData = getOutputByteFrequencyData();
```

> **Note**
>
> ये methods सिर्फ़ वॉइस बातचीत के लिए उपलब्ध हैं। WebRTC मोड में ऑडियो को hardcoded रूप से
> `pcm_48000` इस्तेमाल करने के लिए सेट किया गया है, इसलिए return किए गए डेटा का उपयोग करने वाला कोई भी visualization
> WebSocket कनेक्शनों से अलग patterns दिखा सकता है।

##### sendMCPToolApprovalResult

MCP (Model Context Protocol) tool calls के लिए approval result भेजती है।

```js
const { sendMCPToolApprovalResult } = useConversation();

// Approve a tool call
sendMCPToolApprovalResult("tc_8k2m4n6p8r0t", true);

// Reject a tool call
sendMCPToolApprovalResult("tc_8k2m4n6p8r0t", false);
```

#### Return values

ऊपर दी गई methods के अलावा, `useConversation` यह reactive state return करती है:

* **status** - मौजूदा कनेक्शन स्थिति (`"disconnected"`, `"connecting"`, `"connected"`)।
* **isSpeaking** - क्या एजेंट इस समय बोल रहा है।
* **isListening** - क्या एजेंट इस समय सुन रहा है।
* **mode** - मौजूदा बातचीत मोड (`"speaking"` या `"listening"`)।
* **isMuted** - क्या माइक्रोफ़ोन इस समय म्यूट है।
* **setMuted** - माइक्रोफ़ोन को म्यूट/अनम्यूट करने का function।
* **canSendFeedback** - क्या मौजूदा बातचीत के लिए feedback दिया जा सकता है।
* **message** - बातचीत का नवीनतम संदेश।

```tsx
const { status, isSpeaking, isListening, isMuted, setMuted, canSendFeedback } = useConversation();

return (
  <div>
    <p>Status: {status}</p>
    <p>Agent is {isSpeaking ? 'speaking' : 'listening'}</p>
    <button onClick={() => setMuted(!isMuted)}>
      {isMuted ? 'Unmute' : 'Mute'}
    </button>
  </div>
);
```

---

## Granular Hooks

बेहतर render performance के लिए `useConversation` के बजाय इन hooks का उपयोग करें। हर hook केवल अपनी state के खास हिस्से को subscribe करता है, इसलिए components सिर्फ़ तभी फिर से render होते हैं जब उनके इस्तेमाल का डेटा बदलता है।

सभी granular hooks के लिए ऊपर `ConversationProvider` होना ज़रूरी है।

### useConversationControls

बातचीत को नियंत्रित करने के लिए action methods return करता है। यह hook re-renders नहीं कराता, क्योंकि यह केवल stable function references देता है।

```tsx
import { useConversationControls } from "@elevenlabs/react";

function Controls() {
  const {
    startSession,
    endSession,
    sendUserMessage,
    sendContextualUpdate,
    sendUserActivity,
    setVolume,
    changeInputDevice,
    changeOutputDevice,
    sendMCPToolApprovalResult,
    getId,
    getInputVolume,
    getOutputVolume,
    getInputByteFrequencyData,
    getOutputByteFrequencyData,
  } = useConversationControls();

  return (
    <button onClick={() => startSession({ agentId: "agent_7101k5zvyjhmfg983brhmhkd98n6" })}>
      Start
    </button>
  );
}
```

### useConversationStatus

मौजूदा कनेक्शन स्थिति और वैकल्पिक status message return करता है।

```tsx
import { useConversationStatus } from "@elevenlabs/react";

function StatusIndicator() {
  const { status, message } = useConversationStatus();

  return <p>Status: {status}</p>; // "disconnected" | "connecting" | "connected"
}
```

### useConversationInput

म्यूट स्थिति और माइक्रोफ़ोन टॉगल करने के लिए setter return करता है।

```tsx
import { useConversationInput } from "@elevenlabs/react";

function MuteToggle() {
  const { isMuted, setMuted } = useConversationInput();

  return <button onClick={() => setMuted(!isMuted)}>{isMuted ? "Unmute" : "Mute"}</button>;
}
```

### useConversationMode

एजेंट के लिए speaking/listening state return करता है।

```tsx
import { useConversationMode } from "@elevenlabs/react";

function ModeIndicator() {
  const { mode, isSpeaking, isListening } = useConversationMode();

  return <p>Agent is {isSpeaking ? "speaking" : "listening"}</p>;
}
```

### useConversationFeedback

feedback उपलब्धता और feedback सबमिट करने का method return करता है।

```tsx
import { useConversationFeedback } from "@elevenlabs/react";

function FeedbackButtons() {
  const { canSendFeedback, sendFeedback } = useConversationFeedback();

  if (!canSendFeedback) return null;

  return (
    <div>
      <button onClick={() => sendFeedback(true)}>Like</button>
      <button onClick={() => sendFeedback(false)}>Dislike</button>
    </div>
  );
}
```

### useRawConversation

raw conversation instance return करता है। यह उन्नत उपयोग के मामलों के लिए एक escape hatch है, जहां आपको underlying `VoiceConversation` या `TextConversation` object का सीधा access चाहिए।

```tsx
import { useRawConversation } from "@elevenlabs/react";

function Advanced() {
  const conversation = useRawConversation();
  // Access the raw conversation instance directly
}
```

---

## useConversationClientTool

React कंपोनेंट्स से क्लाइंट टूल्स को डायनामिक रूप से रजिस्टर करने के लिए एक हुक। कंपोनेंट अनमाउंट होने पर टूल्स अपने-आप अनरजिस्टर हो जाते हैं।

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

```tsx
import { useConversationClientTool } from "@elevenlabs/react";
import { useState } from "react";

function MapComponent() {
  const [location, setLocation] = useState({ lat: 0, lng: 0 });

  useConversationClientTool("getLocation", () => {
    return `${location.lat},${location.lng}`;
  });

  useConversationClientTool("setLocation", (params: { lat: number; lng: number }) => {
    setLocation(params);
    return "Location updated";
  });

  return <Map center={location} />;
}
```

यह हुक हमेशा हैंडलर की नवीनतम closure वैल्यू का इस्तेमाल करता है, इसलिए आपको पुराने स्टेट की चिंता करने की ज़रूरत नहीं है।