@convai/web-sdk 1.2.1-beta.0 → 1.2.1-beta.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.
- package/README.md +187 -29
- package/dist/core/ConvaiClient.d.ts +4 -7
- package/dist/core/ConvaiClient.d.ts.map +1 -1
- package/dist/core/ConvaiClient.js +74 -24
- package/dist/core/ConvaiClient.js.map +1 -1
- package/dist/core/MessageHandler.d.ts +1 -7
- package/dist/core/MessageHandler.d.ts.map +1 -1
- package/dist/core/MessageHandler.js +8 -21
- package/dist/core/MessageHandler.js.map +1 -1
- package/dist/core/types.d.ts +116 -8
- package/dist/core/types.d.ts.map +1 -1
- package/dist/index.d.ts +0 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/lipsync-helpers/mappingTypes.d.ts +1 -1
- package/dist/lipsync-helpers/mappingTypes.js +4 -4
- package/dist/react/hooks/useConvaiClient.d.ts.map +1 -1
- package/dist/react/hooks/useConvaiClient.js +0 -1
- package/dist/react/hooks/useConvaiClient.js.map +1 -1
- package/dist/types/index.d.ts +116 -5
- package/dist/types/index.d.ts.map +1 -1
- package/dist/vanilla/ConvaiWidget.d.ts.map +1 -1
- package/dist/vanilla/ConvaiWidget.js.map +1 -1
- package/dist/vanilla/index.d.ts +2 -1
- package/dist/vanilla/index.d.ts.map +1 -1
- package/dist/vanilla/index.js +2 -0
- package/dist/vanilla/index.js.map +1 -1
- package/dist/vanilla/types.d.ts +0 -1
- package/dist/vanilla/types.d.ts.map +1 -1
- package/package.json +1 -1
- package/dist/dev.d.ts +0 -12
- package/dist/dev.d.ts.map +0 -1
- package/dist/dev.js +0 -12
- package/dist/dev.js.map +0 -1
- package/dist/utils/LatencyMonitor.d.ts +0 -88
- package/dist/utils/LatencyMonitor.d.ts.map +0 -1
- package/dist/utils/LatencyMonitor.js +0 -136
- package/dist/utils/LatencyMonitor.js.map +0 -1
package/README.md
CHANGED
|
@@ -55,10 +55,6 @@ Primary exports:
|
|
|
55
55
|
- `ScreenShareControls`
|
|
56
56
|
- `IConvaiClient`
|
|
57
57
|
- All exports from `@convai/web-sdk/lipsync-helpers`
|
|
58
|
-
- Type exports for latency models:
|
|
59
|
-
- `LatencyMonitor` (type)
|
|
60
|
-
- `LatencyMeasurement`
|
|
61
|
-
- `LatencyStats`
|
|
62
58
|
|
|
63
59
|
### `@convai/web-sdk/react`
|
|
64
60
|
|
|
@@ -212,6 +208,11 @@ const convaiClient = useConvaiClient({
|
|
|
212
208
|
apiKey: import.meta.env.VITE_CONVAI_API_KEY,
|
|
213
209
|
characterId: import.meta.env.VITE_CONVAI_CHARACTER_ID,
|
|
214
210
|
endUserId: "<UNIQUE_END_USER_ID>",
|
|
211
|
+
endUserMetadata: {
|
|
212
|
+
name: "John Doe",
|
|
213
|
+
age: "30",
|
|
214
|
+
// Add any additional metadata you want to send
|
|
215
|
+
},
|
|
215
216
|
enableVideo: true,
|
|
216
217
|
startWithVideoOn: false,
|
|
217
218
|
startWithAudioOn: false,
|
|
@@ -268,6 +269,16 @@ useEffect(() => {
|
|
|
268
269
|
|
|
269
270
|
const unsubState = convaiClient.on("stateChange", (state) => {
|
|
270
271
|
console.log("State:", state.agentState);
|
|
272
|
+
|
|
273
|
+
// Access end user information from connection response
|
|
274
|
+
if (state.endUserId) {
|
|
275
|
+
console.log("End User ID:", state.endUserId);
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
if (state.endUserMetadata) {
|
|
279
|
+
console.log("End User Metadata:", state.endUserMetadata);
|
|
280
|
+
// Example: { name: 'John', age: '30' }
|
|
281
|
+
}
|
|
271
282
|
});
|
|
272
283
|
|
|
273
284
|
const unsubMessages = convaiClient.on("messagesChange", (messages) => {
|
|
@@ -389,6 +400,9 @@ await client.disconnect();
|
|
|
389
400
|
- `state.isThinking`: model is generating response
|
|
390
401
|
- `state.isSpeaking`: model audio is currently speaking
|
|
391
402
|
- `state.agentState`: combined high-level state (`disconnected | connected | listening | thinking | speaking`)
|
|
403
|
+
- `state.endUserId`: end user ID returned from the connection response (if provided in config)
|
|
404
|
+
- `state.endUserMetadata`: end user metadata returned from the connection response (if provided in config)
|
|
405
|
+
- `state.metrics`: array of metrics events received during the current session (clears on `resetSession()`)
|
|
392
406
|
|
|
393
407
|
### Widget lifecycle
|
|
394
408
|
|
|
@@ -405,6 +419,7 @@ Both React and vanilla widgets:
|
|
|
405
419
|
| `apiKey` | `string` | Yes | - | Convai API key. |
|
|
406
420
|
| `characterId` | `string` | Yes | - | Target character identifier. |
|
|
407
421
|
| `endUserId` | `string` | No | `undefined` | Stable end-user identity for memory/analytics continuity. |
|
|
422
|
+
| `endUserMetadata` | `Record<string, unknown>` | No | `undefined` | Additional end-user metadata (e.g., name, age) sent with the connection request. |
|
|
408
423
|
| `url` | `string` | No | SDK internal default | Convai base URL. Set explicitly if your deployment requires a specific environment. |
|
|
409
424
|
| `enableVideo` | `boolean` | No | `false` | Enables video-capable connection type. |
|
|
410
425
|
| `startWithVideoOn` | `boolean` | No | `false` | Auto-enable camera after connect. |
|
|
@@ -428,15 +443,16 @@ import { ConvaiClient } from "@convai/web-sdk/core";
|
|
|
428
443
|
For TypeScript, use the types exported from the main package or core:
|
|
429
444
|
|
|
430
445
|
- **`IConvaiClient`** — Interface implemented by `ConvaiClient`. Use this when you need to type variables, props, or function parameters that accept the client (e.g. `client: IConvaiClient`).
|
|
431
|
-
- **`ConvaiClientState`** — Shape of `client.state` (connection and activity flags: `isConnected`, `isBotReady`, `agentState`, `emotion`, etc.).
|
|
446
|
+
- **`ConvaiClientState`** — Shape of `client.state` (connection and activity flags: `isConnected`, `isBotReady`, `agentState`, `emotion`, `endUserId`, `endUserMetadata`, `metrics`, etc.).
|
|
432
447
|
- **`ConvaiConfig`** — Configuration object for `new ConvaiClient(config)` and `client.connect(config)`.
|
|
433
448
|
- **`ChatMessage`** — Single message in `client.chatMessages`.
|
|
449
|
+
- **`ConvaiMetrics`** — Metrics event structure containing data, timestamp, and unique identifier.
|
|
434
450
|
- **`AudioControls`**, **`VideoControls`**, **`ScreenShareControls`** — Types for the control managers exposed as `client.audioControls`, `client.videoControls`, `client.screenShareControls`.
|
|
435
451
|
|
|
436
452
|
Example:
|
|
437
453
|
|
|
438
454
|
```ts
|
|
439
|
-
import type { IConvaiClient, ConvaiClientState, ConvaiConfig } from "@convai/web-sdk";
|
|
455
|
+
import type { IConvaiClient, ConvaiClientState, ConvaiConfig, ConvaiMetrics } from "@convai/web-sdk";
|
|
440
456
|
// or from "@convai/web-sdk/core" when using core-only
|
|
441
457
|
```
|
|
442
458
|
|
|
@@ -463,7 +479,6 @@ new ConvaiClient(config?: ConvaiConfig)
|
|
|
463
479
|
| `audioControls` | `AudioControls` | Microphone controls. |
|
|
464
480
|
| `videoControls` | `VideoControls` | Camera controls. |
|
|
465
481
|
| `screenShareControls` | `ScreenShareControls` | Screen sharing controls. |
|
|
466
|
-
| `latencyMonitor` | `LatencyMonitor` | Measurement manager used by the client for turn latency. |
|
|
467
482
|
| `blendshapeQueue` | `BlendshapeQueue` | Buffer queue for lipsync frames. |
|
|
468
483
|
| `conversationSessionId` | `number` | Incremental turn session ID used by conversation events. |
|
|
469
484
|
|
|
@@ -479,7 +494,7 @@ new ConvaiClient(config?: ConvaiConfig)
|
|
|
479
494
|
| `sendTriggerMessage` | `(triggerName?: string, triggerMessage?: string) => void` | Send trigger/action message. |
|
|
480
495
|
| `sendInterruptMessage` | `() => void` | Interrupt current bot response. |
|
|
481
496
|
| `updateTemplateKeys` | `(templateKeys: Record<string, string>) => void` | Update runtime template variables. |
|
|
482
|
-
| `updateDynamicInfo` | `(dynamicInfo:
|
|
497
|
+
| `updateDynamicInfo` | `(dynamicInfo: string) => void` | Update dynamic context with a text description. |
|
|
483
498
|
| `toggleTts` | `(enabled: boolean) => void` | Enable/disable TTS for subsequent responses. |
|
|
484
499
|
| `on` | `(event: string, callback: (...args: any[]) => void) => () => void` | Subscribe to an event and receive an unsubscribe function. |
|
|
485
500
|
| `off` | `(event: string, callback: (...args: any[]) => void) => void` | Remove a specific listener. |
|
|
@@ -501,7 +516,7 @@ new ConvaiClient(config?: ConvaiConfig)
|
|
|
501
516
|
| `turnEnd` | `{ sessionId, duration, timestamp }` | Server signaled end of turn (bot stopped speaking). Same semantics as `BlendshapeQueue.hasReceivedEndSignal()`. |
|
|
502
517
|
| `blendshapes` | `unknown` | Incoming blendshape chunk payload. |
|
|
503
518
|
| `blendshapeStatsReceived` | `unknown` | End-of-turn blendshape stats marker. |
|
|
504
|
-
| `
|
|
519
|
+
| `metrics` | `Record<string, unknown>` | Metrics data received from server. Multiple metrics events may occur per conversation. |
|
|
505
520
|
|
|
506
521
|
### Control manager APIs
|
|
507
522
|
|
|
@@ -564,30 +579,174 @@ Methods:
|
|
|
564
579
|
- `on("screenShareStateChange", callback)`
|
|
565
580
|
- `off("screenShareStateChange", callback)`
|
|
566
581
|
|
|
567
|
-
### `
|
|
582
|
+
### Using `updateDynamicInfo` for real-time context
|
|
568
583
|
|
|
569
|
-
`
|
|
584
|
+
The `updateDynamicInfo` method allows you to send real-time context to the character using a simple text description.
|
|
570
585
|
|
|
571
|
-
|
|
586
|
+
#### Basic usage
|
|
572
587
|
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
- `cancelMeasurement()`
|
|
578
|
-
- `getMeasurements()`
|
|
579
|
-
- `getLatestMeasurement()`
|
|
580
|
-
- `getStats()`
|
|
581
|
-
- `clear()`
|
|
582
|
-
- `getPendingMeasurement()`
|
|
583
|
-
- `on("measurement", callback)`
|
|
584
|
-
- `on("measurementsChange", callback)`
|
|
585
|
-
- `on("enabledChange", callback)`
|
|
588
|
+
```tsx
|
|
589
|
+
// Simple text description
|
|
590
|
+
convaiClient.updateDynamicInfo("Player health is low");
|
|
591
|
+
```
|
|
586
592
|
|
|
587
|
-
|
|
593
|
+
#### Advanced usage with detailed context
|
|
594
|
+
|
|
595
|
+
```tsx
|
|
596
|
+
// Game state example
|
|
597
|
+
convaiClient.updateDynamicInfo(
|
|
598
|
+
"Player is in combat with 25% health and 40% stamina at battlefield location, 3 enemies nearby, equipped with sword"
|
|
599
|
+
);
|
|
600
|
+
```
|
|
601
|
+
|
|
602
|
+
#### Using in connect config
|
|
603
|
+
|
|
604
|
+
```tsx
|
|
605
|
+
const config: ConvaiConfig = {
|
|
606
|
+
apiKey: 'your-api-key',
|
|
607
|
+
characterId: 'your-character-id',
|
|
608
|
+
dynamicInfo: "Initial game state: Player at spawn point, level 1, tutorial not complete",
|
|
609
|
+
// Other config fields...
|
|
610
|
+
};
|
|
611
|
+
|
|
612
|
+
await convaiClient.connect(config);
|
|
613
|
+
```
|
|
614
|
+
|
|
615
|
+
#### Real-time updates example
|
|
616
|
+
|
|
617
|
+
```tsx
|
|
618
|
+
// Update context as game state changes
|
|
619
|
+
function updateCharacterContext(player: Player) {
|
|
620
|
+
const contextText = `Player health: ${player.health}%, mana: ${player.mana}%, location: ${player.location}, status: ${player.status}`;
|
|
621
|
+
|
|
622
|
+
convaiClient.updateDynamicInfo(contextText);
|
|
623
|
+
}
|
|
624
|
+
|
|
625
|
+
// Call whenever game state changes
|
|
626
|
+
player.on('stateChange', () => updateCharacterContext(player));
|
|
627
|
+
```
|
|
628
|
+
|
|
629
|
+
### Accessing metrics data
|
|
630
|
+
|
|
631
|
+
The SDK exposes metrics events received from the server through the client state. Multiple metrics events can be received during a single conversation.
|
|
632
|
+
|
|
633
|
+
#### Accessing metrics from client state
|
|
634
|
+
|
|
635
|
+
```tsx
|
|
636
|
+
// Access metrics array from state
|
|
637
|
+
const metrics = convaiClient.state.metrics;
|
|
638
|
+
|
|
639
|
+
// Log all metrics
|
|
640
|
+
console.log('Total metrics received:', metrics.length);
|
|
641
|
+
metrics.forEach(metric => {
|
|
642
|
+
console.log('Metric ID:', metric.id);
|
|
643
|
+
console.log('Timestamp:', metric.timestamp);
|
|
644
|
+
console.log('Data:', metric.data);
|
|
645
|
+
});
|
|
646
|
+
|
|
647
|
+
// Get latest metric
|
|
648
|
+
const latestMetric = metrics[metrics.length - 1];
|
|
649
|
+
if (latestMetric) {
|
|
650
|
+
console.log('Latest metric data:', latestMetric.data);
|
|
651
|
+
}
|
|
652
|
+
```
|
|
653
|
+
|
|
654
|
+
#### Listening to metrics events in real-time
|
|
655
|
+
|
|
656
|
+
```tsx
|
|
657
|
+
// Subscribe to metrics events
|
|
658
|
+
const unsubMetrics = convaiClient.on('metrics', (metricsData) => {
|
|
659
|
+
console.log('New metrics received:', metricsData);
|
|
660
|
+
|
|
661
|
+
// Process metrics data
|
|
662
|
+
if (metricsData.processingTime) {
|
|
663
|
+
console.log('Processing time:', metricsData.processingTime);
|
|
664
|
+
}
|
|
665
|
+
});
|
|
666
|
+
|
|
667
|
+
// Cleanup
|
|
668
|
+
unsubMetrics();
|
|
669
|
+
```
|
|
670
|
+
|
|
671
|
+
#### Accessing metrics in React
|
|
672
|
+
|
|
673
|
+
```tsx
|
|
674
|
+
import { useConvaiClient } from '@convai/web-sdk';
|
|
675
|
+
import { useEffect, useState } from 'react';
|
|
676
|
+
|
|
677
|
+
function MetricsDisplay() {
|
|
678
|
+
const convaiClient = useConvaiClient();
|
|
679
|
+
const [metrics, setMetrics] = useState<ConvaiMetrics[]>([]);
|
|
680
|
+
|
|
681
|
+
useEffect(() => {
|
|
682
|
+
// Subscribe to state changes
|
|
683
|
+
const unsubState = convaiClient.on('stateChange', (state) => {
|
|
684
|
+
setMetrics(state.metrics);
|
|
685
|
+
});
|
|
686
|
+
|
|
687
|
+
// Or subscribe to individual metrics events
|
|
688
|
+
const unsubMetrics = convaiClient.on('metrics', (metricsData) => {
|
|
689
|
+
console.log('New metrics:', metricsData);
|
|
690
|
+
});
|
|
691
|
+
|
|
692
|
+
return () => {
|
|
693
|
+
unsubState();
|
|
694
|
+
unsubMetrics();
|
|
695
|
+
};
|
|
696
|
+
}, [convaiClient]);
|
|
697
|
+
|
|
698
|
+
return (
|
|
699
|
+
<div>
|
|
700
|
+
<h3>Metrics ({metrics.length})</h3>
|
|
701
|
+
{metrics.map(metric => (
|
|
702
|
+
<div key={metric.id}>
|
|
703
|
+
<p>Time: {new Date(metric.timestamp).toLocaleTimeString()}</p>
|
|
704
|
+
<pre>{JSON.stringify(metric.data, null, 2)}</pre>
|
|
705
|
+
</div>
|
|
706
|
+
))}
|
|
707
|
+
</div>
|
|
708
|
+
);
|
|
709
|
+
}
|
|
710
|
+
```
|
|
711
|
+
|
|
712
|
+
#### Clearing metrics
|
|
713
|
+
|
|
714
|
+
Metrics are automatically cleared when you call `resetSession()` or `disconnect()`:
|
|
715
|
+
|
|
716
|
+
```tsx
|
|
717
|
+
// Clear conversation history and metrics
|
|
718
|
+
convaiClient.resetSession();
|
|
588
719
|
|
|
589
|
-
|
|
590
|
-
|
|
720
|
+
// Or disconnect (also clears metrics)
|
|
721
|
+
await convaiClient.disconnect();
|
|
722
|
+
```
|
|
723
|
+
|
|
724
|
+
#### Analyzing aggregated metrics
|
|
725
|
+
|
|
726
|
+
```tsx
|
|
727
|
+
function analyzeMetrics(client: IConvaiClient) {
|
|
728
|
+
const metrics = client.state.metrics;
|
|
729
|
+
|
|
730
|
+
// Calculate average processing time if present
|
|
731
|
+
const processingTimes = metrics
|
|
732
|
+
.map(m => m.data.processingTime as number)
|
|
733
|
+
.filter(t => typeof t === 'number');
|
|
734
|
+
|
|
735
|
+
if (processingTimes.length > 0) {
|
|
736
|
+
const avgTime = processingTimes.reduce((a, b) => a + b, 0) / processingTimes.length;
|
|
737
|
+
console.log('Average processing time:', avgTime.toFixed(2), 'ms');
|
|
738
|
+
}
|
|
739
|
+
|
|
740
|
+
// Count metrics by type if available
|
|
741
|
+
const metricsByType = metrics.reduce((acc, metric) => {
|
|
742
|
+
const type = (metric.data.type as string) || 'unknown';
|
|
743
|
+
acc[type] = (acc[type] || 0) + 1;
|
|
744
|
+
return acc;
|
|
745
|
+
}, {} as Record<string, number>);
|
|
746
|
+
|
|
747
|
+
console.log('Metrics by type:', metricsByType);
|
|
748
|
+
}
|
|
749
|
+
```
|
|
591
750
|
|
|
592
751
|
### Advanced core classes (`@convai/web-sdk/core`)
|
|
593
752
|
|
|
@@ -631,7 +790,6 @@ Properties:
|
|
|
631
790
|
Methods:
|
|
632
791
|
|
|
633
792
|
- `getBlendshapeQueue()`
|
|
634
|
-
- `setLatencyMonitor(monitor)`
|
|
635
793
|
- `getChatMessages()`
|
|
636
794
|
- `getUserTranscription()`
|
|
637
795
|
- `getIsBotResponding()`
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { Room } from "livekit-client";
|
|
2
|
-
import { ConvaiConfig, ConvaiClientState, ChatMessage, IConvaiClient, AudioControls, VideoControls, ScreenShareControls } from "./types";
|
|
2
|
+
import { ConvaiConfig, ConvaiClientState, ChatMessage, IConvaiClient, AudioControls, VideoControls, ScreenShareControls, DynamicInfo } from "./types";
|
|
3
3
|
import { EventEmitter } from "./EventEmitter";
|
|
4
|
-
import { LatencyMonitor } from "../utils/LatencyMonitor";
|
|
5
4
|
import { BlendshapeQueue } from "./BlendshapeQueue";
|
|
6
5
|
/**
|
|
7
6
|
* Main Convai client class for managing AI voice assistant connections
|
|
@@ -51,11 +50,12 @@ export declare class ConvaiClient extends EventEmitter implements IConvaiClient
|
|
|
51
50
|
private _participantSid;
|
|
52
51
|
private _audioSettings;
|
|
53
52
|
private _storedConfig;
|
|
53
|
+
private _endUserId;
|
|
54
|
+
private _endUserMetadata;
|
|
54
55
|
private _audioManager;
|
|
55
56
|
private _videoManager;
|
|
56
57
|
private _screenShareManager;
|
|
57
58
|
private _messageHandler;
|
|
58
|
-
private _latencyMonitor;
|
|
59
59
|
private _conversationSessionId;
|
|
60
60
|
private _conversationStartTime;
|
|
61
61
|
constructor(config?: ConvaiConfig);
|
|
@@ -72,7 +72,6 @@ export declare class ConvaiClient extends EventEmitter implements IConvaiClient
|
|
|
72
72
|
get audioControls(): AudioControls;
|
|
73
73
|
get videoControls(): VideoControls;
|
|
74
74
|
get screenShareControls(): ScreenShareControls;
|
|
75
|
-
get latencyMonitor(): LatencyMonitor;
|
|
76
75
|
get blendshapeQueue(): BlendshapeQueue;
|
|
77
76
|
get conversationSessionId(): number;
|
|
78
77
|
/**
|
|
@@ -138,9 +137,7 @@ export declare class ConvaiClient extends EventEmitter implements IConvaiClient
|
|
|
138
137
|
/**
|
|
139
138
|
* Update dynamic information about the current context
|
|
140
139
|
*/
|
|
141
|
-
updateDynamicInfo(dynamicInfo:
|
|
142
|
-
text: string;
|
|
143
|
-
}): void;
|
|
140
|
+
updateDynamicInfo(dynamicInfo: DynamicInfo): void;
|
|
144
141
|
/**
|
|
145
142
|
* Toggle text-to-speech on or off
|
|
146
143
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ConvaiClient.d.ts","sourceRoot":"","sources":["../../src/core/ConvaiClient.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAA8B,MAAM,gBAAgB,CAAC;AAClE,OAAO,EACL,YAAY,EACZ,iBAAiB,EACjB,WAAW,EAEX,aAAa,EACb,aAAa,EACb,aAAa,EACb,mBAAmB,
|
|
1
|
+
{"version":3,"file":"ConvaiClient.d.ts","sourceRoot":"","sources":["../../src/core/ConvaiClient.ts"],"names":[],"mappings":"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"}
|
|
@@ -4,7 +4,6 @@ import { VideoManager } from "./VideoManager";
|
|
|
4
4
|
import { ScreenShareManager } from "./ScreenShareManager";
|
|
5
5
|
import { MessageHandler } from "./MessageHandler";
|
|
6
6
|
import { EventEmitter } from "./EventEmitter";
|
|
7
|
-
import { LatencyMonitor } from "../utils/LatencyMonitor";
|
|
8
7
|
/**
|
|
9
8
|
* Main Convai client class for managing AI voice assistant connections
|
|
10
9
|
* Provides complete interface for connecting to Convai's voice assistants,
|
|
@@ -52,6 +51,8 @@ export class ConvaiClient extends EventEmitter {
|
|
|
52
51
|
this._isBotReady = false;
|
|
53
52
|
this._participantSid = "";
|
|
54
53
|
this._storedConfig = null;
|
|
54
|
+
this._endUserId = null;
|
|
55
|
+
this._endUserMetadata = null;
|
|
55
56
|
// Conversation session tracking
|
|
56
57
|
this._conversationSessionId = 0;
|
|
57
58
|
this._conversationStartTime = 0;
|
|
@@ -70,6 +71,9 @@ export class ConvaiClient extends EventEmitter {
|
|
|
70
71
|
isSpeaking: false,
|
|
71
72
|
agentState: "disconnected",
|
|
72
73
|
emotion: null,
|
|
74
|
+
endUserId: null,
|
|
75
|
+
endUserMetadata: null,
|
|
76
|
+
metrics: [],
|
|
73
77
|
};
|
|
74
78
|
// Default audio settings for optimal interruption handling
|
|
75
79
|
this._audioSettings = {
|
|
@@ -83,8 +87,7 @@ export class ConvaiClient extends EventEmitter {
|
|
|
83
87
|
this._audioManager = new AudioManager(this._room);
|
|
84
88
|
this._videoManager = new VideoManager(this._room);
|
|
85
89
|
this._screenShareManager = new ScreenShareManager(this._room);
|
|
86
|
-
this.
|
|
87
|
-
this._messageHandler = new MessageHandler(this._room, this._latencyMonitor);
|
|
90
|
+
this._messageHandler = new MessageHandler(this._room);
|
|
88
91
|
// Setup event listeners
|
|
89
92
|
this.setupEventListeners();
|
|
90
93
|
// Connect MessageHandler to conversation start events
|
|
@@ -130,9 +133,6 @@ export class ConvaiClient extends EventEmitter {
|
|
|
130
133
|
get screenShareControls() {
|
|
131
134
|
return this._screenShareManager;
|
|
132
135
|
}
|
|
133
|
-
get latencyMonitor() {
|
|
134
|
-
return this._latencyMonitor;
|
|
135
|
-
}
|
|
136
136
|
get blendshapeQueue() {
|
|
137
137
|
return this._messageHandler.getBlendshapeQueue();
|
|
138
138
|
}
|
|
@@ -162,11 +162,7 @@ export class ConvaiClient extends EventEmitter {
|
|
|
162
162
|
this._messageHandler.on("speakingChange", (isSpeaking) => {
|
|
163
163
|
this.updateState({ isSpeaking });
|
|
164
164
|
this.emit("speakingChange", isSpeaking);
|
|
165
|
-
|
|
166
|
-
if (isSpeaking) {
|
|
167
|
-
this._latencyMonitor.endMeasurement();
|
|
168
|
-
}
|
|
169
|
-
else if (this._conversationSessionId > 0) {
|
|
165
|
+
if (!isSpeaking && this._conversationSessionId > 0) {
|
|
170
166
|
// Bot stopped speaking - turn end signal (same semantics as BlendshapeQueue.hasReceivedEndSignal())
|
|
171
167
|
const duration = ((Date.now() - this._conversationStartTime) /
|
|
172
168
|
1000).toFixed(2);
|
|
@@ -186,6 +182,19 @@ export class ConvaiClient extends EventEmitter {
|
|
|
186
182
|
this._messageHandler.on("listeningChange", (isListening) => {
|
|
187
183
|
this.updateState({ isListening });
|
|
188
184
|
});
|
|
185
|
+
// Handle metrics events
|
|
186
|
+
this._messageHandler.on("metrics", (metricsData) => {
|
|
187
|
+
const newMetrics = [
|
|
188
|
+
...this._state.metrics,
|
|
189
|
+
{
|
|
190
|
+
id: `metrics-${Date.now()}-${Math.random()}`,
|
|
191
|
+
data: metricsData,
|
|
192
|
+
timestamp: new Date().toISOString(),
|
|
193
|
+
},
|
|
194
|
+
];
|
|
195
|
+
this.updateState({ metrics: newMetrics });
|
|
196
|
+
this.emit("metrics", metricsData);
|
|
197
|
+
});
|
|
189
198
|
// Forward blendshapes events
|
|
190
199
|
this._messageHandler.on("blendshapes", (data) => {
|
|
191
200
|
this.emit("blendshapes", data);
|
|
@@ -194,10 +203,6 @@ export class ConvaiClient extends EventEmitter {
|
|
|
194
203
|
this._messageHandler.on("blendshapeStatsReceived", (stats) => {
|
|
195
204
|
this.emit("blendshapeStatsReceived", stats);
|
|
196
205
|
});
|
|
197
|
-
// Forward latency monitor events
|
|
198
|
-
this._latencyMonitor.on("measurement", (measurement) => {
|
|
199
|
-
this.emit("latencyMeasurement", measurement);
|
|
200
|
-
});
|
|
201
206
|
}
|
|
202
207
|
/**
|
|
203
208
|
* Setup MessageHandler to respond to conversation start events
|
|
@@ -222,8 +227,13 @@ export class ConvaiClient extends EventEmitter {
|
|
|
222
227
|
isSpeaking: false,
|
|
223
228
|
isThinking: false,
|
|
224
229
|
isListening: false,
|
|
230
|
+
endUserId: null,
|
|
231
|
+
endUserMetadata: null,
|
|
232
|
+
metrics: [],
|
|
225
233
|
});
|
|
226
234
|
this._isBotReady = false;
|
|
235
|
+
this._endUserId = null;
|
|
236
|
+
this._endUserMetadata = null;
|
|
227
237
|
this._messageHandler.reset();
|
|
228
238
|
this.emit("disconnect");
|
|
229
239
|
}
|
|
@@ -336,7 +346,6 @@ export class ConvaiClient extends EventEmitter {
|
|
|
336
346
|
frames_buffer_duration: configWithDefaults.blendshapeConfig?.frames_buffer_duration ?? 0.1,
|
|
337
347
|
output_fps: 90,
|
|
338
348
|
},
|
|
339
|
-
end_user_id: "xauravdas01@gmail.com",
|
|
340
349
|
llm_provider: "dynamic",
|
|
341
350
|
...(configWithDefaults.enableEmotion !== false && {
|
|
342
351
|
emotion_config: {
|
|
@@ -358,6 +367,37 @@ export class ConvaiClient extends EventEmitter {
|
|
|
358
367
|
...(configWithDefaults.actionConfig && {
|
|
359
368
|
action_config: configWithDefaults.actionConfig,
|
|
360
369
|
}),
|
|
370
|
+
...(configWithDefaults.characters && {
|
|
371
|
+
characters: configWithDefaults.characters,
|
|
372
|
+
}),
|
|
373
|
+
...(configWithDefaults.objects && {
|
|
374
|
+
objects: configWithDefaults.objects,
|
|
375
|
+
}),
|
|
376
|
+
...(configWithDefaults.currentAttentionObject && {
|
|
377
|
+
current_attention_object: configWithDefaults.currentAttentionObject,
|
|
378
|
+
}),
|
|
379
|
+
...(configWithDefaults.sceneDescription && {
|
|
380
|
+
scene_description: configWithDefaults.sceneDescription,
|
|
381
|
+
}),
|
|
382
|
+
...(configWithDefaults.dynamicInfo && {
|
|
383
|
+
dynamic_info: { text: configWithDefaults.dynamicInfo },
|
|
384
|
+
}),
|
|
385
|
+
...(configWithDefaults.debug !== undefined && {
|
|
386
|
+
debug: configWithDefaults.debug,
|
|
387
|
+
}),
|
|
388
|
+
...(configWithDefaults.invocationMetadata && {
|
|
389
|
+
invocation_metadata: {
|
|
390
|
+
...(configWithDefaults.invocationMetadata.source && {
|
|
391
|
+
source: configWithDefaults.invocationMetadata.source,
|
|
392
|
+
}),
|
|
393
|
+
...(configWithDefaults.invocationMetadata.clientVersion && {
|
|
394
|
+
client_version: configWithDefaults.invocationMetadata.clientVersion,
|
|
395
|
+
}),
|
|
396
|
+
...(configWithDefaults.invocationMetadata.extraMetadata && {
|
|
397
|
+
extra_metadata: configWithDefaults.invocationMetadata.extraMetadata,
|
|
398
|
+
}),
|
|
399
|
+
},
|
|
400
|
+
}),
|
|
361
401
|
};
|
|
362
402
|
// Call Core Service API
|
|
363
403
|
const response = await fetch(`${configWithDefaults.url}/connect`, {
|
|
@@ -399,6 +439,13 @@ export class ConvaiClient extends EventEmitter {
|
|
|
399
439
|
characterSessionId: connectionData.character_session_id,
|
|
400
440
|
};
|
|
401
441
|
}
|
|
442
|
+
// Capture end_user_id and end_user_metadata from connection response
|
|
443
|
+
if (connectionData.end_user_id) {
|
|
444
|
+
this._endUserId = connectionData.end_user_id;
|
|
445
|
+
}
|
|
446
|
+
if (connectionData.end_user_metadata) {
|
|
447
|
+
this._endUserMetadata = connectionData.end_user_metadata;
|
|
448
|
+
}
|
|
402
449
|
// Connect to LiveKit room
|
|
403
450
|
await this._room.connect(connectionData.room_url, connectionData.token, {
|
|
404
451
|
rtcConfig: {
|
|
@@ -432,6 +479,8 @@ export class ConvaiClient extends EventEmitter {
|
|
|
432
479
|
this.updateState({
|
|
433
480
|
isConnected: true,
|
|
434
481
|
isConnecting: false,
|
|
482
|
+
endUserId: this._endUserId,
|
|
483
|
+
endUserMetadata: this._endUserMetadata,
|
|
435
484
|
});
|
|
436
485
|
this.emit("connect");
|
|
437
486
|
}
|
|
@@ -469,12 +518,17 @@ export class ConvaiClient extends EventEmitter {
|
|
|
469
518
|
isSpeaking: false,
|
|
470
519
|
isThinking: false,
|
|
471
520
|
isListening: false,
|
|
521
|
+
endUserId: null,
|
|
522
|
+
endUserMetadata: null,
|
|
523
|
+
metrics: [],
|
|
472
524
|
});
|
|
473
525
|
this._isBotReady = false;
|
|
474
526
|
this._connectionType = null;
|
|
475
527
|
this._apiKey = null;
|
|
476
528
|
this._characterId = null;
|
|
477
529
|
this._speakerId = null;
|
|
530
|
+
this._endUserId = null;
|
|
531
|
+
this._endUserMetadata = null;
|
|
478
532
|
this._messageHandler.reset();
|
|
479
533
|
this._audioManager.reset();
|
|
480
534
|
this._videoManager.reset();
|
|
@@ -495,6 +549,8 @@ export class ConvaiClient extends EventEmitter {
|
|
|
495
549
|
resetSession() {
|
|
496
550
|
this._characterSessionId = "-1";
|
|
497
551
|
this._messageHandler.reset();
|
|
552
|
+
// Clear metrics when resetting session
|
|
553
|
+
this.updateState({ metrics: [] });
|
|
498
554
|
}
|
|
499
555
|
/**
|
|
500
556
|
* Send a text message to the character
|
|
@@ -519,8 +575,6 @@ export class ConvaiClient extends EventEmitter {
|
|
|
519
575
|
userMessage: text.trim(),
|
|
520
576
|
timestamp: this._conversationStartTime,
|
|
521
577
|
});
|
|
522
|
-
// Start latency measurement for text message
|
|
523
|
-
this._latencyMonitor.startMeasurement("text", text.trim());
|
|
524
578
|
const message = {
|
|
525
579
|
type: "user_text_message",
|
|
526
580
|
data: {
|
|
@@ -534,8 +588,6 @@ export class ConvaiClient extends EventEmitter {
|
|
|
534
588
|
});
|
|
535
589
|
}
|
|
536
590
|
catch (error) {
|
|
537
|
-
// Cancel latency measurement on error
|
|
538
|
-
this._latencyMonitor.cancelMeasurement();
|
|
539
591
|
throw error;
|
|
540
592
|
}
|
|
541
593
|
}
|
|
@@ -611,13 +663,11 @@ export class ConvaiClient extends EventEmitter {
|
|
|
611
663
|
* Update dynamic information about the current context
|
|
612
664
|
*/
|
|
613
665
|
updateDynamicInfo(dynamicInfo) {
|
|
614
|
-
if (this._room && this._room.localParticipant && dynamicInfo
|
|
666
|
+
if (this._room && this._room.localParticipant && dynamicInfo?.trim()) {
|
|
615
667
|
const message = {
|
|
616
668
|
type: "update-dynamic-info",
|
|
617
669
|
data: {
|
|
618
|
-
dynamic_info: {
|
|
619
|
-
text: dynamicInfo.text.trim(),
|
|
620
|
-
},
|
|
670
|
+
dynamic_info: { text: dynamicInfo },
|
|
621
671
|
participant_sid: this._participantSid || this._room.localParticipant.sid,
|
|
622
672
|
},
|
|
623
673
|
};
|