@telnyx/ai-agent-lib 0.1.3 → 0.1.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,3 +1,353 @@
1
- # Telnyx AI Agent Library
1
+ # Telnyx AI Agent Library
2
+
3
+ A TypeScript/React library for building AI-powered voice conversation applications using Telnyx's WebRTC infrastructure. This library provides a comprehensive set of tools for managing AI agent connections, real-time transcriptions, conversation states, and audio streaming.
4
+
5
+ ## Features
6
+
7
+ - 🎯 **Easy AI Agent Integration** - Connect to Telnyx AI agents with minimal setup
8
+ - 🎙️ **Real-time Transcription** - Automatic speech-to-text with live updates
9
+ - 🔊 **Audio Stream Management** - Built-in audio monitoring and playback controls
10
+ - ⚛️ **React Hooks & Components** - Ready-to-use React components and hooks
11
+ - 🔄 **State Management** - Automatic state synchronization using Jotai
12
+ - 📱 **Connection Management** - Robust connection handling with error recovery
13
+ - 🎚️ **Agent State Tracking** - Monitor agent states (listening, speaking, thinking)
14
+
15
+ ## Installation
16
+
17
+ ```bash
18
+ npm install @telnyx/ai-agent-lib
19
+ ```
20
+
21
+ ### Peer Dependencies
22
+
23
+ This library requires React 19.1.1+ as a peer dependency:
24
+
25
+ ```bash
26
+ npm install react@^19.1.1 react-dom@^19.1.0
27
+ ```
28
+
29
+ ## Quick Start
30
+
31
+ ### 1. Wrap your app with the provider
32
+
33
+ ```tsx
34
+ import React from 'react';
35
+ import { createRoot } from 'react-dom/client';
36
+ import { TelnyxAIAgentProvider } from '@telnyx/ai-agent-lib';
37
+ import App from './App';
38
+
39
+ createRoot(document.getElementById('root')!).render(
40
+ <TelnyxAIAgentProvider agentId="your-agent-id">
41
+ <App />
42
+ </TelnyxAIAgentProvider>
43
+ );
44
+ ```
45
+
46
+ ### 2. Use hooks in your components
47
+
48
+ ```tsx
49
+ import React, { useEffect, useRef, useState } from 'react';
50
+ import {
51
+ useClient,
52
+ useTranscript,
53
+ useConnectionState,
54
+ useConversation,
55
+ useAgentState
56
+ } from '@telnyx/ai-agent-lib';
57
+
58
+ function VoiceChat() {
59
+ const client = useClient();
60
+ const transcript = useTranscript();
61
+ const connectionState = useConnectionState();
62
+ const conversation = useConversation();
63
+ const agentState = useAgentState();
64
+ const audioRef = useRef<HTMLAudioElement>(null);
65
+ const [messageInput, setMessageInput] = useState('');
66
+
67
+ // Setup audio playback
68
+ useEffect(() => {
69
+ if (conversation?.call?.remoteStream && audioRef.current) {
70
+ audioRef.current.srcObject = conversation.call.remoteStream;
71
+ }
72
+ }, [conversation]);
73
+
74
+ const handleSendMessage = () => {
75
+ if (messageInput.trim()) {
76
+ client.sendConversationMessage(messageInput);
77
+ setMessageInput('');
78
+ }
79
+ };
80
+
81
+ const isCallActive = conversation?.call?.state === 'active';
82
+
83
+ return (
84
+ <div>
85
+ <h2>Connection: {connectionState}</h2>
86
+ <h3>Agent State: {agentState}</h3>
87
+
88
+ <button
89
+ onClick={() => client.startConversation()}
90
+ disabled={connectionState !== 'connected'}
91
+ >
92
+ Start Conversation
93
+ </button>
94
+
95
+ <button onClick={() => client.endConversation()}>
96
+ End Conversation
97
+ </button>
98
+
99
+ {/* Text message input - only available during active call */}
100
+ {isCallActive && (
101
+ <div style={{ margin: '20px 0' }}>
102
+ <h4>Send Text Message</h4>
103
+ <input
104
+ type="text"
105
+ value={messageInput}
106
+ onChange={(e) => setMessageInput(e.target.value)}
107
+ placeholder="Type a message..."
108
+ onKeyPress={(e) => e.key === 'Enter' && handleSendMessage()}
109
+ />
110
+ <button
111
+ onClick={handleSendMessage}
112
+ disabled={!messageInput.trim()}
113
+ >
114
+ Send Message
115
+ </button>
116
+ </div>
117
+ )}
118
+
119
+ <audio ref={audioRef} autoPlay playsInline controls />
120
+
121
+ <div>
122
+ <h3>Transcript ({transcript.length} items)</h3>
123
+ {transcript.map((item) => (
124
+ <div key={item.id}>
125
+ <strong>{item.role}:</strong> {item.content}
126
+ <small> - {item.timestamp.toLocaleTimeString()}</small>
127
+ </div>
128
+ ))}
129
+ </div>
130
+ </div>
131
+ );
132
+ }
133
+ }
134
+ ```
135
+
136
+ ## API Reference
137
+
138
+ ### TelnyxAIAgentProvider Props
139
+
140
+ | Prop | Type | Required | Default | Description |
141
+ |------|------|----------|---------|-------------|
142
+ | `agentId` | `string` | ✅ | - | Your Telnyx AI agent ID |
143
+ | `versionId` | `string` | ❌ | `"main"` | Agent version to use |
144
+ | `environment` | `"production" \| "development"` | ❌ | `"production"` | Telnyx environment |
145
+
146
+ ### Hooks
147
+
148
+ #### `useClient()`
149
+ Returns the `TelnyxAIAgent` instance for direct API access.
150
+
151
+ **Methods:**
152
+ - `connect()` - Connect to Telnyx platform
153
+ - `disconnect()` - Disconnect and cleanup
154
+ - `startConversation()` - Start a new conversation
155
+ - `endConversation()` - End the current conversation
156
+ - `sendConversationMessage(message: string)` - Send a text message during an active conversation
157
+ - `transcript` - Get current transcript array
158
+
159
+ **Events:**
160
+ - `agent.connected` - Agent successfully connected
161
+ - `agent.disconnected` - Agent disconnected
162
+ - `agent.error` - Connection or operational error
163
+ - `transcript.item` - New transcript item received
164
+ - `conversation.update` - Conversation state updated
165
+ - `conversation.agent.state` - Agent state changed
166
+
167
+ #### `useConnectionState()`
168
+ Returns the current connection state: `"connecting" | "connected" | "disconnected" | "error"`
169
+
170
+ #### `useTranscript()`
171
+ Returns an array of `TranscriptItem` objects representing the conversation history.
172
+
173
+ **TranscriptItem:**
174
+ ```typescript
175
+ {
176
+ id: string;
177
+ role: "user" | "assistant";
178
+ content: string;
179
+ timestamp: Date;
180
+ }
181
+ ```
182
+
183
+ #### `useConversation()`
184
+ Returns the current conversation notification object containing call information and state.
185
+
186
+ #### `useAgentState()`
187
+ Returns the current agent state: `"listening" | "speaking" | "thinking"`
188
+
189
+ ### Direct Usage (Without React)
190
+
191
+ You can also use the library without React:
192
+
193
+ ```typescript
194
+ import { TelnyxAIAgent } from '@telnyx/ai-agent-lib';
195
+
196
+ const agent = new TelnyxAIAgent({
197
+ agentId: 'your-agent-id',
198
+ versionId: 'main',
199
+ environment: 'production'
200
+ });
201
+
202
+ // Connect to the platform
203
+ await agent.connect();
204
+
205
+ // Listen for events
206
+ agent.on('agent.connected', () => {
207
+ console.log('Agent connected!');
208
+ });
209
+
210
+ agent.on('transcript.item', (item) => {
211
+ console.log(`${item.role}: ${item.content}`);
212
+ });
213
+
214
+ agent.on('conversation.agent.state', (state) => {
215
+ console.log(`Agent is now: ${state}`);
216
+ });
217
+
218
+ agent.on('conversation.update', (notification) => {
219
+ if (notification.call?.state === 'active') {
220
+ console.log('Call is now active - you can send messages');
221
+
222
+ // Send a text message during the conversation
223
+ agent.sendConversationMessage('Hello, I have a question about your services.');
224
+ }
225
+ });
226
+
227
+ // Start a conversation
228
+ await agent.startConversation();
229
+
230
+ // Send messages during an active conversation
231
+ // Note: This will only work when there's an active call
232
+ setTimeout(() => {
233
+ agent.sendConversationMessage('Can you help me with my account?');
234
+ }, 5000);
235
+
236
+ // Access transcript
237
+ console.log(agent.transcript);
238
+
239
+ // Cleanup
240
+ await agent.disconnect();
241
+ ```
242
+
243
+ ## Advanced Usage
244
+
245
+ ### Sending Text Messages During Conversations
246
+
247
+ You can send text messages to the AI agent during an active conversation using the `sendConversationMessage` method. This is useful for providing context, asking questions, or sending information that might be easier to type than speak.
248
+
249
+ ```tsx
250
+ // React example
251
+ function ChatInterface() {
252
+ const client = useClient();
253
+ const conversation = useConversation();
254
+ const [message, setMessage] = useState('');
255
+
256
+ const handleSendMessage = () => {
257
+ if (conversation?.call?.state === 'active' && message.trim()) {
258
+ client.sendConversationMessage(message);
259
+ setMessage('');
260
+ }
261
+ };
262
+
263
+ return (
264
+ <div>
265
+ {conversation?.call?.state === 'active' && (
266
+ <div>
267
+ <input
268
+ value={message}
269
+ onChange={(e) => setMessage(e.target.value)}
270
+ placeholder="Type a message to the agent..."
271
+ onKeyPress={(e) => e.key === 'Enter' && handleSendMessage()}
272
+ />
273
+ <button onClick={handleSendMessage}>Send</button>
274
+ </div>
275
+ )}
276
+ </div>
277
+ );
278
+ }
279
+ ```
280
+
281
+ ```typescript
282
+ // Direct usage example
283
+ agent.on('conversation.update', (notification) => {
284
+ if (notification.call?.state === 'active') {
285
+ // Now you can send text messages
286
+ agent.sendConversationMessage('I need help with order #12345');
287
+ }
288
+ });
289
+ ```
290
+
291
+ **Important Notes:**
292
+ - Messages can only be sent during an active conversation (when `call.state === 'active'`)
293
+ - The agent will receive and process text messages just like spoken input
294
+ - Text messages may appear in the transcript depending on the agent configuration
295
+
296
+ ### Custom Audio Handling
297
+
298
+ The library automatically handles audio stream monitoring and agent state detection based on audio levels. The audio stream is available through the conversation object:
299
+
300
+ ```tsx
301
+ const conversation = useConversation();
302
+ const audioStream = conversation?.call?.remoteStream;
303
+ ```
304
+
305
+ ### Error Handling
306
+
307
+ ```tsx
308
+ const client = useClient();
309
+
310
+ useEffect(() => {
311
+ const handleError = (error: Error) => {
312
+ console.error('Agent error:', error);
313
+ // Handle error (show notification, retry connection, etc.)
314
+ };
315
+
316
+ client.on('agent.error', handleError);
317
+
318
+ return () => {
319
+ client.off('agent.error', handleError);
320
+ };
321
+ }, [client]);
322
+ ```
323
+
324
+ ### State Persistence
325
+
326
+ The library uses Jotai for state management, which automatically handles state updates across components. All state is ephemeral and resets when the provider unmounts.
327
+
328
+ ## TypeScript Support
329
+
330
+ This library is built with TypeScript and provides full type definitions. All hooks and components are fully typed for the best development experience.
331
+
332
+ ## Examples
333
+
334
+ Check out the `/src` directory for a complete example application demonstrating all features of the library.
335
+
336
+ ## Dependencies
337
+
338
+ - `@telnyx/webrtc` - Telnyx WebRTC SDK
339
+ - `eventemitter3` - Event handling
340
+ - `jotai` - State management
341
+
342
+ ## License
343
+
344
+ This library is part of the Telnyx ecosystem. Please refer to Telnyx's terms of service and licensing agreements.
345
+
346
+ ## Support
347
+
348
+ For support, please contact Telnyx support or check the [Telnyx documentation](https://developers.telnyx.com/).
349
+
350
+ ## Contributing
351
+
352
+ This library is maintained by Telnyx. For bug reports or feature requests, please contact Telnyx support.elnyx AI Agent Library
2
353
 
3
- This library provides a set of tools and utilities for building AI agents that can interact with Telnyx's services. It includes components for managing audio streams, handling agent states, and more.
package/dist/client.d.ts CHANGED
@@ -16,6 +16,7 @@ export declare class TelnyxAIAgent extends EventEmitter<AIAgentEvents> {
16
16
  constructor(params: TelnyxAIAgentConstructorParams);
17
17
  connect(): Promise<void>;
18
18
  disconnect(): Promise<void>;
19
+ sendConversationMessage(message: string): void;
19
20
  get transcript(): TranscriptItem[];
20
21
  startConversation(): Promise<void>;
21
22
  endConversation(): void | undefined;
package/dist/index.js CHANGED
@@ -2603,7 +2603,7 @@ class mi extends lt {
2603
2603
  switch (e.params.type) {
2604
2604
  case "response.text.delta": {
2605
2605
  const n = gi(e);
2606
- n && (this.transcript.push(n), this.emit("transcript.item", n)), Ee.emit("conversation.agent.state", "listening");
2606
+ n && (this.transcript.push(n), this.emit("transcript.item", n), Ee.emit("conversation.agent.state", "listening"));
2607
2607
  return;
2608
2608
  }
2609
2609
  case "conversation.item.created": {
@@ -2614,16 +2614,23 @@ class mi extends lt {
2614
2614
  }
2615
2615
  };
2616
2616
  }
2617
- const bi = 5;
2618
- class yi {
2617
+ function bi(t, e) {
2618
+ let n = 0;
2619
+ return (...i) => {
2620
+ const s = Date.now();
2621
+ s - n >= e && (n = s, t(...i));
2622
+ };
2623
+ }
2624
+ const yi = 10;
2625
+ class _i {
2619
2626
  animationFrameId = null;
2620
2627
  stream = null;
2621
2628
  audioContext = null;
2622
2629
  source = null;
2623
2630
  analyser = null;
2624
- updateAgentState = (e) => {
2631
+ updateAgentState = bi((e) => {
2625
2632
  Ee.emit("conversation.agent.state", e);
2626
- };
2633
+ }, 100);
2627
2634
  setMonitoredAudioStream(e) {
2628
2635
  this.stream && this.stopAudioStreamMonitor(), this.stream = e, this.startAudioStreamMonitor();
2629
2636
  }
@@ -2635,7 +2642,7 @@ class yi {
2635
2642
  this.audioContext = new AudioContext(), this.source = this.audioContext.createMediaStreamSource(this.stream), this.analyser = this.audioContext.createAnalyser(), this.source.connect(this.analyser), this.analyser.fftSize = 512;
2636
2643
  const e = new Uint8Array(this.analyser.frequencyBinCount), n = () => {
2637
2644
  const i = e.reduce((s, c) => s + c, 0) / e.length;
2638
- this.analyser?.getByteFrequencyData(e), i > bi ? this.updateAgentState("speaking") : this.updateAgentState("listening"), this.animationFrameId = requestAnimationFrame(n);
2645
+ this.analyser?.getByteFrequencyData(e), i >= yi ? this.updateAgentState("speaking") : this.updateAgentState("listening"), this.animationFrameId = requestAnimationFrame(n);
2639
2646
  };
2640
2647
  this.animationFrameId = requestAnimationFrame(n);
2641
2648
  }
@@ -2659,7 +2666,7 @@ class Ot extends lt {
2659
2666
  }), this.telnyxRTC.on(O.Ready, this.onClientReady), this.telnyxRTC.on(O.Error, this.onClientOrSocketError), this.telnyxRTC.on(O.SocketError, this.onClientOrSocketError), this.telnyxRTC.on(O.Notification, this.onNotification), this.transcription = new mi(this.telnyxRTC), this.transcription.addListener("transcript.item", this.onTranscriptItem), Ee.addListener(
2660
2667
  "conversation.agent.state",
2661
2668
  this.onAgentStateChange
2662
- ), this.audioStreamMonitor = new yi();
2669
+ ), this.audioStreamMonitor = new _i();
2663
2670
  }
2664
2671
  async connect() {
2665
2672
  return this.telnyxRTC.connect();
@@ -2667,6 +2674,13 @@ class Ot extends lt {
2667
2674
  async disconnect() {
2668
2675
  this.audioStreamMonitor.stopAudioStreamMonitor(), this.telnyxRTC.disconnect(), this.telnyxRTC.off(O.Ready, this.onClientReady), this.telnyxRTC.off(O.Error, this.onClientOrSocketError), this.telnyxRTC.off(O.SocketError, this.onClientOrSocketError), this.telnyxRTC.off(O.Notification, this.onNotification), this.emit("agent.disconnected"), this.transcription.removeAllListeners(), Ee.removeAllListeners(), this.removeAllListeners();
2669
2676
  }
2677
+ sendConversationMessage(e) {
2678
+ if (!this.activeCall) {
2679
+ console.error("No active call to send message.");
2680
+ return;
2681
+ }
2682
+ this.activeCall.sendConversationMessage(e);
2683
+ }
2670
2684
  get transcript() {
2671
2685
  return this.transcription.transcript;
2672
2686
  }
@@ -2716,7 +2730,7 @@ var Oe = { exports: {} }, ve = {};
2716
2730
  * LICENSE file in the root directory of this source tree.
2717
2731
  */
2718
2732
  var Lt;
2719
- function _i() {
2733
+ function wi() {
2720
2734
  if (Lt) return ve;
2721
2735
  Lt = 1;
2722
2736
  var t = Symbol.for("react.transitional.element"), e = Symbol.for("react.fragment");
@@ -2748,7 +2762,7 @@ var me = {};
2748
2762
  * LICENSE file in the root directory of this source tree.
2749
2763
  */
2750
2764
  var Mt;
2751
- function wi() {
2765
+ function Si() {
2752
2766
  return Mt || (Mt = 1, process.env.NODE_ENV !== "production" && function() {
2753
2767
  function t(v) {
2754
2768
  if (v == null) return null;
@@ -2981,10 +2995,10 @@ React keys must be passed directly to JSX without using spread:
2981
2995
  }()), me;
2982
2996
  }
2983
2997
  var Nt;
2984
- function Si() {
2985
- return Nt || (Nt = 1, process.env.NODE_ENV === "production" ? Oe.exports = _i() : Oe.exports = wi()), Oe.exports;
2998
+ function Ci() {
2999
+ return Nt || (Nt = 1, process.env.NODE_ENV === "production" ? Oe.exports = wi() : Oe.exports = Si()), Oe.exports;
2986
3000
  }
2987
- var be = Si();
3001
+ var be = Ci();
2988
3002
  const we = {}, Dt = (t, e) => t.unstable_is ? t.unstable_is(e) : e === t, Pt = (t) => "init" in t, He = (t) => !!t.write, jt = (t) => "v" in t || "e" in t, Le = (t) => {
2989
3003
  if ("e" in t)
2990
3004
  throw t.e;
@@ -2994,7 +3008,7 @@ const we = {}, Dt = (t, e) => t.unstable_is ? t.unstable_is(e) : e === t, Pt = (
2994
3008
  }, $e = /* @__PURE__ */ new WeakMap(), Ut = (t) => {
2995
3009
  var e;
2996
3010
  return Ve(t) && !!((e = $e.get(t)) != null && e[0]);
2997
- }, Ci = (t) => {
3011
+ }, Ii = (t) => {
2998
3012
  const e = $e.get(t);
2999
3013
  e?.[0] && (e[0] = !1, e[1].forEach((n) => n()));
3000
3014
  }, rn = (t, e) => {
@@ -3021,7 +3035,7 @@ const we = {}, Dt = (t, e) => t.unstable_is ? t.unstable_is(e) : e === t, Pt = (
3021
3035
  if (Ve(e))
3022
3036
  for (const a of i.d.keys())
3023
3037
  an(t, e, n(a));
3024
- i.v = e, delete i.e, (!s || !Object.is(c, i.v)) && (++i.n, Ve(c) && Ci(c));
3038
+ i.v = e, delete i.e, (!s || !Object.is(c, i.v)) && (++i.n, Ve(c) && Ii(c));
3025
3039
  }, $t = (t, e, n) => {
3026
3040
  var i;
3027
3041
  const s = /* @__PURE__ */ new Set();
@@ -3030,7 +3044,7 @@ const we = {}, Dt = (t, e) => t.unstable_is ? t.unstable_is(e) : e === t, Pt = (
3030
3044
  for (const c of e.p)
3031
3045
  s.add(c);
3032
3046
  return s;
3033
- }, Ii = () => {
3047
+ }, Ei = () => {
3034
3048
  const t = /* @__PURE__ */ new Set(), e = () => {
3035
3049
  t.forEach((n) => n());
3036
3050
  };
@@ -3048,7 +3062,7 @@ const we = {}, Dt = (t, e) => t.unstable_is ? t.unstable_is(e) : e === t, Pt = (
3048
3062
  a?.delete(s), a.size || e.delete(c);
3049
3063
  };
3050
3064
  }, n;
3051
- }, Ei = (t) => (t.c || (t.c = Qe()), t.m || (t.m = Qe()), t.u || (t.u = Qe()), t.f || (t.f = Ii()), t), ki = Symbol(), Ti = (t = /* @__PURE__ */ new WeakMap(), e = /* @__PURE__ */ new WeakMap(), n = /* @__PURE__ */ new WeakMap(), i = /* @__PURE__ */ new Set(), s = /* @__PURE__ */ new Set(), c = /* @__PURE__ */ new Set(), a = {}, l = (C, ...I) => C.read(...I), h = (C, ...I) => C.write(...I), p = (C, I) => {
3065
+ }, ki = (t) => (t.c || (t.c = Qe()), t.m || (t.m = Qe()), t.u || (t.u = Qe()), t.f || (t.f = Ei()), t), Ti = Symbol(), Ri = (t = /* @__PURE__ */ new WeakMap(), e = /* @__PURE__ */ new WeakMap(), n = /* @__PURE__ */ new WeakMap(), i = /* @__PURE__ */ new Set(), s = /* @__PURE__ */ new Set(), c = /* @__PURE__ */ new Set(), a = {}, l = (C, ...I) => C.read(...I), h = (C, ...I) => C.write(...I), p = (C, I) => {
3052
3066
  var w;
3053
3067
  return (w = C.unstable_onInit) == null ? void 0 : w.call(C, I);
3054
3068
  }, f = (C, I) => {
@@ -3312,29 +3326,29 @@ const we = {}, Dt = (t, e) => t.unstable_is ? t.unstable_is(e) : e === t, Pt = (
3312
3326
  };
3313
3327
  }
3314
3328
  };
3315
- return Object.defineProperty(ee, ki, { value: G }), ee;
3316
- }, cn = Ti, Ri = Ei, Vt = rn, ut = {};
3317
- let xi = 0;
3329
+ return Object.defineProperty(ee, Ti, { value: G }), ee;
3330
+ }, cn = Ri, xi = ki, Vt = rn, ut = {};
3331
+ let Ai = 0;
3318
3332
  function Fe(t, e) {
3319
- const n = `atom${++xi}`, i = {
3333
+ const n = `atom${++Ai}`, i = {
3320
3334
  toString() {
3321
3335
  return (ut ? "production" : void 0) !== "production" && this.debugLabel ? n + ":" + this.debugLabel : n;
3322
3336
  }
3323
3337
  };
3324
- return typeof t == "function" ? i.read = t : (i.init = t, i.read = Ai, i.write = Oi), i;
3338
+ return typeof t == "function" ? i.read = t : (i.init = t, i.read = Oi, i.write = Li), i;
3325
3339
  }
3326
- function Ai(t) {
3340
+ function Oi(t) {
3327
3341
  return t(this);
3328
3342
  }
3329
- function Oi(t, e, n) {
3343
+ function Li(t, e, n) {
3330
3344
  return e(
3331
3345
  this,
3332
3346
  typeof n == "function" ? n(t(this)) : n
3333
3347
  );
3334
3348
  }
3335
- const Li = () => {
3349
+ const Mi = () => {
3336
3350
  let t = 0;
3337
- const e = Ri({}), n = /* @__PURE__ */ new WeakMap(), i = /* @__PURE__ */ new WeakMap(), s = cn(
3351
+ const e = xi({}), n = /* @__PURE__ */ new WeakMap(), i = /* @__PURE__ */ new WeakMap(), s = cn(
3338
3352
  n,
3339
3353
  i,
3340
3354
  void 0,
@@ -3374,20 +3388,20 @@ const Li = () => {
3374
3388
  }
3375
3389
  });
3376
3390
  };
3377
- function Mi() {
3378
- return (ut ? "production" : void 0) !== "production" ? Li() : cn();
3391
+ function Ni() {
3392
+ return (ut ? "production" : void 0) !== "production" ? Mi() : cn();
3379
3393
  }
3380
3394
  let ye;
3381
- function Ni() {
3382
- return ye || (ye = Mi(), (ut ? "production" : void 0) !== "production" && (globalThis.__JOTAI_DEFAULT_STORE__ || (globalThis.__JOTAI_DEFAULT_STORE__ = ye), globalThis.__JOTAI_DEFAULT_STORE__ !== ye && console.warn(
3395
+ function Di() {
3396
+ return ye || (ye = Ni(), (ut ? "production" : void 0) !== "production" && (globalThis.__JOTAI_DEFAULT_STORE__ || (globalThis.__JOTAI_DEFAULT_STORE__ = ye), globalThis.__JOTAI_DEFAULT_STORE__ !== ye && console.warn(
3383
3397
  "Detected multiple Jotai instances. It may cause unexpected behavior with the default store. https://github.com/pmndrs/jotai/discussions/2044"
3384
3398
  ))), ye;
3385
3399
  }
3386
- const Di = {}, Pi = Bt(
3400
+ const Pi = {}, ji = Bt(
3387
3401
  void 0
3388
3402
  );
3389
3403
  function dn(t) {
3390
- return Gt(Pi) || Ni();
3404
+ return Gt(ji) || Di();
3391
3405
  }
3392
3406
  const st = (t) => typeof t?.then == "function", ot = (t) => {
3393
3407
  t.status || (t.status = "pending", t.then(
@@ -3398,7 +3412,7 @@ const st = (t) => typeof t?.then == "function", ot = (t) => {
3398
3412
  t.status = "rejected", t.reason = e;
3399
3413
  }
3400
3414
  ));
3401
- }, ji = rt.use || // A shim for older React versions
3415
+ }, Ui = rt.use || // A shim for older React versions
3402
3416
  ((t) => {
3403
3417
  if (t.status === "pending")
3404
3418
  throw t;
@@ -3453,7 +3467,7 @@ function Ge(t, e) {
3453
3467
  return h(), f;
3454
3468
  }, [s, t, n, i]), mn(p), st(p)) {
3455
3469
  const f = Ft(p, () => s.get(t));
3456
- return i && ot(f), ji(f);
3470
+ return i && ot(f), Ui(f);
3457
3471
  }
3458
3472
  return p;
3459
3473
  }
@@ -3461,7 +3475,7 @@ function Be(t, e) {
3461
3475
  const n = dn();
3462
3476
  return bn(
3463
3477
  (...s) => {
3464
- if ((Di ? "production" : void 0) !== "production" && !("write" in t))
3478
+ if ((Pi ? "production" : void 0) !== "production" && !("write" in t))
3465
3479
  throw new Error("not writable atom");
3466
3480
  return n.set(t, ...s);
3467
3481
  },
@@ -3469,10 +3483,10 @@ function Be(t, e) {
3469
3483
  );
3470
3484
  }
3471
3485
  const ln = Fe([]);
3472
- function zi() {
3486
+ function Ji() {
3473
3487
  return Ge(ln);
3474
3488
  }
3475
- function Ui() {
3489
+ function $i() {
3476
3490
  return Be(ln);
3477
3491
  }
3478
3492
  const We = () => {
@@ -3481,8 +3495,8 @@ const We = () => {
3481
3495
  throw new Error("useClient must be used within a TelnyxAIAgentProvider");
3482
3496
  return t;
3483
3497
  };
3484
- function $i() {
3485
- const t = We(), e = Ui();
3498
+ function Vi() {
3499
+ const t = We(), e = $i();
3486
3500
  return ce(() => {
3487
3501
  const n = (i) => e((s) => [...s, i]);
3488
3502
  return t.addListener("transcript.item", n), () => {
@@ -3491,14 +3505,14 @@ function $i() {
3491
3505
  }, [t, e]), null;
3492
3506
  }
3493
3507
  const un = Fe("connecting");
3494
- function Ji() {
3508
+ function Hi() {
3495
3509
  return Ge(un);
3496
3510
  }
3497
- function Vi() {
3511
+ function Fi() {
3498
3512
  return Be(un);
3499
3513
  }
3500
- function Fi() {
3501
- const t = We(), e = Vi();
3514
+ function Gi() {
3515
+ const t = We(), e = Fi();
3502
3516
  return ce(() => {
3503
3517
  const n = () => e("connected"), i = () => e("disconnected"), s = () => e("error");
3504
3518
  return t.addListener("agent.connected", n), t.addListener("agent.disconnected", i), t.addListener("agent.error", s), () => {
@@ -3507,14 +3521,14 @@ function Fi() {
3507
3521
  }, [t, e]), null;
3508
3522
  }
3509
3523
  const hn = Fe(null);
3510
- function Hi() {
3524
+ function Ki() {
3511
3525
  return Ge(hn);
3512
3526
  }
3513
- function Gi() {
3527
+ function Bi() {
3514
3528
  return Be(hn);
3515
3529
  }
3516
- const Bi = () => {
3517
- const t = We(), e = Gi();
3530
+ const Wi = () => {
3531
+ const t = We(), e = Bi();
3518
3532
  return ce(() => {
3519
3533
  const n = (i) => {
3520
3534
  e(i);
@@ -3524,14 +3538,14 @@ const Bi = () => {
3524
3538
  };
3525
3539
  }, [t, e]), null;
3526
3540
  }, pn = Fe("listening");
3527
- function Ki() {
3541
+ function Qi() {
3528
3542
  return Ge(pn);
3529
3543
  }
3530
- function Wi() {
3544
+ function qi() {
3531
3545
  return Be(pn);
3532
3546
  }
3533
- function qi() {
3534
- const t = We(), e = Wi();
3547
+ function Yi() {
3548
+ const t = We(), e = qi();
3535
3549
  return ce(() => {
3536
3550
  const n = (i) => {
3537
3551
  e(i);
@@ -3541,7 +3555,7 @@ function qi() {
3541
3555
  };
3542
3556
  }, [t, e]), null;
3543
3557
  }
3544
- const fn = Bt(null), Qi = ({
3558
+ const fn = Bt(null), Xi = ({
3545
3559
  children: t,
3546
3560
  agentId: e,
3547
3561
  environment: n,
@@ -3558,24 +3572,24 @@ const fn = Bt(null), Qi = ({
3558
3572
  }, [e, s, n, i]), ce(() => {
3559
3573
  s?.connect();
3560
3574
  }, [s]), /* @__PURE__ */ be.jsxs(fn.Provider, { value: s, children: [
3561
- /* @__PURE__ */ be.jsx($i, {}),
3562
- /* @__PURE__ */ be.jsx(Fi, {}),
3563
- /* @__PURE__ */ be.jsx(Bi, {}),
3564
- /* @__PURE__ */ be.jsx(qi, {}),
3575
+ /* @__PURE__ */ be.jsx(Vi, {}),
3576
+ /* @__PURE__ */ be.jsx(Gi, {}),
3577
+ /* @__PURE__ */ be.jsx(Wi, {}),
3578
+ /* @__PURE__ */ be.jsx(Yi, {}),
3565
3579
  t
3566
3580
  ] });
3567
3581
  };
3568
3582
  export {
3569
3583
  fn as ClientContext,
3570
3584
  Ot as TelnyxAIAgent,
3571
- Qi as TelnyxAIAgentProvider,
3572
- Ki as useAgentState,
3585
+ Xi as TelnyxAIAgentProvider,
3586
+ Qi as useAgentState,
3573
3587
  We as useClient,
3574
- Ji as useConnectionState,
3575
- Hi as useConversation,
3576
- Wi as useSetAgentState,
3577
- Vi as useSetConnectionState,
3578
- Gi as useSetConversation,
3579
- Ui as useSetTranscript,
3580
- zi as useTranscript
3588
+ Hi as useConnectionState,
3589
+ Ki as useConversation,
3590
+ qi as useSetAgentState,
3591
+ Fi as useSetConnectionState,
3592
+ Bi as useSetConversation,
3593
+ $i as useSetTranscript,
3594
+ Ji as useTranscript
3581
3595
  };
package/dist/util.d.ts CHANGED
@@ -1 +1,2 @@
1
1
  export declare function debounce<T extends unknown[]>(fn: (...args: T) => void, delay: number): (...args: T) => void;
2
+ export declare function throttle<T extends unknown[]>(fn: (...args: T) => void, delay: number): (...args: T) => void;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@telnyx/ai-agent-lib",
3
3
  "private": false,
4
- "version": "0.1.3",
4
+ "version": "0.1.5",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
7
7
  "types": "dist/index.d.ts",
@@ -25,8 +25,8 @@
25
25
  "jotai": "^2.12.5"
26
26
  },
27
27
  "devDependencies": {
28
- "@types/node": "^24.1.0",
29
28
  "@eslint/js": "^9.30.1",
29
+ "@types/node": "^24.1.0",
30
30
  "@types/react": "^19.1.8",
31
31
  "@types/react-dom": "^19.1.6",
32
32
  "@vitejs/plugin-react-swc": "^3.10.2",
@@ -34,6 +34,8 @@
34
34
  "eslint-plugin-react-hooks": "^5.2.0",
35
35
  "eslint-plugin-react-refresh": "^0.4.20",
36
36
  "globals": "^16.3.0",
37
+ "react": "^19.1.1",
38
+ "react-dom": "^19.1.1",
37
39
  "release-it": "^19.0.4",
38
40
  "typescript": "~5.8.3",
39
41
  "typescript-eslint": "^8.35.1",