@hivegpt/hiveai-angular 0.0.576 → 0.0.577
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 +214 -356
- 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/lib/components/voice-agent/components/voice-agent-modal/voice-agent-modal.component.js +54 -85
- package/esm2015/lib/components/voice-agent/services/daily-voice-client.service.js +14 -22
- package/esm2015/lib/components/voice-agent/services/voice-agent.service.js +60 -90
- package/esm2015/lib/components/voice-agent/services/websocket-voice-client.service.js +34 -81
- package/fesm2015/hivegpt-hiveai-angular.js +157 -272
- package/fesm2015/hivegpt-hiveai-angular.js.map +1 -1
- package/hivegpt-hiveai-angular.metadata.json +1 -1
- package/lib/components/voice-agent/components/voice-agent-modal/voice-agent-modal.component.d.ts +1 -7
- package/lib/components/voice-agent/components/voice-agent-modal/voice-agent-modal.component.d.ts.map +1 -1
- package/lib/components/voice-agent/services/daily-voice-client.service.d.ts +3 -5
- package/lib/components/voice-agent/services/daily-voice-client.service.d.ts.map +1 -1
- package/lib/components/voice-agent/services/voice-agent.service.d.ts +1 -3
- 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 +12 -5
- package/lib/components/voice-agent/services/websocket-voice-client.service.d.ts.map +1 -1
- package/package.json +1 -1
|
@@ -1349,7 +1349,6 @@
|
|
|
1349
1349
|
* - Emit roomCreated$, userTranscript$, botTranscript$
|
|
1350
1350
|
* - NO audio logic, NO mic logic. Audio is handled by Daily.js (WebRTC).
|
|
1351
1351
|
*/
|
|
1352
|
-
var WS_CONNECT_TIMEOUT_MS = 10000;
|
|
1353
1352
|
var WebSocketVoiceClientService = /** @class */ (function () {
|
|
1354
1353
|
function WebSocketVoiceClientService() {
|
|
1355
1354
|
this.ws = null;
|
|
@@ -1363,101 +1362,55 @@
|
|
|
1363
1362
|
/** Emits bot transcript updates. */
|
|
1364
1363
|
this.botTranscript$ = this.botTranscriptSubject.asObservable();
|
|
1365
1364
|
}
|
|
1366
|
-
/**
|
|
1367
|
-
* Connect to signaling WebSocket. No audio over this connection.
|
|
1368
|
-
* Resolves when the socket is open; rejects if the connection fails.
|
|
1369
|
-
*/
|
|
1365
|
+
/** Connect to signaling WebSocket. No audio over this connection. */
|
|
1370
1366
|
WebSocketVoiceClientService.prototype.connect = function (wsUrl) {
|
|
1371
1367
|
var _this = this;
|
|
1372
1368
|
var _a;
|
|
1373
1369
|
if (((_a = this.ws) === null || _a === void 0 ? void 0 : _a.readyState) === WebSocket.OPEN) {
|
|
1374
|
-
return
|
|
1370
|
+
return;
|
|
1375
1371
|
}
|
|
1376
1372
|
if (this.ws) {
|
|
1377
1373
|
this.ws.close();
|
|
1378
1374
|
this.ws = null;
|
|
1379
1375
|
}
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1376
|
+
try {
|
|
1377
|
+
this.ws = new WebSocket(wsUrl);
|
|
1378
|
+
this.ws.onmessage = function (event) {
|
|
1383
1379
|
var _a;
|
|
1384
|
-
if (settled)
|
|
1385
|
-
return;
|
|
1386
|
-
settled = true;
|
|
1387
1380
|
try {
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
_this.ws = null;
|
|
1394
|
-
reject(new Error('WebSocket connection timed out'));
|
|
1395
|
-
}, WS_CONNECT_TIMEOUT_MS);
|
|
1396
|
-
var clear = function () {
|
|
1397
|
-
clearTimeout(timeout);
|
|
1398
|
-
};
|
|
1399
|
-
try {
|
|
1400
|
-
var ws = new WebSocket(wsUrl);
|
|
1401
|
-
_this.ws = ws;
|
|
1402
|
-
ws.onopen = function () {
|
|
1403
|
-
if (settled)
|
|
1404
|
-
return;
|
|
1405
|
-
settled = true;
|
|
1406
|
-
clear();
|
|
1407
|
-
resolve();
|
|
1408
|
-
};
|
|
1409
|
-
ws.onmessage = function (event) {
|
|
1410
|
-
var _a;
|
|
1411
|
-
try {
|
|
1412
|
-
var msg = JSON.parse(event.data);
|
|
1413
|
-
if ((msg === null || msg === void 0 ? void 0 : msg.type) === 'room_created') {
|
|
1414
|
-
var roomUrl = ((_a = msg.room_url) !== null && _a !== void 0 ? _a : msg.roomUrl);
|
|
1415
|
-
if (typeof roomUrl === 'string') {
|
|
1416
|
-
_this.roomCreatedSubject.next(roomUrl);
|
|
1417
|
-
}
|
|
1381
|
+
var msg = JSON.parse(event.data);
|
|
1382
|
+
if ((msg === null || msg === void 0 ? void 0 : msg.type) === 'room_created') {
|
|
1383
|
+
var roomUrl = ((_a = msg.room_url) !== null && _a !== void 0 ? _a : msg.roomUrl);
|
|
1384
|
+
if (typeof roomUrl === 'string') {
|
|
1385
|
+
_this.roomCreatedSubject.next(roomUrl);
|
|
1418
1386
|
}
|
|
1419
|
-
else if ((msg === null || msg === void 0 ? void 0 : msg.type) === 'user_transcript' && typeof msg.text === 'string') {
|
|
1420
|
-
_this.userTranscriptSubject.next({
|
|
1421
|
-
text: msg.text,
|
|
1422
|
-
final: msg.final === true,
|
|
1423
|
-
});
|
|
1424
|
-
}
|
|
1425
|
-
else if ((msg === null || msg === void 0 ? void 0 : msg.type) === 'bot_transcript' && typeof msg.text === 'string') {
|
|
1426
|
-
_this.botTranscriptSubject.next(msg.text);
|
|
1427
|
-
}
|
|
1428
|
-
}
|
|
1429
|
-
catch (_b) {
|
|
1430
|
-
// Ignore non-JSON or unknown messages
|
|
1431
1387
|
}
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
_this.disconnect();
|
|
1438
|
-
reject(new Error('WebSocket connection failed'));
|
|
1439
|
-
return;
|
|
1388
|
+
else if ((msg === null || msg === void 0 ? void 0 : msg.type) === 'user_transcript' && typeof msg.text === 'string') {
|
|
1389
|
+
_this.userTranscriptSubject.next({
|
|
1390
|
+
text: msg.text,
|
|
1391
|
+
final: msg.final === true,
|
|
1392
|
+
});
|
|
1440
1393
|
}
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
console.warn('WebSocketVoiceClient: onerror after open (not forcing disconnect)');
|
|
1444
|
-
};
|
|
1445
|
-
ws.onclose = function () {
|
|
1446
|
-
_this.ws = null;
|
|
1447
|
-
if (!settled) {
|
|
1448
|
-
settled = true;
|
|
1449
|
-
clear();
|
|
1450
|
-
reject(new Error('WebSocket connection failed'));
|
|
1394
|
+
else if ((msg === null || msg === void 0 ? void 0 : msg.type) === 'bot_transcript' && typeof msg.text === 'string') {
|
|
1395
|
+
_this.botTranscriptSubject.next(msg.text);
|
|
1451
1396
|
}
|
|
1452
|
-
}
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1397
|
+
}
|
|
1398
|
+
catch (_b) {
|
|
1399
|
+
// Ignore non-JSON or unknown messages
|
|
1400
|
+
}
|
|
1401
|
+
};
|
|
1402
|
+
this.ws.onerror = function () {
|
|
1403
|
+
_this.disconnect();
|
|
1404
|
+
};
|
|
1405
|
+
this.ws.onclose = function () {
|
|
1457
1406
|
_this.ws = null;
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
|
|
1407
|
+
};
|
|
1408
|
+
}
|
|
1409
|
+
catch (err) {
|
|
1410
|
+
console.error('WebSocketVoiceClient: connect failed', err);
|
|
1411
|
+
this.ws = null;
|
|
1412
|
+
throw err;
|
|
1413
|
+
}
|
|
1461
1414
|
};
|
|
1462
1415
|
/** Disconnect and cleanup. */
|
|
1463
1416
|
WebSocketVoiceClientService.prototype.disconnect = function () {
|
|
@@ -1505,8 +1458,7 @@
|
|
|
1505
1458
|
this.remoteAudioElement = null;
|
|
1506
1459
|
/** AnalyserNode-based remote audio monitor for instant bot speaking detection. */
|
|
1507
1460
|
this.remoteAudioContext = null;
|
|
1508
|
-
|
|
1509
|
-
this.remoteSpeakingPollId = null;
|
|
1461
|
+
this.remoteSpeakingRAF = null;
|
|
1510
1462
|
this.speakingSubject = new rxjs.BehaviorSubject(false);
|
|
1511
1463
|
this.userSpeakingSubject = new rxjs.BehaviorSubject(false);
|
|
1512
1464
|
this.micMutedSubject = new rxjs.BehaviorSubject(false);
|
|
@@ -1524,31 +1476,23 @@
|
|
|
1524
1476
|
* Connect to Daily room. Acquires mic first for waveform, then joins with audio.
|
|
1525
1477
|
* @param roomUrl Daily room URL (from room_created)
|
|
1526
1478
|
* @param token Optional meeting token
|
|
1527
|
-
* @param existingStream Optional pre-acquired mic (avoids a second getUserMedia / extra prompts on some browsers)
|
|
1528
1479
|
*/
|
|
1529
|
-
DailyVoiceClientService.prototype.connect = function (roomUrl, token
|
|
1480
|
+
DailyVoiceClientService.prototype.connect = function (roomUrl, token) {
|
|
1530
1481
|
return __awaiter(this, void 0, void 0, function () {
|
|
1531
|
-
var
|
|
1532
|
-
return __generator(this, function (
|
|
1533
|
-
switch (
|
|
1482
|
+
var stream, audioTrack, callObject, joinOptions, participants, err_1;
|
|
1483
|
+
return __generator(this, function (_e) {
|
|
1484
|
+
switch (_e.label) {
|
|
1534
1485
|
case 0:
|
|
1535
1486
|
if (!this.callObject) return [3 /*break*/, 2];
|
|
1536
1487
|
return [4 /*yield*/, this.disconnect()];
|
|
1537
1488
|
case 1:
|
|
1538
|
-
|
|
1539
|
-
|
|
1489
|
+
_e.sent();
|
|
1490
|
+
_e.label = 2;
|
|
1540
1491
|
case 2:
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
return [3 /*break*/, 5];
|
|
1546
|
-
case 3: return [4 /*yield*/, navigator.mediaDevices.getUserMedia({ audio: true })];
|
|
1547
|
-
case 4:
|
|
1548
|
-
_e = _f.sent();
|
|
1549
|
-
_f.label = 5;
|
|
1550
|
-
case 5:
|
|
1551
|
-
stream = _e;
|
|
1492
|
+
_e.trys.push([2, 5, , 6]);
|
|
1493
|
+
return [4 /*yield*/, navigator.mediaDevices.getUserMedia({ audio: true })];
|
|
1494
|
+
case 3:
|
|
1495
|
+
stream = _e.sent();
|
|
1552
1496
|
audioTrack = stream.getAudioTracks()[0];
|
|
1553
1497
|
if (!audioTrack) {
|
|
1554
1498
|
stream.getTracks().forEach(function (t) { return t.stop(); });
|
|
@@ -1567,8 +1511,8 @@
|
|
|
1567
1511
|
joinOptions.token = token;
|
|
1568
1512
|
}
|
|
1569
1513
|
return [4 /*yield*/, callObject.join(joinOptions)];
|
|
1570
|
-
case
|
|
1571
|
-
|
|
1514
|
+
case 4:
|
|
1515
|
+
_e.sent();
|
|
1572
1516
|
console.log("[VoiceDebug] Room connected (Daily join complete) \u2014 " + new Date().toISOString());
|
|
1573
1517
|
participants = callObject.participants();
|
|
1574
1518
|
if (participants === null || participants === void 0 ? void 0 : participants.local) {
|
|
@@ -1576,12 +1520,12 @@
|
|
|
1576
1520
|
}
|
|
1577
1521
|
// Initial mute state: Daily starts with audio on
|
|
1578
1522
|
this.micMutedSubject.next(!callObject.localAudio());
|
|
1579
|
-
return [3 /*break*/,
|
|
1580
|
-
case
|
|
1581
|
-
err_1 =
|
|
1523
|
+
return [3 /*break*/, 6];
|
|
1524
|
+
case 5:
|
|
1525
|
+
err_1 = _e.sent();
|
|
1582
1526
|
this.cleanup();
|
|
1583
1527
|
throw err_1;
|
|
1584
|
-
case
|
|
1528
|
+
case 6: return [2 /*return*/];
|
|
1585
1529
|
}
|
|
1586
1530
|
});
|
|
1587
1531
|
});
|
|
@@ -1682,7 +1626,7 @@
|
|
|
1682
1626
|
};
|
|
1683
1627
|
/**
|
|
1684
1628
|
* Monitor remote audio track energy via AnalyserNode.
|
|
1685
|
-
* Polls at ~
|
|
1629
|
+
* Polls at ~60fps and flips speakingSubject based on actual audio energy.
|
|
1686
1630
|
*/
|
|
1687
1631
|
DailyVoiceClientService.prototype.monitorRemoteAudio = function (track) {
|
|
1688
1632
|
var _this = this;
|
|
@@ -1697,17 +1641,11 @@
|
|
|
1697
1641
|
var dataArray_1 = new Uint8Array(analyser_1.frequencyBinCount);
|
|
1698
1642
|
var THRESHOLD_1 = 5;
|
|
1699
1643
|
var SILENCE_MS_1 = 1500;
|
|
1700
|
-
var POLL_MS = 100;
|
|
1701
1644
|
var lastSoundTime_1 = 0;
|
|
1702
1645
|
var isSpeaking_1 = false;
|
|
1703
|
-
|
|
1704
|
-
if (!_this.remoteAudioContext)
|
|
1705
|
-
if (_this.remoteSpeakingPollId) {
|
|
1706
|
-
clearInterval(_this.remoteSpeakingPollId);
|
|
1707
|
-
_this.remoteSpeakingPollId = null;
|
|
1708
|
-
}
|
|
1646
|
+
var poll_1 = function () {
|
|
1647
|
+
if (!_this.remoteAudioContext)
|
|
1709
1648
|
return;
|
|
1710
|
-
}
|
|
1711
1649
|
analyser_1.getByteFrequencyData(dataArray_1);
|
|
1712
1650
|
var sum = 0;
|
|
1713
1651
|
for (var i = 0; i < dataArray_1.length; i++) {
|
|
@@ -1731,16 +1669,18 @@
|
|
|
1731
1669
|
console.log("[VoiceDebug] Bot audio silence detected (speaking=false) \u2014 " + new Date().toISOString());
|
|
1732
1670
|
_this.ngZone.run(function () { return _this.speakingSubject.next(false); });
|
|
1733
1671
|
}
|
|
1734
|
-
|
|
1672
|
+
_this.remoteSpeakingRAF = requestAnimationFrame(poll_1);
|
|
1673
|
+
};
|
|
1674
|
+
this.remoteSpeakingRAF = requestAnimationFrame(poll_1);
|
|
1735
1675
|
}
|
|
1736
1676
|
catch (err) {
|
|
1737
1677
|
console.warn('DailyVoiceClient: failed to create remote audio monitor', err);
|
|
1738
1678
|
}
|
|
1739
1679
|
};
|
|
1740
1680
|
DailyVoiceClientService.prototype.stopRemoteAudioMonitor = function () {
|
|
1741
|
-
if (this.
|
|
1742
|
-
|
|
1743
|
-
this.
|
|
1681
|
+
if (this.remoteSpeakingRAF) {
|
|
1682
|
+
cancelAnimationFrame(this.remoteSpeakingRAF);
|
|
1683
|
+
this.remoteSpeakingRAF = null;
|
|
1744
1684
|
}
|
|
1745
1685
|
if (this.remoteAudioContext) {
|
|
1746
1686
|
this.remoteAudioContext.close().catch(function () { });
|
|
@@ -1853,8 +1793,6 @@
|
|
|
1853
1793
|
this.callStartTime = 0;
|
|
1854
1794
|
this.durationInterval = null;
|
|
1855
1795
|
this.subscriptions = new rxjs.Subscription();
|
|
1856
|
-
/** Per-call only; cleared on disconnect / reset / new room so handlers do not stack. */
|
|
1857
|
-
this.callSubscriptions = new rxjs.Subscription();
|
|
1858
1796
|
this.destroy$ = new rxjs.Subject();
|
|
1859
1797
|
this.callState$ = this.callStateSubject.asObservable();
|
|
1860
1798
|
this.statusText$ = this.statusTextSubject.asObservable();
|
|
@@ -1866,15 +1804,6 @@
|
|
|
1866
1804
|
this.botTranscript$ = this.botTranscriptSubject.asObservable();
|
|
1867
1805
|
// Waveform visualization only - do NOT use for speaking state
|
|
1868
1806
|
this.subscriptions.add(this.audioAnalyzer.audioLevels$.subscribe(function (levels) { return _this.audioLevelsSubject.next(levels); }));
|
|
1869
|
-
// Transcripts: single subscription for service lifetime (avoid stacking on each connect()).
|
|
1870
|
-
// WebSocket is disconnected between calls; no replay — new subscribers (setupVoiceTranscripts)
|
|
1871
|
-
// only receive messages from the new WS after connect.
|
|
1872
|
-
this.subscriptions.add(this.wsClient.userTranscript$
|
|
1873
|
-
.pipe(operators.takeUntil(this.destroy$))
|
|
1874
|
-
.subscribe(function (t) { return _this.userTranscriptSubject.next(t); }));
|
|
1875
|
-
this.subscriptions.add(this.wsClient.botTranscript$
|
|
1876
|
-
.pipe(operators.takeUntil(this.destroy$))
|
|
1877
|
-
.subscribe(function (t) { return _this.botTranscriptSubject.next(t); }));
|
|
1878
1807
|
}
|
|
1879
1808
|
VoiceAgentService.prototype.ngOnDestroy = function () {
|
|
1880
1809
|
this.destroy$.next();
|
|
@@ -1885,8 +1814,6 @@
|
|
|
1885
1814
|
VoiceAgentService.prototype.resetToIdle = function () {
|
|
1886
1815
|
if (this.callStateSubject.value === 'idle')
|
|
1887
1816
|
return;
|
|
1888
|
-
this.callSubscriptions.unsubscribe();
|
|
1889
|
-
this.callSubscriptions = new rxjs.Subscription();
|
|
1890
1817
|
this.stopDurationTimer();
|
|
1891
1818
|
this.audioAnalyzer.stop();
|
|
1892
1819
|
this.wsClient.disconnect();
|
|
@@ -1896,60 +1823,44 @@
|
|
|
1896
1823
|
this.statusTextSubject.next('');
|
|
1897
1824
|
this.durationSubject.next('0:00');
|
|
1898
1825
|
};
|
|
1899
|
-
VoiceAgentService.prototype.connect = function (apiUrl, token, botId, conversationId, apiKey, eventToken, eventId, eventUrl, domainAuthority, usersApiUrl
|
|
1900
|
-
var _a;
|
|
1826
|
+
VoiceAgentService.prototype.connect = function (apiUrl, token, botId, conversationId, apiKey, eventToken, eventId, eventUrl, domainAuthority, usersApiUrl) {
|
|
1901
1827
|
return __awaiter(this, void 0, void 0, function () {
|
|
1902
|
-
var
|
|
1828
|
+
var accessToken, ensured, e_1, baseUrl, postUrl, headers, res, json, wsUrl, error_1;
|
|
1903
1829
|
var _this = this;
|
|
1904
|
-
return __generator(this, function (
|
|
1905
|
-
switch (
|
|
1830
|
+
return __generator(this, function (_a) {
|
|
1831
|
+
switch (_a.label) {
|
|
1906
1832
|
case 0:
|
|
1907
1833
|
if (this.callStateSubject.value !== 'idle') {
|
|
1908
1834
|
console.warn('Call already in progress');
|
|
1909
1835
|
return [2 /*return*/];
|
|
1910
1836
|
}
|
|
1911
|
-
|
|
1837
|
+
_a.label = 1;
|
|
1912
1838
|
case 1:
|
|
1913
|
-
|
|
1839
|
+
_a.trys.push([1, 8, , 10]);
|
|
1914
1840
|
this.callStateSubject.next('connecting');
|
|
1915
1841
|
this.statusTextSubject.next('Connecting...');
|
|
1916
|
-
|
|
1917
|
-
|
|
1842
|
+
accessToken = token;
|
|
1843
|
+
if (!(usersApiUrl && common.isPlatformBrowser(this.platformId))) return [3 /*break*/, 5];
|
|
1844
|
+
_a.label = 2;
|
|
1845
|
+
case 2:
|
|
1846
|
+
_a.trys.push([2, 4, , 5]);
|
|
1847
|
+
return [4 /*yield*/, this.platformTokenRefresh
|
|
1918
1848
|
.ensureValidAccessToken(token, usersApiUrl)
|
|
1919
1849
|
.pipe(operators.take(1))
|
|
1920
|
-
.toPromise()
|
|
1921
|
-
|
|
1922
|
-
|
|
1923
|
-
|
|
1924
|
-
|
|
1925
|
-
|
|
1926
|
-
|
|
1927
|
-
|
|
1928
|
-
|
|
1929
|
-
|
|
1930
|
-
|
|
1931
|
-
|
|
1932
|
-
|
|
1933
|
-
|
|
1934
|
-
voice: 'alloy',
|
|
1935
|
-
}),
|
|
1936
|
-
};
|
|
1937
|
-
});
|
|
1938
|
-
micPromise = (existingMicStream === null || existingMicStream === void 0 ? void 0 : existingMicStream.getAudioTracks().some(function (t) { return t.readyState === 'live'; }))
|
|
1939
|
-
? Promise.resolve(existingMicStream)
|
|
1940
|
-
: common.isPlatformBrowser(this.platformId) &&
|
|
1941
|
-
((_a = navigator.mediaDevices) === null || _a === void 0 ? void 0 : _a.getUserMedia)
|
|
1942
|
-
? navigator.mediaDevices
|
|
1943
|
-
.getUserMedia({ audio: true })
|
|
1944
|
-
.catch(function () { return undefined; })
|
|
1945
|
-
: Promise.resolve(undefined);
|
|
1946
|
-
return [4 /*yield*/, Promise.all([
|
|
1947
|
-
tokenPromise,
|
|
1948
|
-
prepPromise,
|
|
1949
|
-
micPromise,
|
|
1950
|
-
])];
|
|
1951
|
-
case 2:
|
|
1952
|
-
_b = __read.apply(void 0, [_d.sent(), 3]), accessToken = _b[0], _c = _b[1], postUrl = _c.postUrl, body = _c.body, micStream_1 = _b[2];
|
|
1850
|
+
.toPromise()];
|
|
1851
|
+
case 3:
|
|
1852
|
+
ensured = _a.sent();
|
|
1853
|
+
if (ensured === null || ensured === void 0 ? void 0 : ensured.accessToken) {
|
|
1854
|
+
accessToken = ensured.accessToken;
|
|
1855
|
+
}
|
|
1856
|
+
return [3 /*break*/, 5];
|
|
1857
|
+
case 4:
|
|
1858
|
+
e_1 = _a.sent();
|
|
1859
|
+
console.warn('[HiveGpt Voice] Token refresh before connect failed', e_1);
|
|
1860
|
+
return [3 /*break*/, 5];
|
|
1861
|
+
case 5:
|
|
1862
|
+
baseUrl = apiUrl.replace(/\/$/, '');
|
|
1863
|
+
postUrl = baseUrl + "/ai/ask-voice";
|
|
1953
1864
|
headers = {
|
|
1954
1865
|
'Content-Type': 'application/json',
|
|
1955
1866
|
Authorization: "Bearer " + accessToken,
|
|
@@ -1964,95 +1875,97 @@
|
|
|
1964
1875
|
return [4 /*yield*/, fetch(postUrl, {
|
|
1965
1876
|
method: 'POST',
|
|
1966
1877
|
headers: headers,
|
|
1967
|
-
body:
|
|
1878
|
+
body: JSON.stringify({
|
|
1879
|
+
bot_id: botId,
|
|
1880
|
+
conversation_id: conversationId,
|
|
1881
|
+
voice: 'alloy',
|
|
1882
|
+
}),
|
|
1968
1883
|
})];
|
|
1969
|
-
case
|
|
1970
|
-
res =
|
|
1884
|
+
case 6:
|
|
1885
|
+
res = _a.sent();
|
|
1971
1886
|
if (!res.ok) {
|
|
1972
1887
|
throw new Error("HTTP " + res.status);
|
|
1973
1888
|
}
|
|
1974
1889
|
return [4 /*yield*/, res.json()];
|
|
1975
|
-
case
|
|
1976
|
-
json =
|
|
1890
|
+
case 7:
|
|
1891
|
+
json = _a.sent();
|
|
1977
1892
|
wsUrl = json === null || json === void 0 ? void 0 : json.rn_ws_url;
|
|
1978
1893
|
if (!wsUrl || typeof wsUrl !== 'string') {
|
|
1979
1894
|
throw new Error('No ws_url in response');
|
|
1980
1895
|
}
|
|
1981
|
-
|
|
1982
|
-
|
|
1983
|
-
|
|
1984
|
-
|
|
1985
|
-
|
|
1986
|
-
|
|
1987
|
-
|
|
1988
|
-
|
|
1989
|
-
|
|
1990
|
-
|
|
1991
|
-
|
|
1992
|
-
|
|
1993
|
-
|
|
1994
|
-
|
|
1995
|
-
|
|
1996
|
-
|
|
1997
|
-
|
|
1998
|
-
|
|
1999
|
-
|
|
2000
|
-
|
|
2001
|
-
|
|
2002
|
-
|
|
2003
|
-
|
|
2004
|
-
|
|
2005
|
-
|
|
2006
|
-
|
|
2007
|
-
|
|
2008
|
-
|
|
2009
|
-
|
|
2010
|
-
|
|
2011
|
-
|
|
2012
|
-
|
|
2013
|
-
|
|
2014
|
-
|
|
1896
|
+
// Subscribe to room_created BEFORE connecting to avoid race
|
|
1897
|
+
this.wsClient.roomCreated$
|
|
1898
|
+
.pipe(operators.take(1), operators.takeUntil(this.destroy$))
|
|
1899
|
+
.subscribe(function (roomUrl) { return __awaiter(_this, void 0, void 0, function () {
|
|
1900
|
+
var err_1;
|
|
1901
|
+
return __generator(this, function (_a) {
|
|
1902
|
+
switch (_a.label) {
|
|
1903
|
+
case 0:
|
|
1904
|
+
_a.trys.push([0, 2, , 4]);
|
|
1905
|
+
return [4 /*yield*/, this.onRoomCreated(roomUrl)];
|
|
1906
|
+
case 1:
|
|
1907
|
+
_a.sent();
|
|
1908
|
+
return [3 /*break*/, 4];
|
|
1909
|
+
case 2:
|
|
1910
|
+
err_1 = _a.sent();
|
|
1911
|
+
console.error('Daily join failed:', err_1);
|
|
1912
|
+
this.callStateSubject.next('ended');
|
|
1913
|
+
this.statusTextSubject.next('Connection failed');
|
|
1914
|
+
return [4 /*yield*/, this.disconnect()];
|
|
1915
|
+
case 3:
|
|
1916
|
+
_a.sent();
|
|
1917
|
+
throw err_1;
|
|
1918
|
+
case 4: return [2 /*return*/];
|
|
1919
|
+
}
|
|
1920
|
+
});
|
|
1921
|
+
}); });
|
|
1922
|
+
// Forward transcripts from WebSocket
|
|
1923
|
+
this.subscriptions.add(this.wsClient.userTranscript$
|
|
1924
|
+
.pipe(operators.takeUntil(this.destroy$))
|
|
1925
|
+
.subscribe(function (t) { return _this.userTranscriptSubject.next(t); }));
|
|
1926
|
+
this.subscriptions.add(this.wsClient.botTranscript$
|
|
1927
|
+
.pipe(operators.takeUntil(this.destroy$))
|
|
1928
|
+
.subscribe(function (t) { return _this.botTranscriptSubject.next(t); }));
|
|
1929
|
+
// Connect signaling WebSocket (no audio over WS)
|
|
1930
|
+
this.wsClient.connect(wsUrl);
|
|
1931
|
+
return [3 /*break*/, 10];
|
|
2015
1932
|
case 8:
|
|
2016
|
-
|
|
2017
|
-
roomCreatedSub_1 === null || roomCreatedSub_1 === void 0 ? void 0 : roomCreatedSub_1.unsubscribe();
|
|
2018
|
-
throw e_1;
|
|
2019
|
-
case 9: return [3 /*break*/, 12];
|
|
2020
|
-
case 10:
|
|
2021
|
-
error_1 = _d.sent();
|
|
1933
|
+
error_1 = _a.sent();
|
|
2022
1934
|
console.error('Error connecting voice agent:', error_1);
|
|
2023
1935
|
this.callStateSubject.next('ended');
|
|
2024
1936
|
return [4 /*yield*/, this.disconnect()];
|
|
2025
|
-
case
|
|
2026
|
-
|
|
1937
|
+
case 9:
|
|
1938
|
+
_a.sent();
|
|
2027
1939
|
this.statusTextSubject.next('Connection failed');
|
|
2028
1940
|
throw error_1;
|
|
2029
|
-
case
|
|
1941
|
+
case 10: return [2 /*return*/];
|
|
2030
1942
|
}
|
|
2031
1943
|
});
|
|
2032
1944
|
});
|
|
2033
1945
|
};
|
|
2034
|
-
VoiceAgentService.prototype.onRoomCreated = function (roomUrl
|
|
1946
|
+
VoiceAgentService.prototype.onRoomCreated = function (roomUrl) {
|
|
2035
1947
|
return __awaiter(this, void 0, void 0, function () {
|
|
2036
1948
|
var _this = this;
|
|
2037
|
-
return __generator(this, function (
|
|
2038
|
-
switch (
|
|
2039
|
-
case 0:
|
|
1949
|
+
return __generator(this, function (_a) {
|
|
1950
|
+
switch (_a.label) {
|
|
1951
|
+
case 0:
|
|
1952
|
+
// Connect Daily.js for WebRTC audio
|
|
1953
|
+
return [4 /*yield*/, this.dailyClient.connect(roomUrl)];
|
|
2040
1954
|
case 1:
|
|
2041
|
-
|
|
2042
|
-
|
|
2043
|
-
this.callSubscriptions = new rxjs.Subscription();
|
|
1955
|
+
// Connect Daily.js for WebRTC audio
|
|
1956
|
+
_a.sent();
|
|
2044
1957
|
// Waveform: use local mic stream from Daily client
|
|
2045
|
-
this.
|
|
1958
|
+
this.dailyClient.localStream$
|
|
2046
1959
|
.pipe(operators.filter(function (s) { return s != null; }), operators.take(1))
|
|
2047
1960
|
.subscribe(function (stream) {
|
|
2048
1961
|
_this.audioAnalyzer.start(stream);
|
|
2049
|
-
})
|
|
2050
|
-
this.
|
|
2051
|
-
this.
|
|
1962
|
+
});
|
|
1963
|
+
this.subscriptions.add(this.dailyClient.userSpeaking$.subscribe(function (s) { return _this.isUserSpeakingSubject.next(s); }));
|
|
1964
|
+
this.subscriptions.add(rxjs.combineLatest([
|
|
2052
1965
|
this.dailyClient.speaking$,
|
|
2053
1966
|
this.dailyClient.userSpeaking$,
|
|
2054
|
-
]).subscribe(function (
|
|
2055
|
-
var
|
|
1967
|
+
]).subscribe(function (_a) {
|
|
1968
|
+
var _b = __read(_a, 2), bot = _b[0], user = _b[1];
|
|
2056
1969
|
var current = _this.callStateSubject.value;
|
|
2057
1970
|
if (current === 'connecting' && !bot) {
|
|
2058
1971
|
return;
|
|
@@ -2069,12 +1982,11 @@
|
|
|
2069
1982
|
else if (bot) {
|
|
2070
1983
|
_this.callStateSubject.next('talking');
|
|
2071
1984
|
}
|
|
2072
|
-
else {
|
|
2073
|
-
|
|
2074
|
-
_this.callStateSubject.next('listening');
|
|
1985
|
+
else if (current === 'talking' || current === 'listening') {
|
|
1986
|
+
_this.callStateSubject.next('connected');
|
|
2075
1987
|
}
|
|
2076
1988
|
}));
|
|
2077
|
-
this.
|
|
1989
|
+
this.subscriptions.add(this.dailyClient.micMuted$.subscribe(function (muted) { return _this.isMicMutedSubject.next(muted); }));
|
|
2078
1990
|
this.statusTextSubject.next('Connecting...');
|
|
2079
1991
|
return [2 /*return*/];
|
|
2080
1992
|
}
|
|
@@ -2083,18 +1995,16 @@
|
|
|
2083
1995
|
};
|
|
2084
1996
|
VoiceAgentService.prototype.disconnect = function () {
|
|
2085
1997
|
return __awaiter(this, void 0, void 0, function () {
|
|
2086
|
-
return __generator(this, function (
|
|
2087
|
-
switch (
|
|
1998
|
+
return __generator(this, function (_a) {
|
|
1999
|
+
switch (_a.label) {
|
|
2088
2000
|
case 0:
|
|
2089
|
-
this.callSubscriptions.unsubscribe();
|
|
2090
|
-
this.callSubscriptions = new rxjs.Subscription();
|
|
2091
2001
|
this.stopDurationTimer();
|
|
2092
2002
|
this.audioAnalyzer.stop();
|
|
2093
2003
|
// Daily first, then WebSocket
|
|
2094
2004
|
return [4 /*yield*/, this.dailyClient.disconnect()];
|
|
2095
2005
|
case 1:
|
|
2096
2006
|
// Daily first, then WebSocket
|
|
2097
|
-
|
|
2007
|
+
_a.sent();
|
|
2098
2008
|
this.wsClient.disconnect();
|
|
2099
2009
|
this.callStateSubject.next('ended');
|
|
2100
2010
|
this.statusTextSubject.next('Call Ended');
|
|
@@ -2146,11 +2056,10 @@
|
|
|
2146
2056
|
var VOICE_MODAL_CLOSE_CALLBACK = new i0.InjectionToken('VOICE_MODAL_CLOSE_CALLBACK');
|
|
2147
2057
|
|
|
2148
2058
|
var VoiceAgentModalComponent = /** @class */ (function () {
|
|
2149
|
-
function VoiceAgentModalComponent(voiceAgentService, audioAnalyzer, injector
|
|
2059
|
+
function VoiceAgentModalComponent(voiceAgentService, audioAnalyzer, injector) {
|
|
2150
2060
|
this.voiceAgentService = voiceAgentService;
|
|
2151
2061
|
this.audioAnalyzer = audioAnalyzer;
|
|
2152
2062
|
this.injector = injector;
|
|
2153
|
-
this.platformId = platformId;
|
|
2154
2063
|
this.close = new i0.EventEmitter();
|
|
2155
2064
|
this.apiKey = '';
|
|
2156
2065
|
this.eventToken = '';
|
|
@@ -2162,8 +2071,6 @@
|
|
|
2162
2071
|
this.usersApiUrl = '';
|
|
2163
2072
|
this.injectedConfig = null;
|
|
2164
2073
|
this.onCloseCallback = null;
|
|
2165
|
-
/** Held until destroy; passed to Daily so we do not stop/re-acquire (avoids extra prompts on some browsers). */
|
|
2166
|
-
this.warmMicStream = null;
|
|
2167
2074
|
/** Hardcoded voice agent avatar (Nia). */
|
|
2168
2075
|
this.displayAvatarUrl = 'https://www.jotform.com/uploads/mehmetkarakasli/form_files/1564593667676a8e85f23758.86945537_icon.png';
|
|
2169
2076
|
this.callState = 'idle';
|
|
@@ -2179,108 +2086,63 @@
|
|
|
2179
2086
|
this.isConnecting = false;
|
|
2180
2087
|
}
|
|
2181
2088
|
VoiceAgentModalComponent.prototype.ngOnInit = function () {
|
|
2182
|
-
|
|
2183
|
-
};
|
|
2184
|
-
VoiceAgentModalComponent.prototype.bootstrap = function () {
|
|
2089
|
+
var _this = this;
|
|
2185
2090
|
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
2186
|
-
|
|
2187
|
-
|
|
2188
|
-
|
|
2189
|
-
|
|
2190
|
-
|
|
2191
|
-
|
|
2192
|
-
|
|
2193
|
-
|
|
2194
|
-
|
|
2195
|
-
|
|
2196
|
-
|
|
2197
|
-
|
|
2198
|
-
|
|
2199
|
-
|
|
2200
|
-
|
|
2201
|
-
|
|
2202
|
-
|
|
2203
|
-
|
|
2204
|
-
|
|
2205
|
-
|
|
2206
|
-
|
|
2207
|
-
|
|
2208
|
-
|
|
2209
|
-
|
|
2210
|
-
|
|
2211
|
-
|
|
2212
|
-
|
|
2213
|
-
|
|
2214
|
-
|
|
2215
|
-
|
|
2216
|
-
|
|
2217
|
-
|
|
2218
|
-
|
|
2219
|
-
|
|
2220
|
-
|
|
2221
|
-
|
|
2222
|
-
|
|
2223
|
-
|
|
2224
|
-
|
|
2225
|
-
|
|
2226
|
-
|
|
2227
|
-
|
|
2228
|
-
|
|
2229
|
-
|
|
2230
|
-
|
|
2231
|
-
|
|
2232
|
-
|
|
2233
|
-
}));
|
|
2234
|
-
this.voiceAgentService.resetToIdle();
|
|
2235
|
-
return [4 /*yield*/, this.startCall()];
|
|
2236
|
-
case 1:
|
|
2237
|
-
_j.sent();
|
|
2238
|
-
return [2 /*return*/];
|
|
2239
|
-
}
|
|
2240
|
-
});
|
|
2241
|
-
});
|
|
2091
|
+
// When opened via Overlay, config is provided by injection
|
|
2092
|
+
this.injectedConfig = this.injector.get(VOICE_MODAL_CONFIG, null);
|
|
2093
|
+
this.onCloseCallback = this.injector.get(VOICE_MODAL_CLOSE_CALLBACK, null);
|
|
2094
|
+
if (this.injectedConfig) {
|
|
2095
|
+
this.apiUrl = this.injectedConfig.apiUrl;
|
|
2096
|
+
this.token = this.injectedConfig.token;
|
|
2097
|
+
this.botId = this.injectedConfig.botId;
|
|
2098
|
+
this.conversationId = this.injectedConfig.conversationId;
|
|
2099
|
+
this.apiKey = (_a = this.injectedConfig.apiKey) !== null && _a !== void 0 ? _a : '';
|
|
2100
|
+
this.eventToken = (_b = this.injectedConfig.eventToken) !== null && _b !== void 0 ? _b : '';
|
|
2101
|
+
this.eventId = (_c = this.injectedConfig.eventId) !== null && _c !== void 0 ? _c : '';
|
|
2102
|
+
this.eventUrl = (_d = this.injectedConfig.eventUrl) !== null && _d !== void 0 ? _d : '';
|
|
2103
|
+
this.domainAuthority = (_e = this.injectedConfig.domainAuthority) !== null && _e !== void 0 ? _e : 'prod-lite';
|
|
2104
|
+
this.agentName = (_f = this.injectedConfig.agentName) !== null && _f !== void 0 ? _f : this.agentName;
|
|
2105
|
+
this.agentRole = (_g = this.injectedConfig.agentRole) !== null && _g !== void 0 ? _g : this.agentRole;
|
|
2106
|
+
this.agentAvatar = this.injectedConfig.agentAvatar;
|
|
2107
|
+
this.usersApiUrl = (_h = this.injectedConfig.usersApiUrl) !== null && _h !== void 0 ? _h : this.usersApiUrl;
|
|
2108
|
+
}
|
|
2109
|
+
// Subscribe to observables
|
|
2110
|
+
this.subscriptions.push(this.voiceAgentService.callState$.subscribe(function (state) {
|
|
2111
|
+
_this.callState = state;
|
|
2112
|
+
_this.isSpeaking = state === 'talking';
|
|
2113
|
+
if (state === 'listening' || state === 'talking') {
|
|
2114
|
+
_this.hasLeftConnectedOnce = true;
|
|
2115
|
+
}
|
|
2116
|
+
if (state === 'idle' || state === 'ended') {
|
|
2117
|
+
_this.hasLeftConnectedOnce = false;
|
|
2118
|
+
}
|
|
2119
|
+
}));
|
|
2120
|
+
this.subscriptions.push(this.voiceAgentService.statusText$.subscribe(function (text) {
|
|
2121
|
+
_this.statusText = text;
|
|
2122
|
+
}));
|
|
2123
|
+
this.subscriptions.push(this.voiceAgentService.duration$.subscribe(function (duration) {
|
|
2124
|
+
_this.duration = duration;
|
|
2125
|
+
}));
|
|
2126
|
+
this.subscriptions.push(this.voiceAgentService.isMicMuted$.subscribe(function (muted) {
|
|
2127
|
+
_this.isMicMuted = muted;
|
|
2128
|
+
}));
|
|
2129
|
+
this.subscriptions.push(this.voiceAgentService.isUserSpeaking$.subscribe(function (speaking) {
|
|
2130
|
+
_this.isUserSpeaking = speaking;
|
|
2131
|
+
}));
|
|
2132
|
+
this.subscriptions.push(this.voiceAgentService.audioLevels$.subscribe(function (levels) {
|
|
2133
|
+
_this.audioLevels = levels;
|
|
2134
|
+
}));
|
|
2135
|
+
// Modal opens in idle state, then immediately starts connecting.
|
|
2136
|
+
this.voiceAgentService.resetToIdle();
|
|
2137
|
+
void this.startCall();
|
|
2242
2138
|
};
|
|
2243
2139
|
VoiceAgentModalComponent.prototype.ngOnDestroy = function () {
|
|
2244
|
-
var _this = this;
|
|
2245
2140
|
this.subscriptions.forEach(function (sub) { return sub.unsubscribe(); });
|
|
2246
|
-
|
|
2247
|
-
var _a;
|
|
2248
|
-
(_a = _this.warmMicStream) === null || _a === void 0 ? void 0 : _a.getTracks().forEach(function (t) { return t.stop(); });
|
|
2249
|
-
_this.warmMicStream = null;
|
|
2250
|
-
});
|
|
2251
|
-
};
|
|
2252
|
-
/** Ensures a live mic stream for this call (re-acquire after Daily stops tracks on hang-up). */
|
|
2253
|
-
VoiceAgentModalComponent.prototype.ensureMicForCall = function () {
|
|
2254
|
-
var _a;
|
|
2255
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
2256
|
-
var _j, _b_1;
|
|
2257
|
-
return __generator(this, function (_k) {
|
|
2258
|
-
switch (_k.label) {
|
|
2259
|
-
case 0:
|
|
2260
|
-
if (!common.isPlatformBrowser(this.platformId))
|
|
2261
|
-
return [2 /*return*/, undefined];
|
|
2262
|
-
if ((_a = this.warmMicStream) === null || _a === void 0 ? void 0 : _a.getAudioTracks().some(function (t) { return t.readyState === 'live'; })) {
|
|
2263
|
-
return [2 /*return*/, this.warmMicStream];
|
|
2264
|
-
}
|
|
2265
|
-
_k.label = 1;
|
|
2266
|
-
case 1:
|
|
2267
|
-
_k.trys.push([1, 3, , 4]);
|
|
2268
|
-
_j = this;
|
|
2269
|
-
return [4 /*yield*/, navigator.mediaDevices.getUserMedia({ audio: true })];
|
|
2270
|
-
case 2:
|
|
2271
|
-
_j.warmMicStream = _k.sent();
|
|
2272
|
-
return [2 /*return*/, this.warmMicStream];
|
|
2273
|
-
case 3:
|
|
2274
|
-
_b_1 = _k.sent();
|
|
2275
|
-
return [2 /*return*/, undefined];
|
|
2276
|
-
case 4: return [2 /*return*/];
|
|
2277
|
-
}
|
|
2278
|
-
});
|
|
2279
|
-
});
|
|
2141
|
+
this.disconnect();
|
|
2280
2142
|
};
|
|
2281
2143
|
VoiceAgentModalComponent.prototype.startCall = function () {
|
|
2282
2144
|
return __awaiter(this, void 0, void 0, function () {
|
|
2283
|
-
var
|
|
2145
|
+
var error_1;
|
|
2284
2146
|
return __generator(this, function (_j) {
|
|
2285
2147
|
switch (_j.label) {
|
|
2286
2148
|
case 0:
|
|
@@ -2289,22 +2151,19 @@
|
|
|
2289
2151
|
this.isConnecting = true;
|
|
2290
2152
|
_j.label = 1;
|
|
2291
2153
|
case 1:
|
|
2292
|
-
_j.trys.push([1, 4, 5
|
|
2293
|
-
return [4 /*yield*/, this.
|
|
2154
|
+
_j.trys.push([1, 3, 4, 5]);
|
|
2155
|
+
return [4 /*yield*/, this.voiceAgentService.connect(this.apiUrl, this.token, this.botId, this.conversationId, this.apiKey, this.eventToken, this.eventId, this.eventUrl, this.domainAuthority, this.usersApiUrl || undefined)];
|
|
2294
2156
|
case 2:
|
|
2295
|
-
mic = _j.sent();
|
|
2296
|
-
return [4 /*yield*/, this.voiceAgentService.connect(this.apiUrl, this.token, this.botId, this.conversationId, this.apiKey, this.eventToken, this.eventId, this.eventUrl, this.domainAuthority, this.usersApiUrl || undefined, mic)];
|
|
2297
|
-
case 3:
|
|
2298
2157
|
_j.sent();
|
|
2299
|
-
return [3 /*break*/,
|
|
2300
|
-
case
|
|
2158
|
+
return [3 /*break*/, 5];
|
|
2159
|
+
case 3:
|
|
2301
2160
|
error_1 = _j.sent();
|
|
2302
2161
|
console.error('Failed to connect voice agent:', error_1);
|
|
2303
|
-
return [3 /*break*/,
|
|
2304
|
-
case
|
|
2162
|
+
return [3 /*break*/, 5];
|
|
2163
|
+
case 4:
|
|
2305
2164
|
this.isConnecting = false;
|
|
2306
2165
|
return [7 /*endfinally*/];
|
|
2307
|
-
case
|
|
2166
|
+
case 5: return [2 /*return*/];
|
|
2308
2167
|
}
|
|
2309
2168
|
});
|
|
2310
2169
|
});
|
|
@@ -2349,7 +2208,7 @@
|
|
|
2349
2208
|
/** Call Again: reset to idle then start a new call. */
|
|
2350
2209
|
VoiceAgentModalComponent.prototype.callAgain = function () {
|
|
2351
2210
|
this.voiceAgentService.resetToIdle();
|
|
2352
|
-
|
|
2211
|
+
this.startCall();
|
|
2353
2212
|
};
|
|
2354
2213
|
/** Back to Chat: close modal and disconnect. */
|
|
2355
2214
|
VoiceAgentModalComponent.prototype.backToChat = function () {
|
|
@@ -2377,8 +2236,7 @@
|
|
|
2377
2236
|
VoiceAgentModalComponent.ctorParameters = function () { return [
|
|
2378
2237
|
{ type: VoiceAgentService },
|
|
2379
2238
|
{ type: AudioAnalyzerService },
|
|
2380
|
-
{ type: i0.Injector }
|
|
2381
|
-
{ type: Object, decorators: [{ type: i0.Inject, args: [i0.PLATFORM_ID,] }] }
|
|
2239
|
+
{ type: i0.Injector }
|
|
2382
2240
|
]; };
|
|
2383
2241
|
VoiceAgentModalComponent.propDecorators = {
|
|
2384
2242
|
close: [{ type: i0.Output }],
|