@webex/internal-plugin-voicea 3.11.0 → 3.12.0-llmrefactor.2
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/dist/index.js +13 -4
- package/dist/index.js.map +1 -1
- package/dist/types/index.d.ts +4 -1
- package/dist/types/voicea-plugin.d.ts +23 -0
- package/dist/types/voicea.d.ts +74 -19
- package/dist/types/voicea.types.d.ts +1 -0
- package/dist/voicea-plugin.js +59 -0
- package/dist/voicea-plugin.js.map +1 -0
- package/dist/voicea.js +259 -133
- package/dist/voicea.js.map +1 -1
- package/dist/voicea.types.js.map +1 -1
- package/package.json +9 -9
- package/src/index.ts +5 -3
- package/src/voicea-plugin.ts +33 -0
- package/src/voicea.ts +241 -137
- package/src/voicea.types.ts +1 -0
- package/test/unit/spec/voicea-plugin.js +71 -0
- package/test/unit/spec/voicea.js +649 -842
package/dist/voicea.js
CHANGED
|
@@ -20,6 +20,7 @@ var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime
|
|
|
20
20
|
var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/getPrototypeOf"));
|
|
21
21
|
var _inherits2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/inherits"));
|
|
22
22
|
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/defineProperty"));
|
|
23
|
+
var _events = _interopRequireDefault(require("events"));
|
|
23
24
|
var _uuid = _interopRequireDefault(require("uuid"));
|
|
24
25
|
var _webexCore = require("@webex/webex-core");
|
|
25
26
|
var _constants = require("./constants");
|
|
@@ -27,38 +28,42 @@ var _utils = require("./utils");
|
|
|
27
28
|
function ownKeys(e, r) { var t = _Object$keys(e); if (_Object$getOwnPropertySymbols) { var o = _Object$getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return _Object$getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
28
29
|
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { (0, _defineProperty2.default)(e, r, t[r]); }) : _Object$getOwnPropertyDescriptors ? _Object$defineProperties(e, _Object$getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { _Object$defineProperty(e, r, _Object$getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
29
30
|
function _callSuper(t, o, e) { return o = (0, _getPrototypeOf2.default)(o), (0, _possibleConstructorReturn2.default)(t, _isNativeReflectConstruct() ? _Reflect$construct(o, e || [], (0, _getPrototypeOf2.default)(t).constructor) : o.apply(t, e)); }
|
|
30
|
-
function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.call(_Reflect$construct(Boolean, [], function () {})); } catch (t) {} return (_isNativeReflectConstruct = function _isNativeReflectConstruct() { return !!t; })(); } //
|
|
31
|
+
function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.call(_Reflect$construct(Boolean, [], function () {})); } catch (t) {} return (_isNativeReflectConstruct = function _isNativeReflectConstruct() { return !!t; })(); } // @ts-ignore - webex-core types
|
|
32
|
+
// @ts-ignore - internal-plugin-llm types
|
|
31
33
|
/**
|
|
32
|
-
* @description VoiceaChannel
|
|
34
|
+
* @description VoiceaChannel — handles voicea/transcription functionality for a single LLM connection.
|
|
35
|
+
* Created via `webex.internal.voicea.createChannel(llmChannel)`. The caller owns the
|
|
36
|
+
* channel and is responsible for its lifecycle.
|
|
33
37
|
* @export
|
|
34
38
|
* @class VoiceaChannel
|
|
35
39
|
*/
|
|
36
|
-
var VoiceaChannel = exports.VoiceaChannel = /*#__PURE__*/function (
|
|
40
|
+
var VoiceaChannel = exports.VoiceaChannel = /*#__PURE__*/function (_EventEmitter) {
|
|
37
41
|
/**
|
|
38
|
-
*
|
|
39
|
-
* @param {
|
|
42
|
+
* Creates a VoiceaChannel bound to the given LLMChannel
|
|
43
|
+
* @param {LLMChannel} llmChannel - The LLM channel to use
|
|
44
|
+
* @param {Function} request - The request function for making API calls (typically webex.request bound to webex)
|
|
40
45
|
*/
|
|
41
|
-
function VoiceaChannel() {
|
|
46
|
+
function VoiceaChannel(llmChannel, request) {
|
|
42
47
|
var _this;
|
|
43
48
|
(0, _classCallCheck2.default)(this, VoiceaChannel);
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
_this = _callSuper(this, VoiceaChannel, [].concat(args));
|
|
48
|
-
(0, _defineProperty2.default)(_this, "namespace", _constants.VOICEA);
|
|
49
|
+
_this = _callSuper(this, VoiceaChannel);
|
|
50
|
+
(0, _defineProperty2.default)(_this, "request", void 0);
|
|
51
|
+
(0, _defineProperty2.default)(_this, "llmChannel", void 0);
|
|
49
52
|
(0, _defineProperty2.default)(_this, "seqNum", void 0);
|
|
50
53
|
(0, _defineProperty2.default)(_this, "areCaptionsEnabled", void 0);
|
|
51
54
|
(0, _defineProperty2.default)(_this, "hasSubscribedToEvents", false);
|
|
52
55
|
(0, _defineProperty2.default)(_this, "captionServiceId", void 0);
|
|
53
56
|
(0, _defineProperty2.default)(_this, "announceStatus", void 0);
|
|
54
57
|
(0, _defineProperty2.default)(_this, "captionStatus", void 0);
|
|
58
|
+
(0, _defineProperty2.default)(_this, "keepTranscriptionSubscribed", void 0);
|
|
55
59
|
(0, _defineProperty2.default)(_this, "toggleManualCaptionStatus", void 0);
|
|
56
60
|
(0, _defineProperty2.default)(_this, "currentSpokenLanguage", void 0);
|
|
57
61
|
(0, _defineProperty2.default)(_this, "spokenLanguages", []);
|
|
58
62
|
(0, _defineProperty2.default)(_this, "currentCaptionLanguage", void 0);
|
|
59
63
|
/**
|
|
60
|
-
*
|
|
61
|
-
* @
|
|
64
|
+
* Process events from LLM channel
|
|
65
|
+
* @param {Object} e - Event data
|
|
66
|
+
* @returns {void}
|
|
62
67
|
*/
|
|
63
68
|
(0, _defineProperty2.default)(_this, "eventProcessor", function (e) {
|
|
64
69
|
var _e$headers;
|
|
@@ -93,8 +98,7 @@ var VoiceaChannel = exports.VoiceaChannel = /*#__PURE__*/function (_WebexPlugin)
|
|
|
93
98
|
*/
|
|
94
99
|
(0, _defineProperty2.default)(_this, "processManualTranscription", function (transcriptPayload) {
|
|
95
100
|
if (transcriptPayload.type === _constants.TRANSCRIPTION_TYPE.MANUAL_CAPTION_FINAL_RESULT || transcriptPayload.type === _constants.TRANSCRIPTION_TYPE.MANUAL_CAPTION_INTERIM_RESULT) {
|
|
96
|
-
|
|
97
|
-
_this.trigger(_constants.EVENT_TRIGGERS.NEW_MANUAL_CAPTION, {
|
|
101
|
+
_this.emit(_constants.EVENT_TRIGGERS.NEW_MANUAL_CAPTION, {
|
|
98
102
|
isFinal: transcriptPayload.type === _constants.TRANSCRIPTION_TYPE.MANUAL_CAPTION_FINAL_RESULT,
|
|
99
103
|
transcriptId: transcriptPayload.id,
|
|
100
104
|
transcripts: transcriptPayload.transcripts,
|
|
@@ -109,48 +113,44 @@ var VoiceaChannel = exports.VoiceaChannel = /*#__PURE__*/function (_WebexPlugin)
|
|
|
109
113
|
* @returns {void}
|
|
110
114
|
*/
|
|
111
115
|
(0, _defineProperty2.default)(_this, "processTranscription", function (voiceaPayload) {
|
|
116
|
+
var _voiceaPayload$transc, _voiceaPayload$highli, _voiceaPayload$highli2, _voiceaPayload$highli3, _voiceaPayload$highli4, _voiceaPayload$highli5, _voiceaPayload$highli6, _voiceaPayload$highli7;
|
|
112
117
|
switch (voiceaPayload.type) {
|
|
113
118
|
case _constants.TRANSCRIPTION_TYPE.TRANSCRIPT_INTERIM_RESULTS:
|
|
114
|
-
|
|
115
|
-
_this.trigger(_constants.EVENT_TRIGGERS.NEW_CAPTION, {
|
|
119
|
+
_this.emit(_constants.EVENT_TRIGGERS.NEW_CAPTION, {
|
|
116
120
|
isFinal: false,
|
|
117
121
|
transcriptId: voiceaPayload.transcript_id,
|
|
118
122
|
transcripts: voiceaPayload.transcripts
|
|
119
123
|
});
|
|
120
124
|
break;
|
|
121
125
|
case _constants.TRANSCRIPTION_TYPE.TRANSCRIPT_FINAL_RESULT:
|
|
122
|
-
|
|
123
|
-
_this.trigger(_constants.EVENT_TRIGGERS.NEW_CAPTION, {
|
|
126
|
+
_this.emit(_constants.EVENT_TRIGGERS.NEW_CAPTION, {
|
|
124
127
|
isFinal: true,
|
|
125
128
|
transcriptId: voiceaPayload.transcript_id,
|
|
126
|
-
transcripts: voiceaPayload.transcripts.map(function (transcript) {
|
|
129
|
+
transcripts: (_voiceaPayload$transc = voiceaPayload.transcripts) === null || _voiceaPayload$transc === void 0 ? void 0 : _voiceaPayload$transc.map(function (transcript) {
|
|
127
130
|
transcript.timestamp = (0, _utils.millisToMinutesAndSeconds)(transcript.end_millis);
|
|
128
131
|
return transcript;
|
|
129
132
|
})
|
|
130
133
|
});
|
|
131
134
|
break;
|
|
132
135
|
case _constants.TRANSCRIPTION_TYPE.HIGHLIGHT_CREATED:
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
timestamp: (0, _utils.millisToMinutesAndSeconds)(voiceaPayload.highlight.end_millis)
|
|
136
|
+
_this.emit(_constants.EVENT_TRIGGERS.HIGHLIGHT_CREATED, {
|
|
137
|
+
csis: (_voiceaPayload$highli = voiceaPayload.highlight) === null || _voiceaPayload$highli === void 0 ? void 0 : _voiceaPayload$highli.csis,
|
|
138
|
+
highlightId: (_voiceaPayload$highli2 = voiceaPayload.highlight) === null || _voiceaPayload$highli2 === void 0 ? void 0 : _voiceaPayload$highli2.highlight_id,
|
|
139
|
+
text: (_voiceaPayload$highli3 = voiceaPayload.highlight) === null || _voiceaPayload$highli3 === void 0 ? void 0 : _voiceaPayload$highli3.transcript,
|
|
140
|
+
highlightLabel: (_voiceaPayload$highli4 = voiceaPayload.highlight) === null || _voiceaPayload$highli4 === void 0 ? void 0 : _voiceaPayload$highli4.highlight_label,
|
|
141
|
+
highlightSource: (_voiceaPayload$highli5 = voiceaPayload.highlight) === null || _voiceaPayload$highli5 === void 0 ? void 0 : _voiceaPayload$highli5.highlight_source,
|
|
142
|
+
timestamp: (0, _utils.millisToMinutesAndSeconds)((_voiceaPayload$highli6 = (_voiceaPayload$highli7 = voiceaPayload.highlight) === null || _voiceaPayload$highli7 === void 0 ? void 0 : _voiceaPayload$highli7.end_millis) !== null && _voiceaPayload$highli6 !== void 0 ? _voiceaPayload$highli6 : 0)
|
|
141
143
|
});
|
|
142
144
|
break;
|
|
143
145
|
case _constants.TRANSCRIPTION_TYPE.EVA_THANKS:
|
|
144
|
-
|
|
145
|
-
_this.trigger(_constants.EVENT_TRIGGERS.EVA_COMMAND, {
|
|
146
|
+
_this.emit(_constants.EVENT_TRIGGERS.EVA_COMMAND, {
|
|
146
147
|
isListening: false,
|
|
147
148
|
text: voiceaPayload.command_response
|
|
148
149
|
});
|
|
149
150
|
break;
|
|
150
151
|
case _constants.TRANSCRIPTION_TYPE.EVA_WAKE:
|
|
151
152
|
case _constants.TRANSCRIPTION_TYPE.EVA_CANCEL:
|
|
152
|
-
|
|
153
|
-
_this.trigger(_constants.EVENT_TRIGGERS.EVA_COMMAND, {
|
|
153
|
+
_this.emit(_constants.EVENT_TRIGGERS.EVA_COMMAND, {
|
|
154
154
|
isListening: voiceaPayload.type === _constants.TRANSCRIPTION_TYPE.EVA_WAKE
|
|
155
155
|
});
|
|
156
156
|
break;
|
|
@@ -158,8 +158,7 @@ var VoiceaChannel = exports.VoiceaChannel = /*#__PURE__*/function (_WebexPlugin)
|
|
|
158
158
|
{
|
|
159
159
|
var isInSpokenLanguages = _this.spokenLanguages.includes(voiceaPayload.language);
|
|
160
160
|
if (isInSpokenLanguages) {
|
|
161
|
-
|
|
162
|
-
_this.trigger(_constants.EVENT_TRIGGERS.LANGUAGE_DETECTED, {
|
|
161
|
+
_this.emit(_constants.EVENT_TRIGGERS.LANGUAGE_DETECTED, {
|
|
163
162
|
languageCode: voiceaPayload.language
|
|
164
163
|
});
|
|
165
164
|
}
|
|
@@ -176,13 +175,11 @@ var VoiceaChannel = exports.VoiceaChannel = /*#__PURE__*/function (_WebexPlugin)
|
|
|
176
175
|
*/
|
|
177
176
|
(0, _defineProperty2.default)(_this, "processCaptionLanguageResponse", function (voiceaPayload) {
|
|
178
177
|
if (voiceaPayload.statusCode === 200) {
|
|
179
|
-
|
|
180
|
-
_this.trigger(_constants.EVENT_TRIGGERS.CAPTION_LANGUAGE_UPDATE, {
|
|
178
|
+
_this.emit(_constants.EVENT_TRIGGERS.CAPTION_LANGUAGE_UPDATE, {
|
|
181
179
|
statusCode: 200
|
|
182
180
|
});
|
|
183
181
|
} else {
|
|
184
|
-
|
|
185
|
-
_this.trigger(_constants.EVENT_TRIGGERS.CAPTION_LANGUAGE_UPDATE, {
|
|
182
|
+
_this.emit(_constants.EVENT_TRIGGERS.CAPTION_LANGUAGE_UPDATE, {
|
|
186
183
|
statusCode: voiceaPayload.errorCode,
|
|
187
184
|
errorMessage: voiceaPayload.message
|
|
188
185
|
});
|
|
@@ -202,8 +199,17 @@ var VoiceaChannel = exports.VoiceaChannel = /*#__PURE__*/function (_WebexPlugin)
|
|
|
202
199
|
currentSpokenLanguage: _this.currentSpokenLanguage
|
|
203
200
|
};
|
|
204
201
|
_this.spokenLanguages = (_voiceaPayload$ASR$sp2 = voiceaPayload === null || voiceaPayload === void 0 ? void 0 : (_voiceaPayload$ASR2 = voiceaPayload.ASR) === null || _voiceaPayload$ASR2 === void 0 ? void 0 : _voiceaPayload$ASR2.spoken_languages) !== null && _voiceaPayload$ASR$sp2 !== void 0 ? _voiceaPayload$ASR$sp2 : [];
|
|
205
|
-
|
|
206
|
-
|
|
202
|
+
_this.emit(_constants.EVENT_TRIGGERS.VOICEA_ANNOUNCEMENT, voiceaLanguageOptions);
|
|
203
|
+
});
|
|
204
|
+
/**
|
|
205
|
+
* Indicates whether the LLM channel is connected.
|
|
206
|
+
* @returns {boolean}
|
|
207
|
+
*/
|
|
208
|
+
(0, _defineProperty2.default)(_this, "isLLMConnected", function () {
|
|
209
|
+
return _this.llmChannel.isConnected();
|
|
210
|
+
});
|
|
211
|
+
(0, _defineProperty2.default)(_this, "getKeepTranscriptionSubscribed", function () {
|
|
212
|
+
return _this.keepTranscriptionSubscribed;
|
|
207
213
|
});
|
|
208
214
|
/**
|
|
209
215
|
* Sends Announcement to add voicea to the meeting
|
|
@@ -211,15 +217,14 @@ var VoiceaChannel = exports.VoiceaChannel = /*#__PURE__*/function (_WebexPlugin)
|
|
|
211
217
|
*/
|
|
212
218
|
(0, _defineProperty2.default)(_this, "sendAnnouncement", function () {
|
|
213
219
|
_this.announceStatus = _constants.ANNOUNCE_STATUS.JOINING;
|
|
214
|
-
_this.
|
|
215
|
-
|
|
216
|
-
|
|
220
|
+
var socket = _this.llmChannel.getSocket();
|
|
221
|
+
var binding = _this.llmChannel.getBinding();
|
|
222
|
+
var payload = {
|
|
217
223
|
id: "".concat(_this.seqNum),
|
|
218
224
|
type: 'publishRequest',
|
|
219
|
-
recipients: {
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
},
|
|
225
|
+
recipients: [{
|
|
226
|
+
route: binding
|
|
227
|
+
}],
|
|
223
228
|
// If captionServiceId exists, send it as the 'to' header; otherwise keep headers empty.
|
|
224
229
|
headers: _this.captionServiceId ? {
|
|
225
230
|
to: _this.captionServiceId
|
|
@@ -232,7 +237,8 @@ var VoiceaChannel = exports.VoiceaChannel = /*#__PURE__*/function (_WebexPlugin)
|
|
|
232
237
|
relayType: _constants.AIBRIDGE_RELAY_TYPES.VOICEA.CLIENT_ANNOUNCEMENT
|
|
233
238
|
},
|
|
234
239
|
trackingId: "".concat(_webexCore.config.trackingIdPrefix, "_").concat(_uuid.default.v4().toString())
|
|
235
|
-
}
|
|
240
|
+
};
|
|
241
|
+
socket.send(payload);
|
|
236
242
|
_this.seqNum += 1;
|
|
237
243
|
});
|
|
238
244
|
/**
|
|
@@ -242,26 +248,21 @@ var VoiceaChannel = exports.VoiceaChannel = /*#__PURE__*/function (_WebexPlugin)
|
|
|
242
248
|
* @returns {Promise}
|
|
243
249
|
*/
|
|
244
250
|
(0, _defineProperty2.default)(_this, "setSpokenLanguage", function (languageCode, languageAssignment) {
|
|
245
|
-
return (
|
|
246
|
-
|
|
247
|
-
_this.
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
})
|
|
259
|
-
|
|
260
|
-
_this.trigger(_constants.EVENT_TRIGGERS.SPOKEN_LANGUAGE_UPDATE, {
|
|
261
|
-
languageCode: languageCode
|
|
262
|
-
});
|
|
263
|
-
})
|
|
264
|
-
);
|
|
251
|
+
return _this.request({
|
|
252
|
+
method: 'PUT',
|
|
253
|
+
url: "".concat(_this.llmChannel.getLocusUrl(), "/controls/"),
|
|
254
|
+
body: {
|
|
255
|
+
transcribe: _objectSpread({
|
|
256
|
+
spokenLanguage: languageCode
|
|
257
|
+
}, languageAssignment && {
|
|
258
|
+
languageAssignment: languageAssignment
|
|
259
|
+
})
|
|
260
|
+
}
|
|
261
|
+
}).then(function () {
|
|
262
|
+
_this.emit(_constants.EVENT_TRIGGERS.SPOKEN_LANGUAGE_UPDATE, {
|
|
263
|
+
languageCode: languageCode
|
|
264
|
+
});
|
|
265
|
+
});
|
|
265
266
|
});
|
|
266
267
|
/**
|
|
267
268
|
* Request Language translation
|
|
@@ -269,16 +270,17 @@ var VoiceaChannel = exports.VoiceaChannel = /*#__PURE__*/function (_WebexPlugin)
|
|
|
269
270
|
* @returns {void}
|
|
270
271
|
*/
|
|
271
272
|
(0, _defineProperty2.default)(_this, "requestLanguage", function (languageCode) {
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
_this.
|
|
273
|
+
if (!_this.isLLMConnected()) {
|
|
274
|
+
return;
|
|
275
|
+
}
|
|
276
|
+
var socket = _this.llmChannel.getSocket();
|
|
277
|
+
var binding = _this.llmChannel.getBinding();
|
|
278
|
+
socket.send({
|
|
276
279
|
id: "".concat(_this.seqNum),
|
|
277
280
|
type: 'publishRequest',
|
|
278
|
-
recipients: {
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
},
|
|
281
|
+
recipients: [{
|
|
282
|
+
route: binding
|
|
283
|
+
}],
|
|
282
284
|
headers: {
|
|
283
285
|
to: _this.captionServiceId
|
|
284
286
|
},
|
|
@@ -304,17 +306,17 @@ var VoiceaChannel = exports.VoiceaChannel = /*#__PURE__*/function (_WebexPlugin)
|
|
|
304
306
|
* @returns {void}
|
|
305
307
|
*/
|
|
306
308
|
(0, _defineProperty2.default)(_this, "sendManualClosedCaption", function (text, timeStamp, csis, isFinal) {
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
_this.
|
|
309
|
+
if (!_this.isLLMConnected()) {
|
|
310
|
+
return;
|
|
311
|
+
}
|
|
312
|
+
var socket = _this.llmChannel.getSocket();
|
|
313
|
+
var binding = _this.llmChannel.getBinding();
|
|
314
|
+
socket === null || socket === void 0 ? void 0 : socket.send({
|
|
312
315
|
id: "".concat(_this.seqNum),
|
|
313
316
|
type: 'publishRequest',
|
|
314
|
-
recipients: {
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
},
|
|
317
|
+
recipients: [{
|
|
318
|
+
route: binding
|
|
319
|
+
}],
|
|
318
320
|
headers: {},
|
|
319
321
|
data: {
|
|
320
322
|
eventType: 'relay.event',
|
|
@@ -337,34 +339,31 @@ var VoiceaChannel = exports.VoiceaChannel = /*#__PURE__*/function (_WebexPlugin)
|
|
|
337
339
|
});
|
|
338
340
|
/**
|
|
339
341
|
* request turn on Captions
|
|
340
|
-
* @param {string} [languageCode] - Optional Parameter for spoken language code
|
|
342
|
+
* @param {string} [languageCode] - Optional Parameter for spoken language code
|
|
341
343
|
* @returns {Promise}
|
|
342
344
|
*/
|
|
343
345
|
(0, _defineProperty2.default)(_this, "requestTurnOnCaptions", function (languageCode) {
|
|
344
346
|
_this.captionStatus = _constants.TURN_ON_CAPTION_STATUS.SENDING;
|
|
345
|
-
|
|
346
|
-
// only set the spoken language if it is provided
|
|
347
|
+
var locusUrl = _this.llmChannel.getLocusUrl();
|
|
347
348
|
var body = {
|
|
348
349
|
transcribe: {
|
|
349
350
|
caption: true
|
|
350
351
|
},
|
|
351
352
|
languageCode: languageCode
|
|
352
353
|
};
|
|
353
|
-
|
|
354
|
-
// @ts-ignore
|
|
355
|
-
// eslint-disable-next-line newline-before-return
|
|
356
354
|
return _this.request({
|
|
357
355
|
method: 'PUT',
|
|
358
|
-
|
|
359
|
-
url: "".concat(_this.webex.internal.llm.getLocusUrl(), "/controls/"),
|
|
356
|
+
url: "".concat(locusUrl, "/controls/"),
|
|
360
357
|
body: body
|
|
361
358
|
}).then(function () {
|
|
362
|
-
|
|
363
|
-
_this.trigger(_constants.EVENT_TRIGGERS.CAPTIONS_TURNED_ON);
|
|
359
|
+
_this.emit(_constants.EVENT_TRIGGERS.CAPTIONS_TURNED_ON);
|
|
364
360
|
_this.areCaptionsEnabled = true;
|
|
365
361
|
_this.captionStatus = _constants.TURN_ON_CAPTION_STATUS.ENABLED;
|
|
366
362
|
_this.announce();
|
|
367
|
-
|
|
363
|
+
_this.updateSubchannelSubscriptionsAndSyncCaptionState({
|
|
364
|
+
subscribe: ['transcription']
|
|
365
|
+
}, true);
|
|
366
|
+
}).catch(function (error) {
|
|
368
367
|
_this.captionStatus = _constants.TURN_ON_CAPTION_STATUS.IDLE;
|
|
369
368
|
throw new Error('turn on captions fail');
|
|
370
369
|
});
|
|
@@ -377,13 +376,21 @@ var VoiceaChannel = exports.VoiceaChannel = /*#__PURE__*/function (_WebexPlugin)
|
|
|
377
376
|
return [_constants.ANNOUNCE_STATUS.JOINING, _constants.ANNOUNCE_STATUS.JOINED].includes(_this.announceStatus);
|
|
378
377
|
});
|
|
379
378
|
/**
|
|
380
|
-
* announce
|
|
379
|
+
* is announce processed
|
|
380
|
+
* @returns {boolean}
|
|
381
|
+
*/
|
|
382
|
+
(0, _defineProperty2.default)(_this, "isAnnounceProcessed", function () {
|
|
383
|
+
return _this.announceStatus === _constants.ANNOUNCE_STATUS.JOINED;
|
|
384
|
+
});
|
|
385
|
+
/**
|
|
386
|
+
* announce to voicea data channel
|
|
381
387
|
* @returns {void}
|
|
382
388
|
*/
|
|
383
389
|
(0, _defineProperty2.default)(_this, "announce", function () {
|
|
384
|
-
if (_this.
|
|
385
|
-
|
|
386
|
-
|
|
390
|
+
if (_this.isAnnounceProcessed()) {
|
|
391
|
+
return;
|
|
392
|
+
}
|
|
393
|
+
if (!_this.isLLMConnected()) {
|
|
387
394
|
throw new Error('voicea can not announce before llm connected');
|
|
388
395
|
}
|
|
389
396
|
_this.sendAnnouncement();
|
|
@@ -411,7 +418,7 @@ var VoiceaChannel = exports.VoiceaChannel = /*#__PURE__*/function (_WebexPlugin)
|
|
|
411
418
|
}
|
|
412
419
|
return _context.abrupt("return", undefined);
|
|
413
420
|
case 1:
|
|
414
|
-
if (_this.
|
|
421
|
+
if (_this.isLLMConnected()) {
|
|
415
422
|
_context.next = 2;
|
|
416
423
|
break;
|
|
417
424
|
}
|
|
@@ -435,11 +442,9 @@ var VoiceaChannel = exports.VoiceaChannel = /*#__PURE__*/function (_WebexPlugin)
|
|
|
435
442
|
* @returns {Promise}
|
|
436
443
|
*/
|
|
437
444
|
(0, _defineProperty2.default)(_this, "toggleTranscribing", function (activate, spokenLanguage) {
|
|
438
|
-
// @ts-ignore
|
|
439
445
|
return _this.request({
|
|
440
446
|
method: 'PUT',
|
|
441
|
-
|
|
442
|
-
url: "".concat(_this.webex.internal.llm.getLocusUrl(), "/controls/"),
|
|
447
|
+
url: "".concat(_this.llmChannel.getLocusUrl(), "/controls/"),
|
|
443
448
|
body: {
|
|
444
449
|
transcribe: {
|
|
445
450
|
transcribing: activate
|
|
@@ -461,12 +466,9 @@ var VoiceaChannel = exports.VoiceaChannel = /*#__PURE__*/function (_WebexPlugin)
|
|
|
461
466
|
(0, _defineProperty2.default)(_this, "toggleManualCaption", function (enable) {
|
|
462
467
|
if (_this.toggleManualCaptionStatus === _constants.TOGGLE_MANUAL_CAPTION_STATUS.SENDING) return undefined;
|
|
463
468
|
_this.toggleManualCaptionStatus = _constants.TOGGLE_MANUAL_CAPTION_STATUS.SENDING;
|
|
464
|
-
|
|
465
|
-
// @ts-ignore
|
|
466
469
|
return _this.request({
|
|
467
470
|
method: 'PUT',
|
|
468
|
-
|
|
469
|
-
url: "".concat(_this.webex.internal.llm.getLocusUrl(), "/controls/"),
|
|
471
|
+
url: "".concat(_this.llmChannel.getLocusUrl(), "/controls/"),
|
|
470
472
|
body: {
|
|
471
473
|
manualCaption: {
|
|
472
474
|
enable: enable
|
|
@@ -487,8 +489,7 @@ var VoiceaChannel = exports.VoiceaChannel = /*#__PURE__*/function (_WebexPlugin)
|
|
|
487
489
|
* @returns {void}
|
|
488
490
|
*/
|
|
489
491
|
(0, _defineProperty2.default)(_this, "onSpokenLanguageUpdate", function (languageCode, meetingId) {
|
|
490
|
-
|
|
491
|
-
_this.trigger(_constants.EVENT_TRIGGERS.SPOKEN_LANGUAGE_UPDATE, {
|
|
492
|
+
_this.emit(_constants.EVENT_TRIGGERS.SPOKEN_LANGUAGE_UPDATE, {
|
|
492
493
|
languageCode: languageCode,
|
|
493
494
|
meetingId: meetingId
|
|
494
495
|
});
|
|
@@ -505,7 +506,6 @@ var VoiceaChannel = exports.VoiceaChannel = /*#__PURE__*/function (_WebexPlugin)
|
|
|
505
506
|
}
|
|
506
507
|
if (_this.captionServiceId !== serviceId) {
|
|
507
508
|
_this.captionServiceId = serviceId;
|
|
508
|
-
// if service id value has changed and the translation language has been set, client needs to resend the translator language message to the LLM.
|
|
509
509
|
if (_this.currentCaptionLanguage) {
|
|
510
510
|
_this.requestLanguage(_this.currentCaptionLanguage);
|
|
511
511
|
}
|
|
@@ -525,6 +525,82 @@ var VoiceaChannel = exports.VoiceaChannel = /*#__PURE__*/function (_WebexPlugin)
|
|
|
525
525
|
(0, _defineProperty2.default)(_this, "getAnnounceStatus", function () {
|
|
526
526
|
return _this.announceStatus;
|
|
527
527
|
});
|
|
528
|
+
/**
|
|
529
|
+
* update LLM sub‑channel subscriptions.
|
|
530
|
+
*
|
|
531
|
+
* @param {string[]} options.subscribe Sub‑channels to subscribe to.
|
|
532
|
+
* @param {string[]} options.unsubscribe Sub‑channels to unsubscribe from.
|
|
533
|
+
* @returns {Promise}
|
|
534
|
+
*/
|
|
535
|
+
(0, _defineProperty2.default)(_this, "updateSubchannelSubscriptions", /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee2() {
|
|
536
|
+
var _ref3,
|
|
537
|
+
_ref3$subscribe,
|
|
538
|
+
subscribe,
|
|
539
|
+
_ref3$unsubscribe,
|
|
540
|
+
unsubscribe,
|
|
541
|
+
isDataChannelTokenEnabled,
|
|
542
|
+
socket,
|
|
543
|
+
datachannelUrl,
|
|
544
|
+
_args2 = arguments;
|
|
545
|
+
return _regenerator.default.wrap(function (_context2) {
|
|
546
|
+
while (1) switch (_context2.prev = _context2.next) {
|
|
547
|
+
case 0:
|
|
548
|
+
_ref3 = _args2.length > 0 && _args2[0] !== undefined ? _args2[0] : {}, _ref3$subscribe = _ref3.subscribe, subscribe = _ref3$subscribe === void 0 ? [] : _ref3$subscribe, _ref3$unsubscribe = _ref3.unsubscribe, unsubscribe = _ref3$unsubscribe === void 0 ? [] : _ref3$unsubscribe;
|
|
549
|
+
if (_this.isLLMConnected()) {
|
|
550
|
+
_context2.next = 1;
|
|
551
|
+
break;
|
|
552
|
+
}
|
|
553
|
+
return _context2.abrupt("return");
|
|
554
|
+
case 1:
|
|
555
|
+
_context2.next = 2;
|
|
556
|
+
return _this.llmChannel.isDataChannelTokenEnabled();
|
|
557
|
+
case 2:
|
|
558
|
+
isDataChannelTokenEnabled = _context2.sent;
|
|
559
|
+
if (isDataChannelTokenEnabled) {
|
|
560
|
+
_context2.next = 3;
|
|
561
|
+
break;
|
|
562
|
+
}
|
|
563
|
+
return _context2.abrupt("return");
|
|
564
|
+
case 3:
|
|
565
|
+
socket = _this.llmChannel.getSocket();
|
|
566
|
+
datachannelUrl = _this.llmChannel.getDatachannelUrl();
|
|
567
|
+
socket.send({
|
|
568
|
+
id: "".concat(_this.seqNum),
|
|
569
|
+
type: 'subchannelSubscriptionRequest',
|
|
570
|
+
data: {
|
|
571
|
+
datachannelUri: datachannelUrl,
|
|
572
|
+
subscribe: subscribe,
|
|
573
|
+
unsubscribe: unsubscribe
|
|
574
|
+
},
|
|
575
|
+
trackingId: "".concat(_webexCore.config.trackingIdPrefix, "_").concat(_uuid.default.v4().toString())
|
|
576
|
+
});
|
|
577
|
+
_this.seqNum += 1;
|
|
578
|
+
case 4:
|
|
579
|
+
case "end":
|
|
580
|
+
return _context2.stop();
|
|
581
|
+
}
|
|
582
|
+
}, _callee2);
|
|
583
|
+
})));
|
|
584
|
+
/**
|
|
585
|
+
* Updates transcription subchannel subscriptions and records whether the
|
|
586
|
+
* transcription subscription should be kept (and restored on reconnect).
|
|
587
|
+
*
|
|
588
|
+
* @param {Object} [options] - Subscription options.
|
|
589
|
+
* @param {string[]} [options.subscribe] - Subchannels to subscribe to.
|
|
590
|
+
* @param {string[]} [options.unsubscribe] - Subchannels to unsubscribe from.
|
|
591
|
+
* @param {boolean} [keepSubscribed=false] - Whether the transcription
|
|
592
|
+
* subscription should be kept and restored on reconnect.
|
|
593
|
+
*
|
|
594
|
+
* @returns {Promise<void>}
|
|
595
|
+
*/
|
|
596
|
+
(0, _defineProperty2.default)(_this, "updateSubchannelSubscriptionsAndSyncCaptionState", function () {
|
|
597
|
+
var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
598
|
+
var keepSubscribed = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
|
|
599
|
+
_this.keepTranscriptionSubscribed = keepSubscribed;
|
|
600
|
+
return _this.updateSubchannelSubscriptions(options);
|
|
601
|
+
});
|
|
602
|
+
_this.llmChannel = llmChannel;
|
|
603
|
+
_this.request = request;
|
|
528
604
|
_this.seqNum = 1;
|
|
529
605
|
_this.areCaptionsEnabled = false;
|
|
530
606
|
_this.captionServiceId = undefined;
|
|
@@ -533,43 +609,93 @@ var VoiceaChannel = exports.VoiceaChannel = /*#__PURE__*/function (_WebexPlugin)
|
|
|
533
609
|
_this.toggleManualCaptionStatus = _constants.TOGGLE_MANUAL_CAPTION_STATUS.IDLE;
|
|
534
610
|
_this.currentSpokenLanguage = _constants.DEFAULT_SPOKEN_LANGUAGE;
|
|
535
611
|
_this.currentCaptionLanguage = undefined;
|
|
612
|
+
_this.keepTranscriptionSubscribed = false;
|
|
613
|
+
|
|
614
|
+
// Subscribe to relay events from the LLM channel
|
|
615
|
+
_this.llmChannel.on('event:relay.event', _this.eventProcessor);
|
|
616
|
+
_this.hasSubscribedToEvents = true;
|
|
536
617
|
return _this;
|
|
537
618
|
}
|
|
538
|
-
(0, _inherits2.default)(VoiceaChannel,
|
|
619
|
+
(0, _inherits2.default)(VoiceaChannel, _EventEmitter);
|
|
539
620
|
return (0, _createClass2.default)(VoiceaChannel, [{
|
|
540
|
-
key: "
|
|
621
|
+
key: "deregisterEvents",
|
|
541
622
|
value:
|
|
542
623
|
/**
|
|
543
|
-
*
|
|
544
|
-
* @returns {undefined}
|
|
545
|
-
*/
|
|
546
|
-
function listenToEvents() {
|
|
547
|
-
if (!this.hasSubscribedToEvents) {
|
|
548
|
-
// @ts-ignore
|
|
549
|
-
this.webex.internal.llm.on('event:relay.event', this.eventProcessor);
|
|
550
|
-
this.hasSubscribedToEvents = true;
|
|
551
|
-
}
|
|
552
|
-
}
|
|
553
|
-
|
|
554
|
-
/**
|
|
555
|
-
* Listen to websocket messages
|
|
624
|
+
* Deregister events and clean up
|
|
556
625
|
* @returns {void}
|
|
557
626
|
*/
|
|
558
|
-
|
|
559
|
-
key: "deregisterEvents",
|
|
560
|
-
value: function deregisterEvents() {
|
|
627
|
+
function deregisterEvents() {
|
|
561
628
|
this.areCaptionsEnabled = false;
|
|
629
|
+
this.keepTranscriptionSubscribed = false;
|
|
562
630
|
this.captionServiceId = undefined;
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
631
|
+
if (this.hasSubscribedToEvents) {
|
|
632
|
+
this.llmChannel.off('event:relay.event', this.eventProcessor);
|
|
633
|
+
this.hasSubscribedToEvents = false;
|
|
634
|
+
}
|
|
566
635
|
this.announceStatus = _constants.ANNOUNCE_STATUS.IDLE;
|
|
567
636
|
this.captionStatus = _constants.TURN_ON_CAPTION_STATUS.IDLE;
|
|
568
637
|
this.toggleManualCaptionStatus = _constants.TOGGLE_MANUAL_CAPTION_STATUS.IDLE;
|
|
569
638
|
this.currentSpokenLanguage = undefined;
|
|
570
639
|
this.currentCaptionLanguage = undefined;
|
|
571
640
|
}
|
|
641
|
+
|
|
642
|
+
/**
|
|
643
|
+
* Switch to a different LLM channel while preserving caption state.
|
|
644
|
+
* Used when transitioning between main meeting and practice session.
|
|
645
|
+
* - Preserves keepTranscriptionSubscribed and spokenLanguage state
|
|
646
|
+
* - Unsubscribes from old channel, subscribes to new channel
|
|
647
|
+
* - Re-announces and re-enables captions if they were on
|
|
648
|
+
* @param {LLMChannel} newLLMChannel - The new LLM channel to switch to
|
|
649
|
+
* @returns {Promise<void>}
|
|
650
|
+
*/
|
|
651
|
+
}, {
|
|
652
|
+
key: "switchLLMChannel",
|
|
653
|
+
value: (function () {
|
|
654
|
+
var _switchLLMChannel = (0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee3(newLLMChannel) {
|
|
655
|
+
var captionsWereOn, spokenLanguage;
|
|
656
|
+
return _regenerator.default.wrap(function (_context3) {
|
|
657
|
+
while (1) switch (_context3.prev = _context3.next) {
|
|
658
|
+
case 0:
|
|
659
|
+
// Save current state
|
|
660
|
+
captionsWereOn = this.keepTranscriptionSubscribed;
|
|
661
|
+
spokenLanguage = this.currentSpokenLanguage; // Unsubscribe from old channel
|
|
662
|
+
if (this.hasSubscribedToEvents && this.llmChannel) {
|
|
663
|
+
this.llmChannel.off('event:relay.event', this.eventProcessor);
|
|
664
|
+
this.hasSubscribedToEvents = false;
|
|
665
|
+
}
|
|
666
|
+
|
|
667
|
+
// Switch to new channel
|
|
668
|
+
this.llmChannel = newLLMChannel;
|
|
669
|
+
|
|
670
|
+
// Subscribe to new channel
|
|
671
|
+
this.llmChannel.on('event:relay.event', this.eventProcessor);
|
|
672
|
+
this.hasSubscribedToEvents = true;
|
|
673
|
+
|
|
674
|
+
// Reset announcement state for new connection
|
|
675
|
+
this.announceStatus = _constants.ANNOUNCE_STATUS.IDLE;
|
|
676
|
+
this.captionStatus = _constants.TURN_ON_CAPTION_STATUS.IDLE;
|
|
677
|
+
this.captionServiceId = undefined;
|
|
678
|
+
this.areCaptionsEnabled = false;
|
|
679
|
+
|
|
680
|
+
// Re-announce and re-enable captions if they were on
|
|
681
|
+
if (!captionsWereOn) {
|
|
682
|
+
_context3.next = 1;
|
|
683
|
+
break;
|
|
684
|
+
}
|
|
685
|
+
_context3.next = 1;
|
|
686
|
+
return this.turnOnCaptions(spokenLanguage);
|
|
687
|
+
case 1:
|
|
688
|
+
case "end":
|
|
689
|
+
return _context3.stop();
|
|
690
|
+
}
|
|
691
|
+
}, _callee3, this);
|
|
692
|
+
}));
|
|
693
|
+
function switchLLMChannel(_x2) {
|
|
694
|
+
return _switchLLMChannel.apply(this, arguments);
|
|
695
|
+
}
|
|
696
|
+
return switchLLMChannel;
|
|
697
|
+
}())
|
|
572
698
|
}]);
|
|
573
|
-
}(
|
|
699
|
+
}(_events.default);
|
|
574
700
|
var _default = exports.default = VoiceaChannel;
|
|
575
701
|
//# sourceMappingURL=voicea.js.map
|