@jchaffin/voicekit 0.2.1 → 0.2.3
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/dist/adapters/deepgram.js +15 -12
- package/dist/adapters/deepgram.mjs +15 -12
- package/dist/adapters/elevenlabs.js +5 -11
- package/dist/adapters/elevenlabs.mjs +5 -11
- package/dist/adapters/livekit.js +3 -9
- package/dist/adapters/livekit.mjs +3 -9
- package/dist/index.js +7 -3
- package/dist/index.mjs +7 -3
- package/package.json +10 -6
|
@@ -73,18 +73,21 @@ var DeepgramSession = class extends EventEmitter {
|
|
|
73
73
|
if (this.options.model) url.searchParams.set("model", this.options.model);
|
|
74
74
|
if (this.options.language) url.searchParams.set("language", this.options.language);
|
|
75
75
|
this.ws = new WebSocket(url.toString());
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
76
|
+
await new Promise((resolve, reject) => {
|
|
77
|
+
const ws = this.ws;
|
|
78
|
+
let opened = false;
|
|
79
|
+
ws.onopen = () => {
|
|
80
|
+
opened = true;
|
|
81
|
+
resolve();
|
|
82
|
+
};
|
|
83
|
+
ws.onerror = () => {
|
|
84
|
+
if (!opened) reject(new Error("WebSocket connection failed"));
|
|
85
|
+
};
|
|
86
|
+
ws.onclose = () => {
|
|
87
|
+
this.emit("status_change", "DISCONNECTED");
|
|
88
|
+
if (!opened) reject(new Error("WebSocket closed before connection opened"));
|
|
89
|
+
};
|
|
90
|
+
});
|
|
88
91
|
this.ws.onmessage = (event) => {
|
|
89
92
|
try {
|
|
90
93
|
const msg = JSON.parse(event.data);
|
|
@@ -19,18 +19,21 @@ var DeepgramSession = class extends EventEmitter {
|
|
|
19
19
|
if (this.options.model) url.searchParams.set("model", this.options.model);
|
|
20
20
|
if (this.options.language) url.searchParams.set("language", this.options.language);
|
|
21
21
|
this.ws = new WebSocket(url.toString());
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
22
|
+
await new Promise((resolve, reject) => {
|
|
23
|
+
const ws = this.ws;
|
|
24
|
+
let opened = false;
|
|
25
|
+
ws.onopen = () => {
|
|
26
|
+
opened = true;
|
|
27
|
+
resolve();
|
|
28
|
+
};
|
|
29
|
+
ws.onerror = () => {
|
|
30
|
+
if (!opened) reject(new Error("WebSocket connection failed"));
|
|
31
|
+
};
|
|
32
|
+
ws.onclose = () => {
|
|
33
|
+
this.emit("status_change", "DISCONNECTED");
|
|
34
|
+
if (!opened) reject(new Error("WebSocket closed before connection opened"));
|
|
35
|
+
};
|
|
36
|
+
});
|
|
34
37
|
this.ws.onmessage = (event) => {
|
|
35
38
|
try {
|
|
36
39
|
const msg = JSON.parse(event.data);
|
|
@@ -73,17 +73,11 @@ var ElevenLabsSession = class extends EventEmitter {
|
|
|
73
73
|
async connect(config) {
|
|
74
74
|
const wsUrl = config.authToken?.startsWith("wss://") ? config.authToken : `${ELEVENLABS_WS_BASE}?agent_id=${this.agentId}`;
|
|
75
75
|
this.ws = new WebSocket(wsUrl);
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
});
|
|
82
|
-
} catch (err) {
|
|
83
|
-
this.ws?.close();
|
|
84
|
-
this.ws = null;
|
|
85
|
-
throw err;
|
|
86
|
-
}
|
|
76
|
+
await new Promise((resolve, reject) => {
|
|
77
|
+
const ws = this.ws;
|
|
78
|
+
ws.onopen = () => resolve();
|
|
79
|
+
ws.onerror = () => reject(new Error("ElevenLabs WebSocket connection failed"));
|
|
80
|
+
});
|
|
87
81
|
this.ws.onmessage = (event) => {
|
|
88
82
|
try {
|
|
89
83
|
const msg = JSON.parse(event.data);
|
|
@@ -19,17 +19,11 @@ var ElevenLabsSession = class extends EventEmitter {
|
|
|
19
19
|
async connect(config) {
|
|
20
20
|
const wsUrl = config.authToken?.startsWith("wss://") ? config.authToken : `${ELEVENLABS_WS_BASE}?agent_id=${this.agentId}`;
|
|
21
21
|
this.ws = new WebSocket(wsUrl);
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
});
|
|
28
|
-
} catch (err) {
|
|
29
|
-
this.ws?.close();
|
|
30
|
-
this.ws = null;
|
|
31
|
-
throw err;
|
|
32
|
-
}
|
|
22
|
+
await new Promise((resolve, reject) => {
|
|
23
|
+
const ws = this.ws;
|
|
24
|
+
ws.onopen = () => resolve();
|
|
25
|
+
ws.onerror = () => reject(new Error("ElevenLabs WebSocket connection failed"));
|
|
26
|
+
});
|
|
33
27
|
this.ws.onmessage = (event) => {
|
|
34
28
|
try {
|
|
35
29
|
const msg = JSON.parse(event.data);
|
package/dist/adapters/livekit.js
CHANGED
|
@@ -106,15 +106,9 @@ var LiveKitSession = class extends EventEmitter {
|
|
|
106
106
|
this.room.on(RoomEvent.Reconnected, () => {
|
|
107
107
|
this.emit("status_change", "CONNECTED");
|
|
108
108
|
});
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
this.emit("status_change", "CONNECTED");
|
|
113
|
-
} catch (err) {
|
|
114
|
-
await this.room.disconnect();
|
|
115
|
-
this.room = null;
|
|
116
|
-
throw err;
|
|
117
|
-
}
|
|
109
|
+
await this.room.connect(this.serverUrl, config.authToken);
|
|
110
|
+
await this.room.localParticipant.setMicrophoneEnabled(true);
|
|
111
|
+
this.emit("status_change", "CONNECTED");
|
|
118
112
|
}
|
|
119
113
|
async disconnect() {
|
|
120
114
|
if (this.room) {
|
|
@@ -42,15 +42,9 @@ var LiveKitSession = class extends EventEmitter {
|
|
|
42
42
|
this.room.on(RoomEvent.Reconnected, () => {
|
|
43
43
|
this.emit("status_change", "CONNECTED");
|
|
44
44
|
});
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
this.emit("status_change", "CONNECTED");
|
|
49
|
-
} catch (err) {
|
|
50
|
-
await this.room.disconnect();
|
|
51
|
-
this.room = null;
|
|
52
|
-
throw err;
|
|
53
|
-
}
|
|
45
|
+
await this.room.connect(this.serverUrl, config.authToken);
|
|
46
|
+
await this.room.localParticipant.setMicrophoneEnabled(true);
|
|
47
|
+
this.emit("status_change", "CONNECTED");
|
|
54
48
|
}
|
|
55
49
|
async disconnect() {
|
|
56
50
|
if (this.room) {
|
package/dist/index.js
CHANGED
|
@@ -217,7 +217,12 @@ function VoiceProvider({
|
|
|
217
217
|
}, 500);
|
|
218
218
|
} catch (error) {
|
|
219
219
|
console.error("VoiceKit connection failed:", error);
|
|
220
|
+
try {
|
|
221
|
+
await sessionRef.current?.disconnect();
|
|
222
|
+
} catch {
|
|
223
|
+
}
|
|
220
224
|
sessionRef.current = null;
|
|
225
|
+
currentMsgIdRef.current = null;
|
|
221
226
|
onError?.(error instanceof Error ? error : new Error(String(error)));
|
|
222
227
|
updateStatus("DISCONNECTED");
|
|
223
228
|
}
|
|
@@ -824,7 +829,6 @@ function useAudioRecorder() {
|
|
|
824
829
|
if (mediaRecorderRef.current?.state === "recording") {
|
|
825
830
|
return;
|
|
826
831
|
}
|
|
827
|
-
recordedChunksRef.current = [];
|
|
828
832
|
try {
|
|
829
833
|
const mediaRecorder = new MediaRecorder(stream, { mimeType: "audio/webm" });
|
|
830
834
|
mediaRecorder.ondataavailable = (event) => {
|
|
@@ -1107,6 +1111,8 @@ function useSessionHistory() {
|
|
|
1107
1111
|
updateTranscriptMessage,
|
|
1108
1112
|
updateTranscriptItem
|
|
1109
1113
|
} = useTranscript();
|
|
1114
|
+
const transcriptItemsRef = (0, import_react7.useRef)(transcriptItems);
|
|
1115
|
+
transcriptItemsRef.current = transcriptItems;
|
|
1110
1116
|
const { logServerEvent } = useEvent();
|
|
1111
1117
|
const accumulatedTextRef = (0, import_react7.useRef)(/* @__PURE__ */ new Map());
|
|
1112
1118
|
const pendingDeltasRef = (0, import_react7.useRef)(/* @__PURE__ */ new Map());
|
|
@@ -1272,8 +1278,6 @@ function useSessionHistory() {
|
|
|
1272
1278
|
});
|
|
1273
1279
|
}
|
|
1274
1280
|
}
|
|
1275
|
-
const transcriptItemsRef = (0, import_react7.useRef)(transcriptItems);
|
|
1276
|
-
transcriptItemsRef.current = transcriptItems;
|
|
1277
1281
|
const handlersRef = (0, import_react7.useRef)({
|
|
1278
1282
|
handleAgentToolStart,
|
|
1279
1283
|
handleAgentToolEnd,
|
package/dist/index.mjs
CHANGED
|
@@ -159,7 +159,12 @@ function VoiceProvider({
|
|
|
159
159
|
}, 500);
|
|
160
160
|
} catch (error) {
|
|
161
161
|
console.error("VoiceKit connection failed:", error);
|
|
162
|
+
try {
|
|
163
|
+
await sessionRef.current?.disconnect();
|
|
164
|
+
} catch {
|
|
165
|
+
}
|
|
162
166
|
sessionRef.current = null;
|
|
167
|
+
currentMsgIdRef.current = null;
|
|
163
168
|
onError?.(error instanceof Error ? error : new Error(String(error)));
|
|
164
169
|
updateStatus("DISCONNECTED");
|
|
165
170
|
}
|
|
@@ -605,7 +610,6 @@ function useAudioRecorder() {
|
|
|
605
610
|
if (mediaRecorderRef.current?.state === "recording") {
|
|
606
611
|
return;
|
|
607
612
|
}
|
|
608
|
-
recordedChunksRef.current = [];
|
|
609
613
|
try {
|
|
610
614
|
const mediaRecorder = new MediaRecorder(stream, { mimeType: "audio/webm" });
|
|
611
615
|
mediaRecorder.ondataavailable = (event) => {
|
|
@@ -893,6 +897,8 @@ function useSessionHistory() {
|
|
|
893
897
|
updateTranscriptMessage,
|
|
894
898
|
updateTranscriptItem
|
|
895
899
|
} = useTranscript();
|
|
900
|
+
const transcriptItemsRef = useRef5(transcriptItems);
|
|
901
|
+
transcriptItemsRef.current = transcriptItems;
|
|
896
902
|
const { logServerEvent } = useEvent();
|
|
897
903
|
const accumulatedTextRef = useRef5(/* @__PURE__ */ new Map());
|
|
898
904
|
const pendingDeltasRef = useRef5(/* @__PURE__ */ new Map());
|
|
@@ -1058,8 +1064,6 @@ function useSessionHistory() {
|
|
|
1058
1064
|
});
|
|
1059
1065
|
}
|
|
1060
1066
|
}
|
|
1061
|
-
const transcriptItemsRef = useRef5(transcriptItems);
|
|
1062
|
-
transcriptItemsRef.current = transcriptItems;
|
|
1063
1067
|
const handlersRef = useRef5({
|
|
1064
1068
|
handleAgentToolStart,
|
|
1065
1069
|
handleAgentToolEnd,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jchaffin/voicekit",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.3",
|
|
4
4
|
"description": "A provider-agnostic React library for building voice-enabled AI agents",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.mjs",
|
|
@@ -42,11 +42,12 @@
|
|
|
42
42
|
"README.md"
|
|
43
43
|
],
|
|
44
44
|
"scripts": {
|
|
45
|
-
"build": "tsup
|
|
46
|
-
"dev": "tsup
|
|
45
|
+
"build": "tsup",
|
|
46
|
+
"dev": "tsup --watch",
|
|
47
|
+
"prepare": "tsup",
|
|
47
48
|
"lint": "eslint src/",
|
|
48
49
|
"typecheck": "tsc --noEmit",
|
|
49
|
-
"prepublishOnly": "
|
|
50
|
+
"prepublishOnly": "tsup"
|
|
50
51
|
},
|
|
51
52
|
"keywords": [
|
|
52
53
|
"voice",
|
|
@@ -59,11 +60,13 @@
|
|
|
59
60
|
"react",
|
|
60
61
|
"agent",
|
|
61
62
|
"webrtc",
|
|
62
|
-
"speech"
|
|
63
|
-
"provider-agnostic"
|
|
63
|
+
"speech"
|
|
64
64
|
],
|
|
65
65
|
"author": "Jacob Chaffin",
|
|
66
66
|
"license": "MIT",
|
|
67
|
+
"publishConfig": {
|
|
68
|
+
"access": "public"
|
|
69
|
+
},
|
|
67
70
|
"peerDependencies": {
|
|
68
71
|
"react": ">=18.0.0",
|
|
69
72
|
"react-dom": ">=18.0.0",
|
|
@@ -88,6 +91,7 @@
|
|
|
88
91
|
},
|
|
89
92
|
"devDependencies": {
|
|
90
93
|
"@openai/agents": ">=0.0.15",
|
|
94
|
+
"@types/node": "^25.6.0",
|
|
91
95
|
"@types/react": "^18.2.0",
|
|
92
96
|
"@types/react-dom": "^18.2.0",
|
|
93
97
|
"tsup": "^8.0.0",
|