@centive/aria-sdk 0.9.0 → 0.9.2

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
@@ -122,9 +122,78 @@ The SDK connects to your backend via WebSocket. Your backend handles:
122
122
  1. **User Authentication** - Validate the connecting user
123
123
  2. **Session Token Generation** - Create Anam AI sessions
124
124
  3. **Persona Configuration** - Control AI behavior server-side (avatar, voice, LLM, system prompt)
125
+ 4. **Message Storage** - Store conversation history (optional)
126
+
127
+ ### Messages from SDK to Backend
128
+
129
+ #### 1. Session Request (user_trigger)
130
+
131
+ Sent when user opens the widget to request a new session token.
132
+
133
+ ```json
134
+ {
135
+ "user_trigger": true,
136
+ "userId": "user_123",
137
+ "skip_greeting": true // true after first session (to skip greeting on reopen)
138
+ }
139
+ ```
140
+
141
+ | Field | Type | Description |
142
+ |-------|------|-------------|
143
+ | `user_trigger` | boolean | Always `true` when requesting a session |
144
+ | `userId` | string | User identifier passed to `Aria.init()` |
145
+ | `skip_greeting` | boolean | `true` if user has already had a session (skip greeting on subsequent opens) |
146
+
147
+ #### 2. Message History
148
+
149
+ Sent when conversation messages are updated.
150
+
151
+ ```json
152
+ {
153
+ "type": "message_history",
154
+ "session_id": "anam_session_abc123",
155
+ "user_id": "user_123",
156
+ "messages": [
157
+ { "role": "persona", "content": "Hello! How can I help?", "timestamp": "2026-01-29T12:00:00.000Z" },
158
+ { "role": "user", "content": "I need help with my account", "timestamp": "2026-01-29T12:00:05.000Z" }
159
+ ]
160
+ }
161
+ ```
162
+
163
+ #### 3. Message Stream
164
+
165
+ Sent for real-time message streaming (as user/persona speaks).
166
+
167
+ ```json
168
+ {
169
+ "type": "message_stream",
170
+ "session_id": "anam_session_abc123",
171
+ "user_id": "user_123",
172
+ "message": {
173
+ "role": "user",
174
+ "content": "partial transcript...",
175
+ "timestamp": "2026-01-29T12:00:05.000Z",
176
+ "is_final": false
177
+ }
178
+ }
179
+ ```
180
+
181
+ #### 4. Session End
182
+
183
+ Sent when user closes the widget (hangs up).
184
+
185
+ ```json
186
+ {
187
+ "type": "session_end",
188
+ "session_id": "anam_session_abc123",
189
+ "user_id": "user_123"
190
+ }
191
+ ```
125
192
 
126
193
  ### Expected Response Format
127
194
 
195
+ #### Session Token Response
196
+
128
197
  ```json
129
198
  {
130
199
  "status": "success",
@@ -138,6 +207,19 @@ The SDK connects to your backend via WebSocket. Your backend handles:
138
207
  }
139
208
  ```
140
209
 
210
+ #### Message Acknowledgments (Optional)
211
+
212
+ ```json
213
+ // Message history acknowledgment
214
+ { "status": "ok", "type": "message_history_ack", "message_count": 5 }
215
+
216
+ // Message stream acknowledgment (for is_final: true)
217
+ { "status": "ok", "type": "message_stream_ack" }
218
+
219
+ // Session end acknowledgment
220
+ { "status": "ok", "type": "session_end_ack", "message": "Session ended", "saved_count": 10 }
221
+ ```
222
+
141
223
  ### Backend Example (Node.js)
142
224
 
143
225
  ```javascript
@@ -150,40 +232,94 @@ wss.on('connection', (ws) => {
150
232
  ws.on('message', async (message) => {
151
233
  const data = JSON.parse(message);
152
234
 
235
+ // Handle session request
153
236
  if (data.user_trigger !== undefined) {
154
- const session = await createAnamSession(data.userId);
237
+ const startTime = Date.now();
238
+ const session = await createAnamSession(data.userId, data.skip_greeting);
155
239
 
156
240
  ws.send(JSON.stringify({
157
241
  status: 'success',
158
242
  message: 'Session created',
159
243
  session_data: {
160
244
  session_id: session.id,
161
- token: session.token,
245
+ token: session.sessionToken,
162
246
  expires_at: session.expiresAt,
163
247
  },
164
248
  time_taken: Date.now() - startTime,
165
249
  }));
166
250
  }
251
+
252
+ // Handle message history (store in database)
253
+ if (data.type === 'message_history') {
254
+ await storeMessages(data.session_id, data.user_id, data.messages);
255
+ ws.send(JSON.stringify({
256
+ status: 'ok',
257
+ type: 'message_history_ack',
258
+ message_count: data.messages.length,
259
+ }));
260
+ }
261
+
262
+ // Handle session end
263
+ if (data.type === 'session_end') {
264
+ await finalizeSession(data.session_id, data.user_id);
265
+ ws.send(JSON.stringify({
266
+ status: 'ok',
267
+ type: 'session_end_ack',
268
+ message: 'Session ended',
269
+ saved_count: 10,
270
+ }));
271
+ }
167
272
  });
168
273
  });
169
274
 
170
- async function createAnamSession(userId) {
171
- const response = await axios.post('https://api.anam.ai/v1/sessions', {
172
- persona: {
173
- name: 'Aria',
174
- avatarId: 'your-avatar-id',
175
- voiceId: 'your-voice-id',
176
- llmId: 'your-llm-id',
177
- systemPrompt: 'You are Aria, a helpful AI assistant.',
275
+ async function createAnamSession(userId, skipGreeting = false) {
276
+ const response = await axios.post(
277
+ 'https://api.anam.ai/v1/auth/session-token',
278
+ {
279
+ personaConfig: {
280
+ name: 'Aria',
281
+ avatarId: 'your-avatar-id',
282
+ voiceId: 'your-voice-id',
283
+ llmId: 'your-llm-id',
284
+ systemPrompt: 'You are Aria, a helpful AI assistant.',
285
+ skip_greeting: skipGreeting, // Pass skip_greeting to Anam
286
+ },
178
287
  },
179
- }, {
180
- headers: { 'Authorization': `Bearer ${process.env.ANAM_API_KEY}` }
181
- });
288
+ {
289
+ headers: { 'Authorization': `Bearer ${process.env.ANAM_API_KEY}` },
290
+ }
291
+ );
182
292
 
183
293
  return response.data;
184
294
  }
295
+
296
+ async function storeMessages(sessionId, userId, messages) {
297
+ // Store messages in your database
298
+ console.log(`Storing ${messages.length} messages for user ${userId}`);
299
+ }
300
+
301
+ async function finalizeSession(sessionId, userId) {
302
+ // Mark session as complete, perform any cleanup
303
+ console.log(`Session ${sessionId} ended for user ${userId}`);
304
+ }
185
305
  ```
186
306
 
307
+ ## Session Lifecycle
308
+
309
+ The SDK manages Anam sessions automatically:
310
+
311
+ | Event | What Happens |
312
+ |-------|--------------|
313
+ | **Widget Opens (first time)** | Sends `user_trigger` with `skip_greeting: false` → Creates Anam session with greeting |
314
+ | **Widget Closes (hang up)** | Sends `session_end` → Ends Anam session to free resources |
315
+ | **Widget Reopens** | Sends `user_trigger` with `skip_greeting: true` → Creates new session without greeting |
316
+ | **Page Refresh** | Sends `user_trigger` with `skip_greeting: false` → Fresh session with greeting |
317
+
318
+ This ensures:
319
+ - Anam resources are freed when the widget is closed
320
+ - Users don't hear the greeting repeatedly when reopening the widget
321
+ - Conversation context can be restored via your backend's message storage
322
+
187
323
  ## Session Persistence
188
324
 
189
325
  For video sessions to persist across page navigation, initialize the SDK at the **root level** of your application:
@@ -1 +1 @@
1
- {"version":3,"file":"AriaStandaloneUI.d.ts","sourceRoot":"","sources":["../../src/components/AriaStandaloneUI.tsx"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAA4C,KAAK,EAAE,EAAE,MAAM,OAAO,CAAC;AAgB1E,OAAO,KAAK,EAOV,KAAK,EACN,MAAM,SAAS,CAAC;AAOjB,UAAU,qBAAqB;IAC7B,KAAK,EAAE,KAAK,CAAC;IACb,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,WAAW,CAAC;CACxB;AAED,eAAO,MAAM,gBAAgB,EAAE,EAAE,CAAC,qBAAqB,CAmhBtD,CAAC;AA45BF,eAAe,gBAAgB,CAAC"}
1
+ {"version":3,"file":"AriaStandaloneUI.d.ts","sourceRoot":"","sources":["../../src/components/AriaStandaloneUI.tsx"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAA4C,KAAK,EAAE,EAAE,MAAM,OAAO,CAAC;AAgB1E,OAAO,KAAK,EAOV,KAAK,EACN,MAAM,SAAS,CAAC;AAOjB,UAAU,qBAAqB;IAC7B,KAAK,EAAE,KAAK,CAAC;IACb,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,WAAW,CAAC;CACxB;AAED,eAAO,MAAM,gBAAgB,EAAE,EAAE,CAAC,qBAAqB,CAmjBtD,CAAC;AA45BF,eAAe,gBAAgB,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"AriaProvider.d.ts","sourceRoot":"","sources":["../../src/context/AriaProvider.tsx"],"names":[],"mappings":"AAAA,OAAO,EAA4C,KAAK,EAAE,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAW1F,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAK7C,UAAU,iBAAiB;IACzB,MAAM,EAAE,aAAa,CAAC;IACtB,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB;AAMD,eAAO,MAAM,YAAY,EAAE,EAAE,CAAC,iBAAiB,CAmmB9C,CAAC"}
1
+ {"version":3,"file":"AriaProvider.d.ts","sourceRoot":"","sources":["../../src/context/AriaProvider.tsx"],"names":[],"mappings":"AAAA,OAAO,EAA4C,KAAK,EAAE,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAW1F,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAK7C,UAAU,iBAAiB;IACzB,MAAM,EAAE,aAAa,CAAC;IACtB,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB;AAMD,eAAO,MAAM,YAAY,EAAE,EAAE,CAAC,iBAAiB,CA+nB9C,CAAC"}