@solo3li/client-react 1.0.0 → 1.0.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 ADDED
@@ -0,0 +1,67 @@
1
+ # @solo3li/client-react
2
+
3
+ The official React SDK for connecting your web applications to the **Voice AI CPaaS**. This library provides a seamless React Hook (`useOmniAgent`) to handle WebRTC connections, audio routing, and state management for your AI Voice Agents.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @solo3li/client-react
9
+ ```
10
+ *Note: This package requires `react` and `livekit-client` as peer dependencies.*
11
+
12
+ ## Quick Start
13
+
14
+ The SDK is designed to be extremely simple. All you need is the `token` and `livekitUrl` generated by your backend server using `@solo3li/backend-node`.
15
+
16
+ ```tsx
17
+ import React from 'react';
18
+ import { useOmniAgent } from '@solo3li/client-react';
19
+
20
+ interface CallScreenProps {
21
+ token: string;
22
+ livekitUrl: string;
23
+ }
24
+
25
+ export const CallScreen: React.FC<CallScreenProps> = ({ token, livekitUrl }) => {
26
+ // 1. Initialize the AI Agent Hook
27
+ const { isConnected, isAgentSpeaking, disconnect } = useOmniAgent({
28
+ token,
29
+ livekitUrl,
30
+ onAgentConnected: () => console.log('AI Agent joined the room!'),
31
+ onAgentDisconnected: () => console.log('AI Agent left the room.'),
32
+ });
33
+
34
+ return (
35
+ <div style={{ textAlign: 'center', padding: '50px' }}>
36
+ <h2>Voice AI Assistant</h2>
37
+
38
+ {/* Connection Status */}
39
+ <p>
40
+ Status: {isConnected ? '🟢 Connected' : '🔴 Disconnected'}
41
+ </p>
42
+
43
+ {/* Speaking Indicator */}
44
+ {isConnected && (
45
+ <div style={{ margin: '20px' }}>
46
+ {isAgentSpeaking ? '🗣️ Agent is speaking...' : '👂 Agent is listening...'}
47
+ </div>
48
+ )}
49
+
50
+ {/* End Call Button */}
51
+ {isConnected && (
52
+ <button onClick={disconnect} style={{ color: 'red' }}>
53
+ End Call
54
+ </button>
55
+ )}
56
+ </div>
57
+ );
58
+ };
59
+ ```
60
+
61
+ ## Features
62
+ - **Auto Audio Routing:** Automatically attaches remote audio tracks to the DOM so you don't have to manage `<audio>` elements manually.
63
+ - **Active Speaker Detection:** Easily bind UI animations to the `isAgentSpeaking` state.
64
+ - **Microphone Management:** Automatically requests microphone permissions and publishes the local audio track upon connection.
65
+
66
+ ## License
67
+ MIT
package/dist/index.d.ts CHANGED
@@ -10,3 +10,11 @@ export declare const useOmniAgent: (options: OmniAgentOptions) => {
10
10
  isAgentSpeaking: boolean;
11
11
  disconnect: () => void;
12
12
  };
13
+ export declare const useHumanAgent: (options: {
14
+ token: string;
15
+ livekitUrl: string;
16
+ }) => {
17
+ isConnected: boolean;
18
+ isCustomerSpeaking: boolean;
19
+ disconnect: () => void;
20
+ };
package/dist/index.js CHANGED
@@ -59,3 +59,59 @@ export const useOmniAgent = (options) => {
59
59
  disconnect
60
60
  };
61
61
  };
62
+ export const useHumanAgent = (options) => {
63
+ const [room, setRoom] = useState(null);
64
+ const [isConnected, setIsConnected] = useState(false);
65
+ const [isCustomerSpeaking, setIsCustomerSpeaking] = useState(false);
66
+ useEffect(() => {
67
+ if (!options.token || !options.livekitUrl)
68
+ return;
69
+ const newRoom = new Room({
70
+ adaptiveStream: true,
71
+ dynacast: true,
72
+ });
73
+ newRoom.on(RoomEvent.Connected, () => {
74
+ setIsConnected(true);
75
+ });
76
+ newRoom.on(RoomEvent.Disconnected, () => {
77
+ setIsConnected(false);
78
+ });
79
+ newRoom.on(RoomEvent.ActiveSpeakersChanged, (speakers) => {
80
+ // Anyone who is not the local participant is assumed to be the customer
81
+ const customerSpeaking = speakers.some(s => s.identity !== newRoom.localParticipant.identity);
82
+ setIsCustomerSpeaking(customerSpeaking);
83
+ });
84
+ newRoom.on(RoomEvent.TrackSubscribed, (track) => {
85
+ if (track.kind === Track.Kind.Audio) {
86
+ const element = track.attach();
87
+ document.body.appendChild(element);
88
+ }
89
+ });
90
+ const connect = async () => {
91
+ try {
92
+ await newRoom.connect(options.livekitUrl, options.token);
93
+ await newRoom.localParticipant.enableCameraAndMicrophone();
94
+ setRoom(newRoom);
95
+ }
96
+ catch (error) {
97
+ console.error('Failed to connect Human Agent:', error);
98
+ }
99
+ };
100
+ connect();
101
+ return () => {
102
+ newRoom.disconnect();
103
+ };
104
+ }, [options.token, options.livekitUrl]);
105
+ const disconnect = () => {
106
+ if (room) {
107
+ room.disconnect();
108
+ setRoom(null);
109
+ setIsConnected(false);
110
+ }
111
+ };
112
+ return {
113
+ isConnected,
114
+ isCustomerSpeaking,
115
+ disconnect
116
+ };
117
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@solo3li/client-react",
3
- "version": "1.0.0",
3
+ "version": "1.0.2",
4
4
  "description": "React hooks and components for Voice AI CPaaS",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",