@webex/internal-plugin-llm 3.11.0-next.7 → 3.11.0-next.8
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/constants.js +2 -1
- package/dist/constants.js.map +1 -1
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -1
- package/dist/llm.js +145 -33
- package/dist/llm.js.map +1 -1
- package/dist/llm.types.js +6 -0
- package/dist/llm.types.js.map +1 -1
- package/package.json +1 -1
- package/src/constants.ts +2 -0
- package/src/index.ts +2 -0
- package/src/llm.ts +98 -6
- package/src/llm.types.ts +11 -1
- package/test/unit/spec/llm.js +139 -2
package/dist/constants.js
CHANGED
|
@@ -4,7 +4,8 @@ var _Object$defineProperty = require("@babel/runtime-corejs2/core-js/object/defi
|
|
|
4
4
|
_Object$defineProperty(exports, "__esModule", {
|
|
5
5
|
value: true
|
|
6
6
|
});
|
|
7
|
-
exports.LLM = void 0;
|
|
7
|
+
exports.LLM = exports.DATA_CHANNEL_WITH_JWT_TOKEN = void 0;
|
|
8
8
|
// eslint-disable-next-line import/prefer-default-export
|
|
9
9
|
var LLM = exports.LLM = 'llm';
|
|
10
|
+
var DATA_CHANNEL_WITH_JWT_TOKEN = exports.DATA_CHANNEL_WITH_JWT_TOKEN = 'data-channel-with-jwt-token';
|
|
10
11
|
//# sourceMappingURL=constants.js.map
|
package/dist/constants.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["LLM","exports"],"sources":["constants.ts"],"sourcesContent":["// eslint-disable-next-line import/prefer-default-export\nexport const LLM = 'llm';\n"],"mappings":";;;;;;;AAAA;AACO,IAAMA,GAAG,GAAAC,OAAA,CAAAD,GAAA,GAAG,KAAK","ignoreList":[]}
|
|
1
|
+
{"version":3,"names":["LLM","exports","DATA_CHANNEL_WITH_JWT_TOKEN"],"sources":["constants.ts"],"sourcesContent":["// eslint-disable-next-line import/prefer-default-export\nexport const LLM = 'llm';\n\nexport const DATA_CHANNEL_WITH_JWT_TOKEN = 'data-channel-with-jwt-token';\n"],"mappings":";;;;;;;AAAA;AACO,IAAMA,GAAG,GAAAC,OAAA,CAAAD,GAAA,GAAG,KAAK;AAEjB,IAAME,2BAA2B,GAAAD,OAAA,CAAAC,2BAAA,GAAG,6BAA6B","ignoreList":[]}
|
package/dist/index.js
CHANGED
|
@@ -7,6 +7,12 @@ var _Object$getOwnPropertyDescriptor = require("@babel/runtime-corejs2/core-js/o
|
|
|
7
7
|
_Object$defineProperty(exports, "__esModule", {
|
|
8
8
|
value: true
|
|
9
9
|
});
|
|
10
|
+
_Object$defineProperty(exports, "DataChannelTokenType", {
|
|
11
|
+
enumerable: true,
|
|
12
|
+
get: function get() {
|
|
13
|
+
return _llm2.DataChannelTokenType;
|
|
14
|
+
}
|
|
15
|
+
});
|
|
10
16
|
_Object$defineProperty(exports, "default", {
|
|
11
17
|
enumerable: true,
|
|
12
18
|
get: function get() {
|
|
@@ -15,6 +21,7 @@ _Object$defineProperty(exports, "default", {
|
|
|
15
21
|
});
|
|
16
22
|
var WebexCore = _interopRequireWildcard(require("@webex/webex-core"));
|
|
17
23
|
var _llm = _interopRequireWildcard(require("./llm"));
|
|
24
|
+
var _llm2 = require("./llm.types");
|
|
18
25
|
function _interopRequireWildcard(e, t) { if ("function" == typeof _WeakMap) var r = new _WeakMap(), n = new _WeakMap(); return (_interopRequireWildcard = function _interopRequireWildcard(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 (var _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); }
|
|
19
26
|
WebexCore.registerInternalPlugin('llm', _llm.default, {
|
|
20
27
|
config: _llm.config
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["WebexCore","_interopRequireWildcard","require","_llm","e","t","_WeakMap","r","n","__esModule","o","i","f","__proto__","default","_typeof","has","get","set","_t","hasOwnProperty","call","_Object$defineProperty","_Object$getOwnPropertyDescriptor","registerInternalPlugin","LLMChannel","config"],"sources":["index.ts"],"sourcesContent":["import * as WebexCore from '@webex/webex-core';\nimport LLMChannel, {config} from './llm';\n\nWebexCore.registerInternalPlugin('llm', LLMChannel, {\n config,\n});\n\nexport {default} from './llm';\n"],"mappings":"
|
|
1
|
+
{"version":3,"names":["WebexCore","_interopRequireWildcard","require","_llm","_llm2","e","t","_WeakMap","r","n","__esModule","o","i","f","__proto__","default","_typeof","has","get","set","_t","hasOwnProperty","call","_Object$defineProperty","_Object$getOwnPropertyDescriptor","registerInternalPlugin","LLMChannel","config"],"sources":["index.ts"],"sourcesContent":["import * as WebexCore from '@webex/webex-core';\nimport LLMChannel, {config} from './llm';\nimport {DataChannelTokenType} from './llm.types';\n\nWebexCore.registerInternalPlugin('llm', LLMChannel, {\n config,\n});\n\nexport {DataChannelTokenType};\nexport {default} from './llm';\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAAA,IAAAA,SAAA,GAAAC,uBAAA,CAAAC,OAAA;AACA,IAAAC,IAAA,GAAAF,uBAAA,CAAAC,OAAA;AACA,IAAAE,KAAA,GAAAF,OAAA;AAAiD,SAAAD,wBAAAI,CAAA,EAAAC,CAAA,6BAAAC,QAAA,MAAAC,CAAA,OAAAD,QAAA,IAAAE,CAAA,OAAAF,QAAA,YAAAN,uBAAA,YAAAA,wBAAAI,CAAA,EAAAC,CAAA,SAAAA,CAAA,IAAAD,CAAA,IAAAA,CAAA,CAAAK,UAAA,SAAAL,CAAA,MAAAM,CAAA,EAAAC,CAAA,EAAAC,CAAA,KAAAC,SAAA,QAAAC,OAAA,EAAAV,CAAA,iBAAAA,CAAA,gBAAAW,OAAA,CAAAX,CAAA,0BAAAA,CAAA,SAAAQ,CAAA,MAAAF,CAAA,GAAAL,CAAA,GAAAG,CAAA,GAAAD,CAAA,QAAAG,CAAA,CAAAM,GAAA,CAAAZ,CAAA,UAAAM,CAAA,CAAAO,GAAA,CAAAb,CAAA,GAAAM,CAAA,CAAAQ,GAAA,CAAAd,CAAA,EAAAQ,CAAA,cAAAO,EAAA,IAAAf,CAAA,gBAAAe,EAAA,OAAAC,cAAA,CAAAC,IAAA,CAAAjB,CAAA,EAAAe,EAAA,OAAAR,CAAA,IAAAD,CAAA,GAAAY,sBAAA,KAAAC,gCAAA,CAAAnB,CAAA,EAAAe,EAAA,OAAAR,CAAA,CAAAM,GAAA,IAAAN,CAAA,CAAAO,GAAA,IAAAR,CAAA,CAAAE,CAAA,EAAAO,EAAA,EAAAR,CAAA,IAAAC,CAAA,CAAAO,EAAA,IAAAf,CAAA,CAAAe,EAAA,WAAAP,CAAA,KAAAR,CAAA,EAAAC,CAAA;AAEjDN,SAAS,CAACyB,sBAAsB,CAAC,KAAK,EAAEC,YAAU,EAAE;EAClDC,MAAM,EAANA;AACF,CAAC,CAAC","ignoreList":[]}
|
package/dist/llm.js
CHANGED
|
@@ -7,18 +7,19 @@ _Object$defineProperty(exports, "__esModule", {
|
|
|
7
7
|
value: true
|
|
8
8
|
});
|
|
9
9
|
exports.default = exports.config = void 0;
|
|
10
|
-
var
|
|
10
|
+
var _regenerator = _interopRequireDefault(require("@babel/runtime-corejs2/regenerator"));
|
|
11
|
+
var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/asyncToGenerator"));
|
|
11
12
|
var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/classCallCheck"));
|
|
13
|
+
var _createClass2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/createClass"));
|
|
12
14
|
var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/possibleConstructorReturn"));
|
|
13
15
|
var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/getPrototypeOf"));
|
|
14
16
|
var _inherits2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/inherits"));
|
|
15
|
-
var
|
|
17
|
+
var _defineProperty3 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/defineProperty"));
|
|
16
18
|
var _internalPluginMercury = _interopRequireDefault(require("@webex/internal-plugin-mercury"));
|
|
17
19
|
var _constants = require("./constants");
|
|
20
|
+
var _llm = require("./llm.types");
|
|
18
21
|
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)); }
|
|
19
|
-
function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.call(_Reflect$construct(Boolean, [], function () {})); } catch (t) {} return (_isNativeReflectConstruct = function _isNativeReflectConstruct() { return !!t; })(); } /* eslint-disable consistent-return */
|
|
20
|
-
// eslint-disable-next-line no-unused-vars
|
|
21
|
-
|
|
22
|
+
function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.call(_Reflect$construct(Boolean, [], function () {})); } catch (t) {} return (_isNativeReflectConstruct = function _isNativeReflectConstruct() { return !!t; })(); } /* eslint-disable consistent-return */ // eslint-disable-next-line no-unused-vars
|
|
22
23
|
var config = exports.config = {
|
|
23
24
|
llm: {
|
|
24
25
|
/**
|
|
@@ -61,45 +62,71 @@ var LLMChannel = exports.default = /*#__PURE__*/function (_ref) {
|
|
|
61
62
|
args[_key] = arguments[_key];
|
|
62
63
|
}
|
|
63
64
|
_this = _callSuper(this, LLMChannel, [].concat(args));
|
|
64
|
-
(0,
|
|
65
|
+
(0, _defineProperty3.default)(_this, "namespace", _constants.LLM);
|
|
65
66
|
/**
|
|
66
67
|
* If the LLM plugin has been registered and listening
|
|
67
68
|
* @instance
|
|
68
69
|
* @type {Boolean}
|
|
69
70
|
* @public
|
|
70
71
|
*/
|
|
71
|
-
(0,
|
|
72
|
-
(0,
|
|
73
|
-
(0,
|
|
74
|
-
(0,
|
|
72
|
+
(0, _defineProperty3.default)(_this, "webSocketUrl", void 0);
|
|
73
|
+
(0, _defineProperty3.default)(_this, "binding", void 0);
|
|
74
|
+
(0, _defineProperty3.default)(_this, "locusUrl", void 0);
|
|
75
|
+
(0, _defineProperty3.default)(_this, "datachannelUrl", void 0);
|
|
76
|
+
(0, _defineProperty3.default)(_this, "datachannelToken", void 0);
|
|
77
|
+
(0, _defineProperty3.default)(_this, "datachannelTokens", (0, _defineProperty3.default)((0, _defineProperty3.default)({}, _llm.DataChannelTokenType.Default, undefined), _llm.DataChannelTokenType.PracticeSession, undefined));
|
|
78
|
+
(0, _defineProperty3.default)(_this, "refreshHandler", void 0);
|
|
75
79
|
/**
|
|
76
80
|
* Register to the websocket
|
|
77
81
|
* @param {string} llmSocketUrl
|
|
82
|
+
* @param {string} datachannelToken
|
|
78
83
|
* @returns {Promise<void>}
|
|
79
84
|
*/
|
|
80
|
-
(0,
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
85
|
+
(0, _defineProperty3.default)(_this, "register", /*#__PURE__*/function () {
|
|
86
|
+
var _ref2 = (0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee(llmSocketUrl, datachannelToken) {
|
|
87
|
+
var isDataChannelTokenEnabled;
|
|
88
|
+
return _regenerator.default.wrap(function (_context) {
|
|
89
|
+
while (1) switch (_context.prev = _context.next) {
|
|
90
|
+
case 0:
|
|
91
|
+
_context.next = 1;
|
|
92
|
+
return _this.isDataChannelTokenEnabled();
|
|
93
|
+
case 1:
|
|
94
|
+
isDataChannelTokenEnabled = _context.sent;
|
|
95
|
+
return _context.abrupt("return", _this.request({
|
|
96
|
+
method: 'POST',
|
|
97
|
+
url: llmSocketUrl,
|
|
98
|
+
body: {
|
|
99
|
+
deviceUrl: _this.webex.internal.device.url
|
|
100
|
+
},
|
|
101
|
+
headers: isDataChannelTokenEnabled && datachannelToken ? {
|
|
102
|
+
'Data-Channel-Auth-Token': datachannelToken
|
|
103
|
+
} : {}
|
|
104
|
+
}).then(function (res) {
|
|
105
|
+
_this.webSocketUrl = res.body.webSocketUrl;
|
|
106
|
+
_this.binding = res.body.binding;
|
|
107
|
+
}).catch(function (error) {
|
|
108
|
+
_this.logger.error("Error connecting to websocket: ".concat(error));
|
|
109
|
+
throw error;
|
|
110
|
+
}));
|
|
111
|
+
case 2:
|
|
112
|
+
case "end":
|
|
113
|
+
return _context.stop();
|
|
114
|
+
}
|
|
115
|
+
}, _callee);
|
|
116
|
+
}));
|
|
117
|
+
return function (_x, _x2) {
|
|
118
|
+
return _ref2.apply(this, arguments);
|
|
119
|
+
};
|
|
120
|
+
}());
|
|
95
121
|
/**
|
|
96
122
|
* Register and connect to the websocket
|
|
97
123
|
* @param {string} locusUrl
|
|
98
124
|
* @param {string} datachannelUrl
|
|
125
|
+
* @param {string} datachannelToken
|
|
99
126
|
* @returns {Promise<void>}
|
|
100
127
|
*/
|
|
101
|
-
(0,
|
|
102
|
-
return _this.register(datachannelUrl).then(function () {
|
|
128
|
+
(0, _defineProperty3.default)(_this, "registerAndConnect", function (locusUrl, datachannelUrl, datachannelToken) {
|
|
129
|
+
return _this.register(datachannelUrl, datachannelToken).then(function () {
|
|
103
130
|
if (!locusUrl || !datachannelUrl) return undefined;
|
|
104
131
|
_this.locusUrl = locusUrl;
|
|
105
132
|
_this.datachannelUrl = datachannelUrl;
|
|
@@ -110,36 +137,53 @@ var LLMChannel = exports.default = /*#__PURE__*/function (_ref) {
|
|
|
110
137
|
* Tells if LLM socket is connected
|
|
111
138
|
* @returns {boolean} connected
|
|
112
139
|
*/
|
|
113
|
-
(0,
|
|
140
|
+
(0, _defineProperty3.default)(_this, "isConnected", function () {
|
|
114
141
|
return _this.connected;
|
|
115
142
|
});
|
|
116
143
|
/**
|
|
117
144
|
* Tells if LLM socket is binding
|
|
118
145
|
* @returns {string} binding
|
|
119
146
|
*/
|
|
120
|
-
(0,
|
|
147
|
+
(0, _defineProperty3.default)(_this, "getBinding", function () {
|
|
121
148
|
return _this.binding;
|
|
122
149
|
});
|
|
123
150
|
/**
|
|
124
151
|
* Get Locus URL for the connection
|
|
125
152
|
* @returns {string} locus Url
|
|
126
153
|
*/
|
|
127
|
-
(0,
|
|
154
|
+
(0, _defineProperty3.default)(_this, "getLocusUrl", function () {
|
|
128
155
|
return _this.locusUrl;
|
|
129
156
|
});
|
|
130
157
|
/**
|
|
131
158
|
* Get data channel URL for the connection
|
|
132
159
|
* @returns {string} data channel Url
|
|
133
160
|
*/
|
|
134
|
-
(0,
|
|
161
|
+
(0, _defineProperty3.default)(_this, "getDatachannelUrl", function () {
|
|
135
162
|
return _this.datachannelUrl;
|
|
136
163
|
});
|
|
164
|
+
/**
|
|
165
|
+
* Get data channel token for the connection
|
|
166
|
+
* @param {DataChannelTokenType} dataChannelTokenType
|
|
167
|
+
* @returns {string} data channel token
|
|
168
|
+
*/
|
|
169
|
+
(0, _defineProperty3.default)(_this, "getDatachannelToken", function (dataChannelTokenType) {
|
|
170
|
+
return _this.datachannelTokens[dataChannelTokenType];
|
|
171
|
+
});
|
|
172
|
+
/**
|
|
173
|
+
* Set data channel token for the connection
|
|
174
|
+
* @param {string} datachannelToken - data channel token
|
|
175
|
+
* @param {DataChannelTokenType} dataChannelTokenType
|
|
176
|
+
* @returns {void}
|
|
177
|
+
*/
|
|
178
|
+
(0, _defineProperty3.default)(_this, "setDatachannelToken", function (datachannelToken, dataChannelTokenType) {
|
|
179
|
+
_this.datachannelTokens[dataChannelTokenType] = datachannelToken;
|
|
180
|
+
});
|
|
137
181
|
/**
|
|
138
182
|
* Disconnects websocket connection
|
|
139
183
|
* @param {{code: number, reason: string}} options - The disconnect option object with code and reason
|
|
140
184
|
* @returns {Promise<void>}
|
|
141
185
|
*/
|
|
142
|
-
(0,
|
|
186
|
+
(0, _defineProperty3.default)(_this, "disconnectLLM", function (options) {
|
|
143
187
|
return _this.disconnect(options).then(function () {
|
|
144
188
|
_this.locusUrl = undefined;
|
|
145
189
|
_this.datachannelUrl = undefined;
|
|
@@ -150,6 +194,74 @@ var LLMChannel = exports.default = /*#__PURE__*/function (_ref) {
|
|
|
150
194
|
return _this;
|
|
151
195
|
}
|
|
152
196
|
(0, _inherits2.default)(LLMChannel, _ref);
|
|
153
|
-
return (0, _createClass2.default)(LLMChannel
|
|
197
|
+
return (0, _createClass2.default)(LLMChannel, [{
|
|
198
|
+
key: "setRefreshHandler",
|
|
199
|
+
value:
|
|
200
|
+
/**
|
|
201
|
+
* Set the handler used to refresh the DataChannel token
|
|
202
|
+
*
|
|
203
|
+
* @param {function} handler - Function that returns a refreshed token
|
|
204
|
+
* @returns {void}
|
|
205
|
+
*/
|
|
206
|
+
function setRefreshHandler(handler) {
|
|
207
|
+
this.refreshHandler = handler;
|
|
208
|
+
}
|
|
209
|
+
}, {
|
|
210
|
+
key: "refreshDataChannelToken",
|
|
211
|
+
value: (
|
|
212
|
+
/**
|
|
213
|
+
* Refresh the data channel token using the injected handler.
|
|
214
|
+
* Logs a descriptive error if the handler is missing or fails.
|
|
215
|
+
*
|
|
216
|
+
* @returns {Promise<string>} The refreshed token.
|
|
217
|
+
*/
|
|
218
|
+
function () {
|
|
219
|
+
var _refreshDataChannelToken = (0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee2() {
|
|
220
|
+
var error, res, _t;
|
|
221
|
+
return _regenerator.default.wrap(function (_context2) {
|
|
222
|
+
while (1) switch (_context2.prev = _context2.next) {
|
|
223
|
+
case 0:
|
|
224
|
+
if (this.refreshHandler) {
|
|
225
|
+
_context2.next = 1;
|
|
226
|
+
break;
|
|
227
|
+
}
|
|
228
|
+
error = new Error('LLM refreshHandler is not set');
|
|
229
|
+
this.logger.error("Error refreshing DataChannel token: ".concat(error.message));
|
|
230
|
+
throw error;
|
|
231
|
+
case 1:
|
|
232
|
+
_context2.prev = 1;
|
|
233
|
+
_context2.next = 2;
|
|
234
|
+
return this.refreshHandler();
|
|
235
|
+
case 2:
|
|
236
|
+
res = _context2.sent;
|
|
237
|
+
return _context2.abrupt("return", res);
|
|
238
|
+
case 3:
|
|
239
|
+
_context2.prev = 3;
|
|
240
|
+
_t = _context2["catch"](1);
|
|
241
|
+
this.logger.error("Error refreshing DataChannel token: ".concat(_t));
|
|
242
|
+
throw _t;
|
|
243
|
+
case 4:
|
|
244
|
+
case "end":
|
|
245
|
+
return _context2.stop();
|
|
246
|
+
}
|
|
247
|
+
}, _callee2, this, [[1, 3]]);
|
|
248
|
+
}));
|
|
249
|
+
function refreshDataChannelToken() {
|
|
250
|
+
return _refreshDataChannelToken.apply(this, arguments);
|
|
251
|
+
}
|
|
252
|
+
return refreshDataChannelToken;
|
|
253
|
+
}()
|
|
254
|
+
/**
|
|
255
|
+
* Returns true if data channel token is enabled, false otherwise
|
|
256
|
+
* @returns {Promise<boolean>} resolves with true if data channel token is enabled
|
|
257
|
+
*/
|
|
258
|
+
)
|
|
259
|
+
}, {
|
|
260
|
+
key: "isDataChannelTokenEnabled",
|
|
261
|
+
value: function isDataChannelTokenEnabled() {
|
|
262
|
+
// @ts-ignore
|
|
263
|
+
return this.webex.internal.feature.getFeature('developer', _constants.DATA_CHANNEL_WITH_JWT_TOKEN);
|
|
264
|
+
}
|
|
265
|
+
}]);
|
|
154
266
|
}(_internalPluginMercury.default);
|
|
155
267
|
//# sourceMappingURL=llm.js.map
|
package/dist/llm.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["_internalPluginMercury","_interopRequireDefault","require","_constants","_callSuper","t","o","e","_getPrototypeOf2","default","_possibleConstructorReturn2","_isNativeReflectConstruct","_Reflect$construct","constructor","apply","Boolean","prototype","valueOf","call","config","exports","llm","pingInterval","process","env","MERCURY_PING_INTERVAL","pongTimeout","MERCURY_PONG_TIMEOUT","backoffTimeMax","MERCURY_BACKOFF_TIME_MAX","backoffTimeReset","MERCURY_BACKOFF_TIME_RESET","forceCloseDelay","MERCURY_FORCE_CLOSE_DELAY","LLMChannel","_ref","_this","_classCallCheck2","_len","arguments","length","args","Array","_key","concat","_defineProperty2","LLM","llmSocketUrl","request","method","url","body","deviceUrl","webex","internal","device","then","res","webSocketUrl","binding","catch","error","logger","locusUrl","datachannelUrl","register","undefined","connect","connected","options","disconnect","_inherits2","_createClass2","Mercury"],"sources":["llm.ts"],"sourcesContent":["/* eslint-disable consistent-return */\n\nimport Mercury from '@webex/internal-plugin-mercury';\n\nimport {LLM} from './constants';\n// eslint-disable-next-line no-unused-vars\nimport {ILLMChannel} from './llm.types';\n\nexport const config = {\n llm: {\n /**\n * Milliseconds between pings sent up the socket\n * @type {number}\n */\n pingInterval: process.env.MERCURY_PING_INTERVAL || 15000,\n /**\n * Milliseconds to wait for a pong before declaring the connection dead\n * @type {number}\n */\n pongTimeout: process.env.MERCURY_PONG_TIMEOUT || 14000,\n /**\n * Maximum milliseconds between connection attempts\n * @type {Number}\n */\n backoffTimeMax: process.env.MERCURY_BACKOFF_TIME_MAX || 32000,\n /**\n * Initial milliseconds between connection attempts\n * @type {Number}\n */\n backoffTimeReset: process.env.MERCURY_BACKOFF_TIME_RESET || 1000,\n /**\n * Milliseconds to wait for a close frame before declaring the socket dead and\n * discarding it\n * @type {[type]}\n */\n forceCloseDelay: process.env.MERCURY_FORCE_CLOSE_DELAY || 2000,\n },\n};\n\n/**\n * LLMChannel to provide socket connections\n */\nexport default class LLMChannel extends (Mercury as any) implements ILLMChannel {\n namespace = LLM;\n\n /**\n * If the LLM plugin has been registered and listening\n * @instance\n * @type {Boolean}\n * @public\n */\n\n private webSocketUrl?: string;\n\n private binding?: string;\n\n private locusUrl?: string;\n\n private datachannelUrl?: string;\n\n /**\n * Register to the websocket\n * @param {string} llmSocketUrl\n * @returns {Promise<void>}\n */\n private register = (llmSocketUrl: string): Promise<void> =>\n this.request({\n method: 'POST',\n url: llmSocketUrl,\n body: {deviceUrl: this.webex.internal.device.url},\n })\n .then((res: {body: {webSocketUrl: string; binding: string}}) => {\n this.webSocketUrl = res.body.webSocketUrl;\n this.binding = res.body.binding;\n })\n .catch((error: any) => {\n this.logger.error(`Error connecting to websocket: ${error}`);\n throw error;\n });\n\n /**\n * Register and connect to the websocket\n * @param {string} locusUrl\n * @param {string} datachannelUrl\n * @returns {Promise<void>}\n */\n public registerAndConnect = (locusUrl: string, datachannelUrl: string): Promise<void> =>\n this.register(datachannelUrl).then(() => {\n if (!locusUrl || !datachannelUrl) return undefined;\n this.locusUrl = locusUrl;\n this.datachannelUrl = datachannelUrl;\n this.connect(this.webSocketUrl);\n });\n\n /**\n * Tells if LLM socket is connected\n * @returns {boolean} connected\n */\n public isConnected = (): boolean => this.connected;\n\n /**\n * Tells if LLM socket is binding\n * @returns {string} binding\n */\n public getBinding = (): string => this.binding;\n\n /**\n * Get Locus URL for the connection\n * @returns {string} locus Url\n */\n public getLocusUrl = (): string => this.locusUrl;\n\n /**\n * Get data channel URL for the connection\n * @returns {string} data channel Url\n */\n public getDatachannelUrl = (): string => this.datachannelUrl;\n\n /**\n * Disconnects websocket connection\n * @param {{code: number, reason: string}} options - The disconnect option object with code and reason\n * @returns {Promise<void>}\n */\n public disconnectLLM = (options: object): Promise<void> =>\n this.disconnect(options).then(() => {\n this.locusUrl = undefined;\n this.datachannelUrl = undefined;\n this.binding = undefined;\n this.webSocketUrl = undefined;\n });\n}\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"names":["_internalPluginMercury","_interopRequireDefault","require","_constants","_llm","_callSuper","t","o","e","_getPrototypeOf2","default","_possibleConstructorReturn2","_isNativeReflectConstruct","_Reflect$construct","constructor","apply","Boolean","prototype","valueOf","call","config","exports","llm","pingInterval","process","env","MERCURY_PING_INTERVAL","pongTimeout","MERCURY_PONG_TIMEOUT","backoffTimeMax","MERCURY_BACKOFF_TIME_MAX","backoffTimeReset","MERCURY_BACKOFF_TIME_RESET","forceCloseDelay","MERCURY_FORCE_CLOSE_DELAY","LLMChannel","_ref","_this","_classCallCheck2","_len","arguments","length","args","Array","_key","concat","_defineProperty3","LLM","DataChannelTokenType","Default","undefined","PracticeSession","_ref2","_asyncToGenerator2","_regenerator","mark","_callee","llmSocketUrl","datachannelToken","isDataChannelTokenEnabled","wrap","_context","prev","next","sent","abrupt","request","method","url","body","deviceUrl","webex","internal","device","headers","then","res","webSocketUrl","binding","catch","error","logger","stop","_x","_x2","locusUrl","datachannelUrl","register","connect","connected","dataChannelTokenType","datachannelTokens","options","disconnect","_inherits2","_createClass2","key","value","setRefreshHandler","handler","refreshHandler","_refreshDataChannelToken","_callee2","_t","_context2","Error","message","refreshDataChannelToken","feature","getFeature","DATA_CHANNEL_WITH_JWT_TOKEN","Mercury"],"sources":["llm.ts"],"sourcesContent":["/* eslint-disable consistent-return */\n\nimport Mercury from '@webex/internal-plugin-mercury';\n\nimport {LLM, DATA_CHANNEL_WITH_JWT_TOKEN} from './constants';\n// eslint-disable-next-line no-unused-vars\nimport {ILLMChannel, DataChannelTokenType} from './llm.types';\n\nexport const config = {\n llm: {\n /**\n * Milliseconds between pings sent up the socket\n * @type {number}\n */\n pingInterval: process.env.MERCURY_PING_INTERVAL || 15000,\n /**\n * Milliseconds to wait for a pong before declaring the connection dead\n * @type {number}\n */\n pongTimeout: process.env.MERCURY_PONG_TIMEOUT || 14000,\n /**\n * Maximum milliseconds between connection attempts\n * @type {Number}\n */\n backoffTimeMax: process.env.MERCURY_BACKOFF_TIME_MAX || 32000,\n /**\n * Initial milliseconds between connection attempts\n * @type {Number}\n */\n backoffTimeReset: process.env.MERCURY_BACKOFF_TIME_RESET || 1000,\n /**\n * Milliseconds to wait for a close frame before declaring the socket dead and\n * discarding it\n * @type {[type]}\n */\n forceCloseDelay: process.env.MERCURY_FORCE_CLOSE_DELAY || 2000,\n },\n};\n\n/**\n * LLMChannel to provide socket connections\n */\nexport default class LLMChannel extends (Mercury as any) implements ILLMChannel {\n namespace = LLM;\n\n /**\n * If the LLM plugin has been registered and listening\n * @instance\n * @type {Boolean}\n * @public\n */\n\n private webSocketUrl?: string;\n\n private binding?: string;\n\n private locusUrl?: string;\n\n private datachannelUrl?: string;\n\n private datachannelToken?: string;\n\n private datachannelTokens: Record<DataChannelTokenType, string> = {\n [DataChannelTokenType.Default]: undefined,\n [DataChannelTokenType.PracticeSession]: undefined,\n };\n\n private refreshHandler?: () => Promise<{\n body: {datachannelToken: string; datachannelTokenType: DataChannelTokenType};\n }>;\n\n /**\n * Register to the websocket\n * @param {string} llmSocketUrl\n * @param {string} datachannelToken\n * @returns {Promise<void>}\n */\n private register = async (llmSocketUrl: string, datachannelToken?: string): Promise<void> => {\n const isDataChannelTokenEnabled = await this.isDataChannelTokenEnabled();\n\n return this.request({\n method: 'POST',\n url: llmSocketUrl,\n body: {deviceUrl: this.webex.internal.device.url},\n headers:\n isDataChannelTokenEnabled && datachannelToken\n ? {'Data-Channel-Auth-Token': datachannelToken}\n : {},\n })\n .then((res: {body: {webSocketUrl: string; binding: string}}) => {\n this.webSocketUrl = res.body.webSocketUrl;\n this.binding = res.body.binding;\n })\n .catch((error: any) => {\n this.logger.error(`Error connecting to websocket: ${error}`);\n throw error;\n });\n };\n\n /**\n * Register and connect to the websocket\n * @param {string} locusUrl\n * @param {string} datachannelUrl\n * @param {string} datachannelToken\n * @returns {Promise<void>}\n */\n public registerAndConnect = (\n locusUrl: string,\n datachannelUrl: string,\n datachannelToken?: string\n ): Promise<void> =>\n this.register(datachannelUrl, datachannelToken).then(() => {\n if (!locusUrl || !datachannelUrl) return undefined;\n this.locusUrl = locusUrl;\n this.datachannelUrl = datachannelUrl;\n this.connect(this.webSocketUrl);\n });\n\n /**\n * Tells if LLM socket is connected\n * @returns {boolean} connected\n */\n public isConnected = (): boolean => this.connected;\n\n /**\n * Tells if LLM socket is binding\n * @returns {string} binding\n */\n public getBinding = (): string => this.binding;\n\n /**\n * Get Locus URL for the connection\n * @returns {string} locus Url\n */\n public getLocusUrl = (): string => this.locusUrl;\n\n /**\n * Get data channel URL for the connection\n * @returns {string} data channel Url\n */\n public getDatachannelUrl = (): string => this.datachannelUrl;\n\n /**\n * Get data channel token for the connection\n * @param {DataChannelTokenType} dataChannelTokenType\n * @returns {string} data channel token\n */\n public getDatachannelToken = (dataChannelTokenType: DataChannelTokenType): string => {\n return this.datachannelTokens[dataChannelTokenType];\n };\n\n /**\n * Set data channel token for the connection\n * @param {string} datachannelToken - data channel token\n * @param {DataChannelTokenType} dataChannelTokenType\n * @returns {void}\n */\n public setDatachannelToken = (\n datachannelToken: string,\n dataChannelTokenType: DataChannelTokenType\n ): void => {\n this.datachannelTokens[dataChannelTokenType] = datachannelToken;\n };\n\n /**\n * Set the handler used to refresh the DataChannel token\n *\n * @param {function} handler - Function that returns a refreshed token\n * @returns {void}\n */\n public setRefreshHandler(\n handler: () => Promise<{\n body: {datachannelToken: string; datachannelTokenType: DataChannelTokenType};\n }>\n ) {\n this.refreshHandler = handler;\n }\n\n /**\n * Disconnects websocket connection\n * @param {{code: number, reason: string}} options - The disconnect option object with code and reason\n * @returns {Promise<void>}\n */\n public disconnectLLM = (options: object): Promise<void> =>\n this.disconnect(options).then(() => {\n this.locusUrl = undefined;\n this.datachannelUrl = undefined;\n this.binding = undefined;\n this.webSocketUrl = undefined;\n });\n\n /**\n * Refresh the data channel token using the injected handler.\n * Logs a descriptive error if the handler is missing or fails.\n *\n * @returns {Promise<string>} The refreshed token.\n */\n public async refreshDataChannelToken() {\n if (!this.refreshHandler) {\n const error = new Error('LLM refreshHandler is not set');\n this.logger.error(`Error refreshing DataChannel token: ${error.message}`);\n throw error;\n }\n\n try {\n const res = await this.refreshHandler();\n\n return res;\n } catch (error: any) {\n this.logger.error(`Error refreshing DataChannel token: ${error}`);\n throw error;\n }\n }\n\n /**\n * Returns true if data channel token is enabled, false otherwise\n * @returns {Promise<boolean>} resolves with true if data channel token is enabled\n */\n public isDataChannelTokenEnabled(): Promise<boolean> {\n // @ts-ignore\n return this.webex.internal.feature.getFeature('developer', DATA_CHANNEL_WITH_JWT_TOKEN);\n }\n}\n"],"mappings":"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","ignoreList":[]}
|
package/dist/llm.types.js
CHANGED
|
@@ -4,4 +4,10 @@ var _Object$defineProperty = require("@babel/runtime-corejs2/core-js/object/defi
|
|
|
4
4
|
_Object$defineProperty(exports, "__esModule", {
|
|
5
5
|
value: true
|
|
6
6
|
});
|
|
7
|
+
exports.DataChannelTokenType = void 0;
|
|
8
|
+
var DataChannelTokenType = exports.DataChannelTokenType = /*#__PURE__*/function (DataChannelTokenType) {
|
|
9
|
+
DataChannelTokenType["Default"] = "default";
|
|
10
|
+
DataChannelTokenType["PracticeSession"] = "practiceSession";
|
|
11
|
+
return DataChannelTokenType;
|
|
12
|
+
}({}); // eslint-disable-next-line import/prefer-default-export
|
|
7
13
|
//# sourceMappingURL=llm.types.js.map
|
package/dist/llm.types.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":[],"sources":["llm.types.ts"],"sourcesContent":["interface ILLMChannel {\n registerAndConnect: (locusUrl: string
|
|
1
|
+
{"version":3,"names":["DataChannelTokenType","exports"],"sources":["llm.types.ts"],"sourcesContent":["interface ILLMChannel {\n registerAndConnect: (\n locusUrl: string,\n datachannelUrl: string,\n datachannelToken?: string\n ) => Promise<void>;\n isConnected: () => boolean;\n getBinding: () => string;\n getLocusUrl: () => string;\n disconnectLLM: (options: {code: number; reason: string}) => Promise<void>;\n}\n\nexport enum DataChannelTokenType {\n Default = 'default',\n PracticeSession = 'practiceSession',\n}\n\n// eslint-disable-next-line import/prefer-default-export\nexport type {ILLMChannel};\n"],"mappings":";;;;;;;IAYYA,oBAAoB,GAAAC,OAAA,CAAAD,oBAAA,0BAApBA,oBAAoB;EAApBA,oBAAoB;EAApBA,oBAAoB;EAAA,OAApBA,oBAAoB;AAAA,OAKhC","ignoreList":[]}
|
package/package.json
CHANGED
package/src/constants.ts
CHANGED
package/src/index.ts
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import * as WebexCore from '@webex/webex-core';
|
|
2
2
|
import LLMChannel, {config} from './llm';
|
|
3
|
+
import {DataChannelTokenType} from './llm.types';
|
|
3
4
|
|
|
4
5
|
WebexCore.registerInternalPlugin('llm', LLMChannel, {
|
|
5
6
|
config,
|
|
6
7
|
});
|
|
7
8
|
|
|
9
|
+
export {DataChannelTokenType};
|
|
8
10
|
export {default} from './llm';
|
package/src/llm.ts
CHANGED
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
import Mercury from '@webex/internal-plugin-mercury';
|
|
4
4
|
|
|
5
|
-
import {LLM} from './constants';
|
|
5
|
+
import {LLM, DATA_CHANNEL_WITH_JWT_TOKEN} from './constants';
|
|
6
6
|
// eslint-disable-next-line no-unused-vars
|
|
7
|
-
import {ILLMChannel} from './llm.types';
|
|
7
|
+
import {ILLMChannel, DataChannelTokenType} from './llm.types';
|
|
8
8
|
|
|
9
9
|
export const config = {
|
|
10
10
|
llm: {
|
|
@@ -58,16 +58,34 @@ export default class LLMChannel extends (Mercury as any) implements ILLMChannel
|
|
|
58
58
|
|
|
59
59
|
private datachannelUrl?: string;
|
|
60
60
|
|
|
61
|
+
private datachannelToken?: string;
|
|
62
|
+
|
|
63
|
+
private datachannelTokens: Record<DataChannelTokenType, string> = {
|
|
64
|
+
[DataChannelTokenType.Default]: undefined,
|
|
65
|
+
[DataChannelTokenType.PracticeSession]: undefined,
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
private refreshHandler?: () => Promise<{
|
|
69
|
+
body: {datachannelToken: string; datachannelTokenType: DataChannelTokenType};
|
|
70
|
+
}>;
|
|
71
|
+
|
|
61
72
|
/**
|
|
62
73
|
* Register to the websocket
|
|
63
74
|
* @param {string} llmSocketUrl
|
|
75
|
+
* @param {string} datachannelToken
|
|
64
76
|
* @returns {Promise<void>}
|
|
65
77
|
*/
|
|
66
|
-
private register = (llmSocketUrl: string): Promise<void> =>
|
|
67
|
-
this.
|
|
78
|
+
private register = async (llmSocketUrl: string, datachannelToken?: string): Promise<void> => {
|
|
79
|
+
const isDataChannelTokenEnabled = await this.isDataChannelTokenEnabled();
|
|
80
|
+
|
|
81
|
+
return this.request({
|
|
68
82
|
method: 'POST',
|
|
69
83
|
url: llmSocketUrl,
|
|
70
84
|
body: {deviceUrl: this.webex.internal.device.url},
|
|
85
|
+
headers:
|
|
86
|
+
isDataChannelTokenEnabled && datachannelToken
|
|
87
|
+
? {'Data-Channel-Auth-Token': datachannelToken}
|
|
88
|
+
: {},
|
|
71
89
|
})
|
|
72
90
|
.then((res: {body: {webSocketUrl: string; binding: string}}) => {
|
|
73
91
|
this.webSocketUrl = res.body.webSocketUrl;
|
|
@@ -77,15 +95,21 @@ export default class LLMChannel extends (Mercury as any) implements ILLMChannel
|
|
|
77
95
|
this.logger.error(`Error connecting to websocket: ${error}`);
|
|
78
96
|
throw error;
|
|
79
97
|
});
|
|
98
|
+
};
|
|
80
99
|
|
|
81
100
|
/**
|
|
82
101
|
* Register and connect to the websocket
|
|
83
102
|
* @param {string} locusUrl
|
|
84
103
|
* @param {string} datachannelUrl
|
|
104
|
+
* @param {string} datachannelToken
|
|
85
105
|
* @returns {Promise<void>}
|
|
86
106
|
*/
|
|
87
|
-
public registerAndConnect = (
|
|
88
|
-
|
|
107
|
+
public registerAndConnect = (
|
|
108
|
+
locusUrl: string,
|
|
109
|
+
datachannelUrl: string,
|
|
110
|
+
datachannelToken?: string
|
|
111
|
+
): Promise<void> =>
|
|
112
|
+
this.register(datachannelUrl, datachannelToken).then(() => {
|
|
89
113
|
if (!locusUrl || !datachannelUrl) return undefined;
|
|
90
114
|
this.locusUrl = locusUrl;
|
|
91
115
|
this.datachannelUrl = datachannelUrl;
|
|
@@ -116,6 +140,42 @@ export default class LLMChannel extends (Mercury as any) implements ILLMChannel
|
|
|
116
140
|
*/
|
|
117
141
|
public getDatachannelUrl = (): string => this.datachannelUrl;
|
|
118
142
|
|
|
143
|
+
/**
|
|
144
|
+
* Get data channel token for the connection
|
|
145
|
+
* @param {DataChannelTokenType} dataChannelTokenType
|
|
146
|
+
* @returns {string} data channel token
|
|
147
|
+
*/
|
|
148
|
+
public getDatachannelToken = (dataChannelTokenType: DataChannelTokenType): string => {
|
|
149
|
+
return this.datachannelTokens[dataChannelTokenType];
|
|
150
|
+
};
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* Set data channel token for the connection
|
|
154
|
+
* @param {string} datachannelToken - data channel token
|
|
155
|
+
* @param {DataChannelTokenType} dataChannelTokenType
|
|
156
|
+
* @returns {void}
|
|
157
|
+
*/
|
|
158
|
+
public setDatachannelToken = (
|
|
159
|
+
datachannelToken: string,
|
|
160
|
+
dataChannelTokenType: DataChannelTokenType
|
|
161
|
+
): void => {
|
|
162
|
+
this.datachannelTokens[dataChannelTokenType] = datachannelToken;
|
|
163
|
+
};
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
* Set the handler used to refresh the DataChannel token
|
|
167
|
+
*
|
|
168
|
+
* @param {function} handler - Function that returns a refreshed token
|
|
169
|
+
* @returns {void}
|
|
170
|
+
*/
|
|
171
|
+
public setRefreshHandler(
|
|
172
|
+
handler: () => Promise<{
|
|
173
|
+
body: {datachannelToken: string; datachannelTokenType: DataChannelTokenType};
|
|
174
|
+
}>
|
|
175
|
+
) {
|
|
176
|
+
this.refreshHandler = handler;
|
|
177
|
+
}
|
|
178
|
+
|
|
119
179
|
/**
|
|
120
180
|
* Disconnects websocket connection
|
|
121
181
|
* @param {{code: number, reason: string}} options - The disconnect option object with code and reason
|
|
@@ -128,4 +188,36 @@ export default class LLMChannel extends (Mercury as any) implements ILLMChannel
|
|
|
128
188
|
this.binding = undefined;
|
|
129
189
|
this.webSocketUrl = undefined;
|
|
130
190
|
});
|
|
191
|
+
|
|
192
|
+
/**
|
|
193
|
+
* Refresh the data channel token using the injected handler.
|
|
194
|
+
* Logs a descriptive error if the handler is missing or fails.
|
|
195
|
+
*
|
|
196
|
+
* @returns {Promise<string>} The refreshed token.
|
|
197
|
+
*/
|
|
198
|
+
public async refreshDataChannelToken() {
|
|
199
|
+
if (!this.refreshHandler) {
|
|
200
|
+
const error = new Error('LLM refreshHandler is not set');
|
|
201
|
+
this.logger.error(`Error refreshing DataChannel token: ${error.message}`);
|
|
202
|
+
throw error;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
try {
|
|
206
|
+
const res = await this.refreshHandler();
|
|
207
|
+
|
|
208
|
+
return res;
|
|
209
|
+
} catch (error: any) {
|
|
210
|
+
this.logger.error(`Error refreshing DataChannel token: ${error}`);
|
|
211
|
+
throw error;
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
/**
|
|
216
|
+
* Returns true if data channel token is enabled, false otherwise
|
|
217
|
+
* @returns {Promise<boolean>} resolves with true if data channel token is enabled
|
|
218
|
+
*/
|
|
219
|
+
public isDataChannelTokenEnabled(): Promise<boolean> {
|
|
220
|
+
// @ts-ignore
|
|
221
|
+
return this.webex.internal.feature.getFeature('developer', DATA_CHANNEL_WITH_JWT_TOKEN);
|
|
222
|
+
}
|
|
131
223
|
}
|
package/src/llm.types.ts
CHANGED
|
@@ -1,9 +1,19 @@
|
|
|
1
1
|
interface ILLMChannel {
|
|
2
|
-
registerAndConnect: (
|
|
2
|
+
registerAndConnect: (
|
|
3
|
+
locusUrl: string,
|
|
4
|
+
datachannelUrl: string,
|
|
5
|
+
datachannelToken?: string
|
|
6
|
+
) => Promise<void>;
|
|
3
7
|
isConnected: () => boolean;
|
|
4
8
|
getBinding: () => string;
|
|
5
9
|
getLocusUrl: () => string;
|
|
6
10
|
disconnectLLM: (options: {code: number; reason: string}) => Promise<void>;
|
|
7
11
|
}
|
|
12
|
+
|
|
13
|
+
export enum DataChannelTokenType {
|
|
14
|
+
Default = 'default',
|
|
15
|
+
PracticeSession = 'practiceSession',
|
|
16
|
+
}
|
|
17
|
+
|
|
8
18
|
// eslint-disable-next-line import/prefer-default-export
|
|
9
19
|
export type {ILLMChannel};
|
package/test/unit/spec/llm.js
CHANGED
|
@@ -19,6 +19,11 @@ describe('plugin-llm', () => {
|
|
|
19
19
|
},
|
|
20
20
|
});
|
|
21
21
|
|
|
22
|
+
webex.internal.feature = {
|
|
23
|
+
setFeature: sinon.stub().resolves({value: true}),
|
|
24
|
+
getFeature: sinon.stub().resolves(true),
|
|
25
|
+
};
|
|
26
|
+
|
|
22
27
|
llmService = webex.internal.llm;
|
|
23
28
|
llmService.connect = sinon.stub().callsFake(() => {
|
|
24
29
|
llmService.connected = true;
|
|
@@ -56,10 +61,50 @@ describe('plugin-llm', () => {
|
|
|
56
61
|
await llmService.registerAndConnect();
|
|
57
62
|
assert.equal(llmService.isConnected(), false);
|
|
58
63
|
});
|
|
64
|
+
|
|
65
|
+
it('registers connection with token', async () => {
|
|
66
|
+
llmService.register = sinon.stub().resolves({
|
|
67
|
+
body: {
|
|
68
|
+
binding: 'binding',
|
|
69
|
+
webSocketUrl: 'url',
|
|
70
|
+
},
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
assert.equal(llmService.isConnected(), false);
|
|
74
|
+
|
|
75
|
+
await llmService.registerAndConnect(locusUrl, datachannelUrl, 'abc123');
|
|
76
|
+
|
|
77
|
+
sinon.assert.calledOnceWithExactly(
|
|
78
|
+
llmService.register,
|
|
79
|
+
datachannelUrl,
|
|
80
|
+
'abc123'
|
|
81
|
+
);
|
|
82
|
+
|
|
83
|
+
assert.equal(llmService.isConnected(), true);
|
|
84
|
+
});
|
|
59
85
|
});
|
|
60
86
|
|
|
61
87
|
describe('#register', () => {
|
|
62
|
-
|
|
88
|
+
beforeEach(() => {
|
|
89
|
+
llmService.isDataChannelTokenEnabled = sinon.stub();
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
it('registers connection with token header', async () => {
|
|
93
|
+
llmService.isDataChannelTokenEnabled.resolves(true);
|
|
94
|
+
await llmService.register(datachannelUrl, 'abc123');
|
|
95
|
+
|
|
96
|
+
sinon.assert.calledOnceWithExactly(
|
|
97
|
+
llmService.request,
|
|
98
|
+
sinon.match({
|
|
99
|
+
method: 'POST',
|
|
100
|
+
url: `${datachannelUrl}`,
|
|
101
|
+
body: {deviceUrl: webex.internal.device.url},
|
|
102
|
+
headers: {'Data-Channel-Auth-Token': 'abc123'},
|
|
103
|
+
})
|
|
104
|
+
);
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
it('registers connection without token header when none provided', async () => {
|
|
63
108
|
await llmService.register(datachannelUrl);
|
|
64
109
|
|
|
65
110
|
sinon.assert.calledOnceWithExactly(
|
|
@@ -68,13 +113,28 @@ describe('plugin-llm', () => {
|
|
|
68
113
|
method: 'POST',
|
|
69
114
|
url: `${datachannelUrl}`,
|
|
70
115
|
body: {deviceUrl: webex.internal.device.url},
|
|
116
|
+
headers: {},
|
|
71
117
|
})
|
|
72
118
|
);
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
it('registers connection without token header when toggle disabled', async () => {
|
|
122
|
+
llmService.isDataChannelTokenEnabled.resolves(false);
|
|
73
123
|
|
|
74
|
-
|
|
124
|
+
await llmService.register(datachannelUrl,'abc123');
|
|
125
|
+
sinon.assert.calledOnceWithExactly(
|
|
126
|
+
llmService.request,
|
|
127
|
+
sinon.match({
|
|
128
|
+
method: 'POST',
|
|
129
|
+
url: `${datachannelUrl}`,
|
|
130
|
+
body: {deviceUrl: webex.internal.device.url},
|
|
131
|
+
headers: {},
|
|
132
|
+
})
|
|
133
|
+
);
|
|
75
134
|
});
|
|
76
135
|
});
|
|
77
136
|
|
|
137
|
+
|
|
78
138
|
describe('#getLocusUrl', () => {
|
|
79
139
|
it('gets LocusUrl', async () => {
|
|
80
140
|
llmService.register = sinon.stub().resolves({
|
|
@@ -149,5 +209,82 @@ describe('plugin-llm', () => {
|
|
|
149
209
|
await expect(instance.disconnectLLM({})).rejects.toThrow('Disconnect failed');
|
|
150
210
|
});
|
|
151
211
|
});
|
|
212
|
+
|
|
213
|
+
describe('#setRefreshHandler', () => {
|
|
214
|
+
it('stores the provided handler', () => {
|
|
215
|
+
const handler = sinon.stub().resolves({ body: { datachannelToken: 'newToken' } });
|
|
216
|
+
llmService.setRefreshHandler(handler);
|
|
217
|
+
|
|
218
|
+
// @ts-ignore
|
|
219
|
+
assert.equal(llmService.refreshHandler, handler);
|
|
220
|
+
});
|
|
221
|
+
});
|
|
222
|
+
|
|
223
|
+
describe('#isDataChannelTokenEnabled', () => {
|
|
224
|
+
it('works correctly', async () => {
|
|
225
|
+
webex.internal.feature.getFeature.returns(true);
|
|
226
|
+
|
|
227
|
+
const result = await llmService.isDataChannelTokenEnabled();
|
|
228
|
+
|
|
229
|
+
sinon.assert.calledOnceWithExactly(
|
|
230
|
+
webex.internal.feature.getFeature,
|
|
231
|
+
'developer',
|
|
232
|
+
'data-channel-with-jwt-token'
|
|
233
|
+
);
|
|
234
|
+
|
|
235
|
+
assert.equal(result, true);
|
|
236
|
+
});
|
|
237
|
+
});
|
|
238
|
+
|
|
239
|
+
describe('#refreshDataChannelToken', () => {
|
|
240
|
+
it('throws if no handler is set', async () => {
|
|
241
|
+
try {
|
|
242
|
+
await llmService.refreshDataChannelToken();
|
|
243
|
+
assert.fail('Should have thrown');
|
|
244
|
+
} catch (err) {
|
|
245
|
+
assert.match(err.message, 'LLM refreshHandler is not set');
|
|
246
|
+
}
|
|
247
|
+
});
|
|
248
|
+
|
|
249
|
+
it('returns token when handler resolves', async () => {
|
|
250
|
+
const mockToken = { body: { datachannelToken: 'newToken' ,isPracticeSession: false} }
|
|
251
|
+
const handler = sinon.stub().resolves(mockToken);
|
|
252
|
+
llmService.setRefreshHandler(handler);
|
|
253
|
+
|
|
254
|
+
const token = await llmService.refreshDataChannelToken();
|
|
255
|
+
assert.equal(token, mockToken);
|
|
256
|
+
sinon.assert.calledOnce(handler);
|
|
257
|
+
});
|
|
258
|
+
|
|
259
|
+
it('logs and rethrows when handler rejects', async () => {
|
|
260
|
+
const handler = sinon.stub().rejects(new Error('throw error'));
|
|
261
|
+
|
|
262
|
+
const loggerSpy = llmService.logger.error;
|
|
263
|
+
|
|
264
|
+
llmService.setRefreshHandler(handler);
|
|
265
|
+
|
|
266
|
+
try {
|
|
267
|
+
await llmService.refreshDataChannelToken();
|
|
268
|
+
assert.fail('Should have thrown');
|
|
269
|
+
} catch (err) {
|
|
270
|
+
assert.match(err.message, /throw error/);
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
sinon.assert.calledOnce(loggerSpy);
|
|
274
|
+
sinon.assert.calledWithMatch(
|
|
275
|
+
loggerSpy,
|
|
276
|
+
sinon.match("Error refreshing DataChannel token: Error: throw error")
|
|
277
|
+
);
|
|
278
|
+
});
|
|
279
|
+
});
|
|
280
|
+
|
|
281
|
+
describe('#getDatachannelToken / #setDatachannelToken', () => {
|
|
282
|
+
it('sets and gets datachannel token', () => {
|
|
283
|
+
llmService.setDatachannelToken('abc123','default');
|
|
284
|
+
assert.equal(llmService.getDatachannelToken('default'), 'abc123');
|
|
285
|
+
llmService.setDatachannelToken('123abc','practiceSession');
|
|
286
|
+
assert.equal(llmService.getDatachannelToken('practiceSession'), '123abc');
|
|
287
|
+
});
|
|
288
|
+
});
|
|
152
289
|
});
|
|
153
290
|
});
|