@rqmii_immersive/agent-react-sdk 2.0.0 → 4.0.1

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.
Files changed (126) hide show
  1. package/README.md +103 -357
  2. package/dist/{RqmiiCloudAvatarPlayer-BnsY8xIR.js → RqmiiCloudAvatarPlayer-CESlcAGy.js} +6095 -6108
  3. package/dist/RqmiiCloudAvatarPlayer-CESlcAGy.js.map +1 -0
  4. package/dist/RqmiiCloudAvatarPlayer-D5npgPcs.cjs +2939 -0
  5. package/dist/RqmiiCloudAvatarPlayer-D5npgPcs.cjs.map +1 -0
  6. package/dist/agent-react-sdk.css +1 -1
  7. package/dist/components/RqmiiAgentRoom.d.ts +3 -0
  8. package/dist/components/RqmiiAgentRoom.d.ts.map +1 -0
  9. package/dist/components/RqmiiCloudAvatarPlayer.d.ts +3 -0
  10. package/dist/components/RqmiiCloudAvatarPlayer.d.ts.map +1 -0
  11. package/dist/components/RqmiiErrorBoundary.d.ts +19 -0
  12. package/dist/components/RqmiiErrorBoundary.d.ts.map +1 -0
  13. package/dist/components/pxs/EpicPixelStreamingPlayer.d.ts +5 -0
  14. package/dist/components/pxs/EpicPixelStreamingPlayer.d.ts.map +1 -0
  15. package/dist/core/constants.d.ts +81 -0
  16. package/dist/core/constants.d.ts.map +1 -0
  17. package/dist/core/events/emitter.d.ts +10 -0
  18. package/dist/core/events/emitter.d.ts.map +1 -0
  19. package/dist/core/managers/audio.d.ts +24 -0
  20. package/dist/core/managers/audio.d.ts.map +1 -0
  21. package/dist/core/managers/heartbeat.d.ts +13 -0
  22. package/dist/core/managers/heartbeat.d.ts.map +1 -0
  23. package/dist/core/managers/reconnect.d.ts +29 -0
  24. package/dist/core/managers/reconnect.d.ts.map +1 -0
  25. package/dist/core/managers/session.d.ts +20 -0
  26. package/dist/core/managers/session.d.ts.map +1 -0
  27. package/dist/core/managers/socket.d.ts +15 -0
  28. package/dist/core/managers/socket.d.ts.map +1 -0
  29. package/dist/core/state/reducer.d.ts +4 -0
  30. package/dist/core/state/reducer.d.ts.map +1 -0
  31. package/dist/core/state/selectors.d.ts +24 -0
  32. package/dist/core/state/selectors.d.ts.map +1 -0
  33. package/dist/core/state/types.d.ts +60 -0
  34. package/dist/core/state/types.d.ts.map +1 -0
  35. package/dist/core/utils/accumulator.d.ts +11 -0
  36. package/dist/core/utils/accumulator.d.ts.map +1 -0
  37. package/dist/core/utils/agent-type.d.ts +2 -0
  38. package/dist/core/utils/agent-type.d.ts.map +1 -0
  39. package/dist/core/utils/bytes.d.ts +2 -0
  40. package/dist/core/utils/bytes.d.ts.map +1 -0
  41. package/dist/core/utils/sleep.d.ts +2 -0
  42. package/dist/core/utils/sleep.d.ts.map +1 -0
  43. package/dist/hooks/index.d.ts +12 -0
  44. package/dist/hooks/index.d.ts.map +1 -0
  45. package/dist/hooks/use-rqmii-agent.d.ts +2 -0
  46. package/dist/hooks/use-rqmii-agent.d.ts.map +1 -0
  47. package/dist/hooks/use-rqmii-audio-element.d.ts +2 -0
  48. package/dist/hooks/use-rqmii-audio-element.d.ts.map +1 -0
  49. package/dist/hooks/use-rqmii-avatar.d.ts +13 -0
  50. package/dist/hooks/use-rqmii-avatar.d.ts.map +1 -0
  51. package/dist/hooks/use-rqmii-connection.d.ts +27 -0
  52. package/dist/hooks/use-rqmii-connection.d.ts.map +1 -0
  53. package/dist/hooks/use-rqmii-events.d.ts +3 -0
  54. package/dist/hooks/use-rqmii-events.d.ts.map +1 -0
  55. package/dist/hooks/use-rqmii-messages.d.ts +6 -0
  56. package/dist/hooks/use-rqmii-messages.d.ts.map +1 -0
  57. package/dist/hooks/use-rqmii-press-to-talk.d.ts +3 -0
  58. package/dist/hooks/use-rqmii-press-to-talk.d.ts.map +1 -0
  59. package/dist/hooks/use-rqmii-sdk.d.ts +81 -0
  60. package/dist/hooks/use-rqmii-sdk.d.ts.map +1 -0
  61. package/dist/hooks/use-rqmii-session.d.ts +9 -0
  62. package/dist/hooks/use-rqmii-session.d.ts.map +1 -0
  63. package/dist/hooks/use-rqmii-vad.d.ts +3 -0
  64. package/dist/hooks/use-rqmii-vad.d.ts.map +1 -0
  65. package/dist/hooks/use-rqmii-voice.d.ts +12 -0
  66. package/dist/hooks/use-rqmii-voice.d.ts.map +1 -0
  67. package/dist/index.cjs +1 -1
  68. package/dist/index.cjs.map +1 -1
  69. package/dist/index.d.ts +10 -340
  70. package/dist/index.d.ts.map +1 -0
  71. package/dist/index.js +270 -20
  72. package/dist/index.js.map +1 -1
  73. package/dist/provider/RqmiiAgentProvider.d.ts +4 -0
  74. package/dist/provider/RqmiiAgentProvider.d.ts.map +1 -0
  75. package/dist/provider/socket-handlers.d.ts +77 -0
  76. package/dist/provider/socket-handlers.d.ts.map +1 -0
  77. package/dist/provider/use-manager-lifecycle.d.ts +76 -0
  78. package/dist/provider/use-manager-lifecycle.d.ts.map +1 -0
  79. package/dist/types/index.d.ts +385 -0
  80. package/dist/types/index.d.ts.map +1 -0
  81. package/dist/ui/Orb.d.ts +19 -0
  82. package/dist/ui/Orb.d.ts.map +1 -0
  83. package/dist/ui/RqmiiAgentChat.d.ts +4 -0
  84. package/dist/ui/RqmiiAgentChat.d.ts.map +1 -0
  85. package/dist/ui/agent-data.d.ts +17 -0
  86. package/dist/ui/agent-data.d.ts.map +1 -0
  87. package/dist/ui/chat/ChatBox.d.ts +22 -0
  88. package/dist/ui/chat/ChatBox.d.ts.map +1 -0
  89. package/dist/ui/chat/CreditsExhaustedPanel.d.ts +6 -0
  90. package/dist/ui/chat/CreditsExhaustedPanel.d.ts.map +1 -0
  91. package/dist/ui/chat/chat-box-avatar.d.ts +3 -0
  92. package/dist/ui/chat/chat-box-avatar.d.ts.map +1 -0
  93. package/dist/ui/chat/chat-box-content.d.ts +26 -0
  94. package/dist/ui/chat/chat-box-content.d.ts.map +1 -0
  95. package/dist/ui/chat/chat-box-shared.d.ts +24 -0
  96. package/dist/ui/chat/chat-box-shared.d.ts.map +1 -0
  97. package/dist/ui/chat/chat-box-text-and-voice.d.ts +3 -0
  98. package/dist/ui/chat/chat-box-text-and-voice.d.ts.map +1 -0
  99. package/dist/ui/chat/chat-box-text.d.ts +3 -0
  100. package/dist/ui/chat/chat-box-text.d.ts.map +1 -0
  101. package/dist/ui/chat/chat-box-types.d.ts +83 -0
  102. package/dist/ui/chat/chat-box-types.d.ts.map +1 -0
  103. package/dist/ui/chat/chat-box-voice.d.ts +3 -0
  104. package/dist/ui/chat/chat-box-voice.d.ts.map +1 -0
  105. package/dist/ui/chat/components.d.ts +4 -0
  106. package/dist/ui/chat/components.d.ts.map +1 -0
  107. package/dist/ui/chat/panels.d.ts +78 -0
  108. package/dist/ui/chat/panels.d.ts.map +1 -0
  109. package/dist/ui/chat/primitives.d.ts +47 -0
  110. package/dist/ui/chat/primitives.d.ts.map +1 -0
  111. package/dist/ui/chat/utils.d.ts +7 -0
  112. package/dist/ui/chat/utils.d.ts.map +1 -0
  113. package/dist/ui/faces.d.ts +3 -0
  114. package/dist/ui/faces.d.ts.map +1 -0
  115. package/dist/ui/languages.d.ts +10 -0
  116. package/dist/ui/languages.d.ts.map +1 -0
  117. package/dist/ui.cjs +122 -1
  118. package/dist/ui.cjs.map +1 -1
  119. package/dist/ui.d.ts +11 -10
  120. package/dist/ui.d.ts.map +1 -0
  121. package/dist/ui.js +1771 -4
  122. package/dist/ui.js.map +1 -1
  123. package/package.json +33 -5
  124. package/dist/RqmiiCloudAvatarPlayer-BnsY8xIR.js.map +0 -1
  125. package/dist/RqmiiCloudAvatarPlayer-lqCz2xlU.cjs +0 -2938
  126. package/dist/RqmiiCloudAvatarPlayer-lqCz2xlU.cjs.map +0 -1
package/README.md CHANGED
@@ -1,422 +1,168 @@
1
- # Rqmii React Agent SDK
1
+ # @rqmii_immersive/agent-react-sdk
2
2
 
3
- Standalone React SDK for building realtime agent experiences in web apps.
3
+ Standalone React SDK for Rqmii Agent realtime sessions. Version 4.0.0 — complete TypeScript rewrite with reducer-based state management and event emitter system.
4
4
 
5
- This SDK gives you a LiveKit-style integration model:
6
-
7
- - room wrapper component (`RqmiiAgentRoom`)
8
- - provider (`RqmiiAgentProvider`)
9
- - hooks usable by any child component (`useRqmiiConnection`, `useRqmiiMessages`, `useRqmiiVoice`, `useRqmiiAvatar`)
10
-
11
- ## 1. Installation
5
+ ## Installation
12
6
 
13
7
  ```bash
14
8
  npm install @rqmii_immersive/agent-react-sdk
15
9
  ```
16
10
 
17
- If you are testing locally from this mono-repo:
11
+ ### Peer Dependencies
18
12
 
19
13
  ```bash
20
- npm install file:../RqmiiAgentReactSDK
14
+ npm install react react-dom lucide-react
15
+ # Optional (for 3D orb):
16
+ npm install three @react-three/fiber @react-three/drei
21
17
  ```
22
18
 
23
- ## 2. Required Configuration
24
-
25
- You must provide both URLs to the SDK:
19
+ ## Quick Start
26
20
 
27
- - `restUrl`: REST API base URL (for session init/join)
28
- - `wsUrl`: realtime Socket.IO URL
29
-
30
- Typical env values:
31
-
32
- ```env
33
- VITE_AGENT_API_URL=https://api.example.com
34
- VITE_AGENT_WS_URL=wss://realtime.example.com
35
- ```
36
-
37
- ## 3. Import Surface
38
-
39
- From the package root:
40
-
41
- ```js
42
- import {
43
- RqmiiAgentProvider,
44
- RqmiiAgentRoom,
45
- RqmiiCloudAvatarPlayer,
46
- EpicPixelStreamingPlayer,
47
- useRqmiiAgent,
48
- useRqmiiConnection,
49
- useRqmiiMessages,
50
- useRqmiiVoice,
51
- useRqmiiAvatar,
52
- useRqmiiAudioElement,
53
- useRqmiiPressToTalk,
54
- useRqmiiVAD,
55
- AGENT_TYPES,
56
- CONNECTION_STATE,
57
- CLOUD_STREAM_STATE,
58
- SOCKET_EVENTS,
59
- } from "@rqmii_immersive/agent-react-sdk";
60
- ```
61
-
62
- If your bundler requires explicit style import, also import:
63
-
64
- ```js
65
- import "@rqmii_immersive/agent-react-sdk/style.css";
66
- ```
21
+ ### Core Setup
67
22
 
68
- ## 4. Quick Start (Room Wrapper)
23
+ ```tsx
24
+ import { RqmiiAgentProvider, useRqmiiConnection, useRqmiiMessages } from '@rqmii_immersive/agent-react-sdk';
69
25
 
70
- ```jsx
71
- import {
72
- RqmiiAgentRoom,
73
- RqmiiCloudAvatarPlayer,
74
- useRqmiiConnection,
75
- useRqmiiMessages,
76
- useRqmiiAvatar,
77
- } from "@rqmii_immersive/agent-react-sdk";
26
+ function App() {
27
+ return (
28
+ <RqmiiAgentProvider wsUrl="wss://your-server" restUrl="https://your-api">
29
+ <Chat />
30
+ </RqmiiAgentProvider>
31
+ );
32
+ }
78
33
 
79
- function ChatUI() {
34
+ function Chat() {
35
+ const { initializeSession, isConnected } = useRqmiiConnection();
80
36
  const { messages, sendTextMessage } = useRqmiiMessages();
81
- const { connectionState, isSessionReady, error } = useRqmiiConnection();
82
- const { isAvatarSpeaking, cloudStreamState } = useRqmiiAvatar();
83
37
 
84
38
  return (
85
39
  <div>
86
- <div>Conn: {connectionState}</div>
87
- <div>Ready: {String(isSessionReady)}</div>
88
- <div>Avatar Speaking: {String(isAvatarSpeaking)}</div>
89
- <div>Cloud Stream: {cloudStreamState}</div>
90
- {error && <div style={{ color: "red" }}>{error}</div>}
91
-
40
+ {messages.map(m => <div key={m.id}>{m.text}</div>)}
92
41
  <button onClick={() => sendTextMessage("Hello")}>Send</button>
93
- <pre>{JSON.stringify(messages, null, 2)}</pre>
94
-
95
- <RqmiiCloudAvatarPlayer muted={false} />
96
42
  </div>
97
43
  );
98
44
  }
45
+ ```
46
+
47
+ ### Using RqmiiAgentRoom (auto-connect)
48
+
49
+ ```tsx
50
+ import { RqmiiAgentRoom, useRqmiiMessages } from '@rqmii_immersive/agent-react-sdk';
99
51
 
100
- export default function App() {
52
+ function App() {
101
53
  return (
102
54
  <RqmiiAgentRoom
103
- wsUrl={import.meta.env.VITE_AGENT_WS_URL}
104
- restUrl={import.meta.env.VITE_AGENT_API_URL}
105
- session={{ mode: "initialize", apiKey: "YOUR_API_KEY", language: "en" }}
106
- connect
107
- onError={(e) => console.error(e)}
108
- onInitialized={(data) => console.log("session initialized", data)}
55
+ wsUrl="wss://your-server"
56
+ restUrl="https://your-api"
57
+ session={{ apiKey: 'your-key', language: 'en' }}
109
58
  >
110
- <ChatUI />
59
+ <Chat />
111
60
  </RqmiiAgentRoom>
112
61
  );
113
62
  }
114
63
  ```
115
64
 
116
- ## 5. Agent-Type Integration Flows
117
-
118
- ### 5.1 Cloud Avatar
119
-
120
- Use `session.mode = 'initialize'` with `apiKey` (or `publicChatId` / `agentId`).
121
-
122
- - backend returns `streaming_url`
123
- - render `RqmiiCloudAvatarPlayer`
124
- - speaking state comes from avatar events, not audio chunks
125
-
126
- ```jsx
127
- <RqmiiAgentRoom
128
- wsUrl={WS_URL}
129
- restUrl={REST_URL}
130
- session={{ mode: "initialize", apiKey: API_KEY, language: "en" }}
131
- connect
132
- >
133
- <RqmiiCloudAvatarPlayer muted={false} />
134
- </RqmiiAgentRoom>
135
- ```
136
-
137
- ### 5.2 Desktop Avatar (User Join)
138
-
139
- User joins existing desktop avatar session by `uniqueId`:
140
-
141
- ```jsx
142
- <RqmiiAgentRoom
143
- wsUrl={WS_URL}
144
- restUrl={REST_URL}
145
- session={{ mode: "join_desktop", uniqueId: "A1B2C3" }}
146
- connect
147
- >
148
- <DesktopUI />
149
- </RqmiiAgentRoom>
150
- ```
151
-
152
- ### 5.3 Text Agent
153
-
154
- - initialize session
155
- - send text using `sendTextMessage`
156
- - read assistant chunks/final from `messages`
157
-
158
- ### 5.4 Voice / Text-and-Voice Agent
159
-
160
- - send microphone chunks via `sendAudioChunk`
161
- - signal utterance end via `endAudioStream`
162
- - audio playback handled internally via `pcm-stream-player`
163
-
164
- ## 6. Avatar State Model (Important)
165
-
166
- `isAvatarSpeaking` is server-event driven only:
167
-
168
- - starts on `avatar_speaking`
169
- - ends on `avatar_speaking_done`
170
-
171
- This means avatar speaking state is independent from PCM playback.
172
-
173
- For cloud avatar rendering lifecycle, `useRqmiiAvatar()` exposes:
174
-
175
- - `cloudStreamState`
176
- - `cloudStreamError`
177
- - `isCloudStreamConnected`
178
- - `isCloudStreamLoading`
179
-
180
- `cloudStreamState` values:
181
-
182
- - `idle`
183
- - `connecting`
184
- - `loading`
185
- - `connected`
186
- - `disconnected`
187
- - `error`
188
-
189
- ## 7. Reconnection Model
190
-
191
- The backend uses one-time session JWTs, so default Socket.IO auto-reconnect with the same token is not enough.
192
-
193
- This SDK implements the coordinator reconnect contract:
65
+ ### Full Chat Widget
194
66
 
195
- 1. connect using initial `session_token`
196
- 2. server emits `reconnect_credential` with `{ sessionId, reconnectToken, role }`
197
- 3. on disconnect, SDK reconnects with reconnect handshake auth
198
- 4. on success, server emits `reconnect_success` and rotates token
67
+ ```tsx
68
+ import { RqmiiAgentChat } from '@rqmii_immersive/agent-react-sdk/ui';
199
69
 
200
- Configurable with `reconnectOptions` on provider/room:
201
-
202
- ```jsx
203
- <RqmiiAgentRoom
204
- wsUrl={WS_URL}
205
- restUrl={REST_URL}
206
- reconnectOptions={{
207
- enabled: true,
208
- maxAttempts: 8,
209
- initialDelayMs: 500,
210
- maxDelayMs: 5000,
211
- timeoutMs: 8000,
212
- }}
213
- session={{ mode: "initialize", apiKey: API_KEY }}
214
- connect
215
- >
216
- <UI />
217
- </RqmiiAgentRoom>
218
- ```
219
-
220
- ## 8. Provider-Only Integration (No Room Wrapper)
221
-
222
- Use this when you need full manual control:
223
-
224
- ```jsx
225
- import {
226
- RqmiiAgentProvider,
227
- useRqmiiConnection,
228
- } from "@rqmii_immersive/agent-react-sdk";
229
-
230
- function Controller() {
231
- const { initializeSession, joinDesktopSession, disconnect } =
232
- useRqmiiConnection();
233
-
234
- return (
235
- <div>
236
- <button
237
- onClick={() => initializeSession({ apiKey: API_KEY, language: "en" })}
238
- >
239
- Init
240
- </button>
241
- <button onClick={() => joinDesktopSession({ uniqueId: "A1B2C3" })}>
242
- Join Desktop
243
- </button>
244
- <button onClick={disconnect}>Disconnect</button>
245
- </div>
246
- );
247
- }
248
-
249
- export default function App() {
70
+ function App() {
250
71
  return (
251
- <RqmiiAgentProvider wsUrl={WS_URL} restUrl={REST_URL}>
252
- <Controller />
253
- </RqmiiAgentProvider>
72
+ <RqmiiAgentChat
73
+ wsUrl="wss://your-server"
74
+ restUrl="https://your-api"
75
+ publicChatId="your-chat-id"
76
+ />
254
77
  );
255
78
  }
256
79
  ```
257
80
 
258
- ## 9. Hook Reference
259
-
260
- ### `useRqmiiConnection()`
261
-
262
- Returns:
263
-
264
- - `connectionState`
265
- - `isConnected`
266
- - `isSessionReady`
267
- - `error`
268
- - `reconnectAttempt`
269
- - `session`
270
- - `initializeSession(args)`
271
- - `joinDesktopSession(args)`
272
- - `disconnect()`
273
-
274
- ### `useRqmiiMessages()`
275
-
276
- Returns:
277
-
278
- - `messages`
279
- - `sendTextMessage(text)`
280
- - `clearMessages()`
281
-
282
- Message stream behavior:
283
-
284
- - server chunks update streaming assistant message (`agent_response_chunk`)
285
- - final response completes that message (`agent_response`)
81
+ ## Architecture
286
82
 
287
- ### `useRqmiiVoice()`
83
+ ### Entry Points
288
84
 
289
- Returns:
85
+ - `@rqmii_immersive/agent-react-sdk` — Core: provider, hooks, types, constants
86
+ - `@rqmii_immersive/agent-react-sdk/ui` — UI components: chat widget, avatar player, orb
87
+ - `@rqmii_immersive/agent-react-sdk/style.css` — Chat widget styles
290
88
 
291
- - `sendAudioChunk(audio)`
292
- - `endAudioStream()`
293
- - `isAudioPlaying`
294
- - `transcript`
295
- - `partialTranscript`
296
- - `interrupt()`
297
- - `resumeAudioPlayback()`
298
- - `attachAudioElement(element)`
89
+ ### State Management
299
90
 
300
- ### `useRqmiiAvatar()`
91
+ State is managed via `useReducer` with a single `RqmiiState` shape. All mutations go through typed actions.
301
92
 
302
- Returns:
93
+ ### Event System
303
94
 
304
- - `streamingUrl`
305
- - `isAvatarSpeaking`
306
- - `speakingSource` (`'avatar_events'`)
307
- - `isCloudAvatar`
308
- - `isDesktopAvatar`
309
- - `cloudStreamState`
310
- - `cloudStreamError`
311
- - `isCloudStreamConnected`
312
- - `isCloudStreamLoading`
313
- - `setCloudStreamState(nextState, error?)`
95
+ The provider exposes an `events` EventEmitter for subscribing to lifecycle events:
314
96
 
315
- ### `useRqmiiAudioElement(audioRef)`
97
+ ```tsx
98
+ import { useRqmiiAgent } from '@rqmii_immersive/agent-react-sdk';
316
99
 
317
- Optional helper to bind an audio element and improve autoplay unlock UX.
100
+ function Component() {
101
+ const { events } = useRqmiiAgent();
318
102
 
319
- Note: voice playback does not require HTML audio element because SDK uses WebAudio (`pcm-stream-player`).
320
-
321
- ### `useRqmiiPressToTalk(options?)`
322
-
323
- Built-in press-and-release voice input mode.
324
-
325
- - streams mic chunks to backend (`audio_chunk`)
326
- - sends `audio_end` automatically on release
327
- - exposes ready-to-spread button handlers via `eventHandlers`
328
-
329
- Minimal usage:
330
-
331
- ```jsx
332
- const { eventHandlers, isRecording } = useRqmiiPressToTalk();
333
- <button {...eventHandlers}>
334
- {isRecording ? "Recording..." : "Hold to Talk"}
335
- </button>;
336
- ```
337
-
338
- ### `useRqmiiVAD(options?)`
339
-
340
- Built-in VAD (voice activity detection) mode using `@ricky0123/vad-react`.
341
-
342
- - toggle VAD listening with `toggle()`
343
- - auto interrupts on speech start (configurable)
344
- - handles pre-speech padding and streaming chunks/end events
345
-
346
- Minimal usage:
347
-
348
- ```jsx
349
- const { toggle, isListening, isSpeaking } = useRqmiiVAD();
103
+ useEffect(() => {
104
+ const unsub = events.on('session:ready', (payload) => {
105
+ console.log('Session ready', payload);
106
+ });
107
+ return unsub;
108
+ }, []);
109
+ }
350
110
  ```
351
111
 
352
- ## 10. Cloud Player Wrapper API
353
-
354
- `RqmiiCloudAvatarPlayer` props:
355
-
356
- - `className`
357
- - `style`
358
- - `autoConnect` (default `true`)
359
- - `muted` (default `false`)
360
- - `onConnected()`
361
- - `onDisconnected()`
362
- - `onError(error)`
363
-
364
- Internally it forwards cloud stream lifecycle to context state.
365
-
366
- ## 11. Error Handling Strategy
367
-
368
- - fatal session/socket errors populate `error` in connection state
369
- - `TTS_ERROR` socket errors are treated as non-fatal by default
370
- - reconnect failures transition to `connectionState = failed`
371
-
372
- Recommended UI behavior:
373
-
374
- - show persistent banner for `error`
375
- - show reconnect indicator while `connectionState === reconnecting`
376
- - offer retry button that calls `initializeSession` again
377
-
378
- ## 12. Production Checklist
379
-
380
- - use secure `https/wss` URLs in production
381
- - ensure CORS allows browser origins for REST and Socket.IO
382
- - pass correct API key/public chat id per environment
383
- - monitor reconnect failures and auth errors in logs
384
- - handle browser autoplay policies with user gesture before first audio
112
+ Available events: `session:ready`, `session:joined`, `session:terminated`, `session:expired`, `message:received`, `message:sent`, `audio:playing`, `audio:stopped`, `avatar:speaking`, `avatar:speaking_done`, `state:changed`, `connection:connected`, `connection:disconnected`, `connection:reconnecting`, `connection:failed`, `error`, `credits:exhausted`, `transcript`, `partial_transcript`, `interrupted`.
385
113
 
386
- ## 13. Troubleshooting
114
+ ## API Reference
387
115
 
388
- ### Session initializes but socket fails auth
116
+ ### RqmiiAgentProvider Props
389
117
 
390
- Check:
118
+ | Prop | Type | Default | Description |
119
+ |------|------|---------|-------------|
120
+ | `wsUrl` | `string` | required | WebSocket server URL |
121
+ | `restUrl` | `string` | required | REST API base URL |
122
+ | `reconnectOptions` | `RqmiiReconnectOptions` | `{ enabled: true, maxAttempts: 8, initialDelayMs: 500, maxDelayMs: 5000, timeoutMs: 8000 }` | Reconnection config |
123
+ | `enableAudio` | `boolean` | `true` | Enable PCM audio playback |
124
+ | `pcmOptions` | `RqmiiPCMOptions` | `{ encoding: '16bitInt', channels: 1, sampleRate: 16000 }` | PCM player config |
125
+ | `debug` | `boolean` | `false` | Enable debug logging |
126
+ | `withCredentials` | `boolean` | `false` | Include cookies in CORS requests |
127
+ | `heartbeatIntervalSeconds` | `number` | `15` | Heartbeat interval |
128
+ | `onSessionExpired` | `(payload?) => void` | — | Callback |
129
+ | `onSessionTerminated` | `() => void` | — | Callback |
130
+ | `onError` | `(payload?) => void` | — | Callback |
131
+ | `onDisconnect` | `(reason?) => void` | — | Callback |
132
+ | `onReconnectSuccess` | `(payload?) => void` | — | Callback |
133
+ | `onReconnectFailed` | `(payload?) => void` | — | Callback |
391
134
 
392
- - `wsUrl` points to `RqmiiAgentBackendJs`
393
- - token is passed via SDK flow (do not manually override connect handshake)
394
- - backend clocks are synchronized for JWT expiry
135
+ ### Hooks
395
136
 
396
- ### Cloud avatar not visible
137
+ | Hook | Returns |
138
+ |------|---------|
139
+ | `useRqmiiAgent()` | Full context value |
140
+ | `useRqmiiConnection()` | Connection state + session actions |
141
+ | `useRqmiiSession()` | Session state booleans |
142
+ | `useRqmiiMessages()` | Messages array + send/clear |
143
+ | `useRqmiiVoice()` | Audio controls + transcript |
144
+ | `useRqmiiAvatar()` | Avatar state + cloud stream |
145
+ | `useRqmiiAudioElement(ref)` | Attaches audio element |
146
+ | `useRqmiiPressToTalk(options)` | PTT recording |
147
+ | `useRqmiiVAD(options)` | Voice Activity Detection |
148
+ | `useRqmiiEvents(event, handler, deps)` | Event subscription |
397
149
 
398
- Check:
150
+ ## Breaking Changes from v3
399
151
 
400
- - `/sessions/init` response includes `streaming_url`
401
- - `RqmiiCloudAvatarPlayer` is rendered
402
- - network allows signaling/WebRTC paths
152
+ 1. **`useRqmiiSessionState` renamed to `useRqmiiSession`** — The hook is now `useRqmiiSession()`.
403
153
 
404
- ### Avatar speaking UI not updating
154
+ 2. **Context value spread** — The context value now includes all state fields directly (no nested `state` object). Access `ctx.messages` instead of `ctx.state.messages`.
405
155
 
406
- Check:
156
+ 3. **Event emitter replaces some callbacks** — While legacy callbacks (`onSessionExpired`, etc.) still work, the preferred approach is using `events.on()`.
407
157
 
408
- - server emits `avatar_speaking` and `avatar_speaking_done`
409
- - your UI reads `isAvatarSpeaking` from `useRqmiiAvatar()`
158
+ 4. **TypeScript only** — All source is now `.ts`/`.tsx`. JavaScript consumers get full type inference via bundled `.d.ts` files.
410
159
 
411
- ### Voice playback missing for text-and-voice
160
+ 5. **`terminateSession` return type simplified** — Now returns `Promise<{ success: boolean }>` instead of the previous shape with `skipped` and `error` fields.
412
161
 
413
- Check:
162
+ 6. **`useRqmiiVAD` return** — Added `isErrored` field to match the VAD library's state.
414
163
 
415
- - agent type is not avatar (`cloud_avatar`/`desktop_avatar`)
416
- - browser has user interaction to unlock audio context
417
- - `agent_audio_chunk` events are arriving from server
164
+ 7. **Internal module structure changed** — If you were importing from internal paths (e.g., `@rqmii_immersive/agent-react-sdk/react/core/...`), those paths no longer exist. Use the public exports only.
418
165
 
419
- ## 14. Current Scope
166
+ ## License
420
167
 
421
- This SDK supports React, TypeScript (ships `.d.ts`), and Next.js client-side integration.
422
- Use it inside client components (`"use client"`), since realtime sockets/media APIs are browser runtime features.
168
+ UNLICENSED