@mirai/core 0.4.598 → 0.4.599
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/build/components/Chat/components/Aura/Aura.js +13 -6
- package/build/components/Chat/components/Aura/Aura.js.map +1 -1
- package/build/components/Chat/components/Aura/hooks/useXaiRealtimeSession.js +491 -0
- package/build/components/Chat/components/Aura/hooks/useXaiRealtimeSession.js.map +1 -0
- package/package.json +1 -1
|
@@ -13,29 +13,36 @@ var _Aura = require("./Aura.l10n");
|
|
|
13
13
|
var style = _interopRequireWildcard(require("./Aura.module.css"));
|
|
14
14
|
var _Aura2 = require("./Aura.waveform");
|
|
15
15
|
var _useOpenAiRealtimeSession = require("./hooks/useOpenAiRealtimeSession");
|
|
16
|
+
var _useXaiRealtimeSession = require("./hooks/useXaiRealtimeSession");
|
|
16
17
|
var _Core = require("../../../../Core.constants");
|
|
17
18
|
var _helpers = require("../../../helpers");
|
|
18
19
|
var _Chat = require("../../Chat.constants");
|
|
19
20
|
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
|
|
20
21
|
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
22
|
+
const VOICE_MODEL_XAI = 'xai';
|
|
21
23
|
const Aura = _ref => {
|
|
24
|
+
var _urlParams$voiceMode;
|
|
22
25
|
let {
|
|
23
26
|
hotelId,
|
|
24
27
|
onCallEnd = () => {},
|
|
25
28
|
settings
|
|
26
29
|
} = _ref;
|
|
27
|
-
const
|
|
28
|
-
|
|
29
|
-
endSession,
|
|
30
|
-
audioAnalyzers
|
|
31
|
-
} = (0, _useOpenAiRealtimeSession.useOpenAiRealtimeSession)();
|
|
30
|
+
const openAiSession = (0, _useOpenAiRealtimeSession.useOpenAiRealtimeSession)();
|
|
31
|
+
const xaiSession = (0, _useXaiRealtimeSession.useXaiRealtimeSession)();
|
|
32
32
|
const {
|
|
33
33
|
value: {
|
|
34
34
|
id,
|
|
35
35
|
locale,
|
|
36
|
-
type
|
|
36
|
+
type,
|
|
37
|
+
urlParams = {}
|
|
37
38
|
} = {}
|
|
38
39
|
} = (0, _dataSources.useStore)();
|
|
40
|
+
const useXai = ((_urlParams$voiceMode = urlParams['voice-model']) === null || _urlParams$voiceMode === void 0 ? void 0 : _urlParams$voiceMode.toLowerCase()) === VOICE_MODEL_XAI;
|
|
41
|
+
const {
|
|
42
|
+
startSession,
|
|
43
|
+
endSession,
|
|
44
|
+
audioAnalyzers
|
|
45
|
+
} = useXai ? xaiSession : openAiSession;
|
|
39
46
|
const {
|
|
40
47
|
translate
|
|
41
48
|
} = (0, _locale.useLocale)();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Aura.js","names":["_dataSources","require","_locale","_ui","_propTypes","_interopRequireDefault","_react","_interopRequireWildcard","_Aura","style","_Aura2","_useOpenAiRealtimeSession","_Core","_helpers","_Chat","e","t","WeakMap","r","n","__esModule","o","i","f","__proto__","default","has","get","set","hasOwnProperty","call","Object","defineProperty","getOwnPropertyDescriptor","Aura","_ref","hotelId","onCallEnd","settings","startSession","endSession","audioAnalyzers","useOpenAiRealtimeSession","value","id","locale","type","useStore","translate","useLocale","ai","name","assistantName","DEFAULT_NAME","context","setContext","useState","isConnecting","setIsConnecting","ready","setReady","useEffect","TYPE","CHAIN","handleCallEnd","useCallback","Event","publish","EVENT","METRICS","METRICS_EVENTS","AURA_CALL_END","handleCallStart","callback","subscribe","CHAT_CLOSE","unsubscribe","isChain","chainId","undefined","navigator","mediaDevices","AURA_ERROR","assistant_name","error","createElement","Fragment","Waveform","active","conversation","View","className","footer","Text","action","L10N","LABEL_CALLING","Button","busy","rounded","squared","large","tooltip","LABEL_HANG_UP","onPress","styles","button","Icon","ICON","HANG_UP","exports","displayName","propTypes","PropTypes","string","func","shape"],"sources":["../../../../../src/components/Chat/components/Aura/Aura.jsx"],"sourcesContent":["import { Event, useStore } from '@mirai/data-sources';\nimport { useLocale } from '@mirai/locale';\nimport { Button, Icon, styles, Text, View } from '@mirai/ui';\nimport PropTypes from 'prop-types';\nimport React, { useCallback, useEffect, useState } from 'react';\n\nimport { L10N } from './Aura.l10n';\nimport * as style from './Aura.module.css';\nimport { Waveform } from './Aura.waveform';\nimport { useOpenAiRealtimeSession } from './hooks/useOpenAiRealtimeSession';\nimport { TYPE } from '../../../../Core.constants';\nimport { EVENT, ICON, METRICS_EVENTS } from '../../../helpers';\nimport { DEFAULT_NAME } from '../../Chat.constants';\n\nconst Aura = ({ hotelId, onCallEnd = () => {}, settings }) => {\n const { startSession, endSession, audioAnalyzers } = useOpenAiRealtimeSession();\n const { value: { id, locale, type } = {} } = useStore();\n const { translate } = useLocale();\n const { ai: { name: assistantName = DEFAULT_NAME } = {} } = settings || {};\n\n const [context, setContext] = useState(null);\n const [isConnecting, setIsConnecting] = useState(false);\n const [ready, setReady] = useState(false);\n\n useEffect(() => {\n if (type === TYPE.CHAIN && !hotelId) return;\n\n setContext({ hotelId });\n }, [hotelId, type]);\n\n const handleCallEnd = useCallback(() => {\n endSession();\n setReady(false);\n onCallEnd();\n Event.publish(EVENT.METRICS, { id: METRICS_EVENTS.AURA_CALL_END });\n }, [endSession, onCallEnd]);\n\n useEffect(() => {\n handleCallStart();\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [context]);\n\n useEffect(() => {\n const callback = () => {\n if (ready) handleCallEnd();\n };\n\n Event.subscribe(EVENT.CHAT_CLOSE, callback);\n return () => {\n Event.unsubscribe(EVENT.CHAT_CLOSE, callback);\n };\n }, [handleCallEnd, ready]);\n\n const handleCallStart = async () => {\n const isChain = type === TYPE.CHAIN && !hotelId;\n const chainId = isChain ? id : undefined;\n\n if (!navigator.mediaDevices || (!context && !chainId)) {\n Event.publish(EVENT.METRICS, { id: METRICS_EVENTS.AURA_ERROR });\n return;\n }\n\n setIsConnecting(true);\n try {\n await startSession({\n assistant_name: assistantName,\n chainId,\n hotelId,\n isChain,\n locale,\n setIsConnecting,\n setReady,\n });\n } catch (error) {\n setIsConnecting(false);\n }\n };\n\n return !(!context && !(type === TYPE.CHAIN && !hotelId)) ? (\n <>\n <Waveform active={ready} conversation={audioAnalyzers} />\n <View className={style.footer}>\n {isConnecting && <Text action>{translate(L10N.LABEL_CALLING, { name: assistantName })}</Text>}\n <Button\n busy={isConnecting}\n rounded\n squared\n large\n tooltip={translate(L10N.LABEL_HANG_UP)}\n onPress={handleCallEnd}\n className={styles(style.button, ready && style.ready)}\n >\n <Icon value={ICON.HANG_UP} />\n </Button>\n </View>\n </>\n ) : null;\n};\n\nAura.displayName = 'Mirai:Core:Chat.Aura';\n\nAura.propTypes = {\n hotelId: PropTypes.string,\n onCallEnd: PropTypes.func,\n settings: PropTypes.shape({\n ai: PropTypes.shape({\n name: PropTypes.string,\n }),\n }),\n};\n\nexport { Aura };\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"file":"Aura.js","names":["_dataSources","require","_locale","_ui","_propTypes","_interopRequireDefault","_react","_interopRequireWildcard","_Aura","style","_Aura2","_useOpenAiRealtimeSession","_useXaiRealtimeSession","_Core","_helpers","_Chat","e","t","WeakMap","r","n","__esModule","o","i","f","__proto__","default","has","get","set","hasOwnProperty","call","Object","defineProperty","getOwnPropertyDescriptor","VOICE_MODEL_XAI","Aura","_ref","_urlParams$voiceMode","hotelId","onCallEnd","settings","openAiSession","useOpenAiRealtimeSession","xaiSession","useXaiRealtimeSession","value","id","locale","type","urlParams","useStore","useXai","toLowerCase","startSession","endSession","audioAnalyzers","translate","useLocale","ai","name","assistantName","DEFAULT_NAME","context","setContext","useState","isConnecting","setIsConnecting","ready","setReady","useEffect","TYPE","CHAIN","handleCallEnd","useCallback","Event","publish","EVENT","METRICS","METRICS_EVENTS","AURA_CALL_END","handleCallStart","callback","subscribe","CHAT_CLOSE","unsubscribe","isChain","chainId","undefined","navigator","mediaDevices","AURA_ERROR","assistant_name","error","createElement","Fragment","Waveform","active","conversation","View","className","footer","Text","action","L10N","LABEL_CALLING","Button","busy","rounded","squared","large","tooltip","LABEL_HANG_UP","onPress","styles","button","Icon","ICON","HANG_UP","exports","displayName","propTypes","PropTypes","string","func","shape"],"sources":["../../../../../src/components/Chat/components/Aura/Aura.jsx"],"sourcesContent":["import { Event, useStore } from '@mirai/data-sources';\nimport { useLocale } from '@mirai/locale';\nimport { Button, Icon, styles, Text, View } from '@mirai/ui';\nimport PropTypes from 'prop-types';\nimport React, { useCallback, useEffect, useState } from 'react';\n\nimport { L10N } from './Aura.l10n';\nimport * as style from './Aura.module.css';\nimport { Waveform } from './Aura.waveform';\nimport { useOpenAiRealtimeSession } from './hooks/useOpenAiRealtimeSession';\nimport { useXaiRealtimeSession } from './hooks/useXaiRealtimeSession';\nimport { TYPE } from '../../../../Core.constants';\nimport { EVENT, ICON, METRICS_EVENTS } from '../../../helpers';\nimport { DEFAULT_NAME } from '../../Chat.constants';\n\nconst VOICE_MODEL_XAI = 'xai';\n\nconst Aura = ({ hotelId, onCallEnd = () => {}, settings }) => {\n const openAiSession = useOpenAiRealtimeSession();\n const xaiSession = useXaiRealtimeSession();\n const { value: { id, locale, type, urlParams = {} } = {} } = useStore();\n const useXai = urlParams['voice-model']?.toLowerCase() === VOICE_MODEL_XAI;\n const { startSession, endSession, audioAnalyzers } = useXai ? xaiSession : openAiSession;\n const { translate } = useLocale();\n const { ai: { name: assistantName = DEFAULT_NAME } = {} } = settings || {};\n\n const [context, setContext] = useState(null);\n const [isConnecting, setIsConnecting] = useState(false);\n const [ready, setReady] = useState(false);\n\n useEffect(() => {\n if (type === TYPE.CHAIN && !hotelId) return;\n\n setContext({ hotelId });\n }, [hotelId, type]);\n\n const handleCallEnd = useCallback(() => {\n endSession();\n setReady(false);\n onCallEnd();\n Event.publish(EVENT.METRICS, { id: METRICS_EVENTS.AURA_CALL_END });\n }, [endSession, onCallEnd]);\n\n useEffect(() => {\n handleCallStart();\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [context]);\n\n useEffect(() => {\n const callback = () => {\n if (ready) handleCallEnd();\n };\n\n Event.subscribe(EVENT.CHAT_CLOSE, callback);\n return () => {\n Event.unsubscribe(EVENT.CHAT_CLOSE, callback);\n };\n }, [handleCallEnd, ready]);\n\n const handleCallStart = async () => {\n const isChain = type === TYPE.CHAIN && !hotelId;\n const chainId = isChain ? id : undefined;\n\n if (!navigator.mediaDevices || (!context && !chainId)) {\n Event.publish(EVENT.METRICS, { id: METRICS_EVENTS.AURA_ERROR });\n return;\n }\n\n setIsConnecting(true);\n try {\n await startSession({\n assistant_name: assistantName,\n chainId,\n hotelId,\n isChain,\n locale,\n setIsConnecting,\n setReady,\n });\n } catch (error) {\n setIsConnecting(false);\n }\n };\n\n return !(!context && !(type === TYPE.CHAIN && !hotelId)) ? (\n <>\n <Waveform active={ready} conversation={audioAnalyzers} />\n <View className={style.footer}>\n {isConnecting && <Text action>{translate(L10N.LABEL_CALLING, { name: assistantName })}</Text>}\n <Button\n busy={isConnecting}\n rounded\n squared\n large\n tooltip={translate(L10N.LABEL_HANG_UP)}\n onPress={handleCallEnd}\n className={styles(style.button, ready && style.ready)}\n >\n <Icon value={ICON.HANG_UP} />\n </Button>\n </View>\n </>\n ) : null;\n};\n\nAura.displayName = 'Mirai:Core:Chat.Aura';\n\nAura.propTypes = {\n hotelId: PropTypes.string,\n onCallEnd: PropTypes.func,\n settings: PropTypes.shape({\n ai: PropTypes.shape({\n name: PropTypes.string,\n }),\n }),\n};\n\nexport { Aura };\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,491 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.useXaiRealtimeSession = void 0;
|
|
7
|
+
var _dataSources = require("@mirai/data-sources");
|
|
8
|
+
var _react = require("react");
|
|
9
|
+
var _helpers = require("../../../../helpers");
|
|
10
|
+
var _helpers2 = require("../../../helpers");
|
|
11
|
+
var _lobby = require("../../../services/lobby.service");
|
|
12
|
+
const XAI_REALTIME_URL = 'wss://api.x.ai/v1/realtime';
|
|
13
|
+
const DEFAULT_MODEL = 'grok-voice-latest';
|
|
14
|
+
const SAMPLE_RATE = 24000;
|
|
15
|
+
const PROCESSOR_BUFFER_SIZE = 2048;
|
|
16
|
+
const ALLOWED_OPEN_URL_PREFIX = 'https://api.mirai';
|
|
17
|
+
const float32ToInt16 = float32 => {
|
|
18
|
+
const int16 = new Int16Array(float32.length);
|
|
19
|
+
for (let i = 0; i < float32.length; i += 1) {
|
|
20
|
+
const sample = Math.max(-1, Math.min(1, float32[i]));
|
|
21
|
+
int16[i] = sample < 0 ? sample * 0x8000 : sample * 0x7fff;
|
|
22
|
+
}
|
|
23
|
+
return int16;
|
|
24
|
+
};
|
|
25
|
+
const int16ToFloat32 = int16 => {
|
|
26
|
+
const float32 = new Float32Array(int16.length);
|
|
27
|
+
for (let i = 0; i < int16.length; i += 1) {
|
|
28
|
+
float32[i] = int16[i] / 0x8000;
|
|
29
|
+
}
|
|
30
|
+
return float32;
|
|
31
|
+
};
|
|
32
|
+
const base64FromInt16 = int16 => {
|
|
33
|
+
const bytes = new Uint8Array(int16.buffer, int16.byteOffset, int16.byteLength);
|
|
34
|
+
let binary = '';
|
|
35
|
+
const chunkSize = 0x8000;
|
|
36
|
+
for (let i = 0; i < bytes.length; i += chunkSize) {
|
|
37
|
+
binary += String.fromCharCode.apply(null, bytes.subarray(i, i + chunkSize));
|
|
38
|
+
}
|
|
39
|
+
return btoa(binary);
|
|
40
|
+
};
|
|
41
|
+
const int16FromBase64 = b64 => {
|
|
42
|
+
const binary = atob(b64);
|
|
43
|
+
const bytes = new Uint8Array(binary.length);
|
|
44
|
+
for (let i = 0; i < binary.length; i += 1) bytes[i] = binary.charCodeAt(i);
|
|
45
|
+
return new Int16Array(bytes.buffer, bytes.byteOffset, Math.floor(bytes.byteLength / 2));
|
|
46
|
+
};
|
|
47
|
+
const extractAudioDelta = payload => {
|
|
48
|
+
var _payload$delta;
|
|
49
|
+
// xAI docs show response.output_audio.delta with delta: { type: 'audio_delta', audio: 'base64' }.
|
|
50
|
+
// Stay defensive in case the server returns a plain string in delta or a top-level audio field.
|
|
51
|
+
if (typeof (payload === null || payload === void 0 ? void 0 : payload.delta) === 'string') return payload.delta;
|
|
52
|
+
if (typeof (payload === null || payload === void 0 ? void 0 : (_payload$delta = payload.delta) === null || _payload$delta === void 0 ? void 0 : _payload$delta.audio) === 'string') return payload.delta.audio;
|
|
53
|
+
if (typeof (payload === null || payload === void 0 ? void 0 : payload.audio) === 'string') return payload.audio;
|
|
54
|
+
return null;
|
|
55
|
+
};
|
|
56
|
+
const useXaiRealtimeSession = () => {
|
|
57
|
+
const wsRef = (0, _react.useRef)(null);
|
|
58
|
+
const audioContextRef = (0, _react.useRef)(null);
|
|
59
|
+
const inputSourceRef = (0, _react.useRef)(null);
|
|
60
|
+
const scriptProcessorRef = (0, _react.useRef)(null);
|
|
61
|
+
const inputAnalyserRef = (0, _react.useRef)(null);
|
|
62
|
+
const outputAnalyserRef = (0, _react.useRef)(null);
|
|
63
|
+
const inputMuteGainRef = (0, _react.useRef)(null);
|
|
64
|
+
const localStreamRef = (0, _react.useRef)(null);
|
|
65
|
+
const microphoneEnabledRef = (0, _react.useRef)(false);
|
|
66
|
+
const playbackTimeRef = (0, _react.useRef)(0);
|
|
67
|
+
const activePlaybackSourcesRef = (0, _react.useRef)(new Set());
|
|
68
|
+
const inputFrequencyDataRef = (0, _react.useRef)(null);
|
|
69
|
+
const outputFrequencyDataRef = (0, _react.useRef)(null);
|
|
70
|
+
const audioAnalyzersRef = (0, _react.useRef)({
|
|
71
|
+
inputAnalyser: null,
|
|
72
|
+
outputAnalyser: null,
|
|
73
|
+
getInputByteFrequencyData: () => null,
|
|
74
|
+
getOutputByteFrequencyData: () => null
|
|
75
|
+
});
|
|
76
|
+
const pendingSessionConfigRef = (0, _react.useRef)(null);
|
|
77
|
+
const sessionAppliedRef = (0, _react.useRef)(false);
|
|
78
|
+
const introSentRef = (0, _react.useRef)(false);
|
|
79
|
+
const pendingUserTranscriptRef = (0, _react.useRef)('');
|
|
80
|
+
const handledOpenUrlCallsRef = (0, _react.useRef)(new Set());
|
|
81
|
+
const cleanupSession = (0, _react.useCallback)(() => {
|
|
82
|
+
const ws = wsRef.current;
|
|
83
|
+
if (ws) {
|
|
84
|
+
if (ws.readyState === WebSocket.OPEN || ws.readyState === WebSocket.CONNECTING) ws.close();
|
|
85
|
+
wsRef.current = null;
|
|
86
|
+
}
|
|
87
|
+
if (scriptProcessorRef.current) {
|
|
88
|
+
scriptProcessorRef.current.onaudioprocess = null;
|
|
89
|
+
scriptProcessorRef.current.disconnect();
|
|
90
|
+
scriptProcessorRef.current = null;
|
|
91
|
+
}
|
|
92
|
+
if (inputSourceRef.current) {
|
|
93
|
+
inputSourceRef.current.disconnect();
|
|
94
|
+
inputSourceRef.current = null;
|
|
95
|
+
}
|
|
96
|
+
if (inputMuteGainRef.current) {
|
|
97
|
+
inputMuteGainRef.current.disconnect();
|
|
98
|
+
inputMuteGainRef.current = null;
|
|
99
|
+
}
|
|
100
|
+
if (inputAnalyserRef.current) {
|
|
101
|
+
inputAnalyserRef.current.disconnect();
|
|
102
|
+
inputAnalyserRef.current = null;
|
|
103
|
+
}
|
|
104
|
+
if (outputAnalyserRef.current) {
|
|
105
|
+
outputAnalyserRef.current.disconnect();
|
|
106
|
+
outputAnalyserRef.current = null;
|
|
107
|
+
}
|
|
108
|
+
activePlaybackSourcesRef.current.forEach(source => {
|
|
109
|
+
try {
|
|
110
|
+
source.stop();
|
|
111
|
+
} catch (_unused) {
|
|
112
|
+
// already stopped
|
|
113
|
+
}
|
|
114
|
+
});
|
|
115
|
+
activePlaybackSourcesRef.current = new Set();
|
|
116
|
+
if (localStreamRef.current) {
|
|
117
|
+
localStreamRef.current.getTracks().forEach(track => track.stop());
|
|
118
|
+
localStreamRef.current = null;
|
|
119
|
+
}
|
|
120
|
+
if (audioContextRef.current) {
|
|
121
|
+
audioContextRef.current.close();
|
|
122
|
+
audioContextRef.current = null;
|
|
123
|
+
}
|
|
124
|
+
audioAnalyzersRef.current.inputAnalyser = null;
|
|
125
|
+
audioAnalyzersRef.current.outputAnalyser = null;
|
|
126
|
+
audioAnalyzersRef.current.getInputByteFrequencyData = () => null;
|
|
127
|
+
audioAnalyzersRef.current.getOutputByteFrequencyData = () => null;
|
|
128
|
+
inputFrequencyDataRef.current = null;
|
|
129
|
+
outputFrequencyDataRef.current = null;
|
|
130
|
+
microphoneEnabledRef.current = false;
|
|
131
|
+
playbackTimeRef.current = 0;
|
|
132
|
+
pendingSessionConfigRef.current = null;
|
|
133
|
+
sessionAppliedRef.current = false;
|
|
134
|
+
introSentRef.current = false;
|
|
135
|
+
pendingUserTranscriptRef.current = '';
|
|
136
|
+
handledOpenUrlCallsRef.current = new Set();
|
|
137
|
+
}, []);
|
|
138
|
+
const stopPendingPlayback = (0, _react.useCallback)(() => {
|
|
139
|
+
activePlaybackSourcesRef.current.forEach(source => {
|
|
140
|
+
try {
|
|
141
|
+
source.stop();
|
|
142
|
+
} catch (_unused2) {
|
|
143
|
+
// already stopped
|
|
144
|
+
}
|
|
145
|
+
});
|
|
146
|
+
activePlaybackSourcesRef.current = new Set();
|
|
147
|
+
if (audioContextRef.current) playbackTimeRef.current = audioContextRef.current.currentTime;
|
|
148
|
+
}, []);
|
|
149
|
+
const scheduleAudioPlayback = (0, _react.useCallback)(audioBase64 => {
|
|
150
|
+
const context = audioContextRef.current;
|
|
151
|
+
const analyser = outputAnalyserRef.current;
|
|
152
|
+
if (!context || !analyser) return;
|
|
153
|
+
const int16 = int16FromBase64(audioBase64);
|
|
154
|
+
if (!int16.length) return;
|
|
155
|
+
const float32 = int16ToFloat32(int16);
|
|
156
|
+
const buffer = context.createBuffer(1, float32.length, SAMPLE_RATE);
|
|
157
|
+
buffer.copyToChannel(float32, 0);
|
|
158
|
+
const source = context.createBufferSource();
|
|
159
|
+
source.buffer = buffer;
|
|
160
|
+
source.connect(analyser);
|
|
161
|
+
const startAt = Math.max(context.currentTime, playbackTimeRef.current);
|
|
162
|
+
source.start(startAt);
|
|
163
|
+
playbackTimeRef.current = startAt + buffer.duration;
|
|
164
|
+
activePlaybackSourcesRef.current.add(source);
|
|
165
|
+
source.onended = () => {
|
|
166
|
+
activePlaybackSourcesRef.current.delete(source);
|
|
167
|
+
};
|
|
168
|
+
}, []);
|
|
169
|
+
const sendJson = (0, _react.useCallback)(payload => {
|
|
170
|
+
const ws = wsRef.current;
|
|
171
|
+
if (!ws || ws.readyState !== WebSocket.OPEN) return false;
|
|
172
|
+
ws.send(JSON.stringify(payload));
|
|
173
|
+
return true;
|
|
174
|
+
}, []);
|
|
175
|
+
const sendIntro = (0, _react.useCallback)(_ref => {
|
|
176
|
+
let {
|
|
177
|
+
assistantName,
|
|
178
|
+
locale
|
|
179
|
+
} = _ref;
|
|
180
|
+
if (introSentRef.current) return;
|
|
181
|
+
const localeHint = locale || 'en-US';
|
|
182
|
+
const text = "Respond in the language that matches the locale code \"".concat(localeHint, "\". Introduce yourself using the following sentence, translated into that language: \"Hello, I am ").concat(assistantName, ", your virtual assistant. I can help you with information about our services and facilities. What would you like to know today?\"");
|
|
183
|
+
sendJson({
|
|
184
|
+
type: 'conversation.item.create',
|
|
185
|
+
item: {
|
|
186
|
+
type: 'message',
|
|
187
|
+
role: 'user',
|
|
188
|
+
content: [{
|
|
189
|
+
type: 'input_text',
|
|
190
|
+
text
|
|
191
|
+
}]
|
|
192
|
+
}
|
|
193
|
+
});
|
|
194
|
+
sendJson({
|
|
195
|
+
type: 'response.create'
|
|
196
|
+
});
|
|
197
|
+
introSentRef.current = true;
|
|
198
|
+
}, [sendJson]);
|
|
199
|
+
const handleFunctionCall = (0, _react.useCallback)(payload => {
|
|
200
|
+
var _parsed;
|
|
201
|
+
const {
|
|
202
|
+
name
|
|
203
|
+
} = payload;
|
|
204
|
+
const callId = payload.call_id;
|
|
205
|
+
if (name !== 'open_url' || !callId) return;
|
|
206
|
+
if (handledOpenUrlCallsRef.current.has(callId)) return;
|
|
207
|
+
handledOpenUrlCallsRef.current.add(callId);
|
|
208
|
+
let parsed = null;
|
|
209
|
+
try {
|
|
210
|
+
parsed = JSON.parse(payload.arguments || '{}');
|
|
211
|
+
} catch (_unused3) {
|
|
212
|
+
parsed = null;
|
|
213
|
+
}
|
|
214
|
+
const url = (_parsed = parsed) === null || _parsed === void 0 ? void 0 : _parsed.url;
|
|
215
|
+
const allowed = typeof url === 'string' && url.trim().startsWith(ALLOWED_OPEN_URL_PREFIX);
|
|
216
|
+
if (!allowed) {
|
|
217
|
+
sendJson({
|
|
218
|
+
type: 'conversation.item.create',
|
|
219
|
+
item: {
|
|
220
|
+
type: 'function_call_output',
|
|
221
|
+
call_id: callId,
|
|
222
|
+
output: JSON.stringify({
|
|
223
|
+
error: 'blocked_url',
|
|
224
|
+
allowed_prefix: ALLOWED_OPEN_URL_PREFIX
|
|
225
|
+
})
|
|
226
|
+
}
|
|
227
|
+
});
|
|
228
|
+
sendJson({
|
|
229
|
+
type: 'response.create'
|
|
230
|
+
});
|
|
231
|
+
return;
|
|
232
|
+
}
|
|
233
|
+
cleanupSession();
|
|
234
|
+
window.location.assign(url.trim());
|
|
235
|
+
}, [cleanupSession, sendJson]);
|
|
236
|
+
const persistTranscriptPair = (0, _react.useCallback)(async _ref2 => {
|
|
237
|
+
let {
|
|
238
|
+
fingerprint,
|
|
239
|
+
hotelId,
|
|
240
|
+
locale,
|
|
241
|
+
transcript
|
|
242
|
+
} = _ref2;
|
|
243
|
+
if (!transcript || !pendingUserTranscriptRef.current) return;
|
|
244
|
+
const input = pendingUserTranscriptRef.current.trim();
|
|
245
|
+
pendingUserTranscriptRef.current = '';
|
|
246
|
+
const activeLocale = locale || 'en-US';
|
|
247
|
+
if (hotelId) {
|
|
248
|
+
try {
|
|
249
|
+
const chatId = await (0, _lobby.ensureChatId)({
|
|
250
|
+
fingerprint,
|
|
251
|
+
channelId: hotelId,
|
|
252
|
+
session: {
|
|
253
|
+
locale: activeLocale
|
|
254
|
+
}
|
|
255
|
+
});
|
|
256
|
+
if (chatId) {
|
|
257
|
+
await (0, _lobby.createChatMessage)({
|
|
258
|
+
author: 'user',
|
|
259
|
+
body: input,
|
|
260
|
+
chatId,
|
|
261
|
+
meta: {
|
|
262
|
+
audio: true
|
|
263
|
+
}
|
|
264
|
+
});
|
|
265
|
+
await (0, _lobby.createChatMessage)({
|
|
266
|
+
author: 'ai',
|
|
267
|
+
body: transcript,
|
|
268
|
+
chatId,
|
|
269
|
+
meta: {
|
|
270
|
+
audio: true
|
|
271
|
+
}
|
|
272
|
+
});
|
|
273
|
+
}
|
|
274
|
+
} catch (error) {
|
|
275
|
+
_dataSources.Event.publish(_helpers.EVENT.METRICS, {
|
|
276
|
+
id: _helpers.METRICS_EVENTS.AURA_ERROR,
|
|
277
|
+
error: error === null || error === void 0 ? void 0 : error.message
|
|
278
|
+
});
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
_dataSources.Event.publish(_helpers.EVENT.METRICS, {
|
|
282
|
+
id: 'SYNAPSE_RESPONSE',
|
|
283
|
+
fingerprint,
|
|
284
|
+
text: transcript,
|
|
285
|
+
input,
|
|
286
|
+
agent: 'aura',
|
|
287
|
+
locale: activeLocale
|
|
288
|
+
});
|
|
289
|
+
}, []);
|
|
290
|
+
const startSession = (0, _react.useCallback)(async _ref3 => {
|
|
291
|
+
let {
|
|
292
|
+
assistant_name,
|
|
293
|
+
chainId,
|
|
294
|
+
currency,
|
|
295
|
+
hotelId,
|
|
296
|
+
isChain,
|
|
297
|
+
locale,
|
|
298
|
+
setIsConnecting,
|
|
299
|
+
setReady
|
|
300
|
+
} = _ref3;
|
|
301
|
+
cleanupSession();
|
|
302
|
+
const fingerprint = (0, _helpers2.getClientFingerprint)();
|
|
303
|
+
const finalizeSession = error => {
|
|
304
|
+
const errorMessage = typeof error === 'string' ? error : error === null || error === void 0 ? void 0 : error.message;
|
|
305
|
+
if (errorMessage) {
|
|
306
|
+
_dataSources.Event.publish(_helpers.EVENT.METRICS, {
|
|
307
|
+
id: _helpers.METRICS_EVENTS.AURA_ERROR,
|
|
308
|
+
error: errorMessage
|
|
309
|
+
});
|
|
310
|
+
}
|
|
311
|
+
cleanupSession();
|
|
312
|
+
setReady(false);
|
|
313
|
+
setIsConnecting(false);
|
|
314
|
+
};
|
|
315
|
+
try {
|
|
316
|
+
const sessionResponse = await (0, _dataSources.request)({
|
|
317
|
+
endpoint: "/voice/session?voiceModel=xai&fingerprint=".concat(fingerprint, "&hotelId=").concat(isChain ? '' : hotelId !== null && hotelId !== void 0 ? hotelId : '', "&chainId=").concat(isChain ? chainId !== null && chainId !== void 0 ? chainId : '' : '', "&locale=").concat(locale !== null && locale !== void 0 ? locale : '', "¤cy=").concat(currency !== null && currency !== void 0 ? currency : ''),
|
|
318
|
+
hostname: process.env.SERVICE_SYNAPSE,
|
|
319
|
+
method: 'GET'
|
|
320
|
+
});
|
|
321
|
+
const ephemeralToken = sessionResponse === null || sessionResponse === void 0 ? void 0 : sessionResponse.value;
|
|
322
|
+
const sessionConfig = sessionResponse === null || sessionResponse === void 0 ? void 0 : sessionResponse.session;
|
|
323
|
+
const model = (sessionResponse === null || sessionResponse === void 0 ? void 0 : sessionResponse.model) || DEFAULT_MODEL;
|
|
324
|
+
if (!ephemeralToken || !sessionConfig) throw new Error('Invalid xAI session response');
|
|
325
|
+
pendingSessionConfigRef.current = sessionConfig;
|
|
326
|
+
const AudioContextConstructor = globalThis.AudioContext || globalThis.webkitAudioContext;
|
|
327
|
+
if (!AudioContextConstructor) throw new Error('AudioContext not supported');
|
|
328
|
+
const audioContext = new AudioContextConstructor({
|
|
329
|
+
sampleRate: SAMPLE_RATE
|
|
330
|
+
});
|
|
331
|
+
audioContextRef.current = audioContext;
|
|
332
|
+
if (audioContext.state === 'suspended') await audioContext.resume();
|
|
333
|
+
const mediaStream = await navigator.mediaDevices.getUserMedia({
|
|
334
|
+
audio: {
|
|
335
|
+
echoCancellation: true,
|
|
336
|
+
noiseSuppression: true,
|
|
337
|
+
autoGainControl: true,
|
|
338
|
+
channelCount: 1,
|
|
339
|
+
sampleRate: SAMPLE_RATE
|
|
340
|
+
}
|
|
341
|
+
});
|
|
342
|
+
localStreamRef.current = mediaStream;
|
|
343
|
+
const inputSource = audioContext.createMediaStreamSource(mediaStream);
|
|
344
|
+
inputSourceRef.current = inputSource;
|
|
345
|
+
const inputAnalyser = audioContext.createAnalyser();
|
|
346
|
+
inputAnalyser.fftSize = 1024;
|
|
347
|
+
inputAnalyserRef.current = inputAnalyser;
|
|
348
|
+
inputSource.connect(inputAnalyser);
|
|
349
|
+
const outputAnalyser = audioContext.createAnalyser();
|
|
350
|
+
outputAnalyser.fftSize = 1024;
|
|
351
|
+
outputAnalyserRef.current = outputAnalyser;
|
|
352
|
+
outputAnalyser.connect(audioContext.destination);
|
|
353
|
+
inputFrequencyDataRef.current = new Uint8Array(inputAnalyser.frequencyBinCount);
|
|
354
|
+
outputFrequencyDataRef.current = new Uint8Array(outputAnalyser.frequencyBinCount);
|
|
355
|
+
audioAnalyzersRef.current.inputAnalyser = inputAnalyser;
|
|
356
|
+
audioAnalyzersRef.current.outputAnalyser = outputAnalyser;
|
|
357
|
+
audioAnalyzersRef.current.getInputByteFrequencyData = () => {
|
|
358
|
+
if (!inputAnalyserRef.current || !inputFrequencyDataRef.current) return null;
|
|
359
|
+
inputAnalyserRef.current.getByteFrequencyData(inputFrequencyDataRef.current);
|
|
360
|
+
return inputFrequencyDataRef.current;
|
|
361
|
+
};
|
|
362
|
+
audioAnalyzersRef.current.getOutputByteFrequencyData = () => {
|
|
363
|
+
if (!outputAnalyserRef.current || !outputFrequencyDataRef.current) return null;
|
|
364
|
+
outputAnalyserRef.current.getByteFrequencyData(outputFrequencyDataRef.current);
|
|
365
|
+
return outputFrequencyDataRef.current;
|
|
366
|
+
};
|
|
367
|
+
|
|
368
|
+
// ScriptProcessor is deprecated but still the simplest portable way to obtain
|
|
369
|
+
// raw PCM frames synchronously. It must be connected to the destination to be scheduled;
|
|
370
|
+
// we route it through a muted GainNode so the mic input is never audible locally.
|
|
371
|
+
const processor = audioContext.createScriptProcessor(PROCESSOR_BUFFER_SIZE, 1, 1);
|
|
372
|
+
scriptProcessorRef.current = processor;
|
|
373
|
+
const muteGain = audioContext.createGain();
|
|
374
|
+
muteGain.gain.value = 0;
|
|
375
|
+
inputMuteGainRef.current = muteGain;
|
|
376
|
+
inputSource.connect(processor);
|
|
377
|
+
processor.connect(muteGain);
|
|
378
|
+
muteGain.connect(audioContext.destination);
|
|
379
|
+
processor.onaudioprocess = event => {
|
|
380
|
+
if (!microphoneEnabledRef.current) return;
|
|
381
|
+
const ws = wsRef.current;
|
|
382
|
+
if (!ws || ws.readyState !== WebSocket.OPEN) return;
|
|
383
|
+
const channelData = event.inputBuffer.getChannelData(0);
|
|
384
|
+
const int16 = float32ToInt16(channelData);
|
|
385
|
+
ws.send(JSON.stringify({
|
|
386
|
+
type: 'input_audio_buffer.append',
|
|
387
|
+
audio: base64FromInt16(int16)
|
|
388
|
+
}));
|
|
389
|
+
};
|
|
390
|
+
const ws = new WebSocket("".concat(XAI_REALTIME_URL, "?model=").concat(encodeURIComponent(model)), ["xai-client-secret.".concat(ephemeralToken)]);
|
|
391
|
+
wsRef.current = ws;
|
|
392
|
+
ws.addEventListener('open', () => {
|
|
393
|
+
_dataSources.Event.publish(_helpers.EVENT.METRICS, {
|
|
394
|
+
id: _helpers.METRICS_EVENTS.AURA_START
|
|
395
|
+
});
|
|
396
|
+
sendJson({
|
|
397
|
+
type: 'session.update',
|
|
398
|
+
session: pendingSessionConfigRef.current
|
|
399
|
+
});
|
|
400
|
+
});
|
|
401
|
+
ws.addEventListener('error', () => finalizeSession('xAI WebSocket error'));
|
|
402
|
+
ws.addEventListener('close', () => finalizeSession());
|
|
403
|
+
ws.addEventListener('message', async event => {
|
|
404
|
+
let payload;
|
|
405
|
+
try {
|
|
406
|
+
payload = JSON.parse(event.data);
|
|
407
|
+
} catch (_unused4) {
|
|
408
|
+
return;
|
|
409
|
+
}
|
|
410
|
+
switch (payload.type) {
|
|
411
|
+
case 'session.created':
|
|
412
|
+
case 'session.updated':
|
|
413
|
+
{
|
|
414
|
+
if (sessionAppliedRef.current) break;
|
|
415
|
+
sessionAppliedRef.current = true;
|
|
416
|
+
setReady(true);
|
|
417
|
+
sendIntro({
|
|
418
|
+
assistantName: assistant_name,
|
|
419
|
+
locale
|
|
420
|
+
});
|
|
421
|
+
break;
|
|
422
|
+
}
|
|
423
|
+
case 'response.output_audio.delta':
|
|
424
|
+
{
|
|
425
|
+
const audio = extractAudioDelta(payload);
|
|
426
|
+
if (audio) scheduleAudioPlayback(audio);
|
|
427
|
+
break;
|
|
428
|
+
}
|
|
429
|
+
case 'input_audio_buffer.speech_started':
|
|
430
|
+
{
|
|
431
|
+
// Barge-in: cut current playback so the user can take over the turn cleanly.
|
|
432
|
+
stopPendingPlayback();
|
|
433
|
+
break;
|
|
434
|
+
}
|
|
435
|
+
case 'response.function_call_arguments.done':
|
|
436
|
+
{
|
|
437
|
+
handleFunctionCall(payload);
|
|
438
|
+
break;
|
|
439
|
+
}
|
|
440
|
+
case 'response.done':
|
|
441
|
+
{
|
|
442
|
+
// Open the microphone once the intro response finishes; subsequent turns use server VAD.
|
|
443
|
+
if (!microphoneEnabledRef.current) microphoneEnabledRef.current = true;
|
|
444
|
+
break;
|
|
445
|
+
}
|
|
446
|
+
case 'conversation.item.input_audio_transcription.completed':
|
|
447
|
+
{
|
|
448
|
+
var _payload$transcript;
|
|
449
|
+
const transcript = (_payload$transcript = payload.transcript) === null || _payload$transcript === void 0 ? void 0 : _payload$transcript.trim();
|
|
450
|
+
if (transcript) pendingUserTranscriptRef.current += transcript;
|
|
451
|
+
break;
|
|
452
|
+
}
|
|
453
|
+
case 'response.output_audio_transcript.done':
|
|
454
|
+
case 'response.text.done':
|
|
455
|
+
{
|
|
456
|
+
var _ref4;
|
|
457
|
+
const transcript = (_ref4 = payload.transcript || payload.text) === null || _ref4 === void 0 ? void 0 : _ref4.trim();
|
|
458
|
+
await persistTranscriptPair({
|
|
459
|
+
fingerprint,
|
|
460
|
+
hotelId,
|
|
461
|
+
locale,
|
|
462
|
+
transcript
|
|
463
|
+
});
|
|
464
|
+
break;
|
|
465
|
+
}
|
|
466
|
+
default:
|
|
467
|
+
break;
|
|
468
|
+
}
|
|
469
|
+
});
|
|
470
|
+
} catch (error) {
|
|
471
|
+
_dataSources.Event.publish(_helpers.EVENT.METRICS, {
|
|
472
|
+
id: _helpers.METRICS_EVENTS.AURA_ERROR,
|
|
473
|
+
error: error === null || error === void 0 ? void 0 : error.message
|
|
474
|
+
});
|
|
475
|
+
setReady(false);
|
|
476
|
+
throw error;
|
|
477
|
+
} finally {
|
|
478
|
+
setIsConnecting(false);
|
|
479
|
+
}
|
|
480
|
+
}, [cleanupSession, handleFunctionCall, persistTranscriptPair, scheduleAudioPlayback, sendIntro, sendJson, stopPendingPlayback]);
|
|
481
|
+
const endSession = (0, _react.useCallback)(() => {
|
|
482
|
+
cleanupSession();
|
|
483
|
+
}, [cleanupSession]);
|
|
484
|
+
return {
|
|
485
|
+
startSession,
|
|
486
|
+
endSession,
|
|
487
|
+
audioAnalyzers: audioAnalyzersRef.current
|
|
488
|
+
};
|
|
489
|
+
};
|
|
490
|
+
exports.useXaiRealtimeSession = useXaiRealtimeSession;
|
|
491
|
+
//# sourceMappingURL=useXaiRealtimeSession.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useXaiRealtimeSession.js","names":["_dataSources","require","_react","_helpers","_helpers2","_lobby","XAI_REALTIME_URL","DEFAULT_MODEL","SAMPLE_RATE","PROCESSOR_BUFFER_SIZE","ALLOWED_OPEN_URL_PREFIX","float32ToInt16","float32","int16","Int16Array","length","i","sample","Math","max","min","int16ToFloat32","Float32Array","base64FromInt16","bytes","Uint8Array","buffer","byteOffset","byteLength","binary","chunkSize","String","fromCharCode","apply","subarray","btoa","int16FromBase64","b64","atob","charCodeAt","floor","extractAudioDelta","payload","_payload$delta","delta","audio","useXaiRealtimeSession","wsRef","useRef","audioContextRef","inputSourceRef","scriptProcessorRef","inputAnalyserRef","outputAnalyserRef","inputMuteGainRef","localStreamRef","microphoneEnabledRef","playbackTimeRef","activePlaybackSourcesRef","Set","inputFrequencyDataRef","outputFrequencyDataRef","audioAnalyzersRef","inputAnalyser","outputAnalyser","getInputByteFrequencyData","getOutputByteFrequencyData","pendingSessionConfigRef","sessionAppliedRef","introSentRef","pendingUserTranscriptRef","handledOpenUrlCallsRef","cleanupSession","useCallback","ws","current","readyState","WebSocket","OPEN","CONNECTING","close","onaudioprocess","disconnect","forEach","source","stop","_unused","getTracks","track","stopPendingPlayback","_unused2","currentTime","scheduleAudioPlayback","audioBase64","context","analyser","createBuffer","copyToChannel","createBufferSource","connect","startAt","start","duration","add","onended","delete","sendJson","send","JSON","stringify","sendIntro","_ref","assistantName","locale","localeHint","text","concat","type","item","role","content","handleFunctionCall","_parsed","name","callId","call_id","has","parsed","parse","arguments","_unused3","url","allowed","trim","startsWith","output","error","allowed_prefix","window","location","assign","persistTranscriptPair","_ref2","fingerprint","hotelId","transcript","input","activeLocale","chatId","ensureChatId","channelId","session","createChatMessage","author","body","meta","Event","publish","EVENT","METRICS","id","METRICS_EVENTS","AURA_ERROR","message","agent","startSession","_ref3","assistant_name","chainId","currency","isChain","setIsConnecting","setReady","getClientFingerprint","finalizeSession","errorMessage","sessionResponse","request","endpoint","hostname","process","env","SERVICE_SYNAPSE","method","ephemeralToken","value","sessionConfig","model","Error","AudioContextConstructor","globalThis","AudioContext","webkitAudioContext","audioContext","sampleRate","state","resume","mediaStream","navigator","mediaDevices","getUserMedia","echoCancellation","noiseSuppression","autoGainControl","channelCount","inputSource","createMediaStreamSource","createAnalyser","fftSize","destination","frequencyBinCount","getByteFrequencyData","processor","createScriptProcessor","muteGain","createGain","gain","event","channelData","inputBuffer","getChannelData","encodeURIComponent","addEventListener","AURA_START","data","_unused4","_payload$transcript","_ref4","endSession","audioAnalyzers","exports"],"sources":["../../../../../../src/components/Chat/components/Aura/hooks/useXaiRealtimeSession.js"],"sourcesContent":["import { Event, request } from '@mirai/data-sources';\nimport { useCallback, useRef } from 'react';\n\nimport { EVENT, METRICS_EVENTS } from '../../../../helpers';\nimport { getClientFingerprint } from '../../../helpers';\nimport { createChatMessage, ensureChatId } from '../../../services/lobby.service';\n\nconst XAI_REALTIME_URL = 'wss://api.x.ai/v1/realtime';\nconst DEFAULT_MODEL = 'grok-voice-latest';\nconst SAMPLE_RATE = 24000;\nconst PROCESSOR_BUFFER_SIZE = 2048;\nconst ALLOWED_OPEN_URL_PREFIX = 'https://api.mirai';\n\nconst float32ToInt16 = (float32) => {\n const int16 = new Int16Array(float32.length);\n for (let i = 0; i < float32.length; i += 1) {\n const sample = Math.max(-1, Math.min(1, float32[i]));\n int16[i] = sample < 0 ? sample * 0x8000 : sample * 0x7fff;\n }\n return int16;\n};\n\nconst int16ToFloat32 = (int16) => {\n const float32 = new Float32Array(int16.length);\n for (let i = 0; i < int16.length; i += 1) {\n float32[i] = int16[i] / 0x8000;\n }\n return float32;\n};\n\nconst base64FromInt16 = (int16) => {\n const bytes = new Uint8Array(int16.buffer, int16.byteOffset, int16.byteLength);\n let binary = '';\n const chunkSize = 0x8000;\n for (let i = 0; i < bytes.length; i += chunkSize) {\n binary += String.fromCharCode.apply(null, bytes.subarray(i, i + chunkSize));\n }\n return btoa(binary);\n};\n\nconst int16FromBase64 = (b64) => {\n const binary = atob(b64);\n const bytes = new Uint8Array(binary.length);\n for (let i = 0; i < binary.length; i += 1) bytes[i] = binary.charCodeAt(i);\n return new Int16Array(bytes.buffer, bytes.byteOffset, Math.floor(bytes.byteLength / 2));\n};\n\nconst extractAudioDelta = (payload) => {\n // xAI docs show response.output_audio.delta with delta: { type: 'audio_delta', audio: 'base64' }.\n // Stay defensive in case the server returns a plain string in delta or a top-level audio field.\n if (typeof payload?.delta === 'string') return payload.delta;\n if (typeof payload?.delta?.audio === 'string') return payload.delta.audio;\n if (typeof payload?.audio === 'string') return payload.audio;\n return null;\n};\n\nconst useXaiRealtimeSession = () => {\n const wsRef = useRef(null);\n const audioContextRef = useRef(null);\n const inputSourceRef = useRef(null);\n const scriptProcessorRef = useRef(null);\n const inputAnalyserRef = useRef(null);\n const outputAnalyserRef = useRef(null);\n const inputMuteGainRef = useRef(null);\n const localStreamRef = useRef(null);\n const microphoneEnabledRef = useRef(false);\n const playbackTimeRef = useRef(0);\n const activePlaybackSourcesRef = useRef(new Set());\n const inputFrequencyDataRef = useRef(null);\n const outputFrequencyDataRef = useRef(null);\n const audioAnalyzersRef = useRef({\n inputAnalyser: null,\n outputAnalyser: null,\n getInputByteFrequencyData: () => null,\n getOutputByteFrequencyData: () => null,\n });\n const pendingSessionConfigRef = useRef(null);\n const sessionAppliedRef = useRef(false);\n const introSentRef = useRef(false);\n const pendingUserTranscriptRef = useRef('');\n const handledOpenUrlCallsRef = useRef(new Set());\n\n const cleanupSession = useCallback(() => {\n const ws = wsRef.current;\n if (ws) {\n if (ws.readyState === WebSocket.OPEN || ws.readyState === WebSocket.CONNECTING) ws.close();\n wsRef.current = null;\n }\n\n if (scriptProcessorRef.current) {\n scriptProcessorRef.current.onaudioprocess = null;\n scriptProcessorRef.current.disconnect();\n scriptProcessorRef.current = null;\n }\n if (inputSourceRef.current) {\n inputSourceRef.current.disconnect();\n inputSourceRef.current = null;\n }\n if (inputMuteGainRef.current) {\n inputMuteGainRef.current.disconnect();\n inputMuteGainRef.current = null;\n }\n if (inputAnalyserRef.current) {\n inputAnalyserRef.current.disconnect();\n inputAnalyserRef.current = null;\n }\n if (outputAnalyserRef.current) {\n outputAnalyserRef.current.disconnect();\n outputAnalyserRef.current = null;\n }\n\n activePlaybackSourcesRef.current.forEach((source) => {\n try {\n source.stop();\n } catch {\n // already stopped\n }\n });\n activePlaybackSourcesRef.current = new Set();\n\n if (localStreamRef.current) {\n localStreamRef.current.getTracks().forEach((track) => track.stop());\n localStreamRef.current = null;\n }\n if (audioContextRef.current) {\n audioContextRef.current.close();\n audioContextRef.current = null;\n }\n\n audioAnalyzersRef.current.inputAnalyser = null;\n audioAnalyzersRef.current.outputAnalyser = null;\n audioAnalyzersRef.current.getInputByteFrequencyData = () => null;\n audioAnalyzersRef.current.getOutputByteFrequencyData = () => null;\n inputFrequencyDataRef.current = null;\n outputFrequencyDataRef.current = null;\n microphoneEnabledRef.current = false;\n playbackTimeRef.current = 0;\n pendingSessionConfigRef.current = null;\n sessionAppliedRef.current = false;\n introSentRef.current = false;\n pendingUserTranscriptRef.current = '';\n handledOpenUrlCallsRef.current = new Set();\n }, []);\n\n const stopPendingPlayback = useCallback(() => {\n activePlaybackSourcesRef.current.forEach((source) => {\n try {\n source.stop();\n } catch {\n // already stopped\n }\n });\n activePlaybackSourcesRef.current = new Set();\n if (audioContextRef.current) playbackTimeRef.current = audioContextRef.current.currentTime;\n }, []);\n\n const scheduleAudioPlayback = useCallback((audioBase64) => {\n const context = audioContextRef.current;\n const analyser = outputAnalyserRef.current;\n if (!context || !analyser) return;\n const int16 = int16FromBase64(audioBase64);\n if (!int16.length) return;\n const float32 = int16ToFloat32(int16);\n const buffer = context.createBuffer(1, float32.length, SAMPLE_RATE);\n buffer.copyToChannel(float32, 0);\n const source = context.createBufferSource();\n source.buffer = buffer;\n source.connect(analyser);\n const startAt = Math.max(context.currentTime, playbackTimeRef.current);\n source.start(startAt);\n playbackTimeRef.current = startAt + buffer.duration;\n activePlaybackSourcesRef.current.add(source);\n source.onended = () => {\n activePlaybackSourcesRef.current.delete(source);\n };\n }, []);\n\n const sendJson = useCallback((payload) => {\n const ws = wsRef.current;\n if (!ws || ws.readyState !== WebSocket.OPEN) return false;\n ws.send(JSON.stringify(payload));\n return true;\n }, []);\n\n const sendIntro = useCallback(\n ({ assistantName, locale }) => {\n if (introSentRef.current) return;\n const localeHint = locale || 'en-US';\n const text = `Respond in the language that matches the locale code \"${localeHint}\". Introduce yourself using the following sentence, translated into that language: \"Hello, I am ${assistantName}, your virtual assistant. I can help you with information about our services and facilities. What would you like to know today?\"`;\n\n sendJson({\n type: 'conversation.item.create',\n item: {\n type: 'message',\n role: 'user',\n content: [{ type: 'input_text', text }],\n },\n });\n sendJson({ type: 'response.create' });\n introSentRef.current = true;\n },\n [sendJson],\n );\n\n const handleFunctionCall = useCallback(\n (payload) => {\n const { name } = payload;\n const callId = payload.call_id;\n if (name !== 'open_url' || !callId) return;\n if (handledOpenUrlCallsRef.current.has(callId)) return;\n handledOpenUrlCallsRef.current.add(callId);\n\n let parsed = null;\n try {\n parsed = JSON.parse(payload.arguments || '{}');\n } catch {\n parsed = null;\n }\n const url = parsed?.url;\n const allowed = typeof url === 'string' && url.trim().startsWith(ALLOWED_OPEN_URL_PREFIX);\n\n if (!allowed) {\n sendJson({\n type: 'conversation.item.create',\n item: {\n type: 'function_call_output',\n call_id: callId,\n output: JSON.stringify({ error: 'blocked_url', allowed_prefix: ALLOWED_OPEN_URL_PREFIX }),\n },\n });\n sendJson({ type: 'response.create' });\n return;\n }\n\n cleanupSession();\n window.location.assign(url.trim());\n },\n [cleanupSession, sendJson],\n );\n\n const persistTranscriptPair = useCallback(async ({ fingerprint, hotelId, locale, transcript }) => {\n if (!transcript || !pendingUserTranscriptRef.current) return;\n const input = pendingUserTranscriptRef.current.trim();\n pendingUserTranscriptRef.current = '';\n const activeLocale = locale || 'en-US';\n\n if (hotelId) {\n try {\n const chatId = await ensureChatId({\n fingerprint,\n channelId: hotelId,\n session: { locale: activeLocale },\n });\n if (chatId) {\n await createChatMessage({ author: 'user', body: input, chatId, meta: { audio: true } });\n await createChatMessage({ author: 'ai', body: transcript, chatId, meta: { audio: true } });\n }\n } catch (error) {\n Event.publish(EVENT.METRICS, { id: METRICS_EVENTS.AURA_ERROR, error: error?.message });\n }\n }\n\n Event.publish(EVENT.METRICS, {\n id: 'SYNAPSE_RESPONSE',\n fingerprint,\n text: transcript,\n input,\n agent: 'aura',\n locale: activeLocale,\n });\n }, []);\n\n const startSession = useCallback(\n async ({ assistant_name, chainId, currency, hotelId, isChain, locale, setIsConnecting, setReady }) => {\n cleanupSession();\n\n const fingerprint = getClientFingerprint();\n const finalizeSession = (error) => {\n const errorMessage = typeof error === 'string' ? error : error?.message;\n if (errorMessage) {\n Event.publish(EVENT.METRICS, { id: METRICS_EVENTS.AURA_ERROR, error: errorMessage });\n }\n cleanupSession();\n setReady(false);\n setIsConnecting(false);\n };\n\n try {\n const sessionResponse = await request({\n endpoint: `/voice/session?voiceModel=xai&fingerprint=${fingerprint}&hotelId=${\n isChain ? '' : hotelId ?? ''\n }&chainId=${isChain ? chainId ?? '' : ''}&locale=${locale ?? ''}¤cy=${currency ?? ''}`,\n hostname: process.env.SERVICE_SYNAPSE,\n method: 'GET',\n });\n\n const ephemeralToken = sessionResponse?.value;\n const sessionConfig = sessionResponse?.session;\n const model = sessionResponse?.model || DEFAULT_MODEL;\n if (!ephemeralToken || !sessionConfig) throw new Error('Invalid xAI session response');\n pendingSessionConfigRef.current = sessionConfig;\n\n const AudioContextConstructor = globalThis.AudioContext || globalThis.webkitAudioContext;\n if (!AudioContextConstructor) throw new Error('AudioContext not supported');\n const audioContext = new AudioContextConstructor({ sampleRate: SAMPLE_RATE });\n audioContextRef.current = audioContext;\n if (audioContext.state === 'suspended') await audioContext.resume();\n\n const mediaStream = await navigator.mediaDevices.getUserMedia({\n audio: {\n echoCancellation: true,\n noiseSuppression: true,\n autoGainControl: true,\n channelCount: 1,\n sampleRate: SAMPLE_RATE,\n },\n });\n localStreamRef.current = mediaStream;\n\n const inputSource = audioContext.createMediaStreamSource(mediaStream);\n inputSourceRef.current = inputSource;\n\n const inputAnalyser = audioContext.createAnalyser();\n inputAnalyser.fftSize = 1024;\n inputAnalyserRef.current = inputAnalyser;\n inputSource.connect(inputAnalyser);\n\n const outputAnalyser = audioContext.createAnalyser();\n outputAnalyser.fftSize = 1024;\n outputAnalyserRef.current = outputAnalyser;\n outputAnalyser.connect(audioContext.destination);\n\n inputFrequencyDataRef.current = new Uint8Array(inputAnalyser.frequencyBinCount);\n outputFrequencyDataRef.current = new Uint8Array(outputAnalyser.frequencyBinCount);\n audioAnalyzersRef.current.inputAnalyser = inputAnalyser;\n audioAnalyzersRef.current.outputAnalyser = outputAnalyser;\n audioAnalyzersRef.current.getInputByteFrequencyData = () => {\n if (!inputAnalyserRef.current || !inputFrequencyDataRef.current) return null;\n inputAnalyserRef.current.getByteFrequencyData(inputFrequencyDataRef.current);\n return inputFrequencyDataRef.current;\n };\n audioAnalyzersRef.current.getOutputByteFrequencyData = () => {\n if (!outputAnalyserRef.current || !outputFrequencyDataRef.current) return null;\n outputAnalyserRef.current.getByteFrequencyData(outputFrequencyDataRef.current);\n return outputFrequencyDataRef.current;\n };\n\n // ScriptProcessor is deprecated but still the simplest portable way to obtain\n // raw PCM frames synchronously. It must be connected to the destination to be scheduled;\n // we route it through a muted GainNode so the mic input is never audible locally.\n const processor = audioContext.createScriptProcessor(PROCESSOR_BUFFER_SIZE, 1, 1);\n scriptProcessorRef.current = processor;\n const muteGain = audioContext.createGain();\n muteGain.gain.value = 0;\n inputMuteGainRef.current = muteGain;\n inputSource.connect(processor);\n processor.connect(muteGain);\n muteGain.connect(audioContext.destination);\n\n processor.onaudioprocess = (event) => {\n if (!microphoneEnabledRef.current) return;\n const ws = wsRef.current;\n if (!ws || ws.readyState !== WebSocket.OPEN) return;\n const channelData = event.inputBuffer.getChannelData(0);\n const int16 = float32ToInt16(channelData);\n ws.send(\n JSON.stringify({\n type: 'input_audio_buffer.append',\n audio: base64FromInt16(int16),\n }),\n );\n };\n\n const ws = new WebSocket(`${XAI_REALTIME_URL}?model=${encodeURIComponent(model)}`, [\n `xai-client-secret.${ephemeralToken}`,\n ]);\n wsRef.current = ws;\n\n ws.addEventListener('open', () => {\n Event.publish(EVENT.METRICS, { id: METRICS_EVENTS.AURA_START });\n sendJson({ type: 'session.update', session: pendingSessionConfigRef.current });\n });\n\n ws.addEventListener('error', () => finalizeSession('xAI WebSocket error'));\n ws.addEventListener('close', () => finalizeSession());\n\n ws.addEventListener('message', async (event) => {\n let payload;\n try {\n payload = JSON.parse(event.data);\n } catch {\n return;\n }\n\n switch (payload.type) {\n case 'session.created':\n case 'session.updated': {\n if (sessionAppliedRef.current) break;\n sessionAppliedRef.current = true;\n setReady(true);\n sendIntro({ assistantName: assistant_name, locale });\n break;\n }\n case 'response.output_audio.delta': {\n const audio = extractAudioDelta(payload);\n if (audio) scheduleAudioPlayback(audio);\n break;\n }\n case 'input_audio_buffer.speech_started': {\n // Barge-in: cut current playback so the user can take over the turn cleanly.\n stopPendingPlayback();\n break;\n }\n case 'response.function_call_arguments.done': {\n handleFunctionCall(payload);\n break;\n }\n case 'response.done': {\n // Open the microphone once the intro response finishes; subsequent turns use server VAD.\n if (!microphoneEnabledRef.current) microphoneEnabledRef.current = true;\n break;\n }\n case 'conversation.item.input_audio_transcription.completed': {\n const transcript = payload.transcript?.trim();\n if (transcript) pendingUserTranscriptRef.current += transcript;\n break;\n }\n case 'response.output_audio_transcript.done':\n case 'response.text.done': {\n const transcript = (payload.transcript || payload.text)?.trim();\n await persistTranscriptPair({ fingerprint, hotelId, locale, transcript });\n break;\n }\n default:\n break;\n }\n });\n } catch (error) {\n Event.publish(EVENT.METRICS, { id: METRICS_EVENTS.AURA_ERROR, error: error?.message });\n setReady(false);\n throw error;\n } finally {\n setIsConnecting(false);\n }\n },\n [\n cleanupSession,\n handleFunctionCall,\n persistTranscriptPair,\n scheduleAudioPlayback,\n sendIntro,\n sendJson,\n stopPendingPlayback,\n ],\n );\n\n const endSession = useCallback(() => {\n cleanupSession();\n }, [cleanupSession]);\n\n return { startSession, endSession, audioAnalyzers: audioAnalyzersRef.current };\n};\n\nexport { useXaiRealtimeSession };\n"],"mappings":"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","ignoreList":[]}
|