@hivegpt/hiveai-angular 0.0.583 → 0.0.584
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 +200 -521
- 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 +4 -5
- package/esm2015/lib/components/voice-agent/services/voice-agent.service.js +162 -232
- package/esm2015/lib/components/voice-agent/voice-agent.module.js +3 -5
- package/fesm2015/hivegpt-hiveai-angular.js +161 -432
- package/fesm2015/hivegpt-hiveai-angular.js.map +1 -1
- package/hivegpt-hiveai-angular.d.ts +3 -4
- package/hivegpt-hiveai-angular.d.ts.map +1 -1
- package/hivegpt-hiveai-angular.metadata.json +1 -1
- package/lib/components/voice-agent/services/voice-agent.service.d.ts +24 -26
- package/lib/components/voice-agent/services/voice-agent.service.d.ts.map +1 -1
- package/lib/components/voice-agent/voice-agent.module.d.ts +2 -2
- package/lib/components/voice-agent/voice-agent.module.d.ts.map +1 -1
- package/package.json +1 -1
- package/esm2015/lib/components/voice-agent/services/websocket-voice-client.service.js +0 -206
- package/lib/components/voice-agent/services/websocket-voice-client.service.d.ts +0 -59
- package/lib/components/voice-agent/services/websocket-voice-client.service.d.ts.map +0 -1
|
@@ -1,8 +1,8 @@
|
|
|
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('@angular/common'), require('ngx-socket-io'), require('@angular/forms'), require('microsoft-cognitiveservices-speech-sdk'), require('marked'), 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', '@angular/common', 'ngx-socket-io', '@angular/forms', 'microsoft-cognitiveservices-speech-sdk', 'marked', '@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.ng.common, global.ngxSocketIo, global.ng.forms, global.SpeechSDK, global.marked, global.ng.material.icon, global.ng.material.sidenav, global.ngxQuill));
|
|
5
|
-
})(this, (function (exports, overlay, portal, i1, i0, platformBrowser, rxjs, operators, common, ngxSocketIo, forms, SpeechSDK, marked, icon, sidenav, ngxQuill) { 'use strict';
|
|
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('@angular/common'), require('ngx-socket-io'), require('@angular/forms'), require('microsoft-cognitiveservices-speech-sdk'), require('marked'), require('@pipecat-ai/client-js'), require('@pipecat-ai/websocket-transport'), 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', '@angular/common', 'ngx-socket-io', '@angular/forms', 'microsoft-cognitiveservices-speech-sdk', 'marked', '@pipecat-ai/client-js', '@pipecat-ai/websocket-transport', '@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.ng.common, global.ngxSocketIo, global.ng.forms, global.SpeechSDK, global.marked, global.clientJs, global.websocketTransport, global.ng.material.icon, global.ng.material.sidenav, global.ngxQuill));
|
|
5
|
+
})(this, (function (exports, overlay, portal, i1, i0, platformBrowser, rxjs, operators, common, ngxSocketIo, forms, SpeechSDK, marked, clientJs, websocketTransport, icon, sidenav, ngxQuill) { 'use strict';
|
|
6
6
|
|
|
7
7
|
function _interopNamespace(e) {
|
|
8
8
|
if (e && e.__esModule) return e;
|
|
@@ -1339,237 +1339,24 @@
|
|
|
1339
1339
|
];
|
|
1340
1340
|
|
|
1341
1341
|
/**
|
|
1342
|
-
*
|
|
1343
|
-
* CRITICAL: Uses native WebSocket only. NO Socket.IO, NO ngx-socket-io.
|
|
1342
|
+
* Voice agent orchestrator using the official PipecatClient SDK.
|
|
1344
1343
|
*
|
|
1345
|
-
*
|
|
1346
|
-
*
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
/** True when {@link disconnect} initiated the close (not counted as remote close). */
|
|
1353
|
-
this.closeInitiatedByClient = false;
|
|
1354
|
-
this.openedSubject = new rxjs.Subject();
|
|
1355
|
-
this.remoteCloseSubject = new rxjs.Subject();
|
|
1356
|
-
this.userTranscriptSubject = new rxjs.Subject();
|
|
1357
|
-
this.botTranscriptSubject = new rxjs.Subject();
|
|
1358
|
-
this.assistantSpeakingSubject = new rxjs.Subject();
|
|
1359
|
-
this.serverUserSpeakingSubject = new rxjs.Subject();
|
|
1360
|
-
this.audioChunkSubject = new rxjs.Subject();
|
|
1361
|
-
/** Fires once each time the WebSocket reaches OPEN. */
|
|
1362
|
-
this.opened$ = this.openedSubject.asObservable();
|
|
1363
|
-
/** Fires when the socket closes without a client-initiated {@link disconnect}. */
|
|
1364
|
-
this.remoteClose$ = this.remoteCloseSubject.asObservable();
|
|
1365
|
-
this.userTranscript$ = this.userTranscriptSubject.asObservable();
|
|
1366
|
-
this.botTranscript$ = this.botTranscriptSubject.asObservable();
|
|
1367
|
-
/** Assistant/bot speaking, when the server sends explicit events (see {@link handleJsonMessage}). */
|
|
1368
|
-
this.assistantSpeaking$ = this.assistantSpeakingSubject.asObservable();
|
|
1369
|
-
/** User speaking from server-side VAD, if provided. */
|
|
1370
|
-
this.serverUserSpeaking$ = this.serverUserSpeakingSubject.asObservable();
|
|
1371
|
-
/** Binary audio frames from server (when backend streams bot audio over WS). */
|
|
1372
|
-
this.audioChunk$ = this.audioChunkSubject.asObservable();
|
|
1373
|
-
}
|
|
1374
|
-
WebSocketVoiceClientService.prototype.connect = function (wsUrl) {
|
|
1375
|
-
var _this = this;
|
|
1376
|
-
var _a;
|
|
1377
|
-
if (((_a = this.ws) === null || _a === void 0 ? void 0 : _a.readyState) === WebSocket.OPEN) {
|
|
1378
|
-
return;
|
|
1379
|
-
}
|
|
1380
|
-
if (this.ws) {
|
|
1381
|
-
this.closeInitiatedByClient = true;
|
|
1382
|
-
this.ws.close();
|
|
1383
|
-
}
|
|
1384
|
-
try {
|
|
1385
|
-
var socket_1 = new WebSocket(wsUrl);
|
|
1386
|
-
this.ws = socket_1;
|
|
1387
|
-
socket_1.onopen = function () {
|
|
1388
|
-
if (_this.ws !== socket_1)
|
|
1389
|
-
return;
|
|
1390
|
-
_this.ngZone.run(function () { return _this.openedSubject.next(); });
|
|
1391
|
-
};
|
|
1392
|
-
socket_1.onmessage = function (event) {
|
|
1393
|
-
if (_this.ws !== socket_1)
|
|
1394
|
-
return;
|
|
1395
|
-
void _this.handleIncomingMessage(event.data);
|
|
1396
|
-
};
|
|
1397
|
-
socket_1.onerror = function () {
|
|
1398
|
-
_this.ngZone.run(function () {
|
|
1399
|
-
if (_this.ws === socket_1 && socket_1.readyState !== WebSocket.CLOSED) {
|
|
1400
|
-
socket_1.close();
|
|
1401
|
-
}
|
|
1402
|
-
});
|
|
1403
|
-
};
|
|
1404
|
-
socket_1.onclose = function () {
|
|
1405
|
-
if (_this.ws === socket_1) {
|
|
1406
|
-
_this.ws = null;
|
|
1407
|
-
}
|
|
1408
|
-
var client = _this.closeInitiatedByClient;
|
|
1409
|
-
_this.closeInitiatedByClient = false;
|
|
1410
|
-
if (!client) {
|
|
1411
|
-
_this.ngZone.run(function () { return _this.remoteCloseSubject.next(); });
|
|
1412
|
-
}
|
|
1413
|
-
};
|
|
1414
|
-
}
|
|
1415
|
-
catch (err) {
|
|
1416
|
-
console.error('WebSocketVoiceClient: connect failed', err);
|
|
1417
|
-
this.ws = null;
|
|
1418
|
-
throw err;
|
|
1419
|
-
}
|
|
1420
|
-
};
|
|
1421
|
-
WebSocketVoiceClientService.prototype.handleIncomingMessage = function (payload) {
|
|
1422
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
1423
|
-
var ab;
|
|
1424
|
-
return __generator(this, function (_b) {
|
|
1425
|
-
switch (_b.label) {
|
|
1426
|
-
case 0:
|
|
1427
|
-
if (typeof payload === 'string') {
|
|
1428
|
-
this.handleJsonString(payload);
|
|
1429
|
-
return [2 /*return*/];
|
|
1430
|
-
}
|
|
1431
|
-
if (payload instanceof ArrayBuffer) {
|
|
1432
|
-
this.handleBinaryMessage(payload);
|
|
1433
|
-
return [2 /*return*/];
|
|
1434
|
-
}
|
|
1435
|
-
if (!(payload instanceof Blob)) return [3 /*break*/, 2];
|
|
1436
|
-
return [4 /*yield*/, payload.arrayBuffer()];
|
|
1437
|
-
case 1:
|
|
1438
|
-
ab = _b.sent();
|
|
1439
|
-
this.handleBinaryMessage(ab);
|
|
1440
|
-
_b.label = 2;
|
|
1441
|
-
case 2: return [2 /*return*/];
|
|
1442
|
-
}
|
|
1443
|
-
});
|
|
1444
|
-
});
|
|
1445
|
-
};
|
|
1446
|
-
WebSocketVoiceClientService.prototype.handleJsonString = function (jsonText) {
|
|
1447
|
-
var _this = this;
|
|
1448
|
-
try {
|
|
1449
|
-
var msg_1 = JSON.parse(jsonText);
|
|
1450
|
-
this.ngZone.run(function () { return _this.handleJsonMessage(msg_1); });
|
|
1451
|
-
}
|
|
1452
|
-
catch (_a) {
|
|
1453
|
-
// Ignore non-JSON
|
|
1454
|
-
}
|
|
1455
|
-
};
|
|
1456
|
-
WebSocketVoiceClientService.prototype.handleBinaryMessage = function (buffer) {
|
|
1457
|
-
var _this = this;
|
|
1458
|
-
// Some backends wrap JSON events inside binary WS frames.
|
|
1459
|
-
var maybeText = this.tryDecodeUtf8(buffer);
|
|
1460
|
-
if (maybeText !== null) {
|
|
1461
|
-
this.handleJsonString(maybeText);
|
|
1462
|
-
return;
|
|
1463
|
-
}
|
|
1464
|
-
// Otherwise treat binary as streamed assistant audio.
|
|
1465
|
-
this.ngZone.run(function () { return _this.audioChunkSubject.next(buffer); });
|
|
1466
|
-
};
|
|
1467
|
-
WebSocketVoiceClientService.prototype.tryDecodeUtf8 = function (buffer) {
|
|
1468
|
-
try {
|
|
1469
|
-
var text = new TextDecoder('utf-8', { fatal: true }).decode(buffer);
|
|
1470
|
-
var trimmed = text.trim();
|
|
1471
|
-
if (!trimmed || (trimmed[0] !== '{' && trimmed[0] !== '[')) {
|
|
1472
|
-
return null;
|
|
1473
|
-
}
|
|
1474
|
-
return trimmed;
|
|
1475
|
-
}
|
|
1476
|
-
catch (_a) {
|
|
1477
|
-
return null;
|
|
1478
|
-
}
|
|
1479
|
-
};
|
|
1480
|
-
WebSocketVoiceClientService.prototype.handleJsonMessage = function (msg) {
|
|
1481
|
-
var type = msg.type;
|
|
1482
|
-
var typeStr = typeof type === 'string' ? type : '';
|
|
1483
|
-
if (typeStr === 'session_ready' || typeStr === 'connected' || typeStr === 'voice_session_started') {
|
|
1484
|
-
return;
|
|
1485
|
-
}
|
|
1486
|
-
if (typeStr === 'assistant_speaking' ||
|
|
1487
|
-
typeStr === 'bot_speaking') {
|
|
1488
|
-
if (msg.active === true || msg.speaking === true) {
|
|
1489
|
-
this.assistantSpeakingSubject.next(true);
|
|
1490
|
-
}
|
|
1491
|
-
else if (msg.active === false || msg.speaking === false) {
|
|
1492
|
-
this.assistantSpeakingSubject.next(false);
|
|
1493
|
-
}
|
|
1494
|
-
return;
|
|
1495
|
-
}
|
|
1496
|
-
if (typeStr === 'user_speaking') {
|
|
1497
|
-
if (msg.active === true || msg.speaking === true) {
|
|
1498
|
-
this.serverUserSpeakingSubject.next(true);
|
|
1499
|
-
}
|
|
1500
|
-
else if (msg.active === false || msg.speaking === false) {
|
|
1501
|
-
this.serverUserSpeakingSubject.next(false);
|
|
1502
|
-
}
|
|
1503
|
-
return;
|
|
1504
|
-
}
|
|
1505
|
-
if (typeStr === 'input_audio_buffer.speech_started') {
|
|
1506
|
-
this.serverUserSpeakingSubject.next(true);
|
|
1507
|
-
return;
|
|
1508
|
-
}
|
|
1509
|
-
if (typeStr === 'input_audio_buffer.speech_stopped') {
|
|
1510
|
-
this.serverUserSpeakingSubject.next(false);
|
|
1511
|
-
return;
|
|
1512
|
-
}
|
|
1513
|
-
if (typeStr === 'response.audio.delta') {
|
|
1514
|
-
this.assistantSpeakingSubject.next(true);
|
|
1515
|
-
return;
|
|
1516
|
-
}
|
|
1517
|
-
if (typeStr === 'response.audio.done' ||
|
|
1518
|
-
typeStr === 'response.output_audio.done') {
|
|
1519
|
-
this.assistantSpeakingSubject.next(false);
|
|
1520
|
-
return;
|
|
1521
|
-
}
|
|
1522
|
-
if (typeStr === 'user_transcript' && typeof msg.text === 'string') {
|
|
1523
|
-
this.userTranscriptSubject.next({
|
|
1524
|
-
text: msg.text,
|
|
1525
|
-
final: msg.final === true,
|
|
1526
|
-
});
|
|
1527
|
-
return;
|
|
1528
|
-
}
|
|
1529
|
-
if (typeStr === 'bot_transcript' && typeof msg.text === 'string') {
|
|
1530
|
-
this.botTranscriptSubject.next(msg.text);
|
|
1531
|
-
}
|
|
1532
|
-
};
|
|
1533
|
-
WebSocketVoiceClientService.prototype.disconnect = function () {
|
|
1534
|
-
if (!this.ws) {
|
|
1535
|
-
return;
|
|
1536
|
-
}
|
|
1537
|
-
this.closeInitiatedByClient = true;
|
|
1538
|
-
this.ws.close();
|
|
1539
|
-
};
|
|
1540
|
-
Object.defineProperty(WebSocketVoiceClientService.prototype, "isConnected", {
|
|
1541
|
-
get: function () {
|
|
1542
|
-
var _a;
|
|
1543
|
-
return ((_a = this.ws) === null || _a === void 0 ? void 0 : _a.readyState) === WebSocket.OPEN;
|
|
1544
|
-
},
|
|
1545
|
-
enumerable: false,
|
|
1546
|
-
configurable: true
|
|
1547
|
-
});
|
|
1548
|
-
return WebSocketVoiceClientService;
|
|
1549
|
-
}());
|
|
1550
|
-
WebSocketVoiceClientService.ɵprov = i0__namespace.ɵɵdefineInjectable({ factory: function WebSocketVoiceClientService_Factory() { return new WebSocketVoiceClientService(i0__namespace.ɵɵinject(i0__namespace.NgZone)); }, token: WebSocketVoiceClientService, providedIn: "root" });
|
|
1551
|
-
WebSocketVoiceClientService.decorators = [
|
|
1552
|
-
{ type: i0.Injectable, args: [{
|
|
1553
|
-
providedIn: 'root',
|
|
1554
|
-
},] }
|
|
1555
|
-
];
|
|
1556
|
-
WebSocketVoiceClientService.ctorParameters = function () { return [
|
|
1557
|
-
{ type: i0.NgZone }
|
|
1558
|
-
]; };
|
|
1559
|
-
|
|
1560
|
-
/**
|
|
1561
|
-
* Voice agent orchestrator: single WebSocket (`ws_url` from POST /ai/ask-voice-socket)
|
|
1562
|
-
* for session events, transcripts, and optional speaking hints; local mic for capture
|
|
1563
|
-
* and waveform only (no Daily/WebRTC room).
|
|
1344
|
+
* Audio flow (mirrors the React reference implementation):
|
|
1345
|
+
* - Local mic: acquired by PipecatClient.initDevices(); local track fed to
|
|
1346
|
+
* AudioAnalyzerService for waveform visualisation.
|
|
1347
|
+
* - Bot audio: received as a MediaStreamTrack via RTVIEvent.TrackStarted,
|
|
1348
|
+
* played through a hidden <audio> element.
|
|
1349
|
+
* - All binary protobuf framing / RTVI protocol handled by
|
|
1350
|
+
* @pipecat-ai/client-js + @pipecat-ai/websocket-transport.
|
|
1564
1351
|
*/
|
|
1565
1352
|
var VoiceAgentService = /** @class */ (function () {
|
|
1566
|
-
function VoiceAgentService(audioAnalyzer,
|
|
1353
|
+
function VoiceAgentService(audioAnalyzer, platformTokenRefresh, ngZone,
|
|
1567
1354
|
/** `Object` not `object` — ngc metadata collection rejects the `object` type in DI params. */
|
|
1568
1355
|
platformId) {
|
|
1569
1356
|
var _this = this;
|
|
1570
1357
|
this.audioAnalyzer = audioAnalyzer;
|
|
1571
|
-
this.wsClient = wsClient;
|
|
1572
1358
|
this.platformTokenRefresh = platformTokenRefresh;
|
|
1359
|
+
this.ngZone = ngZone;
|
|
1573
1360
|
this.platformId = platformId;
|
|
1574
1361
|
this.callStateSubject = new rxjs.BehaviorSubject('idle');
|
|
1575
1362
|
this.statusTextSubject = new rxjs.BehaviorSubject('');
|
|
@@ -1581,11 +1368,8 @@
|
|
|
1581
1368
|
this.botTranscriptSubject = new rxjs.Subject();
|
|
1582
1369
|
this.callStartTime = 0;
|
|
1583
1370
|
this.durationInterval = null;
|
|
1584
|
-
this.
|
|
1585
|
-
this.
|
|
1586
|
-
this.pendingRemoteAudio = [];
|
|
1587
|
-
this.remoteAudioPlaying = false;
|
|
1588
|
-
this.endCall$ = new rxjs.Subject();
|
|
1371
|
+
this.pcClient = null;
|
|
1372
|
+
this.botAudioElement = null;
|
|
1589
1373
|
this.subscriptions = new rxjs.Subscription();
|
|
1590
1374
|
this.destroy$ = new rxjs.Subject();
|
|
1591
1375
|
this.callState$ = this.callStateSubject.asObservable();
|
|
@@ -1597,123 +1381,131 @@
|
|
|
1597
1381
|
this.userTranscript$ = this.userTranscriptSubject.asObservable();
|
|
1598
1382
|
this.botTranscript$ = this.botTranscriptSubject.asObservable();
|
|
1599
1383
|
this.subscriptions.add(this.audioAnalyzer.audioLevels$.subscribe(function (levels) { return _this.audioLevelsSubject.next(levels); }));
|
|
1600
|
-
this.subscriptions.add(this.wsClient.remoteClose$
|
|
1601
|
-
.pipe(operators.takeUntil(this.destroy$))
|
|
1602
|
-
.subscribe(function () { return void _this.handleRemoteClose(); }));
|
|
1603
|
-
this.subscriptions.add(this.wsClient.audioChunk$
|
|
1604
|
-
.pipe(operators.takeUntil(this.destroy$))
|
|
1605
|
-
.subscribe(function (chunk) { return _this.enqueueRemoteAudio(chunk); }));
|
|
1606
1384
|
}
|
|
1607
1385
|
VoiceAgentService.prototype.ngOnDestroy = function () {
|
|
1608
1386
|
this.destroy$.next();
|
|
1609
1387
|
this.subscriptions.unsubscribe();
|
|
1610
|
-
this.disconnect();
|
|
1388
|
+
void this.disconnect();
|
|
1611
1389
|
};
|
|
1612
|
-
/** Reset to idle
|
|
1390
|
+
/** Reset to idle (e.g. when modal re-opens so user can click Start Call). */
|
|
1613
1391
|
VoiceAgentService.prototype.resetToIdle = function () {
|
|
1614
1392
|
if (this.callStateSubject.value === 'idle')
|
|
1615
1393
|
return;
|
|
1616
|
-
this.
|
|
1617
|
-
this.stopDurationTimer();
|
|
1618
|
-
this.callStartTime = 0;
|
|
1619
|
-
this.audioAnalyzer.stop();
|
|
1620
|
-
this.stopLocalMic();
|
|
1621
|
-
this.resetRemoteAudioPlayback();
|
|
1622
|
-
this.wsClient.disconnect();
|
|
1394
|
+
void this.disconnect();
|
|
1623
1395
|
this.callStateSubject.next('idle');
|
|
1624
1396
|
this.statusTextSubject.next('');
|
|
1625
1397
|
this.durationSubject.next('0:00');
|
|
1626
1398
|
};
|
|
1627
1399
|
VoiceAgentService.prototype.connect = function (apiUrl, token, botId, conversationId, apiKey, eventToken, eventId, eventUrl, domainAuthority, usersApiUrl) {
|
|
1628
1400
|
return __awaiter(this, void 0, void 0, function () {
|
|
1629
|
-
var accessToken, ensured, e_1, baseUrl,
|
|
1401
|
+
var accessToken, ensured, e_1, baseUrl, pcClient, requestHeaders, error_1;
|
|
1630
1402
|
var _this = this;
|
|
1631
|
-
return __generator(this, function (
|
|
1632
|
-
switch (
|
|
1403
|
+
return __generator(this, function (_d) {
|
|
1404
|
+
switch (_d.label) {
|
|
1633
1405
|
case 0:
|
|
1634
1406
|
if (this.callStateSubject.value !== 'idle') {
|
|
1635
|
-
console.warn('Call already in progress');
|
|
1407
|
+
console.warn('[HiveGpt Voice] Call already in progress');
|
|
1636
1408
|
return [2 /*return*/];
|
|
1637
1409
|
}
|
|
1638
|
-
|
|
1410
|
+
_d.label = 1;
|
|
1639
1411
|
case 1:
|
|
1640
|
-
|
|
1412
|
+
_d.trys.push([1, 8, , 10]);
|
|
1641
1413
|
this.callStateSubject.next('connecting');
|
|
1642
1414
|
this.statusTextSubject.next('Connecting...');
|
|
1643
1415
|
accessToken = token;
|
|
1644
1416
|
if (!(usersApiUrl && common.isPlatformBrowser(this.platformId))) return [3 /*break*/, 5];
|
|
1645
|
-
|
|
1417
|
+
_d.label = 2;
|
|
1646
1418
|
case 2:
|
|
1647
|
-
|
|
1419
|
+
_d.trys.push([2, 4, , 5]);
|
|
1648
1420
|
return [4 /*yield*/, this.platformTokenRefresh
|
|
1649
1421
|
.ensureValidAccessToken(token, usersApiUrl)
|
|
1650
1422
|
.pipe(operators.take(1))
|
|
1651
1423
|
.toPromise()];
|
|
1652
1424
|
case 3:
|
|
1653
|
-
ensured =
|
|
1654
|
-
if (ensured === null || ensured === void 0 ? void 0 : ensured.accessToken)
|
|
1425
|
+
ensured = _d.sent();
|
|
1426
|
+
if (ensured === null || ensured === void 0 ? void 0 : ensured.accessToken)
|
|
1655
1427
|
accessToken = ensured.accessToken;
|
|
1656
|
-
}
|
|
1657
1428
|
return [3 /*break*/, 5];
|
|
1658
1429
|
case 4:
|
|
1659
|
-
e_1 =
|
|
1660
|
-
console.warn('[HiveGpt Voice] Token refresh
|
|
1430
|
+
e_1 = _d.sent();
|
|
1431
|
+
console.warn('[HiveGpt Voice] Token refresh failed', e_1);
|
|
1661
1432
|
return [3 /*break*/, 5];
|
|
1662
1433
|
case 5:
|
|
1663
1434
|
baseUrl = apiUrl.replace(/\/$/, '');
|
|
1664
|
-
|
|
1665
|
-
|
|
1666
|
-
|
|
1667
|
-
|
|
1668
|
-
|
|
1669
|
-
|
|
1670
|
-
|
|
1671
|
-
|
|
1672
|
-
|
|
1673
|
-
|
|
1674
|
-
|
|
1675
|
-
|
|
1676
|
-
|
|
1677
|
-
|
|
1678
|
-
|
|
1679
|
-
|
|
1435
|
+
pcClient = new clientJs.PipecatClient({
|
|
1436
|
+
transport: new websocketTransport.WebSocketTransport(),
|
|
1437
|
+
enableMic: true,
|
|
1438
|
+
enableCam: false,
|
|
1439
|
+
callbacks: {
|
|
1440
|
+
onConnected: function () { return _this.ngZone.run(function () { return _this.onPipecatConnected(); }); },
|
|
1441
|
+
onDisconnected: function () { return _this.ngZone.run(function () { return _this.onPipecatDisconnected(); }); },
|
|
1442
|
+
onBotReady: function () { return _this.ngZone.run(function () { return _this.onBotReady(); }); },
|
|
1443
|
+
onUserTranscript: function (data) { return _this.ngZone.run(function () { return _this.userTranscriptSubject.next({ text: data.text, final: !!data.final }); }); },
|
|
1444
|
+
onBotTranscript: function (data) { return _this.ngZone.run(function () { return _this.botTranscriptSubject.next(data.text); }); },
|
|
1445
|
+
onError: function (err) {
|
|
1446
|
+
_this.ngZone.run(function () {
|
|
1447
|
+
console.error('[HiveGpt Voice] PipecatClient error', err);
|
|
1448
|
+
_this.callStateSubject.next('ended');
|
|
1449
|
+
_this.statusTextSubject.next('Connection failed');
|
|
1450
|
+
});
|
|
1451
|
+
},
|
|
1452
|
+
},
|
|
1453
|
+
});
|
|
1454
|
+
this.pcClient = pcClient;
|
|
1455
|
+
// Bot audio arrives as a MediaStreamTrack — wire to a hidden <audio> element
|
|
1456
|
+
pcClient.on(clientJs.RTVIEvent.TrackStarted, function (track, participant) {
|
|
1457
|
+
if (!(participant === null || participant === void 0 ? void 0 : participant.local) && track.kind === 'audio') {
|
|
1458
|
+
_this.ngZone.run(function () { return _this.setupBotAudioTrack(track); });
|
|
1459
|
+
}
|
|
1460
|
+
});
|
|
1461
|
+
// Speaking state comes straight from RTVI events
|
|
1462
|
+
pcClient.on(clientJs.RTVIEvent.BotStartedSpeaking, function () { return _this.ngZone.run(function () { return _this.onBotStartedSpeaking(); }); });
|
|
1463
|
+
pcClient.on(clientJs.RTVIEvent.BotStoppedSpeaking, function () { return _this.ngZone.run(function () { return _this.onBotStoppedSpeaking(); }); });
|
|
1464
|
+
pcClient.on(clientJs.RTVIEvent.UserStartedSpeaking, function () { return _this.ngZone.run(function () {
|
|
1465
|
+
_this.isUserSpeakingSubject.next(true);
|
|
1466
|
+
_this.callStateSubject.next('listening');
|
|
1467
|
+
}); });
|
|
1468
|
+
pcClient.on(clientJs.RTVIEvent.UserStoppedSpeaking, function () { return _this.ngZone.run(function () {
|
|
1469
|
+
_this.isUserSpeakingSubject.next(false);
|
|
1470
|
+
if (_this.callStateSubject.value === 'listening') {
|
|
1471
|
+
_this.callStateSubject.next('connected');
|
|
1472
|
+
}
|
|
1473
|
+
}); });
|
|
1474
|
+
// Acquire mic (triggers browser permission prompt)
|
|
1475
|
+
return [4 /*yield*/, pcClient.initDevices()];
|
|
1476
|
+
case 6:
|
|
1477
|
+
// Acquire mic (triggers browser permission prompt)
|
|
1478
|
+
_d.sent();
|
|
1479
|
+
requestHeaders = new Headers();
|
|
1480
|
+
requestHeaders.append('Authorization', "Bearer " + accessToken);
|
|
1481
|
+
requestHeaders.append('x-api-key', apiKey);
|
|
1482
|
+
requestHeaders.append('hive-bot-id', botId);
|
|
1483
|
+
requestHeaders.append('domain-authority', domainAuthority);
|
|
1484
|
+
requestHeaders.append('eventUrl', eventUrl);
|
|
1485
|
+
requestHeaders.append('eventId', eventId);
|
|
1486
|
+
requestHeaders.append('eventToken', eventToken);
|
|
1487
|
+
requestHeaders.append('ngrok-skip-browser-warning', 'true');
|
|
1488
|
+
// POST to /ai/ask-voice-socket → receives { ws_url } → WebSocketTransport connects
|
|
1489
|
+
return [4 /*yield*/, pcClient.startBotAndConnect({
|
|
1490
|
+
endpoint: baseUrl + "/ai/ask-voice-socket",
|
|
1491
|
+
headers: requestHeaders,
|
|
1492
|
+
requestData: {
|
|
1680
1493
|
bot_id: botId,
|
|
1681
1494
|
conversation_id: conversationId,
|
|
1682
1495
|
voice: 'alloy',
|
|
1683
|
-
}
|
|
1496
|
+
},
|
|
1684
1497
|
})];
|
|
1685
|
-
case 6:
|
|
1686
|
-
res = _b.sent();
|
|
1687
|
-
if (!res.ok) {
|
|
1688
|
-
throw new Error("HTTP " + res.status);
|
|
1689
|
-
}
|
|
1690
|
-
return [4 /*yield*/, res.json()];
|
|
1691
1498
|
case 7:
|
|
1692
|
-
|
|
1693
|
-
|
|
1694
|
-
(typeof (json === null || json === void 0 ? void 0 : json.rn_ws_url) === 'string' && json.rn_ws_url);
|
|
1695
|
-
if (!wsUrl) {
|
|
1696
|
-
throw new Error('No ws_url in response');
|
|
1697
|
-
}
|
|
1698
|
-
untilCallEnds$ = rxjs.merge(this.destroy$, this.endCall$);
|
|
1699
|
-
this.subscriptions.add(this.wsClient.userTranscript$
|
|
1700
|
-
.pipe(operators.takeUntil(untilCallEnds$))
|
|
1701
|
-
.subscribe(function (t) { return _this.userTranscriptSubject.next(t); }));
|
|
1702
|
-
this.subscriptions.add(this.wsClient.botTranscript$
|
|
1703
|
-
.pipe(operators.takeUntil(untilCallEnds$))
|
|
1704
|
-
.subscribe(function (t) { return _this.botTranscriptSubject.next(t); }));
|
|
1705
|
-
this.subscriptions.add(this.wsClient.opened$
|
|
1706
|
-
.pipe(operators.takeUntil(untilCallEnds$), operators.take(1))
|
|
1707
|
-
.subscribe(function () { return void _this.onWebsocketOpened(); }));
|
|
1708
|
-
this.wsClient.connect(wsUrl);
|
|
1499
|
+
// POST to /ai/ask-voice-socket → receives { ws_url } → WebSocketTransport connects
|
|
1500
|
+
_d.sent();
|
|
1709
1501
|
return [3 /*break*/, 10];
|
|
1710
1502
|
case 8:
|
|
1711
|
-
error_1 =
|
|
1712
|
-
console.error('
|
|
1503
|
+
error_1 = _d.sent();
|
|
1504
|
+
console.error('[HiveGpt Voice] connect failed', error_1);
|
|
1713
1505
|
this.callStateSubject.next('ended');
|
|
1714
|
-
return [4 /*yield*/, this.
|
|
1506
|
+
return [4 /*yield*/, this.cleanupPipecatClient()];
|
|
1715
1507
|
case 9:
|
|
1716
|
-
|
|
1508
|
+
_d.sent();
|
|
1717
1509
|
this.statusTextSubject.next('Connection failed');
|
|
1718
1510
|
throw error_1;
|
|
1719
1511
|
case 10: return [2 /*return*/];
|
|
@@ -1721,249 +1513,138 @@
|
|
|
1721
1513
|
});
|
|
1722
1514
|
});
|
|
1723
1515
|
};
|
|
1724
|
-
VoiceAgentService.prototype.
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
case 0:
|
|
1730
|
-
if (this.callStateSubject.value !== 'connecting') {
|
|
1731
|
-
return [2 /*return*/];
|
|
1732
|
-
}
|
|
1733
|
-
_b.label = 1;
|
|
1734
|
-
case 1:
|
|
1735
|
-
_b.trys.push([1, 3, , 5]);
|
|
1736
|
-
return [4 /*yield*/, this.startLocalMic()];
|
|
1737
|
-
case 2:
|
|
1738
|
-
_b.sent();
|
|
1739
|
-
this.statusTextSubject.next('Connected');
|
|
1740
|
-
this.callStateSubject.next('connected');
|
|
1741
|
-
this.wireSpeakingState();
|
|
1742
|
-
return [3 /*break*/, 5];
|
|
1743
|
-
case 3:
|
|
1744
|
-
err_1 = _b.sent();
|
|
1745
|
-
console.error('[HiveGpt Voice] Mic or session setup failed', err_1);
|
|
1746
|
-
this.callStateSubject.next('ended');
|
|
1747
|
-
this.statusTextSubject.next('Microphone unavailable');
|
|
1748
|
-
return [4 /*yield*/, this.disconnect()];
|
|
1749
|
-
case 4:
|
|
1750
|
-
_b.sent();
|
|
1751
|
-
return [3 /*break*/, 5];
|
|
1752
|
-
case 5: return [2 /*return*/];
|
|
1753
|
-
}
|
|
1754
|
-
});
|
|
1755
|
-
});
|
|
1756
|
-
};
|
|
1757
|
-
VoiceAgentService.prototype.wireSpeakingState = function () {
|
|
1758
|
-
var _this = this;
|
|
1759
|
-
var untilCallEnds$ = rxjs.merge(this.destroy$, this.endCall$);
|
|
1760
|
-
var transcriptDrivenAssistant$ = this.wsClient.botTranscript$.pipe(operators.switchMap(function () { return rxjs.concat(rxjs.of(true), rxjs.timer(800).pipe(operators.map(function () { return false; }))); }), operators.distinctUntilChanged());
|
|
1761
|
-
var assistantTalking$ = rxjs.merge(this.wsClient.assistantSpeaking$, transcriptDrivenAssistant$).pipe(operators.distinctUntilChanged(), operators.startWith(false));
|
|
1762
|
-
var userTalking$ = rxjs.combineLatest([
|
|
1763
|
-
this.audioAnalyzer.isUserSpeaking$,
|
|
1764
|
-
this.wsClient.serverUserSpeaking$.pipe(operators.startWith(false)),
|
|
1765
|
-
]).pipe(operators.map(function (_b) {
|
|
1766
|
-
var _c = __read(_b, 2), local = _c[0], server = _c[1];
|
|
1767
|
-
return local || server;
|
|
1768
|
-
}), operators.distinctUntilChanged(), operators.startWith(false));
|
|
1769
|
-
this.subscriptions.add(rxjs.combineLatest([assistantTalking$, userTalking$])
|
|
1770
|
-
.pipe(operators.takeUntil(untilCallEnds$))
|
|
1771
|
-
.subscribe(function (_b) {
|
|
1772
|
-
var _c = __read(_b, 2), bot = _c[0], user = _c[1];
|
|
1773
|
-
var current = _this.callStateSubject.value;
|
|
1774
|
-
if (user) {
|
|
1775
|
-
_this.isUserSpeakingSubject.next(true);
|
|
1776
|
-
_this.callStateSubject.next('listening');
|
|
1777
|
-
}
|
|
1778
|
-
else {
|
|
1779
|
-
_this.isUserSpeakingSubject.next(false);
|
|
1780
|
-
}
|
|
1781
|
-
if (user) {
|
|
1782
|
-
return;
|
|
1783
|
-
}
|
|
1784
|
-
if (bot) {
|
|
1785
|
-
if (_this.callStartTime === 0) {
|
|
1786
|
-
_this.callStartTime = Date.now();
|
|
1787
|
-
_this.startDurationTimer();
|
|
1788
|
-
}
|
|
1789
|
-
_this.callStateSubject.next('talking');
|
|
1790
|
-
}
|
|
1791
|
-
else if (current === 'talking' || current === 'listening') {
|
|
1792
|
-
_this.callStateSubject.next('connected');
|
|
1793
|
-
}
|
|
1794
|
-
}));
|
|
1516
|
+
VoiceAgentService.prototype.onPipecatConnected = function () {
|
|
1517
|
+
this.callStateSubject.next('connected');
|
|
1518
|
+
this.statusTextSubject.next('Connected');
|
|
1519
|
+
this.isMicMutedSubject.next(false);
|
|
1520
|
+
this.startLocalMicAnalyzer();
|
|
1795
1521
|
};
|
|
1796
|
-
VoiceAgentService.prototype.
|
|
1797
|
-
|
|
1798
|
-
|
|
1799
|
-
|
|
1800
|
-
|
|
1801
|
-
|
|
1802
|
-
|
|
1803
|
-
return [4 /*yield*/, navigator.mediaDevices.getUserMedia({ audio: true })];
|
|
1804
|
-
case 1:
|
|
1805
|
-
stream = _b.sent();
|
|
1806
|
-
track = stream.getAudioTracks()[0];
|
|
1807
|
-
if (!track) {
|
|
1808
|
-
stream.getTracks().forEach(function (t) { return t.stop(); });
|
|
1809
|
-
throw new Error('No audio track');
|
|
1810
|
-
}
|
|
1811
|
-
this.localMicStream = stream;
|
|
1812
|
-
this.isMicMutedSubject.next(!track.enabled);
|
|
1813
|
-
this.audioAnalyzer.start(stream);
|
|
1814
|
-
return [2 /*return*/];
|
|
1815
|
-
}
|
|
1816
|
-
});
|
|
1817
|
-
});
|
|
1818
|
-
};
|
|
1819
|
-
VoiceAgentService.prototype.stopLocalMic = function () {
|
|
1820
|
-
if (this.localMicStream) {
|
|
1821
|
-
this.localMicStream.getTracks().forEach(function (t) { return t.stop(); });
|
|
1822
|
-
this.localMicStream = null;
|
|
1823
|
-
}
|
|
1824
|
-
};
|
|
1825
|
-
VoiceAgentService.prototype.enqueueRemoteAudio = function (chunk) {
|
|
1826
|
-
this.pendingRemoteAudio.push(chunk.slice(0));
|
|
1827
|
-
if (!this.remoteAudioPlaying) {
|
|
1828
|
-
void this.playRemoteAudioQueue();
|
|
1829
|
-
}
|
|
1522
|
+
VoiceAgentService.prototype.onPipecatDisconnected = function () {
|
|
1523
|
+
this.stopDurationTimer();
|
|
1524
|
+
this.callStartTime = 0;
|
|
1525
|
+
this.audioAnalyzer.stop();
|
|
1526
|
+
this.stopBotAudio();
|
|
1527
|
+
this.callStateSubject.next('ended');
|
|
1528
|
+
this.statusTextSubject.next('Call Ended');
|
|
1830
1529
|
};
|
|
1831
|
-
VoiceAgentService.prototype.
|
|
1832
|
-
|
|
1833
|
-
|
|
1834
|
-
|
|
1835
|
-
|
|
1836
|
-
|
|
1837
|
-
|
|
1838
|
-
context = this.getOrCreateRemoteAudioContext();
|
|
1839
|
-
_b.label = 1;
|
|
1840
|
-
case 1:
|
|
1841
|
-
if (!(this.pendingRemoteAudio.length > 0)) return [3 /*break*/, 7];
|
|
1842
|
-
chunk = this.pendingRemoteAudio.shift();
|
|
1843
|
-
if (!chunk)
|
|
1844
|
-
return [3 /*break*/, 1];
|
|
1845
|
-
_b.label = 2;
|
|
1846
|
-
case 2:
|
|
1847
|
-
_b.trys.push([2, 5, , 6]);
|
|
1848
|
-
return [4 /*yield*/, this.decodeAudioChunk(context, chunk)];
|
|
1849
|
-
case 3:
|
|
1850
|
-
decoded = _b.sent();
|
|
1851
|
-
this.assistantAudioStarted();
|
|
1852
|
-
return [4 /*yield*/, this.playDecodedBuffer(context, decoded)];
|
|
1853
|
-
case 4:
|
|
1854
|
-
_b.sent();
|
|
1855
|
-
return [3 /*break*/, 6];
|
|
1856
|
-
case 5:
|
|
1857
|
-
_a_1 = _b.sent();
|
|
1858
|
-
return [3 /*break*/, 6];
|
|
1859
|
-
case 6: return [3 /*break*/, 1];
|
|
1860
|
-
case 7:
|
|
1861
|
-
this.remoteAudioPlaying = false;
|
|
1862
|
-
this.assistantAudioStopped();
|
|
1863
|
-
return [2 /*return*/];
|
|
1864
|
-
}
|
|
1865
|
-
});
|
|
1866
|
-
});
|
|
1530
|
+
VoiceAgentService.prototype.onBotReady = function () {
|
|
1531
|
+
var _a, _b, _c;
|
|
1532
|
+
// Retry track wiring in case tracks weren't ready at onConnected
|
|
1533
|
+
this.startLocalMicAnalyzer();
|
|
1534
|
+
var botTrack = (_c = (_b = (_a = this.pcClient) === null || _a === void 0 ? void 0 : _a.tracks()) === null || _b === void 0 ? void 0 : _b.bot) === null || _c === void 0 ? void 0 : _c.audio;
|
|
1535
|
+
if (botTrack)
|
|
1536
|
+
this.setupBotAudioTrack(botTrack);
|
|
1867
1537
|
};
|
|
1868
|
-
VoiceAgentService.prototype.
|
|
1869
|
-
|
|
1870
|
-
|
|
1871
|
-
|
|
1872
|
-
|
|
1873
|
-
void this.remoteAudioContext.resume();
|
|
1538
|
+
VoiceAgentService.prototype.startLocalMicAnalyzer = function () {
|
|
1539
|
+
var _a, _b, _c;
|
|
1540
|
+
var localTrack = (_c = (_b = (_a = this.pcClient) === null || _a === void 0 ? void 0 : _a.tracks()) === null || _b === void 0 ? void 0 : _b.local) === null || _c === void 0 ? void 0 : _c.audio;
|
|
1541
|
+
if (localTrack) {
|
|
1542
|
+
this.audioAnalyzer.start(new MediaStream([localTrack]));
|
|
1874
1543
|
}
|
|
1875
|
-
return this.remoteAudioContext;
|
|
1876
|
-
};
|
|
1877
|
-
VoiceAgentService.prototype.decodeAudioChunk = function (context, chunk) {
|
|
1878
|
-
return new Promise(function (resolve, reject) {
|
|
1879
|
-
context.decodeAudioData(chunk.slice(0), resolve, reject);
|
|
1880
|
-
});
|
|
1881
|
-
};
|
|
1882
|
-
VoiceAgentService.prototype.playDecodedBuffer = function (context, buffer) {
|
|
1883
|
-
return new Promise(function (resolve) {
|
|
1884
|
-
var source = context.createBufferSource();
|
|
1885
|
-
source.buffer = buffer;
|
|
1886
|
-
source.connect(context.destination);
|
|
1887
|
-
source.onended = function () { return resolve(); };
|
|
1888
|
-
source.start();
|
|
1889
|
-
});
|
|
1890
1544
|
};
|
|
1891
|
-
VoiceAgentService.prototype.
|
|
1545
|
+
VoiceAgentService.prototype.onBotStartedSpeaking = function () {
|
|
1892
1546
|
if (this.callStartTime === 0) {
|
|
1893
1547
|
this.callStartTime = Date.now();
|
|
1894
1548
|
this.startDurationTimer();
|
|
1895
1549
|
}
|
|
1896
1550
|
this.callStateSubject.next('talking');
|
|
1897
1551
|
};
|
|
1898
|
-
VoiceAgentService.prototype.
|
|
1552
|
+
VoiceAgentService.prototype.onBotStoppedSpeaking = function () {
|
|
1899
1553
|
if (this.callStateSubject.value === 'talking') {
|
|
1900
1554
|
this.callStateSubject.next('connected');
|
|
1901
1555
|
}
|
|
1902
1556
|
};
|
|
1903
|
-
VoiceAgentService.prototype.
|
|
1904
|
-
|
|
1905
|
-
this.
|
|
1906
|
-
|
|
1907
|
-
this.
|
|
1557
|
+
VoiceAgentService.prototype.setupBotAudioTrack = function (track) {
|
|
1558
|
+
var _a;
|
|
1559
|
+
if (!this.botAudioElement) {
|
|
1560
|
+
this.botAudioElement = new Audio();
|
|
1561
|
+
this.botAudioElement.autoplay = true;
|
|
1908
1562
|
}
|
|
1909
|
-
this.
|
|
1563
|
+
var existing = (_a = this.botAudioElement.srcObject) === null || _a === void 0 ? void 0 : _a.getAudioTracks()[0];
|
|
1564
|
+
if ((existing === null || existing === void 0 ? void 0 : existing.id) === track.id)
|
|
1565
|
+
return;
|
|
1566
|
+
this.botAudioElement.srcObject = new MediaStream([track]);
|
|
1567
|
+
this.botAudioElement.play().catch(function (err) { return console.warn('[HiveGpt Voice] Bot audio play blocked', err); });
|
|
1910
1568
|
};
|
|
1911
|
-
VoiceAgentService.prototype.
|
|
1569
|
+
VoiceAgentService.prototype.stopBotAudio = function () {
|
|
1570
|
+
var _a;
|
|
1571
|
+
if (this.botAudioElement) {
|
|
1572
|
+
try {
|
|
1573
|
+
this.botAudioElement.pause();
|
|
1574
|
+
(_a = this.botAudioElement.srcObject) === null || _a === void 0 ? void 0 : _a.getAudioTracks().forEach(function (t) { return t.stop(); });
|
|
1575
|
+
this.botAudioElement.srcObject = null;
|
|
1576
|
+
}
|
|
1577
|
+
catch (_b) {
|
|
1578
|
+
// ignore
|
|
1579
|
+
}
|
|
1580
|
+
this.botAudioElement = null;
|
|
1581
|
+
}
|
|
1582
|
+
};
|
|
1583
|
+
VoiceAgentService.prototype.disconnect = function () {
|
|
1912
1584
|
return __awaiter(this, void 0, void 0, function () {
|
|
1913
|
-
|
|
1914
|
-
|
|
1915
|
-
|
|
1916
|
-
|
|
1917
|
-
|
|
1918
|
-
|
|
1919
|
-
|
|
1920
|
-
|
|
1921
|
-
|
|
1922
|
-
|
|
1923
|
-
|
|
1924
|
-
|
|
1925
|
-
|
|
1926
|
-
|
|
1585
|
+
return __generator(this, function (_d) {
|
|
1586
|
+
switch (_d.label) {
|
|
1587
|
+
case 0:
|
|
1588
|
+
this.stopDurationTimer();
|
|
1589
|
+
this.callStartTime = 0;
|
|
1590
|
+
this.audioAnalyzer.stop();
|
|
1591
|
+
this.stopBotAudio();
|
|
1592
|
+
return [4 /*yield*/, this.cleanupPipecatClient()];
|
|
1593
|
+
case 1:
|
|
1594
|
+
_d.sent();
|
|
1595
|
+
this.callStateSubject.next('ended');
|
|
1596
|
+
this.statusTextSubject.next('Call Ended');
|
|
1597
|
+
return [2 /*return*/];
|
|
1598
|
+
}
|
|
1927
1599
|
});
|
|
1928
1600
|
});
|
|
1929
1601
|
};
|
|
1930
|
-
VoiceAgentService.prototype.
|
|
1602
|
+
VoiceAgentService.prototype.cleanupPipecatClient = function () {
|
|
1931
1603
|
return __awaiter(this, void 0, void 0, function () {
|
|
1932
|
-
|
|
1933
|
-
|
|
1934
|
-
|
|
1935
|
-
|
|
1936
|
-
|
|
1937
|
-
|
|
1938
|
-
|
|
1939
|
-
|
|
1940
|
-
|
|
1941
|
-
|
|
1942
|
-
|
|
1604
|
+
var _a_1;
|
|
1605
|
+
return __generator(this, function (_d) {
|
|
1606
|
+
switch (_d.label) {
|
|
1607
|
+
case 0:
|
|
1608
|
+
if (!this.pcClient) return [3 /*break*/, 5];
|
|
1609
|
+
_d.label = 1;
|
|
1610
|
+
case 1:
|
|
1611
|
+
_d.trys.push([1, 3, , 4]);
|
|
1612
|
+
return [4 /*yield*/, this.pcClient.disconnect()];
|
|
1613
|
+
case 2:
|
|
1614
|
+
_d.sent();
|
|
1615
|
+
return [3 /*break*/, 4];
|
|
1616
|
+
case 3:
|
|
1617
|
+
_a_1 = _d.sent();
|
|
1618
|
+
return [3 /*break*/, 4];
|
|
1619
|
+
case 4:
|
|
1620
|
+
this.pcClient = null;
|
|
1621
|
+
_d.label = 5;
|
|
1622
|
+
case 5: return [2 /*return*/];
|
|
1623
|
+
}
|
|
1943
1624
|
});
|
|
1944
1625
|
});
|
|
1945
1626
|
};
|
|
1946
1627
|
VoiceAgentService.prototype.toggleMic = function () {
|
|
1947
|
-
|
|
1628
|
+
if (!this.pcClient)
|
|
1629
|
+
return;
|
|
1948
1630
|
var nextMuted = !this.isMicMutedSubject.value;
|
|
1949
|
-
|
|
1950
|
-
if (track) {
|
|
1951
|
-
track.enabled = !nextMuted;
|
|
1952
|
-
}
|
|
1631
|
+
this.pcClient.enableMic(!nextMuted);
|
|
1953
1632
|
this.isMicMutedSubject.next(nextMuted);
|
|
1633
|
+
if (nextMuted)
|
|
1634
|
+
this.isUserSpeakingSubject.next(false);
|
|
1954
1635
|
};
|
|
1955
1636
|
VoiceAgentService.prototype.startDurationTimer = function () {
|
|
1956
1637
|
var _this = this;
|
|
1957
|
-
var
|
|
1638
|
+
var tick = function () {
|
|
1958
1639
|
if (_this.callStartTime > 0) {
|
|
1959
1640
|
var elapsed = Math.floor((Date.now() - _this.callStartTime) / 1000);
|
|
1960
|
-
var
|
|
1961
|
-
var
|
|
1962
|
-
_this.durationSubject.next(
|
|
1641
|
+
var m = Math.floor(elapsed / 60);
|
|
1642
|
+
var s = elapsed % 60;
|
|
1643
|
+
_this.durationSubject.next(m + ":" + String(s).padStart(2, '0'));
|
|
1963
1644
|
}
|
|
1964
1645
|
};
|
|
1965
|
-
|
|
1966
|
-
this.durationInterval = setInterval(
|
|
1646
|
+
tick();
|
|
1647
|
+
this.durationInterval = setInterval(tick, 1000);
|
|
1967
1648
|
};
|
|
1968
1649
|
VoiceAgentService.prototype.stopDurationTimer = function () {
|
|
1969
1650
|
if (this.durationInterval) {
|
|
@@ -1973,7 +1654,7 @@
|
|
|
1973
1654
|
};
|
|
1974
1655
|
return VoiceAgentService;
|
|
1975
1656
|
}());
|
|
1976
|
-
VoiceAgentService.ɵprov = i0__namespace.ɵɵdefineInjectable({ factory: function VoiceAgentService_Factory() { return new VoiceAgentService(i0__namespace.ɵɵinject(AudioAnalyzerService), i0__namespace.ɵɵinject(
|
|
1657
|
+
VoiceAgentService.ɵprov = i0__namespace.ɵɵdefineInjectable({ factory: function VoiceAgentService_Factory() { return new VoiceAgentService(i0__namespace.ɵɵinject(AudioAnalyzerService), i0__namespace.ɵɵinject(PlatformTokenRefreshService), i0__namespace.ɵɵinject(i0__namespace.NgZone), i0__namespace.ɵɵinject(i0__namespace.PLATFORM_ID)); }, token: VoiceAgentService, providedIn: "root" });
|
|
1977
1658
|
VoiceAgentService.decorators = [
|
|
1978
1659
|
{ type: i0.Injectable, args: [{
|
|
1979
1660
|
providedIn: 'root',
|
|
@@ -1981,8 +1662,8 @@
|
|
|
1981
1662
|
];
|
|
1982
1663
|
VoiceAgentService.ctorParameters = function () { return [
|
|
1983
1664
|
{ type: AudioAnalyzerService },
|
|
1984
|
-
{ type: WebSocketVoiceClientService },
|
|
1985
1665
|
{ type: PlatformTokenRefreshService },
|
|
1666
|
+
{ type: i0.NgZone },
|
|
1986
1667
|
{ type: Object, decorators: [{ type: i0.Inject, args: [i0.PLATFORM_ID,] }] }
|
|
1987
1668
|
]; };
|
|
1988
1669
|
|
|
@@ -6163,8 +5844,8 @@
|
|
|
6163
5844
|
};
|
|
6164
5845
|
|
|
6165
5846
|
/**
|
|
6166
|
-
* Voice agent module. Uses
|
|
6167
|
-
*
|
|
5847
|
+
* Voice agent module. Uses @pipecat-ai/client-js + @pipecat-ai/websocket-transport
|
|
5848
|
+
* (peer dependencies) for WebSocket transport, RTVI protocol, and audio.
|
|
6168
5849
|
*/
|
|
6169
5850
|
var VoiceAgentModule = /** @class */ (function () {
|
|
6170
5851
|
function VoiceAgentModule() {
|
|
@@ -6182,7 +5863,6 @@
|
|
|
6182
5863
|
providers: [
|
|
6183
5864
|
VoiceAgentService,
|
|
6184
5865
|
AudioAnalyzerService,
|
|
6185
|
-
WebSocketVoiceClientService
|
|
6186
5866
|
],
|
|
6187
5867
|
exports: [
|
|
6188
5868
|
VoiceAgentModalComponent
|
|
@@ -6483,10 +6163,9 @@
|
|
|
6483
6163
|
exports["ɵc"] = ConversationService;
|
|
6484
6164
|
exports["ɵd"] = NotificationSocket;
|
|
6485
6165
|
exports["ɵe"] = TranslationService;
|
|
6486
|
-
exports["ɵf"] =
|
|
6487
|
-
exports["ɵg"] =
|
|
6488
|
-
exports["ɵh"] =
|
|
6489
|
-
exports["ɵi"] = BotHtmlEditorComponent;
|
|
6166
|
+
exports["ɵf"] = VideoPlayerComponent;
|
|
6167
|
+
exports["ɵg"] = SafeHtmlPipe;
|
|
6168
|
+
exports["ɵh"] = BotHtmlEditorComponent;
|
|
6490
6169
|
|
|
6491
6170
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
6492
6171
|
|