@hivegpt/hiveai-angular 0.0.586 → 0.0.587
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 +92 -21
- 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/services/daily-voice-client.service.js +15 -1
- package/esm2015/lib/components/voice-agent/services/voice-agent.service.js +34 -2
- package/fesm2015/hivegpt-hiveai-angular.js +47 -1
- package/fesm2015/hivegpt-hiveai-angular.js.map +1 -1
- package/hivegpt-hiveai-angular.metadata.json +1 -1
- package/lib/components/voice-agent/services/daily-voice-client.service.d.ts +5 -0
- 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 +2 -0
- package/lib/components/voice-agent/services/voice-agent.service.d.ts.map +1 -1
- package/package.json +1 -1
|
@@ -1477,6 +1477,29 @@
|
|
|
1477
1477
|
/** Emits true once when first remote audio frame starts playing. */
|
|
1478
1478
|
this.firstRemoteAudioFrame$ = this.firstRemoteAudioFrameSubject.asObservable();
|
|
1479
1479
|
}
|
|
1480
|
+
/**
|
|
1481
|
+
* Prompt for microphone access up front so callers can handle permission
|
|
1482
|
+
* denial before creating backend room/session resources.
|
|
1483
|
+
*/
|
|
1484
|
+
DailyVoiceClientService.prototype.ensureMicrophoneAccess = function () {
|
|
1485
|
+
var _a;
|
|
1486
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
1487
|
+
var stream;
|
|
1488
|
+
return __generator(this, function (_e) {
|
|
1489
|
+
switch (_e.label) {
|
|
1490
|
+
case 0:
|
|
1491
|
+
if (!((_a = navigator === null || navigator === void 0 ? void 0 : navigator.mediaDevices) === null || _a === void 0 ? void 0 : _a.getUserMedia)) {
|
|
1492
|
+
throw new Error('Microphone API unavailable');
|
|
1493
|
+
}
|
|
1494
|
+
return [4 /*yield*/, navigator.mediaDevices.getUserMedia({ audio: true })];
|
|
1495
|
+
case 1:
|
|
1496
|
+
stream = _e.sent();
|
|
1497
|
+
stream.getTracks().forEach(function (t) { return t.stop(); });
|
|
1498
|
+
return [2 /*return*/];
|
|
1499
|
+
}
|
|
1500
|
+
});
|
|
1501
|
+
});
|
|
1502
|
+
};
|
|
1480
1503
|
/**
|
|
1481
1504
|
* Connect to Daily room. Acquires mic first for waveform, then joins with audio.
|
|
1482
1505
|
* @param roomUrl Daily room URL (from room_created)
|
|
@@ -1848,29 +1871,34 @@
|
|
|
1848
1871
|
}
|
|
1849
1872
|
_a.label = 1;
|
|
1850
1873
|
case 1:
|
|
1851
|
-
_a.trys.push([1,
|
|
1874
|
+
_a.trys.push([1, 9, , 13]);
|
|
1852
1875
|
this.callStateSubject.next('connecting');
|
|
1853
1876
|
this.statusTextSubject.next('Connecting...');
|
|
1854
|
-
|
|
1855
|
-
|
|
1856
|
-
_a.label = 2;
|
|
1877
|
+
// Request mic permission before provisioning backend room flow.
|
|
1878
|
+
return [4 /*yield*/, this.dailyClient.ensureMicrophoneAccess()];
|
|
1857
1879
|
case 2:
|
|
1858
|
-
|
|
1880
|
+
// Request mic permission before provisioning backend room flow.
|
|
1881
|
+
_a.sent();
|
|
1882
|
+
accessToken = token;
|
|
1883
|
+
if (!(usersApiUrl && common.isPlatformBrowser(this.platformId))) return [3 /*break*/, 6];
|
|
1884
|
+
_a.label = 3;
|
|
1885
|
+
case 3:
|
|
1886
|
+
_a.trys.push([3, 5, , 6]);
|
|
1859
1887
|
return [4 /*yield*/, this.platformTokenRefresh
|
|
1860
1888
|
.ensureValidAccessToken(token, usersApiUrl)
|
|
1861
1889
|
.pipe(operators.take(1))
|
|
1862
1890
|
.toPromise()];
|
|
1863
|
-
case
|
|
1891
|
+
case 4:
|
|
1864
1892
|
ensured = _a.sent();
|
|
1865
1893
|
if (ensured === null || ensured === void 0 ? void 0 : ensured.accessToken) {
|
|
1866
1894
|
accessToken = ensured.accessToken;
|
|
1867
1895
|
}
|
|
1868
|
-
return [3 /*break*/,
|
|
1869
|
-
case
|
|
1896
|
+
return [3 /*break*/, 6];
|
|
1897
|
+
case 5:
|
|
1870
1898
|
e_1 = _a.sent();
|
|
1871
1899
|
console.warn('[HiveGpt Voice] Token refresh before connect failed', e_1);
|
|
1872
|
-
return [3 /*break*/,
|
|
1873
|
-
case
|
|
1900
|
+
return [3 /*break*/, 6];
|
|
1901
|
+
case 6:
|
|
1874
1902
|
baseUrl = apiUrl.replace(/\/$/, '');
|
|
1875
1903
|
postUrl = baseUrl + "/ai/ask-voice";
|
|
1876
1904
|
headers = {
|
|
@@ -1893,13 +1921,13 @@
|
|
|
1893
1921
|
voice: 'alloy',
|
|
1894
1922
|
}),
|
|
1895
1923
|
})];
|
|
1896
|
-
case
|
|
1924
|
+
case 7:
|
|
1897
1925
|
res = _a.sent();
|
|
1898
1926
|
if (!res.ok) {
|
|
1899
1927
|
throw new Error("HTTP " + res.status);
|
|
1900
1928
|
}
|
|
1901
1929
|
return [4 /*yield*/, res.json()];
|
|
1902
|
-
case
|
|
1930
|
+
case 8:
|
|
1903
1931
|
json = _a.sent();
|
|
1904
1932
|
wsUrl = json === null || json === void 0 ? void 0 : json.rn_ws_url;
|
|
1905
1933
|
if (!wsUrl || typeof wsUrl !== 'string') {
|
|
@@ -1913,21 +1941,30 @@
|
|
|
1913
1941
|
return __generator(this, function (_a) {
|
|
1914
1942
|
switch (_a.label) {
|
|
1915
1943
|
case 0:
|
|
1916
|
-
_a.trys.push([0, 2, ,
|
|
1944
|
+
_a.trys.push([0, 2, , 6]);
|
|
1917
1945
|
return [4 /*yield*/, this.onRoomCreated(roomUrl)];
|
|
1918
1946
|
case 1:
|
|
1919
1947
|
_a.sent();
|
|
1920
|
-
return [3 /*break*/,
|
|
1948
|
+
return [3 /*break*/, 6];
|
|
1921
1949
|
case 2:
|
|
1922
1950
|
err_1 = _a.sent();
|
|
1923
1951
|
console.error('Daily join failed:', err_1);
|
|
1952
|
+
if (!this.isMicPermissionError(err_1)) return [3 /*break*/, 4];
|
|
1953
|
+
return [4 /*yield*/, this.cleanupMediaAndSignal()];
|
|
1954
|
+
case 3:
|
|
1955
|
+
_a.sent();
|
|
1956
|
+
this.callStateSubject.next('idle');
|
|
1957
|
+
this.durationSubject.next('0:00');
|
|
1958
|
+
this.statusTextSubject.next('Microphone permission is required');
|
|
1959
|
+
return [2 /*return*/];
|
|
1960
|
+
case 4:
|
|
1924
1961
|
this.callStateSubject.next('ended');
|
|
1925
1962
|
this.statusTextSubject.next('Connection failed');
|
|
1926
1963
|
return [4 /*yield*/, this.disconnect()];
|
|
1927
|
-
case
|
|
1964
|
+
case 5:
|
|
1928
1965
|
_a.sent();
|
|
1929
|
-
|
|
1930
|
-
case
|
|
1966
|
+
return [3 /*break*/, 6];
|
|
1967
|
+
case 6: return [2 /*return*/];
|
|
1931
1968
|
}
|
|
1932
1969
|
});
|
|
1933
1970
|
}); });
|
|
@@ -1940,17 +1977,26 @@
|
|
|
1940
1977
|
.subscribe(function (t) { return _this.botTranscriptSubject.next(t); }));
|
|
1941
1978
|
// Connect signaling WebSocket (no audio over WS)
|
|
1942
1979
|
this.wsClient.connect(wsUrl);
|
|
1943
|
-
return [3 /*break*/,
|
|
1944
|
-
case
|
|
1980
|
+
return [3 /*break*/, 13];
|
|
1981
|
+
case 9:
|
|
1945
1982
|
error_1 = _a.sent();
|
|
1946
1983
|
console.error('Error connecting voice agent:', error_1);
|
|
1984
|
+
if (!this.isMicPermissionError(error_1)) return [3 /*break*/, 11];
|
|
1985
|
+
return [4 /*yield*/, this.cleanupMediaAndSignal()];
|
|
1986
|
+
case 10:
|
|
1987
|
+
_a.sent();
|
|
1988
|
+
this.callStateSubject.next('idle');
|
|
1989
|
+
this.durationSubject.next('0:00');
|
|
1990
|
+
this.statusTextSubject.next('Microphone permission is required');
|
|
1991
|
+
return [2 /*return*/];
|
|
1992
|
+
case 11:
|
|
1947
1993
|
this.callStateSubject.next('ended');
|
|
1948
1994
|
return [4 /*yield*/, this.disconnect()];
|
|
1949
|
-
case
|
|
1995
|
+
case 12:
|
|
1950
1996
|
_a.sent();
|
|
1951
1997
|
this.statusTextSubject.next('Connection failed');
|
|
1952
1998
|
throw error_1;
|
|
1953
|
-
case
|
|
1999
|
+
case 13: return [2 /*return*/];
|
|
1954
2000
|
}
|
|
1955
2001
|
});
|
|
1956
2002
|
});
|
|
@@ -2062,6 +2108,31 @@
|
|
|
2062
2108
|
this.durationInterval = null;
|
|
2063
2109
|
}
|
|
2064
2110
|
};
|
|
2111
|
+
VoiceAgentService.prototype.isMicPermissionError = function (error) {
|
|
2112
|
+
if (!error || typeof error !== 'object')
|
|
2113
|
+
return false;
|
|
2114
|
+
var maybe = error;
|
|
2115
|
+
return (maybe.name === 'NotAllowedError' ||
|
|
2116
|
+
maybe.name === 'PermissionDeniedError' ||
|
|
2117
|
+
maybe.name === 'SecurityError');
|
|
2118
|
+
};
|
|
2119
|
+
VoiceAgentService.prototype.cleanupMediaAndSignal = function () {
|
|
2120
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
2121
|
+
return __generator(this, function (_a) {
|
|
2122
|
+
switch (_a.label) {
|
|
2123
|
+
case 0:
|
|
2124
|
+
this.stopDurationTimer();
|
|
2125
|
+
this.audioAnalyzer.stop();
|
|
2126
|
+
return [4 /*yield*/, this.dailyClient.disconnect()];
|
|
2127
|
+
case 1:
|
|
2128
|
+
_a.sent();
|
|
2129
|
+
this.wsClient.disconnect();
|
|
2130
|
+
this.hasAutoUnmutedAfterFirstAudio = false;
|
|
2131
|
+
return [2 /*return*/];
|
|
2132
|
+
}
|
|
2133
|
+
});
|
|
2134
|
+
});
|
|
2135
|
+
};
|
|
2065
2136
|
return VoiceAgentService;
|
|
2066
2137
|
}());
|
|
2067
2138
|
VoiceAgentService.ɵprov = i0__namespace.ɵɵdefineInjectable({ factory: function VoiceAgentService_Factory() { return new VoiceAgentService(i0__namespace.ɵɵinject(AudioAnalyzerService), i0__namespace.ɵɵinject(WebSocketVoiceClientService), i0__namespace.ɵɵinject(DailyVoiceClientService), i0__namespace.ɵɵinject(PlatformTokenRefreshService), i0__namespace.ɵɵinject(i0__namespace.PLATFORM_ID)); }, token: VoiceAgentService, providedIn: "root" });
|