@hivegpt/hiveai-angular 0.0.424 → 0.0.427
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/bundles/hivegpt-hiveai-angular.umd.js +474 -158
- package/bundles/hivegpt-hiveai-angular.umd.js.map +1 -1
- package/bundles/hivegpt-hiveai-angular.umd.min.js +1 -1
- package/bundles/hivegpt-hiveai-angular.umd.min.js.map +1 -1
- package/esm2015/hivegpt-hiveai-angular.js +6 -4
- package/esm2015/lib/components/voice-agent/services/audio-analyzer.service.js +5 -1
- package/esm2015/lib/components/voice-agent/services/daily-voice-client.service.js +181 -0
- package/esm2015/lib/components/voice-agent/services/voice-agent.service.js +128 -140
- package/esm2015/lib/components/voice-agent/services/websocket-voice-client.service.js +93 -0
- package/esm2015/lib/components/voice-agent/voice-agent.module.js +6 -2
- package/fesm2015/hivegpt-hiveai-angular.js +399 -143
- package/fesm2015/hivegpt-hiveai-angular.js.map +1 -1
- package/hivegpt-hiveai-angular.d.ts +5 -3
- package/hivegpt-hiveai-angular.d.ts.map +1 -1
- package/hivegpt-hiveai-angular.metadata.json +1 -1
- package/lib/components/voice-agent/services/audio-analyzer.service.d.ts +4 -0
- package/lib/components/voice-agent/services/audio-analyzer.service.d.ts.map +1 -1
- package/lib/components/voice-agent/services/daily-voice-client.service.d.ts +48 -0
- package/lib/components/voice-agent/services/daily-voice-client.service.d.ts.map +1 -0
- package/lib/components/voice-agent/services/voice-agent.service.d.ts +19 -8
- package/lib/components/voice-agent/services/voice-agent.service.d.ts.map +1 -1
- package/lib/components/voice-agent/services/websocket-voice-client.service.d.ts +47 -0
- package/lib/components/voice-agent/services/websocket-voice-client.service.d.ts.map +1 -0
- package/lib/components/voice-agent/voice-agent.module.d.ts.map +1 -1
- package/package.json +2 -1
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
(function (global, factory) {
|
|
2
|
-
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@angular/cdk/overlay'), require('@angular/cdk/portal'), require('@angular/common/http'), require('@angular/core'), require('@angular/platform-browser'), require('rxjs'), require('rxjs/operators'), require('ngx-socket-io'), require('@angular/forms'), require('microsoft-cognitiveservices-speech-sdk'), require('marked'), require('@
|
|
3
|
-
typeof define === 'function' && define.amd ? define('@hivegpt/hiveai-angular', ['exports', '@angular/cdk/overlay', '@angular/cdk/portal', '@angular/common/http', '@angular/core', '@angular/platform-browser', 'rxjs', 'rxjs/operators', 'ngx-socket-io', '@angular/forms', 'microsoft-cognitiveservices-speech-sdk', 'marked', '@
|
|
4
|
-
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory((global.hivegpt = global.hivegpt || {}, global.hivegpt["hiveai-angular"] = {}), global.ng.cdk.overlay, global.ng.cdk.portal, global.ng.common.http, global.ng.core, global.ng.platformBrowser, global.rxjs, global.rxjs.operators, global.ngxSocketIo, global.ng.forms, global.SpeechSDK, global.marked, global.
|
|
5
|
-
})(this, (function (exports, overlay, portal, i1, i0, platformBrowser, rxjs, operators, ngxSocketIo, forms, SpeechSDK, marked,
|
|
2
|
+
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@angular/cdk/overlay'), require('@angular/cdk/portal'), require('@angular/common/http'), require('@angular/core'), require('@angular/platform-browser'), require('rxjs'), require('rxjs/operators'), require('ngx-socket-io'), require('@angular/forms'), require('microsoft-cognitiveservices-speech-sdk'), require('marked'), require('@daily-co/daily-js'), require('@angular/common'), require('@angular/material/icon'), require('@angular/material/sidenav'), require('ngx-quill')) :
|
|
3
|
+
typeof define === 'function' && define.amd ? define('@hivegpt/hiveai-angular', ['exports', '@angular/cdk/overlay', '@angular/cdk/portal', '@angular/common/http', '@angular/core', '@angular/platform-browser', 'rxjs', 'rxjs/operators', 'ngx-socket-io', '@angular/forms', 'microsoft-cognitiveservices-speech-sdk', 'marked', '@daily-co/daily-js', '@angular/common', '@angular/material/icon', '@angular/material/sidenav', 'ngx-quill'], factory) :
|
|
4
|
+
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory((global.hivegpt = global.hivegpt || {}, global.hivegpt["hiveai-angular"] = {}), global.ng.cdk.overlay, global.ng.cdk.portal, global.ng.common.http, global.ng.core, global.ng.platformBrowser, global.rxjs, global.rxjs.operators, global.ngxSocketIo, global.ng.forms, global.SpeechSDK, global.marked, global.Daily, global.ng.common, global.ng.material.icon, global.ng.material.sidenav, global.ngxQuill));
|
|
5
|
+
})(this, (function (exports, overlay, portal, i1, i0, platformBrowser, rxjs, operators, ngxSocketIo, forms, SpeechSDK, marked, Daily, common, icon, sidenav, ngxQuill) { 'use strict';
|
|
6
|
+
|
|
7
|
+
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
|
|
6
8
|
|
|
7
9
|
function _interopNamespace(e) {
|
|
8
10
|
if (e && e.__esModule) return e;
|
|
@@ -26,6 +28,7 @@
|
|
|
26
28
|
var i0__namespace = /*#__PURE__*/_interopNamespace(i0);
|
|
27
29
|
var SpeechSDK__namespace = /*#__PURE__*/_interopNamespace(SpeechSDK);
|
|
28
30
|
var marked__namespace = /*#__PURE__*/_interopNamespace(marked);
|
|
31
|
+
var Daily__default = /*#__PURE__*/_interopDefaultLegacy(Daily);
|
|
29
32
|
|
|
30
33
|
/******************************************************************************
|
|
31
34
|
Copyright (c) Microsoft Corporation.
|
|
@@ -1028,6 +1031,10 @@
|
|
|
1028
1031
|
{ type: i1.HttpClient }
|
|
1029
1032
|
]; };
|
|
1030
1033
|
|
|
1034
|
+
/**
|
|
1035
|
+
* Audio analyzer for waveform visualization only.
|
|
1036
|
+
* Do NOT use isUserSpeaking$ for call state; speaking state must come from Daily.js.
|
|
1037
|
+
*/
|
|
1031
1038
|
var AudioAnalyzerService = /** @class */ (function () {
|
|
1032
1039
|
function AudioAnalyzerService() {
|
|
1033
1040
|
this.audioContext = null;
|
|
@@ -1146,14 +1153,316 @@
|
|
|
1146
1153
|
},] }
|
|
1147
1154
|
];
|
|
1148
1155
|
|
|
1156
|
+
/**
|
|
1157
|
+
* WebSocket-only client for voice agent signaling.
|
|
1158
|
+
* Responsibilities:
|
|
1159
|
+
* - Connect to ws_url
|
|
1160
|
+
* - Parse JSON messages
|
|
1161
|
+
* - Emit roomCreated$, userTranscript$, botTranscript$
|
|
1162
|
+
* - NO audio logic, NO mic logic.
|
|
1163
|
+
*/
|
|
1164
|
+
var WebSocketVoiceClientService = /** @class */ (function () {
|
|
1165
|
+
function WebSocketVoiceClientService() {
|
|
1166
|
+
this.ws = null;
|
|
1167
|
+
this.roomCreatedSubject = new rxjs.Subject();
|
|
1168
|
+
this.userTranscriptSubject = new rxjs.Subject();
|
|
1169
|
+
this.botTranscriptSubject = new rxjs.Subject();
|
|
1170
|
+
/** Emits room_url when backend sends room_created. */
|
|
1171
|
+
this.roomCreated$ = this.roomCreatedSubject.asObservable();
|
|
1172
|
+
/** Emits user transcript updates. */
|
|
1173
|
+
this.userTranscript$ = this.userTranscriptSubject.asObservable();
|
|
1174
|
+
/** Emits bot transcript updates. */
|
|
1175
|
+
this.botTranscript$ = this.botTranscriptSubject.asObservable();
|
|
1176
|
+
}
|
|
1177
|
+
/** Connect to signaling WebSocket. No audio over this connection. */
|
|
1178
|
+
WebSocketVoiceClientService.prototype.connect = function (wsUrl) {
|
|
1179
|
+
var _this = this;
|
|
1180
|
+
var _a;
|
|
1181
|
+
if (((_a = this.ws) === null || _a === void 0 ? void 0 : _a.readyState) === WebSocket.OPEN) {
|
|
1182
|
+
return;
|
|
1183
|
+
}
|
|
1184
|
+
if (this.ws) {
|
|
1185
|
+
this.ws.close();
|
|
1186
|
+
this.ws = null;
|
|
1187
|
+
}
|
|
1188
|
+
try {
|
|
1189
|
+
this.ws = new WebSocket(wsUrl);
|
|
1190
|
+
this.ws.onmessage = function (event) {
|
|
1191
|
+
var _a;
|
|
1192
|
+
try {
|
|
1193
|
+
var msg = JSON.parse(event.data);
|
|
1194
|
+
if ((msg === null || msg === void 0 ? void 0 : msg.type) === 'room_created') {
|
|
1195
|
+
var roomUrl = ((_a = msg.room_url) !== null && _a !== void 0 ? _a : msg.roomUrl);
|
|
1196
|
+
if (typeof roomUrl === 'string') {
|
|
1197
|
+
_this.roomCreatedSubject.next(roomUrl);
|
|
1198
|
+
}
|
|
1199
|
+
}
|
|
1200
|
+
else if ((msg === null || msg === void 0 ? void 0 : msg.type) === 'user_transcript' && typeof msg.text === 'string') {
|
|
1201
|
+
_this.userTranscriptSubject.next({
|
|
1202
|
+
text: msg.text,
|
|
1203
|
+
final: msg.final === true,
|
|
1204
|
+
});
|
|
1205
|
+
}
|
|
1206
|
+
else if ((msg === null || msg === void 0 ? void 0 : msg.type) === 'bot_transcript' && typeof msg.text === 'string') {
|
|
1207
|
+
_this.botTranscriptSubject.next(msg.text);
|
|
1208
|
+
}
|
|
1209
|
+
}
|
|
1210
|
+
catch (_b) {
|
|
1211
|
+
// Ignore non-JSON or unknown messages
|
|
1212
|
+
}
|
|
1213
|
+
};
|
|
1214
|
+
this.ws.onerror = function () {
|
|
1215
|
+
_this.disconnect();
|
|
1216
|
+
};
|
|
1217
|
+
this.ws.onclose = function () {
|
|
1218
|
+
_this.ws = null;
|
|
1219
|
+
};
|
|
1220
|
+
}
|
|
1221
|
+
catch (err) {
|
|
1222
|
+
console.error('WebSocketVoiceClient: connect failed', err);
|
|
1223
|
+
this.ws = null;
|
|
1224
|
+
throw err;
|
|
1225
|
+
}
|
|
1226
|
+
};
|
|
1227
|
+
/** Disconnect and cleanup. */
|
|
1228
|
+
WebSocketVoiceClientService.prototype.disconnect = function () {
|
|
1229
|
+
if (this.ws) {
|
|
1230
|
+
this.ws.close();
|
|
1231
|
+
this.ws = null;
|
|
1232
|
+
}
|
|
1233
|
+
};
|
|
1234
|
+
Object.defineProperty(WebSocketVoiceClientService.prototype, "isConnected", {
|
|
1235
|
+
/** Whether the WebSocket is open. */
|
|
1236
|
+
get: function () {
|
|
1237
|
+
var _a;
|
|
1238
|
+
return ((_a = this.ws) === null || _a === void 0 ? void 0 : _a.readyState) === WebSocket.OPEN;
|
|
1239
|
+
},
|
|
1240
|
+
enumerable: false,
|
|
1241
|
+
configurable: true
|
|
1242
|
+
});
|
|
1243
|
+
return WebSocketVoiceClientService;
|
|
1244
|
+
}());
|
|
1245
|
+
WebSocketVoiceClientService.ɵprov = i0__namespace.ɵɵdefineInjectable({ factory: function WebSocketVoiceClientService_Factory() { return new WebSocketVoiceClientService(); }, token: WebSocketVoiceClientService, providedIn: "root" });
|
|
1246
|
+
WebSocketVoiceClientService.decorators = [
|
|
1247
|
+
{ type: i0.Injectable, args: [{
|
|
1248
|
+
providedIn: 'root',
|
|
1249
|
+
},] }
|
|
1250
|
+
];
|
|
1251
|
+
|
|
1252
|
+
/**
|
|
1253
|
+
* Daily.js WebRTC client for voice agent audio.
|
|
1254
|
+
* Responsibilities:
|
|
1255
|
+
* - Create and manage Daily CallObject
|
|
1256
|
+
* - Join Daily room using room_url
|
|
1257
|
+
* - Handle mic capture + speaker playback
|
|
1258
|
+
* - Provide real-time speaking detection via active-speaker-change (primary)
|
|
1259
|
+
* and track-started/track-stopped (fallback for immediate feedback)
|
|
1260
|
+
* - Expose speaking$ (bot speaking), userSpeaking$ (user speaking), micMuted$
|
|
1261
|
+
* - Expose localStream$ for waveform visualization (AudioAnalyzerService)
|
|
1262
|
+
*
|
|
1263
|
+
* Speaking state flips immediately when agent audio starts playing.
|
|
1264
|
+
* If user speaks while bot is talking, state switches to listening.
|
|
1265
|
+
*/
|
|
1266
|
+
var DailyVoiceClientService = /** @class */ (function () {
|
|
1267
|
+
function DailyVoiceClientService(ngZone) {
|
|
1268
|
+
this.ngZone = ngZone;
|
|
1269
|
+
this.callObject = null;
|
|
1270
|
+
this.localStream = null;
|
|
1271
|
+
this.localSessionId = null;
|
|
1272
|
+
this.speakingSubject = new rxjs.BehaviorSubject(false);
|
|
1273
|
+
this.userSpeakingSubject = new rxjs.BehaviorSubject(false);
|
|
1274
|
+
this.micMutedSubject = new rxjs.BehaviorSubject(false);
|
|
1275
|
+
this.localStreamSubject = new rxjs.BehaviorSubject(null);
|
|
1276
|
+
/** True when bot (remote participant) is the active speaker. */
|
|
1277
|
+
this.speaking$ = this.speakingSubject.asObservable();
|
|
1278
|
+
/** True when user (local participant) is the active speaker. */
|
|
1279
|
+
this.userSpeaking$ = this.userSpeakingSubject.asObservable();
|
|
1280
|
+
/** True when mic is muted. */
|
|
1281
|
+
this.micMuted$ = this.micMutedSubject.asObservable();
|
|
1282
|
+
/** Emits local mic stream for waveform visualization. */
|
|
1283
|
+
this.localStream$ = this.localStreamSubject.asObservable();
|
|
1284
|
+
}
|
|
1285
|
+
/**
|
|
1286
|
+
* Connect to Daily room. Acquires mic first for waveform, then joins with audio.
|
|
1287
|
+
* @param roomUrl Daily room URL (from room_created)
|
|
1288
|
+
* @param token Optional meeting token
|
|
1289
|
+
*/
|
|
1290
|
+
DailyVoiceClientService.prototype.connect = function (roomUrl, token) {
|
|
1291
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
1292
|
+
var stream, audioTrack, callObject, participants, err_1;
|
|
1293
|
+
return __generator(this, function (_c) {
|
|
1294
|
+
switch (_c.label) {
|
|
1295
|
+
case 0:
|
|
1296
|
+
if (!this.callObject) return [3 /*break*/, 2];
|
|
1297
|
+
return [4 /*yield*/, this.disconnect()];
|
|
1298
|
+
case 1:
|
|
1299
|
+
_c.sent();
|
|
1300
|
+
_c.label = 2;
|
|
1301
|
+
case 2:
|
|
1302
|
+
_c.trys.push([2, 5, , 6]);
|
|
1303
|
+
return [4 /*yield*/, navigator.mediaDevices.getUserMedia({ audio: true })];
|
|
1304
|
+
case 3:
|
|
1305
|
+
stream = _c.sent();
|
|
1306
|
+
audioTrack = stream.getAudioTracks()[0];
|
|
1307
|
+
if (!audioTrack) {
|
|
1308
|
+
stream.getTracks().forEach(function (t) { return t.stop(); });
|
|
1309
|
+
throw new Error('No audio track');
|
|
1310
|
+
}
|
|
1311
|
+
this.localStream = stream;
|
|
1312
|
+
this.localStreamSubject.next(stream);
|
|
1313
|
+
callObject = Daily__default["default"].createCallObject({
|
|
1314
|
+
videoSource: false,
|
|
1315
|
+
audioSource: audioTrack,
|
|
1316
|
+
});
|
|
1317
|
+
this.callObject = callObject;
|
|
1318
|
+
this.setupEventHandlers(callObject);
|
|
1319
|
+
// Join room; Daily handles playback of remote (bot) audio automatically
|
|
1320
|
+
return [4 /*yield*/, callObject.join({ url: roomUrl, token: token })];
|
|
1321
|
+
case 4:
|
|
1322
|
+
// Join room; Daily handles playback of remote (bot) audio automatically
|
|
1323
|
+
_c.sent();
|
|
1324
|
+
participants = callObject.participants();
|
|
1325
|
+
if (participants === null || participants === void 0 ? void 0 : participants.local) {
|
|
1326
|
+
this.localSessionId = participants.local.session_id;
|
|
1327
|
+
}
|
|
1328
|
+
// Initial mute state: Daily starts with audio on
|
|
1329
|
+
this.micMutedSubject.next(!callObject.localAudio());
|
|
1330
|
+
return [3 /*break*/, 6];
|
|
1331
|
+
case 5:
|
|
1332
|
+
err_1 = _c.sent();
|
|
1333
|
+
this.cleanup();
|
|
1334
|
+
throw err_1;
|
|
1335
|
+
case 6: return [2 /*return*/];
|
|
1336
|
+
}
|
|
1337
|
+
});
|
|
1338
|
+
});
|
|
1339
|
+
};
|
|
1340
|
+
DailyVoiceClientService.prototype.setupEventHandlers = function (call) {
|
|
1341
|
+
var _this = this;
|
|
1342
|
+
// active-speaker-change: primary source for real-time speaking detection.
|
|
1343
|
+
// Emits when the loudest participant changes; bot speaking = remote is active.
|
|
1344
|
+
call.on('active-speaker-change', function (event) {
|
|
1345
|
+
_this.ngZone.run(function () {
|
|
1346
|
+
var _a;
|
|
1347
|
+
var peerId = (_a = event === null || event === void 0 ? void 0 : event.activeSpeaker) === null || _a === void 0 ? void 0 : _a.peerId;
|
|
1348
|
+
if (!peerId || !_this.localSessionId) {
|
|
1349
|
+
_this.speakingSubject.next(false);
|
|
1350
|
+
_this.userSpeakingSubject.next(false);
|
|
1351
|
+
return;
|
|
1352
|
+
}
|
|
1353
|
+
var isLocal = peerId === _this.localSessionId;
|
|
1354
|
+
_this.userSpeakingSubject.next(isLocal);
|
|
1355
|
+
_this.speakingSubject.next(!isLocal);
|
|
1356
|
+
});
|
|
1357
|
+
});
|
|
1358
|
+
// track-started / track-stopped: fallback for immediate feedback when
|
|
1359
|
+
// remote (bot) audio track starts or stops. Ensures talking indicator
|
|
1360
|
+
// flips as soon as agent audio begins, without waiting for active-speaker-change.
|
|
1361
|
+
call.on('track-started', function (event) {
|
|
1362
|
+
_this.ngZone.run(function () {
|
|
1363
|
+
var _a, _b;
|
|
1364
|
+
var p = event === null || event === void 0 ? void 0 : event.participant;
|
|
1365
|
+
var type = (_a = event === null || event === void 0 ? void 0 : event.type) !== null && _a !== void 0 ? _a : (_b = event === null || event === void 0 ? void 0 : event.track) === null || _b === void 0 ? void 0 : _b.kind;
|
|
1366
|
+
if (p && !p.local && type === 'audio') {
|
|
1367
|
+
_this.speakingSubject.next(true);
|
|
1368
|
+
}
|
|
1369
|
+
});
|
|
1370
|
+
});
|
|
1371
|
+
call.on('track-stopped', function (event) {
|
|
1372
|
+
_this.ngZone.run(function () {
|
|
1373
|
+
var _a, _b;
|
|
1374
|
+
var p = event === null || event === void 0 ? void 0 : event.participant;
|
|
1375
|
+
var type = (_a = event === null || event === void 0 ? void 0 : event.type) !== null && _a !== void 0 ? _a : (_b = event === null || event === void 0 ? void 0 : event.track) === null || _b === void 0 ? void 0 : _b.kind;
|
|
1376
|
+
if (p && !p.local && type === 'audio') {
|
|
1377
|
+
_this.speakingSubject.next(false);
|
|
1378
|
+
}
|
|
1379
|
+
});
|
|
1380
|
+
});
|
|
1381
|
+
call.on('left-meeting', function () {
|
|
1382
|
+
_this.ngZone.run(function () { return _this.cleanup(); });
|
|
1383
|
+
});
|
|
1384
|
+
call.on('error', function (event) {
|
|
1385
|
+
_this.ngZone.run(function () {
|
|
1386
|
+
var _a;
|
|
1387
|
+
console.error('DailyVoiceClient: Daily error', (_a = event === null || event === void 0 ? void 0 : event.errorMsg) !== null && _a !== void 0 ? _a : event);
|
|
1388
|
+
_this.cleanup();
|
|
1389
|
+
});
|
|
1390
|
+
});
|
|
1391
|
+
};
|
|
1392
|
+
/** Set mic muted state. */
|
|
1393
|
+
DailyVoiceClientService.prototype.setMuted = function (muted) {
|
|
1394
|
+
if (!this.callObject)
|
|
1395
|
+
return;
|
|
1396
|
+
this.callObject.setLocalAudio(!muted);
|
|
1397
|
+
this.micMutedSubject.next(muted);
|
|
1398
|
+
};
|
|
1399
|
+
/** Disconnect and cleanup. */
|
|
1400
|
+
DailyVoiceClientService.prototype.disconnect = function () {
|
|
1401
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
1402
|
+
var e_1;
|
|
1403
|
+
return __generator(this, function (_c) {
|
|
1404
|
+
switch (_c.label) {
|
|
1405
|
+
case 0:
|
|
1406
|
+
if (!this.callObject) {
|
|
1407
|
+
this.cleanup();
|
|
1408
|
+
return [2 /*return*/];
|
|
1409
|
+
}
|
|
1410
|
+
_c.label = 1;
|
|
1411
|
+
case 1:
|
|
1412
|
+
_c.trys.push([1, 3, , 4]);
|
|
1413
|
+
return [4 /*yield*/, this.callObject.leave()];
|
|
1414
|
+
case 2:
|
|
1415
|
+
_c.sent();
|
|
1416
|
+
return [3 /*break*/, 4];
|
|
1417
|
+
case 3:
|
|
1418
|
+
e_1 = _c.sent();
|
|
1419
|
+
return [3 /*break*/, 4];
|
|
1420
|
+
case 4:
|
|
1421
|
+
this.cleanup();
|
|
1422
|
+
return [2 /*return*/];
|
|
1423
|
+
}
|
|
1424
|
+
});
|
|
1425
|
+
});
|
|
1426
|
+
};
|
|
1427
|
+
DailyVoiceClientService.prototype.cleanup = function () {
|
|
1428
|
+
if (this.callObject) {
|
|
1429
|
+
this.callObject.destroy().catch(function () { });
|
|
1430
|
+
this.callObject = null;
|
|
1431
|
+
}
|
|
1432
|
+
if (this.localStream) {
|
|
1433
|
+
this.localStream.getTracks().forEach(function (t) { return t.stop(); });
|
|
1434
|
+
this.localStream = null;
|
|
1435
|
+
}
|
|
1436
|
+
this.localSessionId = null;
|
|
1437
|
+
this.speakingSubject.next(false);
|
|
1438
|
+
this.userSpeakingSubject.next(false);
|
|
1439
|
+
this.localStreamSubject.next(null);
|
|
1440
|
+
// Keep last micMuted state; will reset on next connect
|
|
1441
|
+
};
|
|
1442
|
+
return DailyVoiceClientService;
|
|
1443
|
+
}());
|
|
1444
|
+
DailyVoiceClientService.ɵprov = i0__namespace.ɵɵdefineInjectable({ factory: function DailyVoiceClientService_Factory() { return new DailyVoiceClientService(i0__namespace.ɵɵinject(i0__namespace.NgZone)); }, token: DailyVoiceClientService, providedIn: "root" });
|
|
1445
|
+
DailyVoiceClientService.decorators = [
|
|
1446
|
+
{ type: i0.Injectable, args: [{
|
|
1447
|
+
providedIn: 'root',
|
|
1448
|
+
},] }
|
|
1449
|
+
];
|
|
1450
|
+
DailyVoiceClientService.ctorParameters = function () { return [
|
|
1451
|
+
{ type: i0.NgZone }
|
|
1452
|
+
]; };
|
|
1453
|
+
|
|
1454
|
+
/**
|
|
1455
|
+
* Voice agent orchestrator. Coordinates WebSocket (signaling) and Daily.js (WebRTC audio).
|
|
1456
|
+
* - Maintains callState, statusText, duration, isMicMuted, isUserSpeaking, audioLevels
|
|
1457
|
+
* - Uses WebSocket for room_created and transcripts only (no audio)
|
|
1458
|
+
* - Uses Daily.js for all audio, mic, and real-time speaking detection
|
|
1459
|
+
*/
|
|
1149
1460
|
var VoiceAgentService = /** @class */ (function () {
|
|
1150
|
-
function VoiceAgentService(audioAnalyzer) {
|
|
1461
|
+
function VoiceAgentService(audioAnalyzer, wsClient, dailyClient) {
|
|
1151
1462
|
var _this = this;
|
|
1152
1463
|
this.audioAnalyzer = audioAnalyzer;
|
|
1153
|
-
this.
|
|
1154
|
-
this.
|
|
1155
|
-
this.userMediaStream = null;
|
|
1156
|
-
this.botAudioElement = null;
|
|
1464
|
+
this.wsClient = wsClient;
|
|
1465
|
+
this.dailyClient = dailyClient;
|
|
1157
1466
|
this.callStateSubject = new rxjs.BehaviorSubject('idle');
|
|
1158
1467
|
this.statusTextSubject = new rxjs.BehaviorSubject('');
|
|
1159
1468
|
this.durationSubject = new rxjs.BehaviorSubject('00:00');
|
|
@@ -1164,6 +1473,8 @@
|
|
|
1164
1473
|
this.botTranscriptSubject = new rxjs.Subject();
|
|
1165
1474
|
this.callStartTime = 0;
|
|
1166
1475
|
this.durationInterval = null;
|
|
1476
|
+
this.subscriptions = new rxjs.Subscription();
|
|
1477
|
+
this.destroy$ = new rxjs.Subject();
|
|
1167
1478
|
this.callState$ = this.callStateSubject.asObservable();
|
|
1168
1479
|
this.statusText$ = this.statusTextSubject.asObservable();
|
|
1169
1480
|
this.duration$ = this.durationSubject.asObservable();
|
|
@@ -1172,39 +1483,23 @@
|
|
|
1172
1483
|
this.audioLevels$ = this.audioLevelsSubject.asObservable();
|
|
1173
1484
|
this.userTranscript$ = this.userTranscriptSubject.asObservable();
|
|
1174
1485
|
this.botTranscript$ = this.botTranscriptSubject.asObservable();
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
});
|
|
1178
|
-
this.audioAnalyzer.isUserSpeaking$.subscribe(function (isSpeaking) {
|
|
1179
|
-
_this.isUserSpeakingSubject.next(isSpeaking);
|
|
1180
|
-
if (isSpeaking && _this.callStateSubject.value === 'connected') {
|
|
1181
|
-
_this.callStateSubject.next('listening');
|
|
1182
|
-
}
|
|
1183
|
-
else if (!isSpeaking && _this.callStateSubject.value === 'listening') {
|
|
1184
|
-
_this.callStateSubject.next('connected');
|
|
1185
|
-
}
|
|
1186
|
-
});
|
|
1486
|
+
// Waveform visualization only - do NOT use for speaking state
|
|
1487
|
+
this.subscriptions.add(this.audioAnalyzer.audioLevels$.subscribe(function (levels) { return _this.audioLevelsSubject.next(levels); }));
|
|
1187
1488
|
}
|
|
1489
|
+
VoiceAgentService.prototype.ngOnDestroy = function () {
|
|
1490
|
+
this.destroy$.next();
|
|
1491
|
+
this.subscriptions.unsubscribe();
|
|
1492
|
+
this.disconnect();
|
|
1493
|
+
};
|
|
1188
1494
|
/** Reset to idle state (e.g. when modal opens so user can click Start Call). */
|
|
1189
1495
|
VoiceAgentService.prototype.resetToIdle = function () {
|
|
1190
1496
|
if (this.callStateSubject.value === 'idle')
|
|
1191
1497
|
return;
|
|
1192
|
-
|
|
1193
|
-
clearInterval(this.durationInterval);
|
|
1194
|
-
this.durationInterval = null;
|
|
1195
|
-
}
|
|
1498
|
+
this.stopDurationTimer();
|
|
1196
1499
|
this.audioAnalyzer.stop();
|
|
1197
|
-
this.
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
this.userMediaStream.getTracks().forEach(function (track) { return track.stop(); });
|
|
1201
|
-
this.userMediaStream = null;
|
|
1202
|
-
}
|
|
1203
|
-
if (this.botAudioElement) {
|
|
1204
|
-
this.botAudioElement.pause();
|
|
1205
|
-
this.botAudioElement.srcObject = null;
|
|
1206
|
-
this.botAudioElement = null;
|
|
1207
|
-
}
|
|
1500
|
+
this.wsClient.disconnect();
|
|
1501
|
+
// Fire-and-forget: Daily disconnect is async; connect() will await if needed
|
|
1502
|
+
void this.dailyClient.disconnect();
|
|
1208
1503
|
this.callStateSubject.next('idle');
|
|
1209
1504
|
this.statusTextSubject.next('');
|
|
1210
1505
|
this.durationSubject.next('0:00');
|
|
@@ -1212,7 +1507,8 @@
|
|
|
1212
1507
|
VoiceAgentService.prototype.connect = function (apiUrl, token, botId, conversationId, apiKey, eventToken, eventUrl, domainAuthority) {
|
|
1213
1508
|
var _a;
|
|
1214
1509
|
return __awaiter(this, void 0, void 0, function () {
|
|
1215
|
-
var baseUrl,
|
|
1510
|
+
var baseUrl, postUrl, headers, res, json, wsUrl, error_1;
|
|
1511
|
+
var _this = this;
|
|
1216
1512
|
return __generator(this, function (_b) {
|
|
1217
1513
|
switch (_b.label) {
|
|
1218
1514
|
case 0:
|
|
@@ -1222,152 +1518,160 @@
|
|
|
1222
1518
|
}
|
|
1223
1519
|
_b.label = 1;
|
|
1224
1520
|
case 1:
|
|
1225
|
-
_b.trys.push([1,
|
|
1521
|
+
_b.trys.push([1, 4, , 6]);
|
|
1226
1522
|
this.callStateSubject.next('connecting');
|
|
1227
1523
|
this.statusTextSubject.next('Connecting...');
|
|
1228
1524
|
baseUrl = apiUrl.replace(/\/$/, '');
|
|
1229
|
-
|
|
1230
|
-
headers =
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
startBotParams = {
|
|
1239
|
-
endpoint: connectUrl.ws_url,
|
|
1240
|
-
headers: headers,
|
|
1241
|
-
requestData: {
|
|
1242
|
-
bot_id: botId,
|
|
1243
|
-
conversation_id: conversationId,
|
|
1244
|
-
voice: 'alloy',
|
|
1245
|
-
},
|
|
1525
|
+
postUrl = baseUrl + "/ai/ask-voice";
|
|
1526
|
+
headers = {
|
|
1527
|
+
'Content-Type': 'application/json',
|
|
1528
|
+
Authorization: "Bearer " + token,
|
|
1529
|
+
'domain-authority': domainAuthority,
|
|
1530
|
+
'eventtoken': eventToken,
|
|
1531
|
+
'eventurl': eventUrl,
|
|
1532
|
+
'hive-bot-id': botId,
|
|
1533
|
+
'x-api-key': apiKey,
|
|
1246
1534
|
};
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
return [4 /*yield*/, this.client.startBotAndConnect(startBotParams)];
|
|
1535
|
+
return [4 /*yield*/, fetch(postUrl, {
|
|
1536
|
+
method: 'POST',
|
|
1537
|
+
headers: headers,
|
|
1538
|
+
body: JSON.stringify({
|
|
1539
|
+
bot_id: botId,
|
|
1540
|
+
conversation_id: conversationId,
|
|
1541
|
+
voice: 'alloy',
|
|
1542
|
+
}),
|
|
1543
|
+
})];
|
|
1257
1544
|
case 2:
|
|
1258
|
-
_b.sent();
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
this.userMediaStream = new MediaStream([tracks.local.audio]);
|
|
1262
|
-
this.audioAnalyzer.start(this.userMediaStream);
|
|
1545
|
+
res = _b.sent();
|
|
1546
|
+
if (!res.ok) {
|
|
1547
|
+
throw new Error("HTTP " + res.status);
|
|
1263
1548
|
}
|
|
1264
|
-
|
|
1265
|
-
this.callStateSubject.next('connected');
|
|
1266
|
-
this.statusTextSubject.next('Connected');
|
|
1267
|
-
this.callStartTime = Date.now();
|
|
1268
|
-
this.startDurationTimer();
|
|
1269
|
-
return [3 /*break*/, 5];
|
|
1549
|
+
return [4 /*yield*/, res.json()];
|
|
1270
1550
|
case 3:
|
|
1551
|
+
json = _b.sent();
|
|
1552
|
+
wsUrl = (_a = json === null || json === void 0 ? void 0 : json.ws_url) !== null && _a !== void 0 ? _a : json === null || json === void 0 ? void 0 : json.rn_ws_url;
|
|
1553
|
+
if (!wsUrl || typeof wsUrl !== 'string') {
|
|
1554
|
+
throw new Error('No ws_url in response');
|
|
1555
|
+
}
|
|
1556
|
+
// Subscribe to room_created BEFORE connecting to avoid race
|
|
1557
|
+
this.wsClient.roomCreated$
|
|
1558
|
+
.pipe(operators.take(1), operators.takeUntil(this.destroy$))
|
|
1559
|
+
.subscribe(function (roomUrl) { return __awaiter(_this, void 0, void 0, function () {
|
|
1560
|
+
var err_1;
|
|
1561
|
+
return __generator(this, function (_b) {
|
|
1562
|
+
switch (_b.label) {
|
|
1563
|
+
case 0:
|
|
1564
|
+
_b.trys.push([0, 2, , 4]);
|
|
1565
|
+
return [4 /*yield*/, this.onRoomCreated(roomUrl)];
|
|
1566
|
+
case 1:
|
|
1567
|
+
_b.sent();
|
|
1568
|
+
return [3 /*break*/, 4];
|
|
1569
|
+
case 2:
|
|
1570
|
+
err_1 = _b.sent();
|
|
1571
|
+
console.error('Daily join failed:', err_1);
|
|
1572
|
+
this.callStateSubject.next('ended');
|
|
1573
|
+
this.statusTextSubject.next('Connection failed');
|
|
1574
|
+
return [4 /*yield*/, this.disconnect()];
|
|
1575
|
+
case 3:
|
|
1576
|
+
_b.sent();
|
|
1577
|
+
throw err_1;
|
|
1578
|
+
case 4: return [2 /*return*/];
|
|
1579
|
+
}
|
|
1580
|
+
});
|
|
1581
|
+
}); });
|
|
1582
|
+
// Forward transcripts from WebSocket
|
|
1583
|
+
this.subscriptions.add(this.wsClient.userTranscript$
|
|
1584
|
+
.pipe(operators.takeUntil(this.destroy$))
|
|
1585
|
+
.subscribe(function (t) { return _this.userTranscriptSubject.next(t); }));
|
|
1586
|
+
this.subscriptions.add(this.wsClient.botTranscript$
|
|
1587
|
+
.pipe(operators.takeUntil(this.destroy$))
|
|
1588
|
+
.subscribe(function (t) { return _this.botTranscriptSubject.next(t); }));
|
|
1589
|
+
// Connect signaling WebSocket (no audio over WS)
|
|
1590
|
+
this.wsClient.connect(wsUrl);
|
|
1591
|
+
return [3 /*break*/, 6];
|
|
1592
|
+
case 4:
|
|
1271
1593
|
error_1 = _b.sent();
|
|
1272
1594
|
console.error('Error connecting voice agent:', error_1);
|
|
1273
1595
|
this.callStateSubject.next('ended');
|
|
1274
1596
|
return [4 /*yield*/, this.disconnect()];
|
|
1275
|
-
case
|
|
1597
|
+
case 5:
|
|
1276
1598
|
_b.sent();
|
|
1277
1599
|
this.statusTextSubject.next('Connection failed');
|
|
1278
1600
|
throw error_1;
|
|
1279
|
-
case
|
|
1601
|
+
case 6: return [2 /*return*/];
|
|
1602
|
+
}
|
|
1603
|
+
});
|
|
1604
|
+
});
|
|
1605
|
+
};
|
|
1606
|
+
VoiceAgentService.prototype.onRoomCreated = function (roomUrl) {
|
|
1607
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
1608
|
+
var _this = this;
|
|
1609
|
+
return __generator(this, function (_b) {
|
|
1610
|
+
switch (_b.label) {
|
|
1611
|
+
case 0:
|
|
1612
|
+
// Connect Daily.js for WebRTC audio
|
|
1613
|
+
return [4 /*yield*/, this.dailyClient.connect(roomUrl)];
|
|
1614
|
+
case 1:
|
|
1615
|
+
// Connect Daily.js for WebRTC audio
|
|
1616
|
+
_b.sent();
|
|
1617
|
+
// Waveform: use local mic stream from Daily client
|
|
1618
|
+
this.dailyClient.localStream$
|
|
1619
|
+
.pipe(operators.filter(function (s) { return s != null; }), operators.take(1))
|
|
1620
|
+
.subscribe(function (stream) {
|
|
1621
|
+
_this.audioAnalyzer.start(stream);
|
|
1622
|
+
});
|
|
1623
|
+
// Speaking state from Daily only (NOT from AudioAnalyzer).
|
|
1624
|
+
// User speaking overrides bot talking: if user speaks while bot talks, state = listening.
|
|
1625
|
+
this.subscriptions.add(this.dailyClient.userSpeaking$.subscribe(function (s) { return _this.isUserSpeakingSubject.next(s); }));
|
|
1626
|
+
this.subscriptions.add(rxjs.combineLatest([
|
|
1627
|
+
this.dailyClient.speaking$,
|
|
1628
|
+
this.dailyClient.userSpeaking$,
|
|
1629
|
+
]).subscribe(function (_b) {
|
|
1630
|
+
var _c = __read(_b, 2), bot = _c[0], user = _c[1];
|
|
1631
|
+
if (user) {
|
|
1632
|
+
_this.callStateSubject.next('listening');
|
|
1633
|
+
}
|
|
1634
|
+
else if (bot) {
|
|
1635
|
+
_this.callStateSubject.next('talking');
|
|
1636
|
+
}
|
|
1637
|
+
else if (_this.callStateSubject.value === 'talking' ||
|
|
1638
|
+
_this.callStateSubject.value === 'listening') {
|
|
1639
|
+
_this.callStateSubject.next('connected');
|
|
1640
|
+
}
|
|
1641
|
+
}));
|
|
1642
|
+
this.subscriptions.add(this.dailyClient.micMuted$.subscribe(function (muted) { return _this.isMicMutedSubject.next(muted); }));
|
|
1643
|
+
this.callStateSubject.next('connected');
|
|
1644
|
+
this.statusTextSubject.next('Connected');
|
|
1645
|
+
this.callStartTime = Date.now();
|
|
1646
|
+
this.startDurationTimer();
|
|
1647
|
+
return [2 /*return*/];
|
|
1280
1648
|
}
|
|
1281
1649
|
});
|
|
1282
1650
|
});
|
|
1283
1651
|
};
|
|
1284
1652
|
VoiceAgentService.prototype.disconnect = function () {
|
|
1285
1653
|
return __awaiter(this, void 0, void 0, function () {
|
|
1286
|
-
var error_2;
|
|
1287
1654
|
return __generator(this, function (_b) {
|
|
1288
1655
|
switch (_b.label) {
|
|
1289
1656
|
case 0:
|
|
1290
|
-
|
|
1291
|
-
if (this.durationInterval) {
|
|
1292
|
-
clearInterval(this.durationInterval);
|
|
1293
|
-
this.durationInterval = null;
|
|
1294
|
-
}
|
|
1657
|
+
this.stopDurationTimer();
|
|
1295
1658
|
this.audioAnalyzer.stop();
|
|
1296
|
-
|
|
1297
|
-
return [4 /*yield*/, this.
|
|
1659
|
+
// Daily first, then WebSocket
|
|
1660
|
+
return [4 /*yield*/, this.dailyClient.disconnect()];
|
|
1298
1661
|
case 1:
|
|
1662
|
+
// Daily first, then WebSocket
|
|
1299
1663
|
_b.sent();
|
|
1300
|
-
this.
|
|
1301
|
-
_b.label = 2;
|
|
1302
|
-
case 2:
|
|
1303
|
-
this.transport = null;
|
|
1304
|
-
if (this.userMediaStream) {
|
|
1305
|
-
this.userMediaStream.getTracks().forEach(function (track) { return track.stop(); });
|
|
1306
|
-
this.userMediaStream = null;
|
|
1307
|
-
}
|
|
1308
|
-
if (this.botAudioElement) {
|
|
1309
|
-
this.botAudioElement.pause();
|
|
1310
|
-
this.botAudioElement.srcObject = null;
|
|
1311
|
-
this.botAudioElement = null;
|
|
1312
|
-
}
|
|
1664
|
+
this.wsClient.disconnect();
|
|
1313
1665
|
this.callStateSubject.next('ended');
|
|
1314
1666
|
this.statusTextSubject.next('Call Ended');
|
|
1315
|
-
return [
|
|
1316
|
-
case 3:
|
|
1317
|
-
error_2 = _b.sent();
|
|
1318
|
-
console.error('Error disconnecting voice agent:', error_2);
|
|
1319
|
-
return [3 /*break*/, 4];
|
|
1320
|
-
case 4: return [2 /*return*/];
|
|
1667
|
+
return [2 /*return*/];
|
|
1321
1668
|
}
|
|
1322
1669
|
});
|
|
1323
1670
|
});
|
|
1324
1671
|
};
|
|
1325
1672
|
VoiceAgentService.prototype.toggleMic = function () {
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
var newState = !this.client.isMicEnabled;
|
|
1329
|
-
this.client.enableMic(newState);
|
|
1330
|
-
this.isMicMutedSubject.next(!newState);
|
|
1331
|
-
};
|
|
1332
|
-
VoiceAgentService.prototype.setupEventHandlers = function () {
|
|
1333
|
-
var _this = this;
|
|
1334
|
-
if (!this.client)
|
|
1335
|
-
return;
|
|
1336
|
-
this.client.on(clientJs.RTVIEvent.BotStartedSpeaking, function () {
|
|
1337
|
-
_this.callStateSubject.next('talking');
|
|
1338
|
-
});
|
|
1339
|
-
this.client.on(clientJs.RTVIEvent.BotStoppedSpeaking, function () {
|
|
1340
|
-
if (_this.callStateSubject.value === 'talking') {
|
|
1341
|
-
_this.callStateSubject.next('connected');
|
|
1342
|
-
}
|
|
1343
|
-
});
|
|
1344
|
-
this.client.on(clientJs.RTVIEvent.TrackStarted, function (track, participant) {
|
|
1345
|
-
if (_this.botAudioElement && participant && !participant.local && track.kind === 'audio') {
|
|
1346
|
-
var stream = new MediaStream([track]);
|
|
1347
|
-
_this.botAudioElement.srcObject = stream;
|
|
1348
|
-
_this.botAudioElement.play().catch(console.error);
|
|
1349
|
-
}
|
|
1350
|
-
});
|
|
1351
|
-
this.client.on(clientJs.RTVIEvent.UserTranscript, function (data) {
|
|
1352
|
-
var _a;
|
|
1353
|
-
_this.userTranscriptSubject.next({
|
|
1354
|
-
text: data.text,
|
|
1355
|
-
final: (_a = data.final) !== null && _a !== void 0 ? _a : false,
|
|
1356
|
-
});
|
|
1357
|
-
});
|
|
1358
|
-
this.client.on(clientJs.RTVIEvent.BotTranscript, function (data) {
|
|
1359
|
-
if (data === null || data === void 0 ? void 0 : data.text) {
|
|
1360
|
-
_this.botTranscriptSubject.next(data.text);
|
|
1361
|
-
}
|
|
1362
|
-
});
|
|
1363
|
-
this.client.on(clientJs.RTVIEvent.Error, function () {
|
|
1364
|
-
_this.statusTextSubject.next('Error occurred');
|
|
1365
|
-
});
|
|
1366
|
-
this.client.on(clientJs.RTVIEvent.Disconnected, function () {
|
|
1367
|
-
_this.callStateSubject.next('ended');
|
|
1368
|
-
_this.statusTextSubject.next('Disconnected');
|
|
1369
|
-
_this.disconnect();
|
|
1370
|
-
});
|
|
1673
|
+
var current = this.isMicMutedSubject.value;
|
|
1674
|
+
this.dailyClient.setMuted(!current);
|
|
1371
1675
|
};
|
|
1372
1676
|
VoiceAgentService.prototype.startDurationTimer = function () {
|
|
1373
1677
|
var _this = this;
|
|
@@ -1379,19 +1683,27 @@
|
|
|
1379
1683
|
_this.durationSubject.next(minutes + ":" + String(seconds).padStart(2, '0'));
|
|
1380
1684
|
}
|
|
1381
1685
|
};
|
|
1382
|
-
updateDuration();
|
|
1686
|
+
updateDuration();
|
|
1383
1687
|
this.durationInterval = setInterval(updateDuration, 1000);
|
|
1384
1688
|
};
|
|
1689
|
+
VoiceAgentService.prototype.stopDurationTimer = function () {
|
|
1690
|
+
if (this.durationInterval) {
|
|
1691
|
+
clearInterval(this.durationInterval);
|
|
1692
|
+
this.durationInterval = null;
|
|
1693
|
+
}
|
|
1694
|
+
};
|
|
1385
1695
|
return VoiceAgentService;
|
|
1386
1696
|
}());
|
|
1387
|
-
VoiceAgentService.ɵprov = i0__namespace.ɵɵdefineInjectable({ factory: function VoiceAgentService_Factory() { return new VoiceAgentService(i0__namespace.ɵɵinject(AudioAnalyzerService)); }, token: VoiceAgentService, providedIn: "root" });
|
|
1697
|
+
VoiceAgentService.ɵprov = i0__namespace.ɵɵdefineInjectable({ factory: function VoiceAgentService_Factory() { return new VoiceAgentService(i0__namespace.ɵɵinject(AudioAnalyzerService), i0__namespace.ɵɵinject(WebSocketVoiceClientService), i0__namespace.ɵɵinject(DailyVoiceClientService)); }, token: VoiceAgentService, providedIn: "root" });
|
|
1388
1698
|
VoiceAgentService.decorators = [
|
|
1389
1699
|
{ type: i0.Injectable, args: [{
|
|
1390
|
-
providedIn: 'root'
|
|
1700
|
+
providedIn: 'root',
|
|
1391
1701
|
},] }
|
|
1392
1702
|
];
|
|
1393
1703
|
VoiceAgentService.ctorParameters = function () { return [
|
|
1394
|
-
{ type: AudioAnalyzerService }
|
|
1704
|
+
{ type: AudioAnalyzerService },
|
|
1705
|
+
{ type: WebSocketVoiceClientService },
|
|
1706
|
+
{ type: DailyVoiceClientService }
|
|
1395
1707
|
]; };
|
|
1396
1708
|
|
|
1397
1709
|
var VOICE_MODAL_CONFIG = new i0.InjectionToken('VOICE_MODAL_CONFIG');
|
|
@@ -3572,7 +3884,9 @@
|
|
|
3572
3884
|
],
|
|
3573
3885
|
providers: [
|
|
3574
3886
|
VoiceAgentService,
|
|
3575
|
-
AudioAnalyzerService
|
|
3887
|
+
AudioAnalyzerService,
|
|
3888
|
+
WebSocketVoiceClientService,
|
|
3889
|
+
DailyVoiceClientService
|
|
3576
3890
|
],
|
|
3577
3891
|
exports: [
|
|
3578
3892
|
VoiceAgentModalComponent
|
|
@@ -3870,9 +4184,11 @@
|
|
|
3870
4184
|
exports["ɵc"] = ConversationService;
|
|
3871
4185
|
exports["ɵd"] = NotificationSocket;
|
|
3872
4186
|
exports["ɵe"] = TranslationService;
|
|
3873
|
-
exports["ɵf"] =
|
|
3874
|
-
exports["ɵg"] =
|
|
3875
|
-
exports["ɵh"] =
|
|
4187
|
+
exports["ɵf"] = WebSocketVoiceClientService;
|
|
4188
|
+
exports["ɵg"] = DailyVoiceClientService;
|
|
4189
|
+
exports["ɵh"] = VideoPlayerComponent;
|
|
4190
|
+
exports["ɵi"] = SafeHtmlPipe;
|
|
4191
|
+
exports["ɵj"] = BotHtmlEditorComponent;
|
|
3876
4192
|
|
|
3877
4193
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
3878
4194
|
|